using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ItemStackerFix")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ItemStackerFix")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("68fef771-f28c-4880-bfed-027323d829a8")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("com.travv.aleandtale.itemstack99safe", "ItemStack99 Safe (Vanilla Shop + 99 Stacks)", "1.0.9")]
public class ItemStack99Safe : BaseUnityPlugin
{
internal const ushort NewMax = 99;
internal static readonly Dictionary<ushort, ushort> OriginalMaxById = new Dictionary<ushort, ushort>();
[ThreadStatic]
internal static bool InShopTransaction;
internal static ItemStack99Safe Instance;
private void Awake()
{
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
Instance = this;
ItemData[] array = Resources.FindObjectsOfTypeAll<ItemData>();
int num = 0;
ItemData[] array2 = array;
foreach (ItemData val in array2)
{
if (!((Object)(object)val == (Object)null))
{
if (!OriginalMaxById.ContainsKey(val.id))
{
OriginalMaxById[val.id] = val.maxStack;
}
if (val.maxStack > 1 && val.maxStack < 99)
{
val.maxStack = 99;
num++;
}
}
}
new Harmony("com.travv.aleandtale.itemstack99safe").PatchAll();
((BaseUnityPlugin)this).Logger.LogInfo((object)$"ItemStack99Safe loaded. Updated {num}/{array.Length} ItemData maxStack values to {(ushort)99}.");
}
internal static ushort GetOriginalMax(ushort itemDataId)
{
ushort value;
return (ushort)((!OriginalMaxById.TryGetValue(itemDataId, out value) || value <= 0) ? 1 : value);
}
internal static ushort GetVanillaMaxForMath(ItemData data)
{
if ((Object)(object)data == (Object)null)
{
return 1;
}
return GetOriginalMax(data.id);
}
internal static ushort GetShopPurchaseAmount(ItemData data)
{
if ((Object)(object)data == (Object)null)
{
return 1;
}
return (ushort)(data.buyByOne ? 1 : GetOriginalMax(data.id));
}
internal static void ApplyShopAmount(ref Item item)
{
ItemData val = default(ItemData);
if (!((Object)(object)ItemManager.Instance == (Object)null) && ItemManager.Instance.GetItemData((uint)item.dataId, ref val) && !((Object)(object)val == (Object)null))
{
item.amount = GetShopPurchaseAmount(val);
if (item.amount <= 0)
{
item.amount = 1;
}
}
}
internal static bool IsInShopSellContext()
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Invalid comparison between Unknown and I4
if (InShopTransaction)
{
return true;
}
if ((Object)(object)PlayerInventory.Instance != (Object)null && (int)PlayerInventory.Instance.state == 15)
{
return true;
}
return false;
}
}
[HarmonyPatch(typeof(ItemManager), "BuyServerRpc")]
public static class Patch_ItemManager_BuyServerRpc_Flag
{
private static void Prefix()
{
ItemStack99Safe.InShopTransaction = true;
}
private static void Postfix()
{
ItemStack99Safe.InShopTransaction = false;
}
}
[HarmonyPatch(typeof(ItemManager), "SellItemServerRpc")]
public static class Patch_ItemManager_SellItemServerRpc_Flag
{
private static void Prefix()
{
ItemStack99Safe.InShopTransaction = true;
}
private static void Postfix()
{
ItemStack99Safe.InShopTransaction = false;
}
}
[HarmonyPatch(typeof(ItemData), "GetItemPrice")]
public static class Patch_ItemData_GetItemPrice_ShopVanilla
{
private static bool Prefix(ItemData __instance, ref ushort __result)
{
if (!ItemStack99Safe.InShopTransaction || (Object)(object)__instance == (Object)null)
{
return true;
}
ushort num = ItemStack99Safe.GetOriginalMax(__instance.id);
if (num <= 0)
{
num = 1;
}
ushort num2 = (__instance.buyByOne ? ((ushort)Mathf.FloorToInt(1f * (float)(int)__instance.price / (float)(int)num)) : __instance.price);
if (__instance.maxCharge > 0 && (Object)(object)__instance.containerClean != (Object)null)
{
num2 += __instance.containerClean.price;
}
__result = num2;
return false;
}
}
[HarmonyPatch(typeof(ItemManager), "GetItemSellPrice")]
public static class Patch_ItemManager_GetItemSellPrice_ShopVanilla
{
private static bool Prefix(ItemManager __instance, Item item, ItemData itemData, ref ushort __result)
{
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Invalid comparison between Unknown and I4
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
if (!ItemStack99Safe.IsInShopSellContext() || (Object)(object)itemData == (Object)null)
{
return true;
}
ushort num = ItemStack99Safe.GetOriginalMax(itemData.id);
if (num <= 0)
{
num = 1;
}
int num2 = itemData.price;
if ((int)itemData.type == 10 && itemData.durability > 0)
{
num2 = Mathf.FloorToInt(1f * (float)num2 / (1f + (float)(int)item.repairCount));
}
else if (num > 1 && item.amount < num)
{
num2 = Mathf.FloorToInt(1f * (float)num2 * (float)(int)item.amount / (float)(int)num);
}
else if (itemData.maxCharge > 0 && (Object)(object)itemData.containerClean != (Object)null)
{
num2 = itemData.containerClean.price + Mathf.FloorToInt(1f * (float)num2 * (float)(int)item.charge / (float)(int)itemData.maxCharge);
}
else if (itemData.durability > 0 && item.durability < itemData.durability)
{
num2 = Mathf.FloorToInt(1f * (float)num2 * (float)(int)item.durability / (float)(int)itemData.durability);
}
__result = (ushort)num2;
return false;
}
}
[HarmonyPatch]
public static class Patch_ContainerNet_AddNewItem_AllOverloads
{
private static IEnumerable<MethodBase> TargetMethods()
{
Type typeFromHandle = typeof(ContainerNet);
return (from m in typeFromHandle.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
where m.Name == "AddNewItem"
select m).Where(delegate(MethodInfo m)
{
ParameterInfo[] parameters = m.GetParameters();
return parameters.Length >= 1 && parameters[0].ParameterType == typeof(Item);
}).Cast<MethodBase>();
}
private static void Prefix(ref Item item)
{
if (ItemStack99Safe.InShopTransaction)
{
ItemStack99Safe.ApplyShopAmount(ref item);
return;
}
if (item.amount <= 0)
{
item.amount = 1;
}
if (item.amount > 99)
{
item.amount = 99;
}
}
}
[HarmonyPatch(typeof(ShopItemUI), "SetItemData")]
public static class Patch_ShopItemUI_SetItemData_ShowVanilla
{
[ThreadStatic]
private static ItemData _swapped;
[ThreadStatic]
private static ushort _saved;
private static void Prefix(ItemData itemData)
{
_swapped = null;
if (!((Object)(object)itemData == (Object)null))
{
_swapped = itemData;
_saved = itemData.maxStack;
itemData.maxStack = ItemStack99Safe.GetVanillaMaxForMath(itemData);
}
}
private static void Postfix()
{
if ((Object)(object)_swapped != (Object)null)
{
_swapped.maxStack = _saved;
_swapped = null;
}
}
}
[HarmonyPatch(typeof(ShopItemUI), "Upd")]
public static class Patch_ShopItemUI_Upd_ShowVanilla
{
[ThreadStatic]
private static ItemData _swapped;
[ThreadStatic]
private static ushort _saved;
private static void Prefix(ShopItemUI __instance)
{
_swapped = null;
if (!((Object)(object)__instance == (Object)null))
{
ItemData value = Traverse.Create((object)__instance).Field("_itemData").GetValue<ItemData>();
if (!((Object)(object)value == (Object)null))
{
_swapped = value;
_saved = value.maxStack;
value.maxStack = ItemStack99Safe.GetVanillaMaxForMath(value);
}
}
}
private static void Postfix()
{
if ((Object)(object)_swapped != (Object)null)
{
_swapped.maxStack = _saved;
_swapped = null;
}
}
}
[HarmonyPatch(typeof(ItemManager), "GetCommonLootItem")]
public static class Patch_ItemManager_GetCommonLootItem_VanillaAmounts
{
private static void Postfix(ref Item __result)
{
ItemData val = default(ItemData);
if ((Object)(object)ItemManager.Instance == (Object)null || !ItemManager.Instance.GetItemData((uint)__result.dataId, ref val) || (Object)(object)val == (Object)null || val.maxStack <= 1)
{
return;
}
ushort originalMax = ItemStack99Safe.GetOriginalMax(val.id);
if (originalMax > 1)
{
if (__result.amount < 1)
{
__result.amount = 1;
}
if (__result.amount > originalMax)
{
__result.amount = originalMax;
}
}
}
}
[HarmonyPatch(typeof(ItemManager), "GetCommonLootItem")]
public static class Patch_ItemManager_GetCommonLootItem_RandomVanilla
{
private static void Postfix(ref Item __result)
{
ItemData val = default(ItemData);
if ((Object)(object)ItemManager.Instance == (Object)null || !ItemManager.Instance.GetItemData((uint)__result.dataId, ref val) || (Object)(object)val == (Object)null)
{
return;
}
ushort originalMax = ItemStack99Safe.GetOriginalMax(val.id);
if (originalMax > 1)
{
if (val.buyByOne)
{
__result.amount = 1;
}
else
{
__result.amount = (ushort)Random.Range(1, originalMax + 1);
}
}
}
}