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 MyLittleUI v1.2.21
MyLittleUI.dll
Decompiled 4 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using AzuExtendedPlayerInventory; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using ConditionalConfigSync; using ExtraSlotsAPI; using GUIFramework; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using MyLittleUI; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.UI; using Valheim.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("My Little UI")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("My Little UI")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("345181bf-e9ed-4c88-a4f4-38450f53cc41")] [assembly: AssemblyFileVersion("1.2.21")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.21.0")] [module: UnverifiableCode] [HarmonyPatch] public static class Advize_StumpsRegrow_Compat { internal const string GUID = "advize.StumpsRegrow"; private static ConfigEntry<float> stumpGrowthTime; private static bool initialized; private static bool hasGrowthTime; public static MethodBase target; private static double GetTimeSincePlanted(ZNetView nview) { return (ZNet.instance.GetTime() - new DateTime(nview.GetZDO().GetLong(ZDOVars.s_plantTime, 0L))).TotalSeconds; } private static float GetGrowTime() { return (stumpGrowthTime != null) ? Mathf.Max(stumpGrowthTime.Value, 1f) : 1f; } private static void Postfix(object __instance, ref string __result) { if (!global::MyLittleUI.MyLittleUI.modEnabled.Value || __instance == null || !global::MyLittleUI.MyLittleUI.hoverStumpGrowerEnabled.Value || global::MyLittleUI.MyLittleUI.hoverStumpGrower.Value == global::MyLittleUI.MyLittleUI.StationHover.Vanilla || string.IsNullOrWhiteSpace(__result)) { return; } if (!initialized) { initialized = true; hasGrowthTime = Chainloader.PluginInfos.TryGetValue("advize.StumpsRegrow", out var value) && value.Instance.Config.TryGetEntry<float>("General", "StumpGrowthTime", ref stumpGrowthTime); } if (!hasGrowthTime) { return; } object obj = ((__instance is MonoBehaviour) ? __instance : null); ZNetView val = ((obj != null) ? ((Component)obj).GetComponent<ZNetView>() : null); if (!((Object)(object)val == (Object)null) && val.IsValid()) { if (global::MyLittleUI.MyLittleUI.hoverStumpGrower.Value == global::MyLittleUI.MyLittleUI.StationHover.Percentage) { __result += $"\n{GetTimeSincePlanted(val) / (double)GetGrowTime():P0}"; } else if (global::MyLittleUI.MyLittleUI.hoverStumpGrower.Value == global::MyLittleUI.MyLittleUI.StationHover.Bar) { __result = __result + "\n" + global::MyLittleUI.MyLittleUI.FromPercent(GetTimeSincePlanted(val) / (double)GetGrowTime()); } else if (global::MyLittleUI.MyLittleUI.hoverStumpGrower.Value == global::MyLittleUI.MyLittleUI.StationHover.MinutesSeconds) { __result = __result + "\n" + global::MyLittleUI.MyLittleUI.FromSeconds((double)GetGrowTime() - GetTimeSincePlanted(val)); } } } public static bool Prepare(MethodBase original) { if (!Chainloader.PluginInfos.TryGetValue("advize.StumpsRegrow", out var value)) { return false; } if ((object)target == null) { target = AccessTools.Method(((object)value.Instance).GetType().Assembly.GetType("Advize_StumpsRegrow.StumpGrower"), "GetHoverText", (Type[])null, (Type[])null); } if (target == null) { return false; } if (original == null) { global::MyLittleUI.MyLittleUI.LogInfo("Advize_StumpsRegrow.StumpGrower:GetHoverText method is patched to show configurable hover"); } return true; } public static MethodBase TargetMethod() { return target; } } namespace MyLittleUI { internal class AmmoCountIcon { public class ElementExtraData { public TMP_Text m_ammo; public Image m_icon; public Image m_bait; public Image m_mead; public ItemData m_item; public void UpdateState(ElementData elementData) { if (m_item == null) { TMP_Text ammo = m_ammo; if (ammo != null) { ((Component)ammo).gameObject.SetActive(false); } Image icon = m_icon; if (icon != null) { ((Component)icon).gameObject.SetActive(false); } Image bait = m_bait; if (bait != null) { ((Component)bait).gameObject.SetActive(false); } Image mead = m_mead; if (mead != null) { ((Component)mead).gameObject.SetActive(false); } return; } ItemData currentAmmo = GetCurrentAmmo(); int num = ((currentAmmo != null) ? ((Humanoid)Player.m_localPlayer).GetInventory().CountItems(currentAmmo.m_shared.m_name, -1, true) : 0); TMP_Text ammo2 = m_ammo; if (ammo2 != null) { ((Component)ammo2).gameObject.SetActive(MyLittleUI.ammoCountEnabled.Value && num > 0); } if (num > 0) { TMP_Text ammo3 = m_ammo; if (ammo3 != null) { ammo3.SetText(num.ToString()); } } Sprite val = ((currentAmmo != null) ? currentAmmo.GetIcon() : null); Image icon2 = m_icon; if (icon2 != null) { ((Component)icon2).gameObject.SetActive(MyLittleUI.ammoIconEnabled.Value && (Object)(object)val != (Object)null); } if ((Object)(object)val != (Object)null && (Object)(object)m_icon != (Object)null) { m_icon.overrideSprite = val; } ItemData currentBait = GetCurrentBait(); Sprite val2 = ((currentBait != null) ? currentBait.GetIcon() : null); Image bait2 = m_bait; if (bait2 != null) { ((Component)bait2).gameObject.SetActive(MyLittleUI.baitIconEnabled.Value && (Object)(object)val2 != (Object)null); } if ((Object)(object)val2 != (Object)null && (Object)(object)m_bait != (Object)null) { m_bait.overrideSprite = val2; } int num2 = ((currentBait != null) ? ((Humanoid)Player.m_localPlayer).GetInventory().CountItems(currentBait.m_shared.m_name, -1, true) : 0); if (num2 > 0 && MyLittleUI.baitCountEnabled.Value && !((Component)elementData.m_amount).gameObject.activeSelf) { ((Component)elementData.m_amount).gameObject.SetActive(true); elementData.m_amount.SetText(num2.ToString()); } ItemData currentMead = GetCurrentMead(); Sprite val3 = ((currentMead != null) ? currentMead.GetIcon() : null); Image mead2 = m_mead; if (mead2 != null) { ((Component)mead2).gameObject.SetActive(MyLittleUI.meadIconEnabled.Value && (Object)(object)val3 != (Object)null); } if ((Object)(object)val3 != (Object)null && (Object)(object)m_mead != (Object)null) { m_mead.overrideSprite = val3; } } private ItemData GetCurrentAmmo() { if (m_item == null || Utility.IsNullOrWhiteSpace(m_item.m_shared.m_ammoType) || IsBaitAmmo() || IsAmmo() || IsMeadAmmo()) { return null; } ItemData ammoItem = ((Humanoid)Player.m_localPlayer).GetAmmoItem(); if (ammoItem == null || ammoItem.m_shared.m_ammoType != m_item.m_shared.m_ammoType || !((Humanoid)Player.m_localPlayer).GetInventory().ContainsItem(ammoItem)) { ammoItem = ((Humanoid)Player.m_localPlayer).GetInventory().GetAmmoItem(m_item.m_shared.m_ammoType, (string)null); } return ammoItem; } private ItemData GetCurrentBait() { if (m_item == null || Utility.IsNullOrWhiteSpace(m_item.m_shared.m_ammoType) || !IsBaitAmmo() || IsAmmo()) { return null; } ItemData ammoItem = ((Humanoid)Player.m_localPlayer).GetAmmoItem(); if (ammoItem == null || ammoItem.m_shared.m_ammoType != m_item.m_shared.m_ammoType || !((Humanoid)Player.m_localPlayer).GetInventory().ContainsItem(ammoItem)) { ammoItem = ((Humanoid)Player.m_localPlayer).GetInventory().GetAmmoItem(m_item.m_shared.m_ammoType, (string)null); } return ammoItem; } private ItemData GetCurrentMead() { if (m_item == null || Utility.IsNullOrWhiteSpace(m_item.m_shared.m_ammoType) || IsBaitAmmo() || IsAmmo() || !IsMeadAmmo()) { return null; } return ((Humanoid)Player.m_localPlayer).GetInventory().GetAmmoItem(m_item.m_shared.m_ammoType, (string)null); } private bool IsAmmo() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 return (int)m_item.m_shared.m_itemType == 9 || (int)m_item.m_shared.m_itemType == 23 || (int)m_item.m_shared.m_itemType == 2; } private bool IsBaitAmmo() { return m_item.m_shared.m_ammoType == "$item_fishingbait"; } private bool IsMeadAmmo() { return m_item.m_shared.m_ammoType == "mead"; } } [HarmonyPatch(typeof(HotkeyBar), "OnEnable")] public static class HotkeyBar_OnEnable_AddCustomElementsToHotkeyPrefab { private static void FillFields(RectTransform rtSource, RectTransform rtDestination) { //IL_0003: 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) rtDestination.anchoredPosition = rtSource.anchoredPosition; rtDestination.sizeDelta = rtSource.sizeDelta; } public static void Postfix(HotkeyBar __instance) { if (!((Object)(object)__instance.m_elementPrefab == (Object)null)) { isDirty[__instance] = false; elementPrefab = __instance.m_elementPrefab; int num = __instance.m_elementPrefab.transform.Find("icon").GetSiblingIndex() + 1; Transform obj = __instance.m_elementPrefab.transform.Find("MLUI_AmmoAmount"); ammoCount = ((obj != null) ? ((Component)obj).gameObject : null); if ((Object)(object)ammoCount == (Object)null) { GameObject gameObject = ((Component)__instance.m_elementPrefab.transform.Find("amount")).gameObject; ammoCount = Object.Instantiate<GameObject>(gameObject); ((Object)ammoCount).name = "MLUI_AmmoAmount"; ammoCount.transform.SetParent(__instance.m_elementPrefab.transform); ammoCount.transform.SetSiblingIndex(num); num++; ammoCount.SetActive(false); FillFields(gameObject.GetComponent<RectTransform>(), ammoCount.GetComponent<RectTransform>()); } Transform obj2 = __instance.m_elementPrefab.transform.Find("MLUI_AmmoIcon"); ammoIcon = ((obj2 != null) ? ((Component)obj2).gameObject : null); if ((Object)(object)ammoIcon == (Object)null) { GameObject gameObject2 = ((Component)__instance.m_elementPrefab.transform.Find("icon")).gameObject; ammoIcon = Object.Instantiate<GameObject>(gameObject2); ((Object)ammoIcon).name = "MLUI_AmmoIcon"; ammoIcon.transform.SetParent(__instance.m_elementPrefab.transform); ammoIcon.transform.SetSiblingIndex(num); num++; ammoIcon.SetActive(false); FillFields(gameObject2.GetComponent<RectTransform>(), ammoIcon.GetComponent<RectTransform>()); } Transform obj3 = __instance.m_elementPrefab.transform.Find("MLUI_AmmoBait"); ammoBait = ((obj3 != null) ? ((Component)obj3).gameObject : null); if ((Object)(object)ammoBait == (Object)null) { GameObject gameObject3 = ((Component)__instance.m_elementPrefab.transform.Find("icon")).gameObject; ammoBait = Object.Instantiate<GameObject>(gameObject3); ((Object)ammoBait).name = "MLUI_AmmoBait"; ammoBait.transform.SetParent(__instance.m_elementPrefab.transform); ammoBait.transform.SetSiblingIndex(num); num++; ammoBait.SetActive(false); FillFields(gameObject3.GetComponent<RectTransform>(), ammoBait.GetComponent<RectTransform>()); } Transform obj4 = __instance.m_elementPrefab.transform.Find("MLUI_AmmoMead"); ammoMead = ((obj4 != null) ? ((Component)obj4).gameObject : null); if ((Object)(object)ammoMead == (Object)null) { GameObject gameObject4 = ((Component)__instance.m_elementPrefab.transform.Find("icon")).gameObject; ammoMead = Object.Instantiate<GameObject>(gameObject4); ((Object)ammoMead).name = "MLUI_AmmoMead"; ammoMead.transform.SetParent(__instance.m_elementPrefab.transform); ammoMead.transform.SetSiblingIndex(num); num++; ammoMead.SetActive(false); FillFields(gameObject4.GetComponent<RectTransform>(), ammoMead.GetComponent<RectTransform>()); } UpdateVisibility(); } } } [HarmonyPatch(typeof(HotkeyBar), "Update")] public static class HotkeyBar_Update_UpdateAmmoIconCountDirtyState { [HarmonyPriority(0)] [HarmonyBefore(new string[] { "Azumatt.AzuExtendedPlayerInventory", "shudnal.ExtraSlots" })] public static void Prefix(HotkeyBar __instance) { if (MyLittleUI.modEnabled.Value && GeneralExtensions.GetValueSafe<HotkeyBar, bool>(isDirty, __instance)) { isDirty[__instance] = false; if (__instance.m_elements.Count > 0) { __instance.m_items.Clear(); __instance.UpdateIcons((Player)null); } } } } [HarmonyPatch(typeof(HotkeyBar), "UpdateIcons")] public static class HotkeyBar_UpdateIcons_UpdateAmmoCountAndIcon { [HarmonyPriority(0)] [HarmonyAfter(new string[] { "Azumatt.AzuExtendedPlayerInventory", "shudnal.ExtraSlots" })] public static void Postfix(HotkeyBar __instance, Player player) { if (!MyLittleUI.modEnabled.Value) { return; } if (!elementExtraDatas.ContainsKey(__instance)) { elementExtraDatas.Add(__instance, new Dictionary<ElementData, ElementExtraData>()); } Dictionary<ElementData, ElementExtraData> dictionary = elementExtraDatas[__instance]; if (!Object.op_Implicit((Object)(object)player) || ((Character)player).IsDead()) { dictionary.Clear(); return; } if (dictionary.Count != __instance.m_elements.Count) { dictionary.Clear(); } if (dictionary.Count > 0 && __instance.m_elements.Count > 0 && !dictionary.ContainsKey(__instance.m_elements[0])) { dictionary.Clear(); } if (dictionary.Count == 0) { for (int i = 0; i < __instance.m_elements.Count; i++) { ElementData val = __instance.m_elements[i]; ElementExtraData value = new ElementExtraData { m_ammo = ((Component)val.m_go.transform.Find("MLUI_AmmoAmount")).GetComponent<TMP_Text>(), m_icon = ((Component)val.m_go.transform.Find("MLUI_AmmoIcon")).GetComponent<Image>(), m_bait = ((Component)val.m_go.transform.Find("MLUI_AmmoBait")).GetComponent<Image>(), m_mead = ((Component)val.m_go.transform.Find("MLUI_AmmoMead")).GetComponent<Image>() }; dictionary.Add(val, value); } } int num = 0; for (int j = 0; j < __instance.m_elements.Count; j++) { ElementData val2 = __instance.m_elements[j]; ElementExtraData elementExtraData = dictionary[val2]; if (elementExtraData == null) { continue; } if (!val2.m_used || num >= __instance.m_items.Count) { elementExtraData.m_item = null; } else { elementExtraData.m_item = __instance.m_items[num]; if ((Object)(object)elementExtraData.m_item.GetIcon() != (Object)(object)val2.m_icon.sprite) { elementExtraData.m_item = null; } num++; } elementExtraData.UpdateState(val2); } } } internal const string objectAmmoName = "MLUI_AmmoAmount"; internal const string objectIconName = "MLUI_AmmoIcon"; internal const string objectBaitName = "MLUI_AmmoBait"; internal const string objectMeadName = "MLUI_AmmoMead"; internal static GameObject elementPrefab; internal static GameObject ammoCount; internal static GameObject ammoIcon; internal static GameObject ammoBait; internal static GameObject ammoMead; internal static readonly Dictionary<HotkeyBar, bool> isDirty = new Dictionary<HotkeyBar, bool>(); internal static readonly Dictionary<HotkeyBar, Dictionary<ElementData, ElementExtraData>> elementExtraDatas = new Dictionary<HotkeyBar, Dictionary<ElementData, ElementExtraData>>(); public static void UpdateVisibility() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //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_00c1: 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) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)ammoCount) || !Object.op_Implicit((Object)(object)ammoIcon) || !Object.op_Implicit((Object)(object)ammoBait) || !Object.op_Implicit((Object)(object)ammoMead) || !Object.op_Implicit((Object)(object)elementPrefab)) { return; } RectTransform component = ammoCount.GetComponent<RectTransform>(); component.anchoredPosition = MyLittleUI.ammoCountPosition.Value; TMP_Text component2 = ammoCount.GetComponent<TMP_Text>(); component2.fontSize = MyLittleUI.ammoCountFontSize.Value; ((Graphic)component2).color = ((MyLittleUI.ammoCountColor.Value == Color.clear) ? ((Graphic)((Component)elementPrefab.transform.Find("amount")).GetComponent<TMP_Text>()).color : MyLittleUI.ammoCountColor.Value); component2.horizontalAlignment = MyLittleUI.ammoCountAlignment.Value; RectTransform component3 = ammoIcon.GetComponent<RectTransform>(); component3.anchoredPosition = MyLittleUI.ammoIconPosition.Value; component3.sizeDelta = MyLittleUI.ammoIconSize.Value; RectTransform component4 = ammoBait.GetComponent<RectTransform>(); component4.anchorMin = new Vector2(0.5f, 0f); component4.anchorMax = new Vector2(1f, 0.5f); RectTransform component5 = ammoMead.GetComponent<RectTransform>(); component5.anchorMin = new Vector2(0.6f, 0.6f); component5.anchorMax = new Vector2(1f, 1f); foreach (HotkeyBar item in isDirty.Keys.ToList()) { isDirty[item] = true; } } } internal class ChestItem { public int m_stack; public int m_value; public string m_name; public float m_weight; public ItemType m_itemType; public ChestItem(ItemData itemData) { //IL_0020: 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) m_name = itemData.m_shared.m_name; m_itemType = itemData.m_shared.m_itemType; } } internal static class ChestHoverText { [HarmonyPatch(typeof(Container), "OnContainerChanged")] private static class Container_OnContainerChanged_HoverCacheReset { private static void Postfix(Container __instance) { if (MyLittleUI.modEnabled.Value) { ResetCache(__instance); } } } [HarmonyPatch(typeof(Container), "GetHoverText")] private static class Container_GetHoverText_Duration { private static readonly StringBuilder result = new StringBuilder(); private static void ReorderItemList(ref List<ChestItem> itemsInChest) { if (MyLittleUI.chestContentSortType.Value == MyLittleUI.ContentSortType.Position) { return; } if (MyLittleUI.chestContentSortDir.Value == MyLittleUI.ContentSortDir.Desc) { if (MyLittleUI.chestContentSortType.Value == MyLittleUI.ContentSortType.Name) { itemsInChest = itemsInChest.OrderByDescending((ChestItem item) => item.m_name).ToList(); } else if (MyLittleUI.chestContentSortType.Value == MyLittleUI.ContentSortType.Weight) { itemsInChest = itemsInChest.OrderByDescending((ChestItem item) => item.m_weight).ToList(); } else if (MyLittleUI.chestContentSortType.Value == MyLittleUI.ContentSortType.Amount) { itemsInChest = itemsInChest.OrderByDescending((ChestItem item) => item.m_stack).ToList(); } else if (MyLittleUI.chestContentSortType.Value == MyLittleUI.ContentSortType.Value) { itemsInChest = itemsInChest.OrderByDescending((ChestItem item) => item.m_value).ToList(); } } else if (MyLittleUI.chestContentSortType.Value == MyLittleUI.ContentSortType.Name) { itemsInChest = itemsInChest.OrderBy((ChestItem item) => item.m_name).ToList(); } else if (MyLittleUI.chestContentSortType.Value == MyLittleUI.ContentSortType.Weight) { itemsInChest = itemsInChest.OrderBy((ChestItem item) => item.m_weight).ToList(); } else if (MyLittleUI.chestContentSortType.Value == MyLittleUI.ContentSortType.Amount) { itemsInChest = itemsInChest.OrderBy((ChestItem item) => item.m_stack).ToList(); } else if (MyLittleUI.chestContentSortType.Value == MyLittleUI.ContentSortType.Value) { itemsInChest = itemsInChest.OrderBy((ChestItem item) => item.m_value).ToList(); } } private static void AddChestContent(Container container) { //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: 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_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Expected I4, but got Unknown if (container.GetInventory().NrOfItems() == 0) { return; } result.Append("\n"); List<ChestItem> itemsInChest = new List<ChestItem>(); foreach (ItemData itemData in container.GetInventory().GetAllItemsInGridOrder()) { ChestItem chestItem = itemsInChest.Find((ChestItem item) => item.m_name == itemData.m_shared.m_name); if (chestItem == null) { chestItem = new ChestItem(itemData); itemsInChest.Add(chestItem); } chestItem.m_stack += itemData.m_stack; chestItem.m_value += itemData.GetValue(); chestItem.m_weight += itemData.GetWeight(-1); } ReorderItemList(ref itemsInChest); string itemFormat = "<color=#" + ColorUtility.ToHtmlStringRGBA(MyLittleUI.chestContentItemColor.Value) + ">{0}</color>"; string amountFormat = "<color=#" + ColorUtility.ToHtmlStringRGBA(MyLittleUI.chestContentAmountColor.Value) + ">{0}</color>"; int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; for (int num6 = 0; num6 < itemsInChest.Count; num6++) { ChestItem chestItem2 = itemsInChest[num6]; if (num6 < MyLittleUI.chestContentLinesToShow.Value) { AddItemLine(chestItem2.m_name, chestItem2.m_stack); continue; } ItemType itemType = chestItem2.m_itemType; ItemType val = itemType; switch (val - 1) { case 1: num3++; break; case 0: num5++; break; case 2: case 3: case 4: case 13: case 14: case 18: case 19: case 21: num4++; break; case 5: case 6: case 9: case 10: case 11: case 16: case 17: num2++; break; default: num++; break; } } if (num + num2 + num3 + num4 + num5 != 0) { result.Append("\n+"); if (num4 != 0) { AddItemLine("$radial_handitems", num4); } if (num2 != 0) { AddItemLine("$radial_armor_utility", num2); } if (num3 != 0) { AddItemLine("$radial_consumables", num3); } if (num5 != 0) { AddItemLine("$hud_crafting", num5); } if (num != 0) { AddItemLine("$hud_misc", num); } } void AddItemLine(string itemName, int amount) { result.AppendFormat("\n" + MyLittleUI.chestContentEntryFormat.Value, string.Format(itemFormat, itemName), string.Format(amountFormat, amount)); } } private static void Postfix(Container __instance, ref string __result, bool ___m_checkGuardStone, string ___m_name, Inventory ___m_inventory) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (!MyLittleUI.modEnabled.Value || (MyLittleUI.chestHoverName.Value == MyLittleUI.ChestNameHover.Vanilla && MyLittleUI.chestHoverItems.Value == MyLittleUI.ChestItemsHover.Vanilla) || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid() || (___m_checkGuardStone && !PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, false, false))) { return; } string key = ((object)__instance.m_nview.GetZDO()).ToString(); if (hoverTextCache.TryGetValue(key, out var value)) { __result = value; return; } result.Clear(); string text = __instance.m_nview.GetZDO().GetString(ZDOVars.s_text, ""); if (MyLittleUI.chestHoverName.Value == MyLittleUI.ChestNameHover.Vanilla || !MyLittleUI.chestCustomName.Value || Utility.IsNullOrWhiteSpace(text)) { result.Append(___m_name); } else if (MyLittleUI.chestHoverName.Value == MyLittleUI.ChestNameHover.CustomName) { result.Append(text); } else if (MyLittleUI.chestHoverName.Value == MyLittleUI.ChestNameHover.TypeThenCustomName) { result.Append(___m_name); result.Append(" ("); result.Append(text); result.Append(")"); } else if (MyLittleUI.chestHoverName.Value == MyLittleUI.ChestNameHover.CustomNameThenType) { result.Append(text); result.Append(" ("); result.Append(___m_name); result.Append(")"); } if (__instance.CheckAccess(Game.instance.GetPlayerProfile().GetPlayerID())) { result.Append(" "); if (MyLittleUI.chestHoverItems.Value == MyLittleUI.ChestItemsHover.Percentage) { result.Append($"{___m_inventory.SlotsUsedPercentage():F0}%"); } else if (MyLittleUI.chestHoverItems.Value == MyLittleUI.ChestItemsHover.FreeSlots) { result.Append($"{___m_inventory.GetEmptySlots()}"); } else if (MyLittleUI.chestHoverItems.Value == MyLittleUI.ChestItemsHover.ItemsMaxRoom) { result.Append($"{___m_inventory.NrOfItems()}/{___m_inventory.GetWidth() * ___m_inventory.GetHeight()}"); } else if (___m_inventory.NrOfItems() == 0) { result.Append("( $piece_container_empty )"); } result.Append("\n[<color=#ffff00ff><b>$KEY_Use</b></color>] $piece_container_open"); if (MyLittleUI.chestShowHoldToStack.Value) { result.Append(" $msg_stackall_hover"); } if (MyLittleUI.chestShowRename.Value) { if (!ZInput.IsNonClassicFunctionality() || !ZInput.IsGamepadActive()) { result.Append("\n[<color=#ffff00ff><b>$KEY_AltPlace + $KEY_Use</b></color>] $hud_rename"); } else { result.Append("\n[<color=#ffff00ff><b>$KEY_JoyAltKeys + $KEY_Use</b></color>] $hud_rename"); } } if (MyLittleUI.chestContentEnabled.Value) { AddChestContent(__instance); } } __result = Localization.instance.Localize(result.ToString()); hoverTextCache.Add(key, __result); } } [HarmonyPatch(typeof(Container), "Interact")] private class Container_Interact_ChestRename { private static bool Prefix(Container __instance, Humanoid character, bool hold, bool alt, bool ___m_checkGuardStone, bool __runOriginal) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (!__runOriginal) { return false; } if (!MyLittleUI.modEnabled.Value) { return true; } if (!MyLittleUI.chestCustomName.Value) { return true; } if (!alt) { return true; } if (hold) { return true; } if (___m_checkGuardStone && !PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, true, false)) { ((Character)character).Message((MessageType)2, "$piece_noaccess", 0, (Sprite)null, false); return true; } long playerID = Game.instance.GetPlayerProfile().GetPlayerID(); if (!__instance.CheckAccess(playerID)) { ((Character)character).Message((MessageType)2, "$piece_noaccess", 0, (Sprite)null, false); return true; } textInputForContainer = __instance; TextInput.instance.Show("$hud_rename " + __instance.m_name, __instance.m_nview.GetZDO().GetString(ZDOVars.s_text, ""), 32); return false; } } [HarmonyPatch(typeof(TextInput), "setText")] private class TextInput_setText_ChestRename { private static void Postfix(string text) { if (MyLittleUI.modEnabled.Value && !((Object)(object)textInputForContainer == (Object)null)) { textInputForContainer.m_nview.GetZDO().Set(ZDOVars.s_text, text); textInputForContainer.OnContainerChanged(); textInputForContainer = null; } } } [HarmonyPatch(typeof(TextInput), "Hide")] private class TextInput_Hide_ChestRename { private static void Postfix() { if (MyLittleUI.modEnabled.Value && !((Object)(object)textInputForContainer == (Object)null)) { textInputForContainer = null; } } } private static Container textInputForContainer; private static readonly Dictionary<string, string> hoverTextCache = new Dictionary<string, string>(); internal static void ResetCache(Container container) { if (!((Object)(object)container == (Object)null) && !((Object)(object)container.m_nview == (Object)null) && container.m_nview.IsValid()) { hoverTextCache.Remove(((object)container.m_nview.GetZDO()).ToString()); } } internal static void ResetHoverCache() { hoverTextCache.Clear(); } } internal static class RadialMenuHover { [HarmonyPatch] private static class KnownHoverMethods_Localize_AddRadialHint { private static IEnumerable<MethodBase> TargetMethods() { return GetKnownHoverMethods(); } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { return ReplaceLocalizationCall(instructions); } } [HarmonyPatch(typeof(RadialBase), "SelectStartElement")] private static class RadialBase_SelectStartElement_AdjustInitialMousePosition { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { foreach (CodeInstruction instruction in instructions) { if (SetMousePositionMethod != null && SetInitialMousePositionMethod != null && CodeInstructionExtensions.Calls(instruction, SetMousePositionMethod)) { CodeInstruction loadRadial = new CodeInstruction(OpCodes.Ldarg_0, (object)null); loadRadial.labels.AddRange(instruction.labels); instruction.labels.Clear(); yield return loadRadial; instruction.opcode = OpCodes.Call; instruction.operand = SetInitialMousePositionMethod; } yield return instruction; } } } [HarmonyPatch(typeof(Hud), "Awake")] private static class Hud_Awake_ApplyHoverTextWidth { [HarmonyPriority(0)] [HarmonyAfter(new string[] { "Azumatt.MinimalUI" })] private static void Postfix(Hud __instance) { ApplyHoverTextWidth(__instance); } } [HarmonyPatch(typeof(OpenRadialConfig), "TryOpenNonDefaultRadials")] private static class OpenRadialConfig_TryOpenNonDefaultRadials_PreferRegisteredReceiver { [HarmonyPriority(800)] private static bool Prefix(OpenRadialConfig __instance, RadialBase radial, ref bool __result) { if (!MyLittleUI.modEnabled.Value) { return true; } Player localPlayer = Player.m_localPlayer; GameObject val = (Object.op_Implicit((Object)(object)localPlayer) ? ((Humanoid)localPlayer).GetHoverObject() : null); if (!Object.op_Implicit((Object)(object)localPlayer) || !CanOpenContextualRadial(val)) { return true; } RadialMenuItemReceiver componentInParent = val.GetComponentInParent<RadialMenuItemReceiver>(); if (!Object.op_Implicit((Object)(object)componentInParent) || !componentInParent.IsActive) { return true; } if (!componentInParent.TryGetItems(localPlayer, out var items)) { return true; } if (items == null || items.Count <= 0) { if (RadialData.SO.OpenNormalRadialWhenHoverMenuFails) { __result = false; } else { if (radial != null) { radial.QueuedClose(); } __result = true; } return false; } __instance.OpenItemMenu(radial, localPlayer, items, val); __result = true; return false; } } [HarmonyPatch(typeof(OpenRadialConfig), "TryOpenNonDefaultRadials")] private static class OpenRadialConfig_TryOpenNonDefaultRadials_SuppressDefaultRadial { [HarmonyPriority(0)] private static void Postfix(RadialBase radial, ref bool __result) { if (__result || !MyLittleUI.modEnabled.Value) { return; } ConfigEntry<bool> hoverRadialMenuSuppressDefault = MyLittleUI.hoverRadialMenuSuppressDefault; if (hoverRadialMenuSuppressDefault == null || !hoverRadialMenuSuppressDefault.Value) { return; } Player localPlayer = Player.m_localPlayer; if (Object.op_Implicit((Object)(object)localPlayer) && Object.op_Implicit((Object)(object)((Humanoid)localPlayer).GetHoverObject())) { if (radial != null) { radial.QueuedClose(); } __result = true; } } } private const string UseKey = "$KEY_Use"; private const string RadialKey = "$KEY_OpenRadial"; private const string RadialHint = "[<color=yellow><b>$KEY_OpenRadial</b></color>] $settings_open_radial"; private static readonly HashSet<Type> CanUseErrorTypes = new HashSet<Type>(); private static RectTransform hoverTextTransform; private static float originalHoverTextWidth; private static readonly MethodInfo LocalizeMethod = AccessTools.Method(typeof(Localization), "Localize", new Type[1] { typeof(string) }, (Type[])null); private static readonly MethodInfo LocalizeHoverTextMethod = AccessTools.Method(typeof(RadialMenuHover), "LocalizeHoverText", (Type[])null, (Type[])null); private static readonly MethodInfo SetMousePositionMethod = AccessTools.Method(typeof(ZInput), "SetMousePosition", new Type[1] { typeof(Vector2) }, (Type[])null); private static readonly MethodInfo SetInitialMousePositionMethod = AccessTools.Method(typeof(RadialMenuHover), "SetInitialMousePosition", new Type[2] { typeof(Vector2), typeof(RadialBase) }, (Type[])null); private static bool CanOpenContextualRadial(GameObject hoverObject) { if (!Object.op_Implicit((Object)(object)hoverObject)) { return false; } Catapult val = default(Catapult); ShieldGenerator val2 = default(ShieldGenerator); Chair val3 = default(Chair); Switch val4 = default(Switch); if ((RadialUtilityExtensions.TryGetComponentInParent<Catapult>(hoverObject, ref val) || RadialUtilityExtensions.TryGetComponentInParent<ShieldGenerator>(hoverObject, ref val2) || RadialUtilityExtensions.TryGetComponentInParent<Chair>(hoverObject, ref val3)) && !hoverObject.TryGetComponent<Switch>(ref val4)) { return false; } return hoverObject.GetComponentInParent<Interactable>() != null; } private static bool CanUseHoveredItems(Player player, GameObject hoverObject) { Type type = null; try { RadialMenuItemReceiver componentInParent = hoverObject.GetComponentInParent<RadialMenuItemReceiver>(); if (Object.op_Implicit((Object)(object)componentInParent)) { type = ((object)componentInParent).GetType(); return componentInParent.IsActive && componentInParent.CanUseItems(player, sendErrorMessage: false); } IHasHoverMenu val = default(IHasHoverMenu); if (RadialUtilityExtensions.TryGetComponentInParent<IHasHoverMenu>(hoverObject, ref val)) { type = ((object)val).GetType(); return val.CanUseItems(player, false); } IHasHoverMenuExtended val2 = default(IHasHoverMenuExtended); if (RadialUtilityExtensions.TryGetComponentInParent<IHasHoverMenuExtended>(hoverObject, ref val2)) { type = ((object)val2).GetType(); return val2.CanUseItems(player, hoverObject.GetComponent<Switch>(), false); } } catch (Exception arg) { if (type == null || CanUseErrorTypes.Add(type)) { MyLittleUI.LogWarning(string.Format("Failed to evaluate contextual radial availability for '{0}'.{1}{2}", type?.FullName ?? "unknown type", Environment.NewLine, arg)); } } return false; } internal static string AddRadialHint(string hoverText) { if (MyLittleUI.modEnabled.Value) { ConfigEntry<bool> hoverRadialMenuHint = MyLittleUI.hoverRadialMenuHint; if (hoverRadialMenuHint != null && hoverRadialMenuHint.Value && !string.IsNullOrWhiteSpace(hoverText) && hoverText.IndexOf("$KEY_OpenRadial", StringComparison.Ordinal) < 0) { Player localPlayer = Player.m_localPlayer; GameObject hoverObject = (Object.op_Implicit((Object)(object)localPlayer) ? ((Humanoid)localPlayer).GetHoverObject() : null); if (!Object.op_Implicit((Object)(object)localPlayer) || !CanOpenContextualRadial(hoverObject) || !CanUseHoveredItems(localPlayer, hoverObject)) { return hoverText; } int num = hoverText.IndexOf("$KEY_Use", StringComparison.Ordinal); if (num < 0) { return hoverText; } int num2 = hoverText.IndexOf('\n', num); if (num2 < 0) { return hoverText + "\n[<color=yellow><b>$KEY_OpenRadial</b></color>] $settings_open_radial"; } return hoverText.Insert(num2 + 1, "[<color=yellow><b>$KEY_OpenRadial</b></color>] $settings_open_radial\n"); } } return hoverText; } private static string LocalizeHoverText(Localization localization, string hoverText) { return localization.Localize(AddRadialHint(hoverText)); } private static void SetInitialMousePosition(Vector2 selectedPosition, RadialBase radial) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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) float num = ((MyLittleUI.modEnabled.Value && MyLittleUI.radialMenuInitialCursorDistance != null) ? Mathf.Clamp(MyLittleUI.radialMenuInitialCursorDistance.Value, 0f, 2f) : 1f); Vector2 val = ((Object.op_Implicit((Object)(object)radial) && Object.op_Implicit((Object)(object)radial.m_elementInfo) && Object.op_Implicit((Object)(object)radial.m_elementInfo.m_title)) ? Vector2.op_Implicit(((TMP_Text)radial.m_elementInfo.m_title).transform.position) : selectedPosition); ZInput.SetMousePosition(Vector2.LerpUnclamped(val, selectedPosition, num)); } private static IEnumerable<MethodInfo> GetArmorStandHoverMethods() { IEnumerable<Type> nestedTypes = typeof(ArmorStand).GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic); return from method in typeof(ArmorStand).GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Concat(nestedTypes.SelectMany((Type type) => type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))) where method.Name.IndexOf("<Awake>", StringComparison.Ordinal) >= 0 && method.ReturnType == typeof(string) && method.GetParameters().Length == 0 select method; } private static IEnumerable<MethodBase> GetKnownHoverMethods() { MethodBase[] source = new MethodBase[8] { AccessTools.Method(typeof(Fireplace), "GetHoverText", (Type[])null, (Type[])null), AccessTools.Method(typeof(CookingStation), "GetHoverText", (Type[])null, (Type[])null), AccessTools.Method(typeof(CookingStation), "OnHoverFuelSwitch", (Type[])null, (Type[])null), AccessTools.Method(typeof(Smelter), "OnHoverAddFuel", (Type[])null, (Type[])null), AccessTools.Method(typeof(Smelter), "OnHoverAddOre", (Type[])null, (Type[])null), AccessTools.Method(typeof(ShieldGenerator), "OnHoverAddFuel", (Type[])null, (Type[])null), AccessTools.Method(typeof(Turret), "GetHoverText", (Type[])null, (Type[])null), AccessTools.Method(typeof(Switch), "GetHoverText", (Type[])null, (Type[])null) }; return source.Where((MethodBase method) => method != null).Concat(GetArmorStandHoverMethods()).Concat(RadialMenuItemReceiver.GetHoverTextMethods()) .Distinct(); } private static IEnumerable<CodeInstruction> ReplaceLocalizationCall(IEnumerable<CodeInstruction> instructions) { foreach (CodeInstruction instruction in instructions) { if (LocalizeMethod != null && LocalizeHoverTextMethod != null && CodeInstructionExtensions.Calls(instruction, LocalizeMethod)) { instruction.opcode = OpCodes.Call; instruction.operand = LocalizeHoverTextMethod; } yield return instruction; } } internal static void ApplyHoverTextWidth(Hud hud = null) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) if (hud == null) { hud = Hud.instance; } if (Object.op_Implicit((Object)(object)hud) && Object.op_Implicit((Object)(object)hud.m_hoverName) && MyLittleUI.hoverTextWidth != null) { RectTransform rectTransform = ((TMP_Text)hud.m_hoverName).rectTransform; if ((Object)(object)hoverTextTransform != (Object)(object)rectTransform) { hoverTextTransform = rectTransform; Rect rect = rectTransform.rect; originalHoverTextWidth = ((Rect)(ref rect)).width; } rectTransform.SetSizeWithCurrentAnchors((Axis)0, MyLittleUI.modEnabled.Value ? MyLittleUI.hoverTextWidth.Value : originalHoverTextWidth); } } } internal sealed class RadialMenuItemReceiver : MonoBehaviour, IHasHoverMenu { private sealed class ReceiverDefinition { internal Type TargetType { get; } internal Func<bool> Enabled { get; } internal Func<Component, Player, IEnumerable<string>> GetItems { get; } internal Func<Component, Player, bool, bool> CanUseItems { get; } internal MethodBase[] HoverTextMethods { get; } internal bool OverrideTargetHoverMenu { get; } internal ReceiverDefinition(Type targetType, Func<bool> enabled, Func<Component, Player, IEnumerable<string>> getItems, Func<Component, Player, bool, bool> canUseItems, MethodBase[] hoverTextMethods, bool overrideTargetHoverMenu) { TargetType = targetType; Enabled = enabled; GetItems = getItems; CanUseItems = canUseItems; HoverTextMethods = hoverTextMethods; OverrideTargetHoverMenu = overrideTargetHoverMenu; } } [HarmonyPatch] private static class RegisteredReceiver_Initialize_AttachAdapter { private static IEnumerable<MethodBase> TargetMethods() { return GetTargetInitializationMethods(); } [HarmonyPriority(0)] private static void Postfix(object __instance) { Component val = (Component)((__instance is Component) ? __instance : null); if (val != null) { TryAttach(val); } } } private static readonly ReceiverDefinition[] Definitions = new ReceiverDefinition[2] { Create<Fermenter>((Func<bool>)(() => MyLittleUI.radialMenuFermenterItemSelection?.Value ?? false), (Func<Fermenter, Player, IEnumerable<string>>)GetFermenterItems, (Func<Fermenter, Player, bool, bool>)CanUseFermenterItems, new MethodBase[1] { AccessTools.Method(typeof(Fermenter), "GetHoverText", (Type[])null, (Type[])null) }), Create<ShieldGenerator>((Func<bool>)(() => MyLittleUI.radialMenuShieldGeneratorItemSelection?.Value ?? false), (Func<ShieldGenerator, Player, IEnumerable<string>>)GetShieldGeneratorItems, (Func<ShieldGenerator, Player, bool, bool>)CanUseShieldGeneratorItems, overrideTargetHoverMenu: true, new MethodBase[1] { AccessTools.Method(typeof(ShieldGenerator), "OnHoverAddFuel", (Type[])null, (Type[])null) }) }; private static readonly HashSet<Type> ErrorTypes = new HashSet<Type>(); private Component target; private ReceiverDefinition definition; internal bool IsActive { get { int result; if (Object.op_Implicit((Object)(object)target) && definition != null) { ConfigEntry<bool> modEnabled = MyLittleUI.modEnabled; if (modEnabled != null && modEnabled.Value) { result = (definition.Enabled() ? 1 : 0); goto IL_003b; } } result = 0; goto IL_003b; IL_003b: return (byte)result != 0; } } private static ReceiverDefinition Create<T>(Func<bool> enabled, Func<T, Player, IEnumerable<string>> getItems, Func<T, Player, bool, bool> canUseItems, params MethodBase[] hoverTextMethods) where T : Component { return Create(enabled, getItems, canUseItems, overrideTargetHoverMenu: false, hoverTextMethods); } private static ReceiverDefinition Create<T>(Func<bool> enabled, Func<T, Player, IEnumerable<string>> getItems, Func<T, Player, bool, bool> canUseItems, bool overrideTargetHoverMenu, params MethodBase[] hoverTextMethods) where T : Component { return new ReceiverDefinition(typeof(T), enabled, (Component component, Player player) => getItems((T)(object)component, player), (Component component, Player player, bool sendErrorMessage) => canUseItems((T)(object)component, player, sendErrorMessage), hoverTextMethods?.Where((MethodBase method) => method != null).ToArray() ?? Array.Empty<MethodBase>(), overrideTargetHoverMenu); } internal static IEnumerable<MethodBase> GetHoverTextMethods() { return Definitions.SelectMany((ReceiverDefinition receiver) => receiver.HoverTextMethods).Distinct(); } private static IEnumerable<MethodBase> GetTargetInitializationMethods() { return (from receiver in Definitions select AccessTools.Method(receiver.TargetType, "Awake", Type.EmptyTypes, (Type[])null) ?? AccessTools.Method(receiver.TargetType, "Start", Type.EmptyTypes, (Type[])null) into method where method != null select method).Distinct(); } private static void TryAttach(Component targetComponent) { if (!Object.op_Implicit((Object)(object)targetComponent)) { return; } ReceiverDefinition targetDefinition = Definitions.FirstOrDefault((ReceiverDefinition receiver) => receiver.TargetType.IsInstanceOfType(targetComponent)); if (targetDefinition != null) { MonoBehaviour[] components = targetComponent.GetComponents<MonoBehaviour>(); if (!components.Any((MonoBehaviour component) => !(component is RadialMenuItemReceiver) && (component is IHasHoverMenu || component is IHasHoverMenuExtended) && (!targetDefinition.OverrideTargetHoverMenu || (Object)(object)component != (Object)(object)targetComponent))) { RadialMenuItemReceiver radialMenuItemReceiver = components.OfType<RadialMenuItemReceiver>().FirstOrDefault() ?? targetComponent.gameObject.AddComponent<RadialMenuItemReceiver>(); radialMenuItemReceiver.target = targetComponent; radialMenuItemReceiver.definition = targetDefinition; } } } public bool TryGetItems(Player player, out List<string> items) { items = new List<string>(); if (!IsActive) { return false; } try { if (!definition.CanUseItems(target, player, arg3: true)) { return true; } items = (definition.GetItems(target, player) ?? Enumerable.Empty<string>()).Where((string item) => !string.IsNullOrWhiteSpace(item)).Distinct().ToList(); return true; } catch (Exception exception) { LogFailure(exception); return false; } } public bool CanUseItems(Player player, bool sendErrorMessage = true) { if (!IsActive) { return false; } try { return definition.CanUseItems(target, player, sendErrorMessage); } catch (Exception exception) { LogFailure(exception); return false; } } private void LogFailure(Exception exception) { Type type = definition?.TargetType; if (type == null || ErrorTypes.Add(type)) { MyLittleUI.LogWarning(string.Format("Failed to evaluate radial menu item receiver for '{0}'.{1}{2}", type?.FullName ?? "unknown type", Environment.NewLine, exception)); } } private static IEnumerable<string> GetFermenterItems(Fermenter fermenter, Player _) { if (!Object.op_Implicit((Object)(object)fermenter) || fermenter.m_conversion == null) { yield break; } foreach (ItemConversion conversion in fermenter.m_conversion) { if ((Object)(object)conversion?.m_from != (Object)null) { yield return conversion.m_from.m_itemData.m_shared.m_name; } } } private static bool CanUseFermenterItems(Fermenter fermenter, Player player, bool sendErrorMessage) { //IL_0054: 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_007a: Invalid comparison between Unknown and I4 if (!Object.op_Implicit((Object)(object)fermenter) || !Object.op_Implicit((Object)(object)player) || (Object)(object)fermenter.m_nview == (Object)null || fermenter.m_nview.GetZDO() == null) { return false; } if (sendErrorMessage) { fermenter.UpdateCover(0f, true); } if (!PrivateArea.CheckAccess(((Component)fermenter).transform.position, 0f, sendErrorMessage, false)) { return false; } if ((int)fermenter.GetStatus() > 0) { return false; } if (!fermenter.m_hasRoof) { if (sendErrorMessage) { ((Character)player).Message((MessageType)2, "$piece_fermenter_needroof", 0, (Sprite)null, false); } return false; } if (fermenter.m_exposed) { if (sendErrorMessage) { ((Character)player).Message((MessageType)2, "$piece_fermenter_exposed", 0, (Sprite)null, false); } return false; } if (fermenter.FindCookableItem(((Humanoid)player).GetInventory()) != null) { return true; } if (sendErrorMessage) { ((Character)player).Message((MessageType)2, "$msg_noprocessableitems", 0, (Sprite)null, false); } return false; } private static IEnumerable<string> GetShieldGeneratorItems(ShieldGenerator shieldGenerator, Player _) { if (!Object.op_Implicit((Object)(object)shieldGenerator) || shieldGenerator.m_fuelItems == null) { yield break; } foreach (ItemDrop fuelItem in shieldGenerator.m_fuelItems) { if ((Object)(object)fuelItem != (Object)null) { yield return fuelItem.m_itemData.m_shared.m_name; } } } private static bool CanUseShieldGeneratorItems(ShieldGenerator shieldGenerator, Player player, bool sendErrorMessage) { if (!Object.op_Implicit((Object)(object)shieldGenerator) || !Object.op_Implicit((Object)(object)player) || (Object)(object)shieldGenerator.m_nview == (Object)null || !shieldGenerator.m_nview.IsValid()) { return false; } if (shieldGenerator.GetFuel() > (float)shieldGenerator.m_maxFuel - 1f) { if (sendErrorMessage) { ((Character)player).Message((MessageType)2, "$msg_itsfull", 0, (Sprite)null, false); } return false; } if (shieldGenerator.m_fuelItems != null && shieldGenerator.m_fuelItems.Any((ItemDrop item) => (Object)(object)item != (Object)null && ((Humanoid)player).GetInventory().HaveItem(item.m_itemData.m_shared.m_name, true))) { return true; } if (sendErrorMessage) { ((Character)player).Message((MessageType)2, "$msg_donthaveany $piece_shieldgenerator_fuelname", 0, (Sprite)null, false); } return false; } } public static class CraftFilter { [HarmonyPatch(typeof(InventoryGui), "Awake")] public static class StoreGui_Awake_InitializePanel { [HarmonyPriority(800)] private static void Postfix() { InitFilterField(); UpdateVisibility(); } } [HarmonyPatch(typeof(InventoryGui), "Show")] public static class InventoryGui_Show_ClearCache { public static void Postfix() { ClearText(); } } [HarmonyPatch(typeof(InventoryGui), "OnDestroy")] public static class InventoryGui_OnDestroy_ClearCache { public static void Postfix() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) ((MonoBehaviour)MyLittleUI.instance).CancelInvoke("UpdateCraftingPanel"); recipeCache.Clear(); playerFilter = null; applyFilter = false; filterString = Array.Empty<string>(); listAnchorMin = new Vector2(-1f, -1f); } } [HarmonyPatch(typeof(Chat), "HasFocus")] public static class Chat_HasFocus_FocusOverride { public static void Postfix(ref bool __result) { __result = __result || (IsCraftingFilterEnabled && Object.op_Implicit((Object)(object)playerFilter) && ((TMP_InputField)playerFilter).isFocused); } } [HarmonyPatch(typeof(Player), "GetAvailableRecipes")] public static class Player_GetAvailableRecipes_FilterRecipeList { [HarmonyPriority(0)] public static void Postfix(ref List<Recipe> available) { if (IsCraftingFilterEnabled && applyFilter) { Stopwatch stopwatch = Stopwatch.StartNew(); CollectionExtensions.Do<Recipe>((IEnumerable<Recipe>)available, (Action<Recipe>)CacheRecipe); MyLittleUI.LogInfo($"Recipe cache: verified {recipeCache.Count} in {(double)stopwatch.ElapsedTicks / (double)Stopwatch.Frequency * 1000.0:F2} ms"); stopwatch.Restart(); int num = available.RemoveAll((Recipe recipe) => !FitsFilterString(recipe)); MyLittleUI.LogInfo($"Recipe filter: removed {num} in {(double)stopwatch.ElapsedTicks / (double)Stopwatch.Frequency * 1000.0:F2} ms"); stopwatch.Stop(); } } } [HarmonyPatch(typeof(InventoryGui), "UpdateRecipe")] public static class InventoryGui_UpdateRecipe_HandleFieldFocus { public static void Postfix() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 if (!IsCraftingFilterEnabled || !Object.op_Implicit((Object)(object)playerFilter) || !((Behaviour)playerFilter).isActiveAndEnabled) { return; } bool flag = (int)ZInput.InputLayout == 1; bool button = ZInput.GetButton("JoyLBumper"); bool button2 = ZInput.GetButton("JoyLTrigger"); if (((TMP_InputField)playerFilter).isFocused) { if (ZInput.GetButtonDown("Chat") || ZInput.GetButtonDown("Block") || ZInput.GetButtonDown("Console") || ZInput.GetButtonDown("Escape") || ZInput.GetButtonDown("Inventory") || (ZInput.GetButtonDown("JoyChat") && ZInput.GetButton("JoyAltKeys") && !(flag && button2) && !(!flag && button))) { ((TMP_InputField)playerFilter).DeactivateInputField(false); } } else if ((Object)(object)Player.m_localPlayer != (Object)null && !Console.IsVisible() && !TextInput.IsVisible() && !Minimap.InTextInput() && !Menu.IsVisible() && (ZInput.GetButtonDown("Chat") || (ZInput.GetButtonDown("JoyChat") && ZInput.GetButton("JoyAltKeys") && !(flag && button2) && !(!flag && button)))) { playerFilter.ActivateInputField(); } } } private const float fieldHeight = 32f; private static Vector2 listAnchorMin = new Vector2(-1f, -1f); private static readonly Dictionary<Recipe, string> recipeCache = new Dictionary<Recipe, string>(); private static GuiInputField playerFilter; private static string[] filterString = Array.Empty<string>(); private static bool applyFilter; private static readonly StringBuilder sb = new StringBuilder(); private static readonly StringBuilder sbItem = new StringBuilder(); public static bool IsCraftingFilterEnabled => MyLittleUI.modEnabled.Value && MyLittleUI.craftingFilterEnabled.Value && !MyLittleUI.AAA_Crafting && !MyLittleUI.ZenUI; private static void InitFilterField() { //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Expected O, but got Unknown //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Expected O, but got Unknown //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) if (MyLittleUI.AAA_Crafting || MyLittleUI.ZenUI || Object.op_Implicit((Object)(object)playerFilter)) { return; } InventoryGui instance = InventoryGui.instance; if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)instance.m_recipeListScroll) || !Object.op_Implicit((Object)(object)TextInput.instance) || !Object.op_Implicit((Object)(object)TextInput.instance.m_inputField) || !Object.op_Implicit((Object)(object)instance.m_splitDialog) || !Object.op_Implicit((Object)(object)instance.m_splitDialog.m_splitOkButton)) { return; } Transform parent = ((Component)instance.m_recipeListScroll).transform.parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if (!Object.op_Implicit((Object)(object)val)) { return; } GameObject val2 = Object.Instantiate<GameObject>(((Component)TextInput.instance.m_inputField).gameObject, ((Transform)val).parent); ((Object)val2).name = "MLUI_FilterField"; val2.transform.SetSiblingIndex(((Transform)val).GetSiblingIndex() + 1); RectTransform component = val2.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.zero; Rect rect = val.rect; component.sizeDelta = new Vector2(((Rect)(ref rect)).width, 32f); component.anchoredPosition = new Vector2(val.anchoredPosition.x, 4f); component.pivot = Vector2.zero; playerFilter = val2.GetComponent<GuiInputField>(); playerFilter.VirtualKeyboardTitle = "$menu_filter"; Transform obj = ((Component)playerFilter).transform.Find("Text Area/Placeholder"); if (obj != null) { TMP_Text component2 = ((Component)obj).GetComponent<TMP_Text>(); if (component2 != null) { component2.SetText(Localization.instance.Localize("$menu_filter")); } } ((TMP_InputField)playerFilter).restoreOriginalTextOnEscape = false; Button val3 = Object.Instantiate<Button>(instance.m_splitDialog.m_splitOkButton, val2.transform); ((Object)val3).name = "ClearTextButton"; val3.onClick = new ButtonClickedEvent(); ((UnityEvent)val3.onClick).AddListener(new UnityAction(ClearText)); RectTransform component3 = ((Component)val3).GetComponent<RectTransform>(); component3.anchorMin = new Vector2(1f, 0.5f); component3.anchorMax = new Vector2(1f, 0.5f); component3.sizeDelta = Vector2.one * 28f; component3.anchoredPosition = new Vector2(-16f, 0f); TMP_Text componentInChildren = ((Component)val3).GetComponentInChildren<TMP_Text>(true); if (Object.op_Implicit((Object)(object)componentInChildren)) { componentInChildren.SetText("✖"); componentInChildren.margin = Vector4.one * -2f; } UIGamePad component4 = ((Component)val3).GetComponent<UIGamePad>(); if (Object.op_Implicit((Object)(object)component4)) { component4.m_zinputKey = ""; component4.m_keyCode = (KeyCode)0; ((Behaviour)component4).enabled = false; if (Object.op_Implicit((Object)(object)component4.m_hint) && component4.m_hint.transform.IsChildOf(((Component)val3).transform)) { component4.m_hint.SetActive(false); } component4.m_hint = null; } ((UnityEvent<string>)(object)((TMP_InputField)playerFilter).onValueChanged).AddListener((UnityAction<string>)delegate { UpdateFilterString(); StartPanelUpdate(); }); } public static void UpdateVisibility() { //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) if (MyLittleUI.AAA_Crafting || MyLittleUI.ZenUI || !Object.op_Implicit((Object)(object)InventoryGui.instance)) { return; } if (Object.op_Implicit((Object)(object)playerFilter)) { if (!IsCraftingFilterEnabled && ((TMP_InputField)playerFilter).isFocused) { ((TMP_InputField)playerFilter).DeactivateInputField(false); } ((Component)playerFilter).gameObject.SetActive(IsCraftingFilterEnabled); } if (!Object.op_Implicit((Object)(object)InventoryGui.instance.m_recipeListScroll)) { return; } Transform parent = ((Component)InventoryGui.instance.m_recipeListScroll).transform.parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if (Object.op_Implicit((Object)(object)val)) { if (listAnchorMin.x == -1f) { listAnchorMin = val.anchorMin; } val.anchorMin = ((Object.op_Implicit((Object)(object)playerFilter) && ((Behaviour)playerFilter).isActiveAndEnabled) ? (listAnchorMin + new Vector2(0f, 0.05f)) : listAnchorMin); } } public static void UpdateFilterString() { GuiInputField obj = playerFilter; applyFilter = !string.IsNullOrWhiteSpace((obj != null) ? ((TMP_InputField)obj).text : null); filterString = (applyFilter ? ((TMP_InputField)playerFilter).text.ToLowerInvariant().Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries) : Array.Empty<string>()); } public static void ClearText() { applyFilter = false; filterString = Array.Empty<string>(); if (Object.op_Implicit((Object)(object)playerFilter)) { ((TMP_InputField)playerFilter).text = ""; } } private static string GetItemFullString(ItemDrop itemDrop) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)itemDrop)) { return ""; } sbItem.Clear(); sbItem.Append(((Object)itemDrop).name); sbItem.Append(' '); sbItem.Append(itemDrop.m_itemData.m_shared.m_itemType); sbItem.Append(' '); sbItem.Append(itemDrop.m_itemData.m_shared.m_setName); sbItem.Append(' '); sbItem.Append(itemDrop.m_itemData.m_shared.m_name); sbItem.Append(' '); sbItem.Append(Localization.instance.Localize(itemDrop.m_itemData.m_shared.m_name)); sbItem.Append(' '); sbItem.Append(itemDrop.m_itemData.GetTooltip(-1)); return sbItem.ToString(); } private static void CacheRecipe(Recipe recipe) { if (!Object.op_Implicit((Object)(object)recipe) || recipeCache.ContainsKey(recipe)) { return; } sb.Clear(); sb.Append(((Object)recipe).name); sb.Append(' '); sb.Append(GetItemFullString(recipe.m_item)); sb.Append(' '); Requirement[] resources = recipe.m_resources; foreach (Requirement val in resources) { if (val != null) { sb.Append(GetItemFullString(val.m_resItem)); sb.Append(' '); } } recipeCache[recipe] = sb.ToString().ToLowerInvariant(); } private static bool FitsFilterString(Recipe recipe) { return Object.op_Implicit((Object)(object)recipe) && recipeCache.ContainsKey(recipe) && filterString.All((string substr) => recipeCache[recipe].Contains(substr)); } private static void StartPanelUpdate() { ((MonoBehaviour)MyLittleUI.instance).CancelInvoke("UpdateCraftingPanel"); ((MonoBehaviour)MyLittleUI.instance).Invoke("UpdateCraftingPanel", (recipeCache.Count == 0) ? 0.4f : 0.2f); } public static void UpdateCraftingPanel() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)InventoryGui.instance) && Object.op_Implicit((Object)(object)Player.m_localPlayer)) { InventoryGui.instance.UpdateCraftingPanel(true); InventoryGui.instance.m_moveItemEffects.Create(((Component)Player.m_localPlayer).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } } } public static class CraftSort { public class FilteringPanel { public string name; public RectTransform panel; public RectTransform selectedFrame; public List<FilteringState> filters; public bool enabled; public int enabledFilters; public override string ToString() { return name; } public FilteringPanel(string name) { this.name = name; ref RectTransform reference = ref panel; Transform repairPanel = InventoryGui.instance.m_repairPanel; reference = Object.Instantiate<RectTransform>((RectTransform)(object)((repairPanel is RectTransform) ? repairPanel : null), (Transform)(object)sortPanel); ((Object)panel).name = "MLUI_SortingPanel_" + name; if (Object.op_Implicit((Object)(object)InventoryGui.instance.m_repairPanelSelection)) { ref RectTransform reference2 = ref selectedFrame; Transform repairPanelSelection = InventoryGui.instance.m_repairPanelSelection; reference2 = Object.Instantiate<RectTransform>((RectTransform)(object)((repairPanelSelection is RectTransform) ? repairPanelSelection : null), ((Component)InventoryGui.instance.m_repairPanelSelection).transform.parent); ((Object)selectedFrame).name = "selected (" + ((Object)panel).name + ")"; } filters = new List<FilteringState>(); panels.Add(this); } public void AddFilter(FilteringState filter) { filters.Add(filter); } public void UpdatePosition(ref int height) { //IL_0054: 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_009d: 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_00b1: 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_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.CeilToInt((float)enabledFilters / 3f); int num2 = 34 * num - 2 + 12; int num3 = 0; if (enabledFilters == 2) { num3 = 34; } else if (enabledFilters == 1) { num3 = 68; } panel.sizeDelta = new Vector2(120f - (float)num3, (float)num2); height += num2; panel.anchoredPosition = new Vector2(0f, (float)(-height)); if (Object.op_Implicit((Object)(object)selectedFrame)) { selectedFrame.sizeDelta = panel.sizeDelta + new Vector2(4f, 4f); selectedFrame.anchoredPosition = panel.anchoredPosition - new Vector2(panel.sizeDelta.x + 2f, 202f); } } public void UpdateVisibility() { RectTransform obj = panel; if (obj != null) { ((Component)obj).gameObject.SetActive(enabled); } RectTransform obj2 = selectedFrame; if (obj2 != null) { ((Component)obj2).gameObject.SetActive(enabled); } } public void ClearPanel() { enabled = false; enabledFilters = 0; CollectionExtensions.Do<FilteringState>((IEnumerable<FilteringState>)filters, (Action<FilteringState>)delegate(FilteringState state) { state.ClearFiltering(); }); UpdateVisibility(); } } public class FilteringState { public int position; public bool selectable; public bool enabled; public bool selected; public bool lastSelected; public string category; public string tooltip; public Sprite icon; public string name; public Color imageColor; public bool unique = true; public RectTransform element; public Button button; public Image image; public GameObject active; public GameObject select; public FilteringPanel panel; public Comparison<RecipeDataPair> sort; public Func<ItemData, bool> filter; public FilteringState() { filteringStates.Add(this); } public void CreateElement() { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)element)) { element = Object.Instantiate<RectTransform>(elementPrefab, (Transform)(object)panel.panel); ((Object)element).name = name; ((Component)element).gameObject.SetActive(true); ((Component)element).GetComponent<UITooltip>().m_text = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(Localization.instance.Localize(tooltip)); image = ((Component)((Transform)element).Find("icon")).GetComponent<Image>(); if (Object.op_Implicit((Object)(object)image)) { image.overrideSprite = icon; ((Graphic)image).color = ((imageColor != Color.clear) ? imageColor : Color.white); Transform transform = ((Component)image).transform; transform.localScale *= 0.9f; } button = ((Component)element).GetComponent<Button>(); Transform obj = ((Transform)element).Find("active"); active = ((obj != null) ? ((Component)obj).gameObject : null); Transform obj2 = ((Transform)element).Find("selected"); select = ((obj2 != null) ? ((Component)obj2).gameObject : null); ((UnityEvent)button.onClick).AddListener(new UnityAction(OnClick)); UpdateElementPosition(); } } public void UpdateElementPosition() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)element)) { element.anchoredPosition = new Vector2(8f + (float)(position % 3) * 34f, -6f - (float)(position / 3) * 34f); } } public void UpdatePosition(ref int currentPosition) { position = currentPosition; if (selectable) { currentPosition++; } UpdateElementPosition(); } public void UpdateEnabled() { GameObject obj = active; if (obj != null) { obj.SetActive(enabled); } } public void UpdateSelectable() { RectTransform obj = element; if (obj != null) { GameObject gameObject = ((Component)obj).gameObject; if (gameObject != null) { gameObject.SetActive(selectable); } } } public void UpdateSelect() { GameObject obj = select; if (obj != null) { obj.SetActive(selected); } } public void SetSelected(bool selected) { this.selected = selected; if (selected) { lastSelected = true; CollectionExtensions.DoIf<FilteringState>((IEnumerable<FilteringState>)filteringStates, (Func<FilteringState, bool>)((FilteringState fs) => fs != this), (Action<FilteringState>)delegate(FilteringState fs) { fs.lastSelected = false; }); } } public void ClearFiltering() { selectable = false; enabled = false; selected = false; position = 0; UpdateEnabled(); UpdateSelectable(); UpdateSelect(); } public bool IsSelectable(ItemData item) { return filter != null && filter(item); } public void OnClick() { enabled = !enabled; UpdateEnabled(); if (unique) { CollectionExtensions.DoIf<FilteringState>((IEnumerable<FilteringState>)filteringStates, (Func<FilteringState, bool>)((FilteringState fs) => fs != this), (Action<FilteringState>)delegate(FilteringState fs) { fs.enabled = false; fs.UpdateEnabled(); }); } InventoryGui.instance.UpdateCraftingPanel(true); } } [HarmonyPatch(typeof(Game), "SpawnPlayer")] public static class Game_SpawnPlayer_InitializePanel { public static void Postfix() { CheckPanels(); } } [HarmonyPatch(typeof(InventoryGui), "Update")] public static class InventoryGui_Update_SortingPanelVisibility { public static void Postfix() { UpdateVisibility(); } } [HarmonyPatch(typeof(InventoryGui), "Show")] public static class InventoryGui_Show_ClearFiltersState { public static void Prefix() { ClearPanels(); } } [HarmonyPatch(typeof(InventoryGui), "OnDestroy")] public static class InventoryGui_OnDestroy_ClearData { public static void Prefix() { filteringStates.Clear(); tempEnabledStates.Clear(); panels.Clear(); sortPanel = null; elementPrefab = null; foodSprite = null; } } [HarmonyPatch(typeof(InventoryGui), "UpdateCraftingPanel")] public static class InventoryGui_UpdateCraftingPanel_HideWithOtherMods { [HarmonyPriority(0)] public static void Postfix(InventoryGui __instance) { if (!__instance.InCraftTab() && !__instance.InUpradeTab()) { ClearPanels(); } } } [HarmonyPatch(typeof(InventoryGui), "Update")] public static class InventoryGui_Update_HideWithOtherMods { [HarmonyPriority(0)] public static void Postfix(InventoryGui __instance) { if (!__instance.InCraftTab() && !__instance.InUpradeTab()) { ClearPanels(); } } } [HarmonyPatch(typeof(InventoryGui), "UpdateRecipeList")] public static class InventoryGui_UpdateRecipeList_FilteringAndSorting { [HarmonyPriority(800)] [HarmonyAfter(new string[] { "ZenDragon.ZenUI" })] public static void Prefix(InventoryGui __instance, List<Recipe> recipes) { FilterRecipes(recipes, __instance.InCraftTab(), __instance.InUpradeTab()); } [HarmonyPriority(800)] [HarmonyAfter(new string[] { "ZenDragon.ZenUI" })] public static void Postfix() { SortRecipes(); } } [HarmonyPatch(typeof(InventoryGui), "Update")] public static class InventoryGui_Update_GamepadControls { public static FilteringState GetSelectedFilter() { return filteringStates.FirstOrDefault((FilteringState fs) => fs.selectable && fs.selected); } [HarmonyPriority(800)] public static void Prefix(InventoryGui __instance) { if (!IsCraftingFilterEnabled || !InventoryGui.IsVisible() || !__instance.m_inventoryGroup.IsActive || __instance.m_activeGroup != 3) { return; } if (!ZInput.IsGamepadActive() || ZInput.GetButtonDown("JoyLStickDown") || ZInput.GetButtonDown("JoyLStickUp") || ((MyLittleUI.ZenUI || MyLittleUI.AAA_Crafting) ? ZInput.GetButtonDown("JoyRStickRight") : ZInput.GetButtonDown("JoyLStickRight"))) { CollectionExtensions.Do<FilteringState>((IEnumerable<FilteringState>)filteringStates, (Action<FilteringState>)delegate(FilteringState fs) { fs.SetSelected(selected: false); }); return; } string text = ((MyLittleUI.ZenUI || MyLittleUI.AAA_Crafting) ? "JoyRStickLeft" : "JoyLStickLeft"); if (ZInput.GetButtonDown(text)) { FilteringState filteringState = filteringStates.FirstOrDefault((FilteringState fs) => fs.selectable && fs.enabled); if (filteringState != null) { filteringState.SetSelected(selected: true); ZInput.ResetButtonStatus(text); } else if (panels.Count > 0) { FilteringState selectedFilter = GetSelectedFilter(); selectedFilter = filteringStates.FirstOrDefault((FilteringState fs) => fs.selectable && fs.lastSelected) ?? filteringStates.FirstOrDefault((FilteringState fs) => fs.selectable); if (selectedFilter != null) { selectedFilter.SetSelected(selected: true); ZInput.ResetButtonStatus(text); } } } else if (ZInput.GetButtonDown("JoyDPadLeft")) { FilteringState selectedFilter2 = GetSelectedFilter(); if (selectedFilter2 != null) { for (int num = selectedFilter2.panel.filters.IndexOf(selectedFilter2) - 1; num >= 0; num--) { if (selectedFilter2.panel.filters[num].selectable) { selectedFilter2.SetSelected(selected: false); selectedFilter2.panel.filters[num].SetSelected(selected: true); ZInput.ResetButtonStatus("JoyDPadLeft"); return; } } int num2 = panels.IndexOf(selectedFilter2.panel); for (int num3 = num2 - 1; num3 >= 0; num3--) { FilteringState filteringState2 = panels[num3].filters.LastOrDefault((FilteringState fs) => fs.selectable); if (filteringState2 != null) { selectedFilter2.SetSelected(selected: false); filteringState2.SetSelected(selected: true); ZInput.ResetButtonStatus("JoyDPadLeft"); return; } } FilteringState filteringState3 = filteringStates.LastOrDefault((FilteringState fs) => fs.selectable); if (filteringState3 != null) { selectedFilter2.SetSelected(selected: false); filteringState3.SetSelected(selected: true); ZInput.ResetButtonStatus("JoyDPadLeft"); } return; } if (!MyLittleUI.AAA_Crafting) { FilteringState filteringState4 = filteringStates.FirstOrDefault((FilteringState fs) => fs.selectable && fs.enabled); if (filteringState4 != null) { filteringState4.SetSelected(selected: true); ZInput.ResetButtonStatus("JoyDPadLeft"); return; } } if (!MyLittleUI.AAA_Crafting && panels.Count > 0) { selectedFilter2 = filteringStates.FirstOrDefault((FilteringState fs) => fs.selectable && fs.lastSelected) ?? filteringStates.FirstOrDefault((FilteringState fs) => fs.selectable); if (selectedFilter2 != null) { selectedFilter2.SetSelected(selected: true); ZInput.ResetButtonStatus("JoyDPadLeft"); } } } else if (ZInput.GetButtonDown("JoyDPadRight")) { FilteringState selectedFilter3 = GetSelectedFilter(); if (selectedFilter3 == null) { return; } for (int num4 = selectedFilter3.panel.filters.IndexOf(selectedFilter3) + 1; num4 < selectedFilter3.panel.filters.Count; num4++) { if (selectedFilter3.panel.filters[num4].selectable) { selectedFilter3.SetSelected(selected: false); selectedFilter3.panel.filters[num4].SetSelected(selected: true); ZInput.ResetButtonStatus("JoyDPadRight"); return; } } int num5 = panels.IndexOf(selectedFilter3.panel); for (int num6 = num5 + 1; num6 < panels.Count; num6++) { FilteringState filteringState5 = panels[num6].filters.FirstOrDefault((FilteringState fs) => fs.selectable); if (filteringState5 != null) { selectedFilter3.SetSelected(selected: false); filteringState5.SetSelected(selected: true); ZInput.ResetButtonStatus("JoyDPadRight"); return; } } FilteringState filteringState6 = filteringStates.FirstOrDefault((FilteringState fs) => fs.selectable); if (filteringState6 != null) { selectedFilter3.SetSelected(selected: false); filteringState6.SetSelected(selected: true); ZInput.ResetButtonStatus("JoyDPadRight"); } } else if (ZInput.GetButtonDown("JoyDPadUp")) { FilteringState selectedFilter4 = GetSelectedFilter(); if (selectedFilter4 == null) { return; } int num7 = 0; for (int num8 = selectedFilter4.panel.filters.IndexOf(selectedFilter4); num8 >= 0; num8--) { if (selectedFilter4.panel.filters[num8].selectable) { if (num7 >= 3) { selectedFilter4.SetSelected(selected: false); selectedFilter4.panel.filters[num8].SetSelected(selected: true); ZInput.ResetButtonStatus("JoyDPadUp"); return; } num7++; } } int num9 = panels.IndexOf(selectedFilter4.panel); List<FilteringState> list = selectedFilter4.panel.filters.Where((FilteringState fs) => fs.selectable).ToList(); int column = list.IndexOf(selectedFilter4) % 3; if (list.Count == 2) { column++; } else if (list.Count == 1) { column += 2; } for (int num10 = num9 + panels.Count - 1; num10 > num9; num10--) { FilteringPanel filteringPanel = panels[num10 % panels.Count]; list = filteringPanel.filters.Where((FilteringState fs) => fs.selectable).ToList(); if (list.Count == 2) { column = Math.Max(0, column - 1); } else if (list.Count == 1) { column = Math.Max(0, column - 2); } FilteringState filteringState7 = list.LastOrDefault((FilteringState fs) => list.IndexOf(fs) % 3 == column) ?? filteringPanel.filters.LastOrDefault((FilteringState fs) => fs.selectable); if (filteringState7 != null) { selectedFilter4.SetSelected(selected: false); filteringState7.SetSelected(selected: true); ZInput.ResetButtonStatus("JoyDPadUp"); break; } } } else if (ZInput.GetButtonDown("JoyDPadDown")) { FilteringState selectedFilter5 = GetSelectedFilter(); if (selectedFilter5 == null) { return; } int num11 = 0; for (int num12 = selectedFilter5.panel.filters.IndexOf(selectedFilter5); num12 < selectedFilter5.panel.filters.Count; num12++) { if (selectedFilter5.panel.filters[num12].selectable) { if (num11 >= 3) { selectedFilter5.SetSelected(selected: false); selectedFilter5.panel.filters[num12].SetSelected(selected: true); ZInput.ResetButtonStatus("JoyDPadDown"); return; } num11++; } } int num13 = panels.IndexOf(selectedFilter5.panel); List<FilteringState> list2 = selectedFilter5.panel.filters.Where((FilteringState fs) => fs.selectable).ToList(); int column2 = list2.IndexOf(selectedFilter5) % 3; if (list2.Count == 2) { column2++; } else if (list2.Count == 1) { column2 += 2; } for (int num14 = num13 + 1; num14 < panels.Count + num13; num14++) { FilteringPanel filteringPanel2 = panels[num14 % panels.Count]; list2 = filteringPanel2.filters.Where((FilteringState fs) => fs.selectable).ToList(); if (list2.Count == 2) { column2 = Math.Max(0, column2 - 1); } else if (list2.Count == 1) { column2 = Math.Max(0, column2 - 2); } FilteringState filteringState8 = list2.FirstOrDefault((FilteringState fs) => list2.IndexOf(fs) % 3 == column2) ?? filteringPanel2.filters.FirstOrDefault((FilteringState fs) => fs.selectable); if (filteringState8 != null) { selectedFilter5.SetSelected(selected: false); filteringState8.SetSelected(selected: true); ZInput.ResetButtonStatus("JoyDPadDown"); break; } } } else if (ZInput.GetButtonDown("JoyRStick")) { FilteringState selectedFilter6 = GetSelectedFilter(); if (selectedFilter6 != null) { selectedFilter6.OnClick(); ZInput.ResetButtonStatus("JoyRStick"); } } else if (ZInput.GetButtonDown("JoyJump")) { FilteringState selectedFilter7 = GetSelectedFilter(); if (selectedFilter7 != null) { selectedFilter7.OnClick(); ZInput.ResetButtonStatus("JoyJump"); } } } public static void Postfix() { CollectionExtensions.Do<FilteringState>((IEnumerable<FilteringState>)filteringStates, (Action<FilteringState>)delegate(FilteringState fs) { fs.UpdateSelect(); }); } } public static readonly List<FilteringPanel> panels = new List<FilteringPanel>(); public static readonly List<FilteringState> filteringStates = new List<FilteringState>(); public static readonly List<FilteringState> tempEnabledStates = new List<FilteringState>(); public static readonly List<string> tempUnfitItems = new List<string>(); public static RectTransform sortPanel; public static RectTransform elementPrefab; public static Sprite foodSprite; public static bool IsCraftingFilterEnabled => MyLittleUI.modEnabled.Value && MyLittleUI.craftingSortingEnabled.Value; public static void UpdateVisibility() { RectTransform obj = sortPanel; if (obj != null) { ((Component)obj).gameObject.SetActive(IsCraftingFilterEnabled); } } internal static void InitElementPrefab(Transform parent) { //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)elementPrefab)) { return; } elementPrefab = Object.Instantiate<GameObject>(InventoryGui.instance.m_playerGrid.m_elementPrefab, parent).GetComponent<RectTransform>(); for (int num = ((Transform)elementPrefab).childCount - 1; num >= 0; num--) { Transform child = ((Transform)elementPrefab).GetChild(num); ((Component)child).gameObject.SetActive(false); switch (((Object)child).name) { case "foodicon": if (foodSprite == null) { foodSprite = ((Component)child).GetComponent<Image>().sprite; } Object.DestroyImmediate((Object)(object)((Component)child).gameObject); break; case "amount": case "durability": case "binding": case "quality": case "noteleport": case "equiped": Object.DestroyImmediate((Object)(object)((Component)child).gameObject); break; case "icon": ((Component)child).gameObject.SetActive(true); break; case "queued": ((Object)child).name = "active"; break; } } ((Object)elementPrefab).name = "filterElement"; elementPrefab.sizeDelta = Vector2.one * 32f; ((Component)elementPrefab).gameObject.SetActive(false); ((Component)elementPrefab).GetComponent<UITooltip>().m_tooltipPrefab = ((Component)InventoryGui.instance.m_repairButton).GetComponent<UITooltip>().m_tooltipPrefab; ((UnityEventBase)((Component)elementPrefab).GetComponent<Button>().onClick).RemoveAllListeners(); } internal static void InitSortingPanel() { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) if (IsCraftingFilterEnabled && Object.op_Implicit((Object)(object)InventoryGui.instance) && !Object.op_Implicit((Object)(object)sortPanel) && Object.op_Implicit((Object)(object)InventoryGui.instance.m_repairPanel) && Object.op_Implicit((Object)(object)InventoryGui.instance.m_repairButton) && Object.op_Implicit((Object)(object)InventoryGui.instance.m_playerGrid.m_elementPrefab)) { Transform repairPanel = InventoryGui.instance.m_repairPanel; sortPanel = Object.Instantiate<RectTransform>((RectTransform)(object)((repairPanel is RectTransform) ? repairPanel : null), ((Component)InventoryGui.instance.m_repairPanel).transform.parent); ((Object)sortPanel).name = "MLUI_SortingPanels"; ((Transform)sortPanel).SetSiblingIndex(InventoryGui.instance.m_repairPanel.GetSiblingIndex() + 1); sortPanel.anchoredPosition = new Vector2(0f, -200f); sortPanel.sizeDelta = new Vector2(0f, 0f); ((Component)sortPanel).gameObject.SetActive(false); panels.Clear(); filteringStates.Clear(); InitElementPrefab((Transform)(object)sortPanel); InitFoodCategory(); InitArmorCategory(); InitSkillsCategory(); InitBowsCategory(); InitCrossbowsCategory(); InitMagicCategory(); InitToolsCategory(); filteringStates.ForEach(delegate(FilteringState fs) { fs.CreateElement(); }); } } private static void InitFoodCategory() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) FilteringPanel filteringPanel = new FilteringPanel("Food"); filteringPanel.AddFilter(new FilteringState { panel = filteringPanel, name = "food", category = "$hud_food", tooltip = "$item_food_health", icon = foodSprite, imageColor = InventoryGui.instance.m_playerGrid.m_foodHealthColor, unique = true, sort = delegate(RecipeDataPair a, RecipeDataPair b) { float num = ((RecipeDataPair)(ref b)).Recipe.m_item.m_itemData.m_shared.m_appendToolTip?.m_itemData.m_shared.m_food ?? ((RecipeDataPair)(ref b)).Recipe.m_item.m_itemData.m_shared.m_food; float value = ((RecipeDataPair)(ref a)).Recipe.m_item.m_itemData.m_shared.m_appendToolTip?.m_itemData.m_shared.m_food ?? ((RecipeDataPair)(ref a)).Recipe.m_item.m_itemData.m_shared.m_food; return num.CompareTo(value); }, filter = (ItemData item) => ((int)item.m_shared.m_itemType == 2 && item.m_shared.m_food > 0f) || ((int)item.m_shared.m_itemType == 1 && (Object)(object)item.m_shared.m_appendToolTip != (Object)null && item.m_shared.m_appendToolTip.m_itemData.m_shared.m_food > 0f) }); filteringPanel.AddFilter(new FilteringState { panel = filteringPanel, name = "food_stamina", category = "$hud_food", tooltip = "$item_food_stamina", icon = foodSprite, imageColor = InventoryGui.instance.m_playerGrid.m_foodStaminaColor, unique = true, sort = delegate(RecipeDataPair a, RecipeDataPair b) { float num = ((RecipeDataPair)(ref b)).Recipe.m_item.m_itemData.m_shared.m_appendToolTip?.m_itemData.m_shared.m_foodStamina ?? ((RecipeDataPair)(ref b)).Recipe.m_item.m_itemData.m_shared.m_foodStamina; float value = ((RecipeDataPair)(ref a)).Recipe.m_item.m_itemData.m_shared.m_appendToolTip?.m_itemData.m_shared.m_foodStamina ?? ((RecipeDataPair)(ref a)).Recipe.m_item.m_itemData.m_shared.m_foodStamina; return num.CompareTo(value); }, filter = (ItemData item) => ((int)item.m_shared.m_itemType == 2 && item.m_shared.m_foodStamina > 0f) || ((int)item.m_shared.m_itemType == 1 && (Object)(object)item.m_shared.m_appendToolTip != (Object)null && item.m_shared.m_appendToolTip.m_itemData.m_shared.m_foodStamina > 0f) }); filteringPanel.AddFilter(new FilteringState { panel = filteringPanel, name = "food_eitr", category = "$hud_food", tooltip = "$item_food_eitr", icon = foodSprite, imageColor = InventoryGui.instance.m_playerGrid.m_foodEitrColor, unique = true, sort = delegate(RecipeDataPair a, RecipeDataPair b) { float num = ((RecipeDataPair)(ref b)).Recipe.m_item.m_itemData.m_shared.m_appendToolTip?.m_itemData.m_shared.m_foodEitr ?? ((RecipeDataPair)(ref b)).Recipe.m_item.m_itemData.m_shared.m_foodEitr; float value = ((RecipeDataPair)(ref a)).Recipe.m_item.m_itemData.m_shared.m_appendToolTip?.m_itemData.m_shared.m_foodEitr ?? ((RecipeDataPair)(ref a)).Recipe.m_item.m_itemData.m_shared.m_foodEitr; return num.CompareTo(value); }, filter = (ItemData item) => ((int)item.m_shared.m_itemType == 2 && item.m_shared.m_foodEitr > 0f) || ((int)item.m_shared.m_itemType == 1 && (Object)(object)item.m_shared.m_appendToolTip != (Object)null && item.m_shared.m_appendToolTip.m_itemData.m_shared.m_foodEitr > 0f) }); } private static void InitArmorCategory() { FilteringPanel filteringPanel = new FilteringPanel("Armor"); filteringPanel.AddFilter(new FilteringState { panel = filteringPanel, name = "armor_helmet", category = "Armor", tooltip = "$radial_armor_utility", icon = GetItemIcon("HelmetBronze"), sort = ByArmor, filter = (ItemData item) => (int)item.m_shared.m_itemType == 6 || (int)item.m_shared.m_attachOverride == 6 }); filteringPanel.AddFilter(new FilteringState { panel = filteringPanel, name = "armor_chest", category = "Armor", tooltip = "$radial_armor_utility", icon = GetItemIcon("ArmorIronChest"), sort = ByArmor, filter = (ItemData item) => (int)item.m_shared.m_itemType == 7 || (int)item.m_shared.m_attachOverride == 7 }); filteringPanel.AddFilter(new FilteringState { panel = filteringPanel, name = "armor_legs", category = "Armor", tooltip = "$radial_armor_utility", icon = GetItemIcon("ArmorIronLegs"), sort = ByArmor, filter = (ItemData item) => (int)item.m_shared.m_itemType == 11 || (int)item.m_shared.m_attachOverride == 11 }); filteringPanel.AddFilter(new FilteringState { panel = filteringPanel, name = "armor_cape", category = "Armor", tooltip = "$radial_armor_utility", icon = GetItemIcon("CapeDeerHide"), sort = SortCape, filter = (ItemData item) => (int)item.m_shared.m_itemType == 17 || (int)item.m_shared.m_attachOverride == 17 }); filteringPanel.AddFilter(new FilteringState { panel = filteringPanel, name = "armor_utility", category = "Armor", tooltip = "$radial_armor_utility", icon = GetItemIcon("Demister"), sort = ByArmor, filter = (ItemData item) => (int)item.m_shared.m_itemType == 18 || (int)item.m_shared.m_attachOverride == 18 }); filteringPanel.AddFilter(new FilteringState { panel = filteringPanel, name = "armor_trinket", category = "Armor", tooltip = "$radial_armor_utility", icon = GetItemIcon("TrinketBronzeHealth"), sort = ByAdrenaline, filter = (ItemData item) => (int)item.m_shared.m_itemType == 24 || (int)item.m_shared.m_attachOverride == 24 }); } private static void InitSkillsCategory() { FilteringPanel panel = new FilteringPanel("Skills"); Skills skills = ((Character)Player.m_localPlayer).GetSkills(); AddMelee(skills, (SkillType)1); AddMelee(skills, (SkillType)2); AddMelee(skills, (SkillType)3); AddMelee(skills, (SkillType)4); AddMelee(skills, (SkillType)5); AddMelee(skills, (SkillType)7); AddMelee(skills, (SkillType)11); AddMelee(skills, (SkillType)12); panel.AddFilter(new FilteringState { panel = panel, name = "skill_shields", category = "Melee", tooltip = "$skill_shields", icon = skills.GetSkillDef((SkillType)6).m_icon, sort = SortShield, filter = (ItemData item) => (int)item.m_shared.m_skillType == 6 }); unsafe void AddMelee(Skills val, SkillType skill) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) panel.AddFilter(new FilteringState { panel = panel, name = "skill_" + ((object)(*(SkillType*)(&skill))/*cast due to .constrained prefix*/).ToString().ToLower(), category = "Melee", tooltip = "$skill_" + ((object)(*(SkillType*)(&skill))/*cast due to .constrained prefix*/).ToString().ToLower(), icon = val.GetSkillDef(skill).m_icon, sort = ByTotalDamage, filter = (ItemData item) => item.m_shared.m_skillType == skill && item.m_shared.m_attack.m_attackAnimation != "" && ((DamageTypes)(ref item.m_shared.m_damages)).GetTotalDamage() > 0f }); } } private static void InitBowsCategory() { FilteringPanel filteringPanel = new FilteringPanel("Bows"); filteringPanel.AddFilter(new FilteringState { panel = filteringPanel, name = "skill_bows", category = "Bows", tooltip = "$skill_bows", icon = ((Character)Player.m_localPlayer).GetSkills().GetSkillDef((SkillType)8).m_icon, sort = ByTotalDamage, filter = (ItemData item) => (int)item.m_shared.m_skillType == 8 && item.m_shared.m_attack.m_attackAnimation != "" && ((DamageTypes)(ref item.m_shared.m_damages)).GetTotalDamage() > 0f }); filteringPanel.AddFilter(new FilteringState { panel = filteringPanel, name = "ammo_arrows", category = "Bows", tooltip = "$ammo_arrows", icon = GetItemIcon("ArrowIron"), sort = ByTotalDamage, filter = (ItemData item) => item.m_shared.m_attack.m_attackAnimation == "" && item.m_shared.m_ammoType == "$ammo_arrows" && ((DamageTypes)(ref item.m_shared.m_damages)).GetTotalDamage() > 0f }); } private static void InitCrossbowsCategory() { FilteringPanel filteringPanel = new FilteringPanel("Crossbows"); filteringPanel.AddFilter(new FilteringState { panel = filteringPanel, name = "skill_crossbows", category = "Crossbows", tooltip = "$skill_crossbows", icon = ((Character)Player.m_localPlayer).GetSkills().GetSkillDef((SkillType)14).m_icon, sort = ByTotalDamage, filter = (ItemData item) => (int)item.m_shared.m_skillType == 14 && item.m_shared.m_attack.m_attackAnimation != "" && ((DamageTypes)(ref item.m_shared.m_damages)).GetTotalDamage() > 0f }); filteringPanel.AddFilter(new FilteringState { panel = filteringPanel, name = "ammo_arrows", category = "Crossbows", tooltip = "$ammo_bolts", icon = GetItemIcon("BoltIron"), sort = ByTotalDamage, filter = (ItemData item) => item.m_shared.m_attack.m_attackAnimation == "" && item.m_shared.m_ammoType == "$ammo_bolts" && ((DamageTypes)(ref item.m_shared.m_damages)).GetTotalDamage() > 0f }); } private static void InitMagicCategory() { FilteringPanel filteringPanel = new FilteringPanel("Magic"); filteringPanel.AddFilter(new FilteringState { panel = filteringPanel, name = "skill_elementalmagic", category = "Magic", tooltip = "$skill_elementalmagic", icon = ((Character)Player.m_localPlayer).GetSkills().GetSkillDef((SkillType)9).m_icon, sort = ByTotalDamage, filter = (ItemData item) => (int)item.m_shared.m_skillType == 9 && item.m_shared.m_attack.m_attackAnimation != "" && ((DamageTypes)(ref item.m_shared.m_damages)).GetTotalDamage() > 0f }); filteringPanel.AddFilter(new FilteringState { panel = filteringPanel, name = "skill_bloodmagic", category = "Magic", tooltip = "$skill_bloodmagic", icon = ((Character)Player.m_localPlayer).GetSkills().GetSkillDef((SkillType)10).m_icon, sort = ByDefault, filter = (ItemData item) => (int)item.m_shared.m_skillType == 10 && item.m_shared.m_attack.m_attackAnimation != "" }); } private static void InitToolsCategory() { Filte