using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Logging;
using GGECS;
using HarmonyLib;
using Inventory;
using Inventory.Unity;
using Unity.Collections;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Tower Storage Plus")]
[assembly: AssemblyProduct("Tower Storage Plus")]
[assembly: AssemblyDescription("Tower-wide crafting storage and larger item stacks for Wizard with a Gun")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyInformationalVersion("1.0.3")]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyVersion("1.0.3.0")]
namespace BoogaJoker.TowerStoragePlus;
[BepInPlugin("com.boogajoker.towerstorageplus", "Tower Storage Plus", "1.0.3")]
public sealed class Plugin : BaseUnityPlugin
{
public const string PluginGuid = "com.boogajoker.towerstorageplus";
public const string PluginName = "Tower Storage Plus";
public const string PluginVersion = "1.0.3";
private const int TowerRegionWidth = 84;
private const int TowerRegionHeight = 86;
private const int FullTowerStorageWidth = 100;
private Harmony _patches;
private int _reportedWidth = -1;
internal static ManualLogSource ModLog { get; private set; }
internal static int TowerSearchWidth { get; private set; }
private async void Awake()
{
ModLog = ((BaseUnityPlugin)this).Logger;
_patches = new Harmony("com.boogajoker.towerstorageplus");
_patches.PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Tower Storage Plus 1.0.3 loaded. Waiting for the Tower map.");
await SyncTowerRange();
SetLoadedItemLimits();
}
private async Task SyncTowerRange()
{
do
{
await Task.Delay(1000);
}
while (!SimUtil.worldRunning || (Object)(object)GameUniverse.towerWorld == (Object)null || GameUniverse.towerWorld.world == null);
Dictionary<int, Dictionary<Type, GameData>> dictionary = typeof(GameDataCache).GetField("_sceneCache", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null) as Dictionary<int, Dictionary<Type, GameData>>;
Scene scene = ((Component)GameUniverse.towerWorld).gameObject.scene;
int handle = ((Scene)(ref scene)).handle;
if (dictionary != null && dictionary.TryGetValue(handle, out var value) && value.TryGetValue(typeof(AdditionalStorageGameData), out var value2))
{
AdditionalStorageGameData val = (AdditionalStorageGameData)(object)((value2 is AdditionalStorageGameData) ? value2 : null);
if (val != null)
{
val.connectionAreaWidth = 100;
val.arcHeight = 3f;
TowerSearchWidth = 100;
LockAndAssignInteractableOnInteractSystem system = GameUniverse.towerWorld.world.GetSystem<LockAndAssignInteractableOnInteractSystem>();
if (system != null)
{
system.GetSystemData();
StorageSystemPatches.SetSearchWidth(system, 100);
}
if (_reportedWidth != 100)
{
_reportedWidth = 100;
ModLog.LogInfo((object)($"Tower storage is active across the game's {84} x {86} " + $"Tower region (search width {100}, including safety margin)."));
}
return;
}
}
ModLog.LogError((object)"Tower storage data was not found in the Tower scene cache.");
}
private void SetLoadedItemLimits()
{
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
try
{
int num = 0;
foreach (GameWorld world2 in GameUniverse.worlds)
{
if ((Object)(object)world2 == (Object)null || world2.world == null || world2.world.GetSystem<InventoryDataSystem>() == null)
{
continue;
}
ECSWorld world = world2.world;
NativeArray<ECSEntity> entitiesArray = ((EntityQueryBase)world.entityManager.CreateDefaultEntityQuery((CompType[])(object)new CompType[2]
{
CompType.ReadOnly<ItemComp>(),
CompType.ReadOnly<ItemCountComp>()
})).GetEntitiesArray((Allocator)2);
for (int i = 0; i < entitiesArray.Length; i++)
{
if (InventoryUtil.IsStackManageableType(world.entityManager.GetComponent<ItemComp>(entitiesArray[i]).itemType))
{
ItemCountComp component = world.entityManager.GetComponent<ItemCountComp>(entitiesArray[i]);
if (component.maxCount != 999)
{
component.maxCount = 999;
world.entityManager.SetComponent<ItemCountComp>(entitiesArray[i], component);
num++;
}
}
}
entitiesArray.Dispose();
}
ModLog.LogInfo((object)$"Stack update finished: {num} item stacks set to 999.");
}
catch (Exception arg)
{
ModLog.LogError((object)$"Could not update loaded item limits: {arg}");
}
}
private void OnDestroy()
{
Harmony patches = _patches;
if (patches != null)
{
patches.UnpatchSelf();
}
}
}
[HarmonyPatch(typeof(StaticItem), "GetItemCreateDesc")]
internal static class NewItemStackPatch
{
private static void Postfix(ref UnsafeCreateEntityDesc __result)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
if (((UnsafeCreateEntityDesc)(ref __result)).HasComponent<ItemComp>() && ((UnsafeCreateEntityDesc)(ref __result)).HasComponent<ItemCountComp>() && InventoryUtil.IsStackManageableType(((UnsafeCreateEntityDesc)(ref __result)).GetComponentData<ItemComp>().itemType))
{
ItemCountComp componentData = ((UnsafeCreateEntityDesc)(ref __result)).GetComponentData<ItemCountComp>();
componentData.maxCount = 999;
((UnsafeCreateEntityDesc)(ref __result)).SetComponentData<ItemCountComp>(componentData);
}
}
}
internal static class StackPatches
{
internal const int MaximumStack = 999;
internal static bool CanStack(InventoryData inventory, ItemEntity item)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
if (((InventoryData)(ref inventory)).IsItemValid(item))
{
return InventoryUtil.IsStackManageableType(((InventoryData)(ref inventory)).GetItemType(item));
}
return false;
}
}
[HarmonyPatch(typeof(InventoryData), "GetItemCountData")]
internal static class ExistingItemCountDataPatch
{
private static void Postfix(InventoryData __instance, ItemEntity item, ref int maxCount)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
if (StackPatches.CanStack(__instance, item))
{
maxCount = 999;
}
}
}
[HarmonyPatch(typeof(InventoryData), "GetItemMaxCount", new Type[] { typeof(ItemEntity) })]
internal static class ExistingItemMaxPatch
{
private static void Postfix(InventoryData __instance, ItemEntity item, ref int __result)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
if (StackPatches.CanStack(__instance, item))
{
__result = 999;
}
}
}
[HarmonyPatch(typeof(InventoryData), "IsItemFull")]
internal static class ExistingItemFullPatch
{
private static bool Prefix(InventoryData __instance, ItemEntity item, ref bool __result)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
if (!StackPatches.CanStack(__instance, item))
{
return true;
}
__result = ((InventoryData)(ref __instance)).GetItemCount(item) >= 999;
return false;
}
}
[HarmonyPatch(typeof(InventoryData), "SetItemCount")]
internal static class ExistingItemSetCountPatch
{
private static void Prefix(ref InventoryData __instance, ItemEntity item)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
if (StackPatches.CanStack(__instance, item))
{
ItemCountComp itemComponent = ((InventoryData)(ref __instance)).GetItemComponent<ItemCountComp>(item);
if (itemComponent.maxCount != 999)
{
itemComponent.maxCount = 999;
((InventoryData)(ref __instance)).SetItemComponent<ItemCountComp>(item, itemComponent);
}
}
}
}
[HarmonyPatch(typeof(LockAndAssignInteractableOnInteractSystem), "GetSystemData")]
internal static class StorageSystemDataPatch
{
private static void Postfix(LockAndAssignInteractableOnInteractSystem __instance)
{
if (Plugin.TowerSearchWidth > 0)
{
StorageSystemPatches.SetSearchWidth(__instance, Plugin.TowerSearchWidth);
}
}
}
[HarmonyPatch(typeof(LockAndAssignInteractableOnInteractSystem), "OnHandleCommand")]
internal static class StorageInteractionPatch
{
private static void Prefix(LockAndAssignInteractableOnInteractSystem __instance)
{
if (Plugin.TowerSearchWidth > 0)
{
StorageSystemPatches.SetSearchWidth(__instance, Plugin.TowerSearchWidth);
}
}
}
internal static class StorageSystemPatches
{
private static readonly FieldRef<LockAndAssignInteractableOnInteractSystem, int2> SearchWidth = AccessTools.FieldRefAccess<LockAndAssignInteractableOnInteractSystem, int2>("_additionalStorageWidth");
internal static void SetSearchWidth(LockAndAssignInteractableOnInteractSystem system, int width)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
SearchWidth.Invoke(system) = new int2(width, width);
}
}