SPT-AKI 3.5.x

This commit is contained in:
SamSWAT 2023-06-21 00:59:14 +03:00
parent 1bdddc3dc5
commit c6576c0e11
8 changed files with 159 additions and 91 deletions

View File

@ -1,22 +0,0 @@
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
namespace SamSWAT.HeliCrash.Json
{
public class GeneratedContainer
{
public string Id { get; set; }
public string Root { get; set; }
public List<ItemInfo> Items { get; set; }
}
public class ItemInfo
{
public string _id { get; set; }
public string _tpl { get; set; }
public string parentId { get; set; }
public string slotId { get; set; }
public LocationInGrid location { get; set; }
public JObject upd { get; set; }
}
}

View File

@ -1,82 +1,37 @@
using Aki.Common.Http; using Comfort.Common;
using Comfort.Common;
using EFT; using EFT;
using EFT.Interactive; using EFT.Interactive;
using EFT.InventoryLogic;
using Newtonsoft.Json;
using SamSWAT.HeliCrash.Json;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Aki.Custom.Airdrops.Utils;
using UnityEngine; using UnityEngine;
namespace SamSWAT.HeliCrash namespace SamSWAT.HeliCrash
{ {
public class HeliCrash : MonoBehaviour public class HeliCrash : MonoBehaviour
{ {
private AssetBundle _uh60Bundle; private AssetBundle _heliBundle;
private LootableContainer _choppaContainer;
private List<ResourceKey> _resources;
private string _playerLocation;
public async void Init(string location) public async void Init(string location)
{ {
_playerLocation = location; var heliLocation = GetHeliCrashLocation(location);
var choppa = Instantiate(await LoadChoppaAsync(), heliLocation.Position, Quaternion.Euler(heliLocation.Rotation));
var container = choppa.GetComponentInChildren<LootableContainer>();
Location heliLocation = GetHeliCrashLocation(); var itemCrate = Utils.CreateItem("goofyahcontainer", "6223349b3136504a544d1608");
var _choppa = Instantiate(await LoadChoppaAsync(), heliLocation.Position, Quaternion.Euler(heliLocation.Rotation)); LootItem.CreateLootContainer(container, itemCrate, "Heavy crate", Singleton<GameWorld>.Instance);
_choppaContainer = _choppa.GetComponentInChildren<LootableContainer>();
Item itemCrate = Singleton<ItemFactory>.Instance.CreateItem("goofyahcontainer", "61a89e5445a2672acf66c877", null); new ItemFactoryUtil().AddLoot(container);
LootItem.CreateLootContainer(_choppaContainer, itemCrate, "Heavy crate", Singleton<GameWorld>.Instance);
await Task.Run(() => GenerateLoot());
await Singleton<PoolManager>.Instance.LoadBundlesAndCreatePools(PoolManager.PoolsCategory.Raid, PoolManager.AssemblyType.Local, _resources.ToArray(), JobPriority.Low, null, default);
} }
void OnDestroy() private void OnDestroy()
{ {
_uh60Bundle.Unload(true); _heliBundle.Unload(true);
} }
private void GenerateLoot() private Location GetHeliCrashLocation(string location)
{ {
var itemFactory = Singleton<ItemFactory>.Instance; switch (location)
var json = RequestHandler.GetJson("/client/helicrash/getLoot");
var akiContainer = JsonConvert.DeserializeObject<GeneratedContainer>(json);
_resources = new List<ResourceKey>();
for (int i = 1; i < akiContainer.Items.Count; i++)
{
var item = akiContainer.Items[i];
if (item.slotId != "main")
continue;
Item actualItem;
if (Array.Exists(itemFactory.SavedPresets, x => x.Encyclopedia == item._tpl))
{
actualItem = itemFactory.GetPresetItem(item._tpl);
_resources.AddRange(actualItem.GetAllItems().Select(x => x.Template).SelectMany(x => x.AllResources));
}
else
{
actualItem = itemFactory.CreateItem(item._id, item._tpl, null);
_resources.AddRange(actualItem.Template.AllResources);
}
if (item.upd != null)
actualItem.StackObjectsCount = item.upd.Value<int>("StackObjectsCount");
_choppaContainer.ItemOwner.MainStorage[0].Add(actualItem, item.location, false);
}
}
private Location GetHeliCrashLocation()
{
switch (_playerLocation)
{ {
case "bigmap": case "bigmap":
{ {
@ -102,6 +57,10 @@ namespace SamSWAT.HeliCrash
{ {
return PickRandom(Plugin.HeliCrashLocations.Lighthouse); return PickRandom(Plugin.HeliCrashLocations.Lighthouse);
} }
case "TarkovStreets":
{
return PickRandom(Plugin.HeliCrashLocations.StreetsOfTarkov);
}
case "develop": case "develop":
{ {
return PickRandom(Plugin.HeliCrashLocations.Develop); return PickRandom(Plugin.HeliCrashLocations.Develop);
@ -119,15 +78,15 @@ namespace SamSWAT.HeliCrash
while (!bundleLoadRequest.isDone) while (!bundleLoadRequest.isDone)
await Task.Yield(); await Task.Yield();
_uh60Bundle = bundleLoadRequest.assetBundle; _heliBundle = bundleLoadRequest.assetBundle;
if (_uh60Bundle == null) if (_heliBundle == null)
{ {
Debug.LogError("[SamSWAT.HeliCrash]: Can't load UH-60 Blackhawk bundle"); Debug.LogError("[SamSWAT.HeliCrash]: Can't load UH-60 Blackhawk bundle");
return null; return null;
} }
var assetLoadRequest = _uh60Bundle.LoadAllAssetsAsync<GameObject>(); var assetLoadRequest = _heliBundle.LoadAllAssetsAsync<GameObject>();
while (!assetLoadRequest.isDone) while (!assetLoadRequest.isDone)
await Task.Yield(); await Task.Yield();
@ -145,7 +104,7 @@ namespace SamSWAT.HeliCrash
private T PickRandom<T>(List<T> list) private T PickRandom<T>(List<T> list)
{ {
return list[UnityEngine.Random.Range(0, list.Count)]; return list[Random.Range(0, list.Count)];
} }
} }
} }

View File

@ -17,6 +17,7 @@ namespace SamSWAT.HeliCrash
public List<Location> Lighthouse { get; set; } public List<Location> Lighthouse { get; set; }
public List<Location> Rezerv { get; set; } public List<Location> Rezerv { get; set; }
public List<Location> Shoreline { get; set; } public List<Location> Shoreline { get; set; }
public List<Location> StreetsOfTarkov { get; set; }
public List<Location> Develop { get; set; } public List<Location> Develop { get; set; }
} }
} }

View File

@ -13,7 +13,7 @@ namespace SamSWAT.HeliCrash
{ {
protected override MethodBase GetTargetMethod() protected override MethodBase GetTargetMethod()
{ {
return PatchConstants.LocalGameType.BaseType.GetMethod("method_11", BindingFlags.NonPublic | BindingFlags.Instance); return PatchConstants.LocalGameType.BaseType.GetMethod("method_10", BindingFlags.NonPublic | BindingFlags.Instance);
} }
[PatchPostfix] [PatchPostfix]

View File

@ -5,7 +5,7 @@ using System.IO;
namespace SamSWAT.HeliCrash namespace SamSWAT.HeliCrash
{ {
[BepInPlugin("com.SamSWAT.HeliCrash", "SamSWAT.HeliCrash", "1.2.0")] [BepInPlugin("com.SamSWAT.HeliCrash", "SamSWAT.HeliCrash", "2.0.0")]
public class Plugin : BaseUnityPlugin public class Plugin : BaseUnityPlugin
{ {
public static HeliCrashLocations HeliCrashLocations; public static HeliCrashLocations HeliCrashLocations;
@ -16,7 +16,7 @@ namespace SamSWAT.HeliCrash
{ {
Directory = Path.Combine(BepInEx.Paths.PluginPath, "SamSWAT.HeliCrash/").Replace("\\", "/"); Directory = Path.Combine(BepInEx.Paths.PluginPath, "SamSWAT.HeliCrash/").Replace("\\", "/");
new HeliCrashPatch().Enable(); new HeliCrashPatch().Enable();
var json = new StreamReader(Directory + "HeliCrashLocations.json").ReadToEnd(); var json = File.ReadAllText(Directory + "HeliCrashLocations.json");
HeliCrashLocations = JsonConvert.DeserializeObject<HeliCrashLocations>(json); HeliCrashLocations = JsonConvert.DeserializeObject<HeliCrashLocations>(json);
HeliCrashChance = Config.Bind( HeliCrashChance = Config.Bind(

Binary file not shown.

View File

@ -31,9 +31,8 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Aki.Common, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="aki-custom">
<SpecificVersion>False</SpecificVersion> <HintPath>References\aki-custom.dll</HintPath>
<HintPath>References\Aki.Common.dll</HintPath>
</Reference> </Reference>
<Reference Include="Aki.Reflection"> <Reference Include="Aki.Reflection">
<HintPath>References\Aki.Reflection.dll</HintPath> <HintPath>References\Aki.Reflection.dll</HintPath>
@ -63,12 +62,12 @@
</Reference> </Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="GeneratedContainer.cs" />
<Compile Include="HeliCrash.cs" /> <Compile Include="HeliCrash.cs" />
<Compile Include="HeliCrashLocations.cs" /> <Compile Include="HeliCrashLocations.cs" />
<Compile Include="HeliCrashPatch.cs" /> <Compile Include="HeliCrashPatch.cs" />
<Compile Include="Plugin.cs" /> <Compile Include="Plugin.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utils.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project> </Project>

View File

@ -0,0 +1,131 @@
using System;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using Comfort.Common;
using EFT.InventoryLogic;
namespace SamSWAT.HeliCrash
{
public static class Utils
{
private static CreateItemDelegate _createItemDelegate;
private delegate Item CreateItemDelegate(object instance, string id, string tplId, object diff = null);
static Utils()
{
var createItemMethod = typeof(ItemFactory).GetMethod("CreateItem");
_createItemDelegate = MethodDelegate<CreateItemDelegate>(createItemMethod, false);
}
public static Item CreateItem(string id, string tplId)
{
return _createItemDelegate(Singleton<ItemFactory>.Instance, id, tplId);
}
//stolen from kmyuhkyuk
private static DelegateType MethodDelegate<DelegateType>(MethodInfo method, bool virtualCall = true) where DelegateType : Delegate
{
if (method == null)
{
throw new ArgumentNullException(nameof(method));
}
var delegateType = typeof(DelegateType);
var declaringType = method.DeclaringType;
var delegateMethod = delegateType.GetMethod("Invoke");
var delegateParameters = delegateMethod.GetParameters();
var delegateParameterTypes = delegateParameters.Select(x => x.ParameterType).ToArray();
Type returnType;
bool needBox;
if (delegateMethod.ReturnType == typeof(object) && method.ReturnType.IsValueType)
{
returnType = typeof(object);
needBox = true;
}
else
{
returnType = method.ReturnType;
needBox = false;
}
var dmd = new DynamicMethod("OpenInstanceDelegate_" + method.Name, returnType, delegateParameterTypes);
var ilGen = dmd.GetILGenerator();
Type[] parameterTypes;
int num;
if (!method.IsStatic)
{
var parameters = method.GetParameters();
var numParameters = parameters.Length;
parameterTypes = new Type[numParameters + 1];
parameterTypes[0] = typeof(object);
for (int i = 0; i < numParameters; i++)
{
parameterTypes[i + 1] = parameters[i].ParameterType;
}
if (declaringType != null && declaringType.IsValueType)
{
ilGen.Emit(OpCodes.Ldarga_S, 0);
}
else
{
ilGen.Emit(OpCodes.Ldarg_0);
}
ilGen.Emit(OpCodes.Castclass, declaringType);
num = 1;
}
else
{
parameterTypes = method.GetParameters().Select(x => x.ParameterType).ToArray();
num = 0;
}
for (int i = num; i < parameterTypes.Length; i++)
{
ilGen.Emit(OpCodes.Ldarg, i);
var parameterType = parameterTypes[i];
var isValueType = parameterType.IsValueType;
if (!isValueType)
{
ilGen.Emit(OpCodes.Castclass, parameterType);
}
else if (delegateParameterTypes[i] == typeof(object))
{
ilGen.Emit(OpCodes.Unbox_Any, parameterType);
}
}
if (method.IsStatic || !virtualCall)
{
ilGen.Emit(OpCodes.Call, method);
}
else
{
ilGen.Emit(OpCodes.Callvirt, method);
}
if (needBox)
{
ilGen.Emit(OpCodes.Box, method.ReturnType);
}
ilGen.Emit(OpCodes.Ret);
return (DelegateType)dmd.CreateDelegate(delegateType);
}
}
}