Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Carturs Waste Management v1.1.0
plugins/CarturWasteManagement/CarturWasteManagement.dll
Decompiled 11 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("CarturWasteManagement")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+6b3d88bc3fe8badb50465fd02db0a0ca0ff6305d")] [assembly: AssemblyProduct("CarturWasteManagement")] [assembly: AssemblyTitle("CarturWasteManagement")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace CarturWasteManagement { [BepInPlugin("com.jekkle.valheim.carturwastemanagement", "Cartur's Waste Management", "1.1.0")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.jekkle.valheim.carturwastemanagement"; public const string PluginName = "Cartur's Waste Management"; public const string PluginVersion = "1.1.0"; internal static Sprite CanSprite; internal static ManualLogSource Log; private void Awake() { Log = ((BaseUnityPlugin)this).Logger; CanSprite = LoadSprite("trashcan_128.png"); try { Harmony.CreateAndPatchAll(typeof(Plugin).Assembly, "com.jekkle.valheim.carturwastemanagement"); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Cartur's Waste Management 1.1.0 loaded - trash can refunds half the item's own recipe, sort button added."); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"Failed to patch InventoryGui - no can and no sort button this run. {arg}"); } } private Sprite LoadSprite(string fileName) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) string text = Path.Combine(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? "", "assets"), fileName); if (!File.Exists(text)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("asset missing: " + text)); return null; } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false) { wrapMode = (TextureWrapMode)1 }; MethodInfo methodInfo = null; MethodInfo[] array = AccessTools.TypeByName("UnityEngine.ImageConversion")?.GetMethods(BindingFlags.Static | BindingFlags.Public) ?? new MethodInfo[0]; foreach (MethodInfo methodInfo2 in array) { ParameterInfo[] parameters = methodInfo2.GetParameters(); if (methodInfo2.Name == "LoadImage" && parameters.Length == 3 && parameters[1].ParameterType == typeof(byte[])) { methodInfo = methodInfo2; break; } } if (!(methodInfo == null)) { object obj = methodInfo.Invoke(null, new object[3] { val, File.ReadAllBytes(text), false }); if (obj is bool && (bool)obj) { return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } } ((BaseUnityPlugin)this).Logger.LogWarning((object)("could not decode " + text)); return null; } } [HarmonyPatch(typeof(InventoryGui), "Show")] public static class Patch_InventoryGui_Show { [CompilerGenerated] private static class <>O { public static UnityAction <0>__SortOpenContainer; public static UnityAction <1>__DropCarriedItem; public static UnityAction <2>__SortPlayerInventory; } private const float CanSize = 54f; private const float ButtonWidth = 54f; private const float ButtonHeight = 30f; private const float Gap = 6f; private static GameObject s_can; private static GameObject s_sort; private static GameObject s_containerSort; private static void Postfix(InventoryGui __instance) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return; } BuildContainerSort(__instance); if (!((Object)(object)s_can != (Object)null) && !((Object)(object)__instance.m_weight == (Object)null)) { RectTransform rectTransform = __instance.m_weight.rectTransform; Transform parent = ((Transform)rectTransform).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if (!((Object)(object)val == (Object)null)) { float num = rectTransform.anchoredPosition.y + 30f + 6f; float num2 = num + 15f + 27f + 6f; s_can = BuildCan(val, new Vector2(rectTransform.anchoredPosition.x, num2)); s_sort = BuildSort(__instance, val, new Vector2(rectTransform.anchoredPosition.x, num)); } } } private static void BuildContainerSort(InventoryGui gui) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_containerSort != (Object)null || (Object)(object)gui.m_takeAllButton == (Object)null || (Object)(object)gui.m_container == (Object)null) { return; } RectTransform val = (((Object)(object)gui.m_stackAllButton != (Object)null) ? ((Component)gui.m_stackAllButton).GetComponent<RectTransform>() : null); if (!((Object)(object)val == (Object)null)) { GameObject val2 = Object.Instantiate<GameObject>(((Component)gui.m_takeAllButton).gameObject, ((Transform)val).parent); ((Object)val2).name = "CarturSortContainerButton"; val2.SetActive(true); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = val.anchorMin; val3.anchorMax = val.anchorMax; val3.pivot = val.pivot; val3.sizeDelta = val.sizeDelta; Vector2 anchoredPosition = val.anchoredPosition; Rect rect = val.rect; val3.anchoredPosition = anchoredPosition - new Vector2(0f, ((Rect)(ref rect)).height + 6f); TMP_Text[] componentsInChildren = val2.GetComponentsInChildren<TMP_Text>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].text = "Sort"; } Button component = val2.GetComponent<Button>(); ((UnityEventBase)component.onClick).RemoveAllListeners(); ButtonClickedEvent onClick = component.onClick; object obj = <>O.<0>__SortOpenContainer; if (obj == null) { UnityAction val4 = WasteBin.SortOpenContainer; <>O.<0>__SortOpenContainer = val4; obj = (object)val4; } ((UnityEvent)onClick).AddListener((UnityAction)obj); s_containerSort = val2; RectTransform component2 = ((Component)gui.m_takeAllButton).GetComponent<RectTransform>(); RectTransform val5 = (((Object)(object)gui.m_dropButton != (Object)null) ? ((Component)gui.m_dropButton).GetComponent<RectTransform>() : null); ManualLogSource log = Plugin.Log; string[] obj2 = new string[13] { "container sort button at ", ((object)val3.anchoredPosition/*cast due to .constrained prefix*/).ToString(), " size ", null, null, null, null, null, null, null, null, null, null }; rect = val3.rect; obj2[3] = ((object)((Rect)(ref rect)).size/*cast due to .constrained prefix*/).ToString(); obj2[4] = " (place stacks "; obj2[5] = ((object)val.anchoredPosition/*cast due to .constrained prefix*/).ToString(); obj2[6] = " size "; rect = val.rect; obj2[7] = ((object)((Rect)(ref rect)).size/*cast due to .constrained prefix*/).ToString(); obj2[8] = ", take all "; obj2[9] = (((Object)(object)component2 != (Object)null) ? ((object)component2.anchoredPosition/*cast due to .constrained prefix*/).ToString() : "?"); obj2[10] = ", drop "; obj2[11] = (((Object)(object)val5 != (Object)null) ? ((object)val5.anchoredPosition/*cast due to .constrained prefix*/).ToString() : "none"); obj2[12] = ")"; log.LogInfo((object)string.Concat(obj2)); } } private static GameObject BuildCan(RectTransform parent, Vector2 pos) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00e5: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Expected O, but got Unknown GameObject val = new GameObject("CarturTrashCan", new Type[3] { typeof(RectTransform), typeof(Image), typeof(Button) }); RectTransform val2 = (RectTransform)val.transform; ((Transform)val2).SetParent((Transform)(object)parent, false); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 0.5f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(0.5f, 0.5f); val2.sizeDelta = new Vector2(54f, 54f); val2.anchoredPosition = pos; Image component = val.GetComponent<Image>(); component.sprite = Plugin.CanSprite; component.preserveAspect = true; Button component2 = val.GetComponent<Button>(); ((Selectable)component2).targetGraphic = (Graphic)(object)component; ButtonClickedEvent onClick = component2.onClick; object obj = <>O.<1>__DropCarriedItem; if (obj == null) { UnityAction val4 = WasteBin.DropCarriedItem; <>O.<1>__DropCarriedItem = val4; obj = (object)val4; } ((UnityEvent)onClick).AddListener((UnityAction)obj); return val; } private static GameObject BuildSort(InventoryGui gui, RectTransform parent, Vector2 pos) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown if ((Object)(object)gui.m_takeAllButton == (Object)null) { return null; } GameObject val = Object.Instantiate<GameObject>(((Component)gui.m_takeAllButton).gameObject, (Transform)(object)parent); ((Object)val).name = "CarturSortButton"; val.SetActive(true); RectTransform val2 = (RectTransform)val.transform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 0.5f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(0.5f, 0.5f); val2.sizeDelta = new Vector2(54f, 30f); val2.anchoredPosition = pos; TMP_Text[] componentsInChildren = val.GetComponentsInChildren<TMP_Text>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].text = "Sort"; } Button component = val.GetComponent<Button>(); ((UnityEventBase)component.onClick).RemoveAllListeners(); ButtonClickedEvent onClick = component.onClick; object obj = <>O.<2>__SortPlayerInventory; if (obj == null) { UnityAction val4 = WasteBin.SortPlayerInventory; <>O.<2>__SortPlayerInventory = val4; obj = (object)val4; } ((UnityEvent)onClick).AddListener((UnityAction)obj); return val; } } internal static class WasteBin { private static readonly FieldInfo DragItem = AccessTools.Field(typeof(InventoryGui), "m_dragItem"); private static readonly FieldInfo DragInventory = AccessTools.Field(typeof(InventoryGui), "m_dragInventory"); private static readonly FieldInfo DragAmount = AccessTools.Field(typeof(InventoryGui), "m_dragAmount"); private static readonly MethodInfo SetupDragItem = AccessTools.Method(typeof(InventoryGui), "SetupDragItem", (Type[])null, (Type[])null); private static readonly MethodInfo InventoryChanged = AccessTools.Method(typeof(Inventory), "Changed", new Type[2] { typeof(bool), typeof(bool) }, (Type[])null); private static readonly Type RarityType = AccessTools.TypeByName("EpicLoot.ItemRarity"); private static readonly MethodInfo EnchantCostFor = ((RarityType == null) ? null : AccessTools.Method(AccessTools.TypeByName("EpicLoot.Crafting.EnchantCostsHelper"), "GetEnchantCost", new Type[2] { typeof(ItemData), RarityType }, (Type[])null)); private static readonly MethodInfo SacrificeProductsFor = AccessTools.Method(AccessTools.TypeByName("EpicLoot.Crafting.EnchantCostsHelper"), "GetSacrificeProducts", new Type[1] { typeof(ItemData) }, (Type[])null); private static readonly MethodInfo IsMagicItem = AccessTools.Method(AccessTools.TypeByName("EpicLoot.API"), "IsMagicItem", new Type[1] { typeof(ItemData) }, (Type[])null); private static readonly MethodInfo TryGetRarity = AccessTools.Method(AccessTools.TypeByName("EpicLoot.API"), "TryGetRarity", new Type[2] { typeof(ItemData), typeof(int).MakeByRefType() }, (Type[])null); private static readonly FieldInfo CostItem = AccessTools.Field(AccessTools.TypeByName("EpicLoot.Crafting.ItemAmountConfig"), "Item"); private static readonly FieldInfo CostAmount = AccessTools.Field(AccessTools.TypeByName("EpicLoot.Crafting.ItemAmountConfig"), "Amount"); private static readonly MethodInfo VisibleRowsGetter = AccessTools.PropertyGetter(AccessTools.TypeByName("CarturUIHud.Slots"), "VisibleRows"); private static bool s_boundaryLogged; private static readonly FieldInfo CurrentContainer = AccessTools.Field(typeof(InventoryGui), "m_currentContainer"); private static readonly MethodInfo ContainerSave = AccessTools.Method(typeof(Container), "Save", (Type[])null, (Type[])null); private static readonly MethodInfo ContainerCheckAccess = AccessTools.Method(typeof(Container), "CheckAccess", (Type[])null, (Type[])null); private static readonly FieldInfo ContainerWagon = AccessTools.Field(typeof(Container), "m_wagon"); private const float GatherRange = 20f; private static void NotifyChanged(Inventory inv) { if (inv != null) { InventoryChanged?.Invoke(inv, new object[2] { false, false }); } } internal static void DropCarriedItem() { InventoryGui instance = InventoryGui.instance; Player localPlayer = Player.m_localPlayer; if (!((Object)(object)instance == (Object)null) && !((Object)(object)localPlayer == (Object)null)) { object? obj = DragItem?.GetValue(instance); ItemData val = (ItemData)((obj is ItemData) ? obj : null); object? obj2 = DragInventory?.GetValue(instance); Inventory val2 = (Inventory)((obj2 is Inventory) ? obj2 : null); if (val != null && val2 != null) { int amount = Mathf.Clamp((DragAmount?.GetValue(instance) is int num) ? num : val.m_stack, 1, val.m_stack); Recycle(localPlayer, val2, val, amount); SetupDragItem?.Invoke(instance, new object[3] { null, null, 0 }); NotifyChanged(val2); } } } private static void Recycle(Player player, Inventory from, ItemData item, int amount) { Recipe val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetRecipe(item) : null); int num = (((Object)(object)val != (Object)null) ? Mathf.Max(1, val.m_amount) : 0); int num2 = (((Object)(object)val != (Object)null) ? (amount / num) : 0); if (num2 > 0) { Requirement[] resources = val.m_resources; foreach (Requirement val2 in resources) { if (val2 != null && !((Object)(object)val2.m_resItem == (Object)null) && val2.m_recover) { int num3 = Half(val2.GetAmount(item.m_quality) * num2); if (num3 > 0) { Give(player, ((Component)val2.m_resItem).gameObject, num3); Plugin.Log.LogDebug((object)$"returned {num3} {((Object)((Component)val2.m_resItem).gameObject).name}"); } } } } GiveEpicLootRefund(player, item, amount); if (item.m_equipped) { ((Humanoid)player).UnequipItem(item, false); } if (amount >= item.m_stack) { from.RemoveItem(item); } else { from.RemoveItem(item, amount); } } private static int Half(int n) { return (n + 1) / 2; } private static void Give(Player player, GameObject prefab, int amount) { //IL_002d: 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) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (!((Humanoid)player).GetInventory().AddItem(prefab, amount)) { ItemDrop component = prefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { ItemDrop.DropItem(component.m_itemData, amount, ((Component)player).transform.position + ((Component)player).transform.forward, Quaternion.identity); } } } private static void GiveEpicLootRefund(Player player, ItemData item, int amount) { if (EnchantCostFor == null || SacrificeProductsFor == null || IsMagicItem == null || TryGetRarity == null || CostItem == null || CostAmount == null) { return; } bool flag2; IEnumerable enumerable; try { object obj = IsMagicItem.Invoke(null, new object[1] { item }); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } flag2 = (byte)((uint)num & (flag ? 1u : 0u)) != 0; if (flag2) { object[] array = new object[2] { item, 0 }; obj = TryGetRarity.Invoke(null, array); if (!(obj is bool) || !(bool)obj) { return; } object obj2 = Enum.ToObject(RarityType, array[1]); enumerable = EnchantCostFor.Invoke(null, new object[2] { item, obj2 }) as IEnumerable; } else { enumerable = SacrificeProductsFor.Invoke(null, new object[1] { item }) as IEnumerable; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("EpicLoot cost lookup threw, no magic materials given. " + ex.Message)); return; } if (enumerable == null) { return; } foreach (object item2 in enumerable) { string text = CostItem.GetValue(item2) as string; int num2 = ((CostAmount.GetValue(item2) is int num3) ? num3 : 0) * amount; if (flag2) { num2 = Half(num2); } if (num2 > 0 && !string.IsNullOrEmpty(text)) { GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(text) : null); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("EpicLoot material is not in the ObjectDB: " + text)); continue; } Give(player, val, num2); Plugin.Log.LogDebug((object)$"refunded {num2} {text}"); } } } private static int VisibleRows(Inventory inv) { if (VisibleRowsGetter != null && VisibleRowsGetter.Invoke(null, null) is int num && num > 0) { return num; } return inv.GetHeight(); } internal static void SortPlayerInventory() { //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } Inventory inventory = ((Humanoid)localPlayer).GetInventory(); int num = VisibleRows(inventory); if (!s_boundaryLogged) { s_boundaryLogged = true; Plugin.Log.LogInfo((object)("sort covers rows 1-" + (num - 1) + " of " + num + " visible (" + ((VisibleRowsGetter != null) ? "row count from CarturUIHud.Slots" : "no slot mod found, using the grid height") + ")")); } List<ItemData> list = new List<ItemData>(); foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem.m_gridPos.y > 0 && allItem.m_gridPos.y < num) { list.Add(allItem); } } MergeStacks(inventory, list); list.Sort(Compare); int width = inventory.GetWidth(); for (int i = 0; i < list.Count; i++) { list[i].m_gridPos = new Vector2i(i % width, 1 + i / width); } NotifyChanged(inventory); } internal static void SortOpenContainer() { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || !instance.IsContainerOpen()) { return; } object? obj = CurrentContainer?.GetValue(instance); Container val = (Container)((obj is Container) ? obj : null); Inventory val2 = ((val != null) ? val.GetInventory() : null); if (val2 != null) { GatherLikeItems(val, val2); List<ItemData> list = new List<ItemData>(val2.GetAllItems()); MergeStacks(val2, list); list.Sort(Compare); int width = val2.GetWidth(); for (int i = 0; i < list.Count; i++) { list[i].m_gridPos = new Vector2i(i % width, i / width); } NotifyChanged(val2); } } private static void GatherLikeItems(Container target, Inventory inv) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); foreach (ItemData allItem in inv.GetAllItems()) { if (allItem?.m_shared != null) { hashSet.Add(allItem.m_shared.m_name); } } if (hashSet.Count == 0 || (Object)(object)Game.instance == (Object)null) { return; } long playerID = Game.instance.GetPlayerProfile().GetPlayerID(); Vector3 position = ((Component)target).transform.position; float rangeSq = 400f; int num = 0; Container[] array = Object.FindObjectsByType<Container>((FindObjectsSortMode)0); foreach (Container val in array) { if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)target || !Reachable(val, position, rangeSq, playerID)) { continue; } Inventory inventory = val.GetInventory(); if (inventory == null) { continue; } bool flag = false; foreach (ItemData item in new List<ItemData>(inventory.GetAllItems())) { if (item?.m_shared != null && hashSet.Contains(item.m_shared.m_name) && inv.CanAddItem(item, item.m_stack)) { inv.MoveItemToThis(inventory, item); flag = true; num++; } } if (flag) { ContainerSave?.Invoke(val, null); NotifyChanged(inventory); } } if (num > 0) { Plugin.Log.LogInfo((object)$"sort gathered {num} stack(s) into {Utils.GetPrefabName(((Component)target).gameObject)}."); } } private static bool Reachable(Container other, Vector3 at, float rangeSq, long playerId) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)other).transform.position - at; if (((Vector3)(ref val)).sqrMagnitude > rangeSq) { return false; } if (other.IsInUse() && !other.IsOwner()) { return false; } object? obj = ContainerWagon?.GetValue(other); Vagon val2 = (Vagon)((obj is Vagon) ? obj : null); if (val2 != null && val2.InUse()) { return false; } if ((Object)(object)((Component)other).GetComponentInParent<Player>() != (Object)null) { return false; } object obj2 = ContainerCheckAccess?.Invoke(other, new object[1] { playerId }); if (!(obj2 is bool) || !(bool)obj2) { return false; } return PrivateArea.CheckAccess(((Component)other).transform.position, 0f, false, true); } private static void MergeStacks(Inventory inv, List<ItemData> items) { List<ItemData> list = null; for (int i = 0; i < items.Count; i++) { ItemData val = items[i]; for (int j = i + 1; j < items.Count; j++) { if (val.m_stack >= val.m_shared.m_maxStackSize) { break; } ItemData val2 = items[j]; if (val2.m_stack > 0 && SameStack(val, val2)) { int num = Mathf.Min(val2.m_stack, val.m_shared.m_maxStackSize - val.m_stack); val.m_stack += num; val2.m_stack -= num; if (val2.m_stack == 0) { (list ?? (list = new List<ItemData>())).Add(val2); } } } } if (list == null) { return; } foreach (ItemData item in list) { inv.RemoveItem(item); items.Remove(item); } } private static bool SameStack(ItemData a, ItemData b) { if (a.m_shared.m_maxStackSize > 1 && a.m_shared.m_name == b.m_shared.m_name && a.m_quality == b.m_quality) { return a.m_worldLevel == b.m_worldLevel; } return false; } private static int Compare(ItemData a, ItemData b) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) ref ItemType itemType = ref a.m_shared.m_itemType; object target = b.m_shared.m_itemType; int num = ((Enum)Unsafe.As<ItemType, ItemType>(ref itemType)/*cast due to .constrained prefix*/).CompareTo(target); if (num != 0) { return num; } int num2 = string.Compare(a.m_shared.m_name, b.m_shared.m_name, StringComparison.Ordinal); if (num2 == 0) { return b.m_quality.CompareTo(a.m_quality); } return num2; } } }