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 SonicPickupFilters v0.1.0
SonicPickupFilters.dll
Decompiled 2 weeks 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.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("SonicPickupFilters")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+45fa2e7778d4f902d8abdef9dceea0c84bb38e66")] [assembly: AssemblyProduct("SonicPickupFilters")] [assembly: AssemblyTitle("SonicPickupFilters")] [assembly: AssemblyVersion("0.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SonicPickupFilters { [HarmonyPatch(typeof(Player), "AutoPickup")] internal static class AutoPickupPatches { private enum CapDecision { Allow, Suppress, Skip } private static readonly List<ItemDrop> Suppressed = new List<ItemDrop>(64); private static readonly Dictionary<string, int> PendingPickup = new Dictionary<string, int>(StringComparer.Ordinal); private static Collider[] _overlapBuffer = (Collider[])(object)new Collider[128]; private static readonly FieldInfo AutoPickupMaskField = AccessTools.Field(typeof(Player), "m_autoPickupMask"); private static float _nextSummaryLog; private static float _nextFailLog; private static int _passSeq; private static int _failLogs; private static string _step = "init"; private static string _item = "-"; internal static void ResetRuntimeState() { try { RestoreSuppressed(); } catch { Suppressed.Clear(); } PendingPickup.Clear(); _step = "reset"; _item = "-"; } internal static string DumpNearby(Player player) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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_017f: Expected O, but got Unknown //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Expected O, but got Unknown //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Expected O, but got Unknown StringBuilder stringBuilder = new StringBuilder(1024); stringBuilder.AppendLine("=== spf_dump ==="); stringBuilder.AppendLine("rules=" + PickupRuleStore.FormatRulesSnapshot()); stringBuilder.AppendLine("enabled=" + SonicPickupFiltersPlugin.IsModEnabled() + " debug=" + SonicPickupFiltersPlugin.DebugEnabled); if ((Object)player == (Object)null) { stringBuilder.AppendLine("player=null"); return stringBuilder.ToString(); } string how; object obj = TryGetInventoryObject(player, out how); stringBuilder.AppendLine("inventory=" + ((obj != null) ? "ok" : "null") + " via=" + how); Vector3 val = ((Component)player).transform.position + Vector3.up * 0.5f; float autoPickupRange = player.m_autoPickupRange; int num = ResolveMask(player); int num2 = ((num >= 0) ? Physics.OverlapSphereNonAlloc(val, autoPickupRange, _overlapBuffer, num) : Physics.OverlapSphereNonAlloc(val, autoPickupRange, _overlapBuffer)); stringBuilder.AppendLine($"range={autoPickupRange:0.##} mask={num} hits={num2}"); int num3 = 0; for (int i = 0; i < num2; i++) { Collider val2 = _overlapBuffer[i]; if ((Object)val2 == (Object)null) { continue; } ItemDrop val3 = null; string text = "?"; try { text = ((Object)((Component)val2).gameObject).name; val3 = ((Component)val2).GetComponent<ItemDrop>(); if ((Object)val3 == (Object)null && (Object)val2.attachedRigidbody != (Object)null) { val3 = ((Component)val2.attachedRigidbody).GetComponent<ItemDrop>() ?? ((Component)val2.attachedRigidbody).GetComponentInParent<ItemDrop>(); } } catch (Exception ex) { stringBuilder.AppendLine($" hit[{i}] col='{text}' GetItemDrop FAIL {ex.GetType().Name}: {ex.Message}"); continue; } if (!((Object)val3 == (Object)null)) { num3++; string text2; try { text2 = ((Object)((Component)val3).gameObject).name; } catch { text2 = text; } string text3 = PickupRuleStore.NormalizePrefabName(text2); PickupRule rule = PickupRuleStore.GetRule(text3); string text4 = TryShared(val3, text3); int num4 = TryStack(val3, text3); int num5 = TryMaxStack(val3, text3); bool flag = false; try { flag = val3.m_autoPickup; } catch (Exception ex2) { stringBuilder.AppendLine(" " + text3 + " m_autoPickup FAIL " + ex2.GetType().Name + ": " + ex2.Message); continue; } string text5 = "-"; if (!string.IsNullOrEmpty(text4) && obj != null) { text5 = CountHaveReflect(obj, text4, text3, out var method) + " via " + method; } stringBuilder.AppendLine($" {text3} raw='{text2}' rule={FormatRule(rule)} auto={flag} " + $"shared='{text4}' stack={num4} max={num5} invHave={text5}"); } } stringBuilder.AppendLine("dropsListed=" + num3); return stringBuilder.ToString(); } [HarmonyPrefix] private static void Prefix(Player __instance, float dt) { _step = "Prefix.enter"; _item = "-"; try { RunPrefix(__instance); _step = "Prefix.done"; } catch (Exception ex) { Fail("Prefix.uncaught", ex); try { RestoreSuppressed(); } catch (Exception ex2) { Fail("Prefix.restoreAfterFail", ex2); Suppressed.Clear(); } PendingPickup.Clear(); } } private static void RunPrefix(Player __instance) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown //IL_006a: Expected O, but got Unknown //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Expected O, but got Unknown //IL_0144: 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) _step = "RestoreSuppressed"; RestoreSuppressed(); PendingPickup.Clear(); _step = "IsModEnabled"; if (!SonicPickupFiltersPlugin.IsModEnabled()) { return; } _step = "LocalPlayerCheck"; if ((Object)__instance == (Object)null || (Object)Player.m_localPlayer == (Object)null || (Object)__instance != (Object)Player.m_localPlayer) { return; } _step = "ReadRange"; Vector3 val = ((Component)__instance).transform.position + Vector3.up * 0.5f; float autoPickupRange = __instance.m_autoPickupRange; _step = "ResolveMask"; int num = ResolveMask(__instance); _step = "OverlapSphere"; _item = $"range={autoPickupRange:0.##} mask={num}"; int num2 = ((num >= 0) ? Physics.OverlapSphereNonAlloc(val, autoPickupRange, _overlapBuffer, num) : Physics.OverlapSphereNonAlloc(val, autoPickupRange, _overlapBuffer)); if (num2 >= _overlapBuffer.Length) { _step = "GrowOverlapBuffer"; Collider[] array = (Collider[])(object)new Collider[_overlapBuffer.Length * 2]; Array.Copy(_overlapBuffer, array, _overlapBuffer.Length); _overlapBuffer = array; num2 = ((num >= 0) ? Physics.OverlapSphereNonAlloc(val, autoPickupRange, _overlapBuffer, num) : Physics.OverlapSphereNonAlloc(val, autoPickupRange, _overlapBuffer)); } _passSeq++; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; int num7 = 0; int num8 = 0; int num9 = 0; int errors = 0; bool flag = false; object obj = null; bool flag2 = false; string how = "not-needed"; for (int i = 0; i < num2; i++) { _step = "Loop.collider"; _item = $"hit[{i}/{num2}]"; Collider val2 = _overlapBuffer[i]; if ((Object)val2 == (Object)null) { continue; } string text = "?"; try { _step = "Loop.colliderName"; text = (_item = ((Object)((Component)val2).gameObject).name); } catch (Exception ex) { errors++; Fail("Loop.colliderName", ex); continue; } _step = "Loop.GetItemDrop"; _item = text; ItemDrop val3 = TryGetItemDrop(val2, text, ref errors); if ((Object)val3 == (Object)null) { continue; } num3++; string text2 = text; try { _step = "Loop.dropGameObjectName"; text2 = (_item = ((Object)((Component)val3).gameObject).name); } catch (Exception ex2) { errors++; Fail("Loop.dropGameObjectName item=" + text, ex2); continue; } string text3 = PickupRuleStore.NormalizePrefabName(text2); _item = text3 + " raw=" + text2; bool autoPickup; try { _step = "Loop.read_m_autoPickup"; autoPickup = val3.m_autoPickup; } catch (Exception ex3) { errors++; Fail("Loop.read_m_autoPickup", ex3); continue; } if (!autoPickup) { num9++; continue; } PickupRule rule = PickupRuleStore.GetRule(text3); if (rule.Mode == PickupRuleMode.Allow) { num4++; continue; } flag = true; if (rule.Mode == PickupRuleMode.Block) { _step = "Block.suppress"; _item = text3; Suppress(val3, text3); num5++; continue; } if (!flag2) { flag2 = true; obj = TryGetInventoryObject(__instance, out how); } _step = "Cap.enter"; _item = text3; if (obj == null) { Log("Cap SUPPRESS prefab='" + text3 + "' reason=no-inventory (" + how + ")"); Suppress(val3, text3); num7++; continue; } switch (ApplyCap(obj, val3, text3, text2, rule.Cap)) { case CapDecision.Allow: num6++; break; case CapDecision.Suppress: num7++; break; default: num8++; break; } } _step = "Summary"; _item = "-"; if (SonicPickupFiltersPlugin.DebugEnabled && Time.unscaledTime >= _nextSummaryLog && (flag || num3 > 0)) { _nextSummaryLog = Time.unscaledTime + 2f; Log($"SUMMARY hits={num2} drops={num3} allow={num4} block={num5} " + $"capAllow={num6} capSuppress={num7} capSkip={num8} " + $"alreadyOff={num9} errors={errors} suppressed={Suppressed.Count} " + "inv=" + how + " rules=" + PickupRuleStore.FormatRulesSnapshot()); } } private static string FormatRule(PickupRule rule) { if (rule.Mode == PickupRuleMode.Block) { return "Block"; } if (rule.Mode == PickupRuleMode.Cap) { return "Cap:" + rule.Cap; } return "Allow"; } private static object TryGetInventoryObject(object player, out string how) { if (player == null) { how = "player-null"; return null; } try { _step = "inv.RuntimeGetInventory"; Type type = player.GetType(); MethodInfo method = type.GetMethod("GetInventory", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if (method != null) { object result = method.Invoke(player, null); how = "RuntimeGetInventory"; return result; } how = "GetInventory-missing"; } catch (TargetInvocationException ex) { how = "GetInventory-threw"; Fail("inv.RuntimeGetInventory", ex.InnerException ?? ex); } catch (Exception ex2) { how = "GetInventory-threw"; Fail("inv.RuntimeGetInventory", ex2); } try { _step = "inv.RuntimeField"; Type type2 = player.GetType(); while (type2 != null) { FieldInfo field = type2.GetField("m_inventory", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { object value = field.GetValue(player); how = "RuntimeField:" + type2.Name + " type=" + ((value == null) ? "null" : value.GetType().FullName); return value; } type2 = type2.BaseType; } how += "+no-m_inventory-field"; } catch (Exception ex3) { Fail("inv.RuntimeField", ex3); how += "+field-threw"; } return null; } private static int ResolveMask(Player player) { if (AutoPickupMaskField == null) { return -1; } try { object value = AutoPickupMaskField.GetValue(player); if (value is int) { return (int)value; } Log("m_autoPickupMask unexpected type=" + ((value == null) ? "null" : value.GetType().FullName)); } catch (Exception ex) { Fail("ResolveMask", ex); } return -1; } private static ItemDrop TryGetItemDrop(Collider col, string colName, ref int errors) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown try { _step = "GetComponent<ItemDrop>"; _item = colName; ItemDrop component = ((Component)col).GetComponent<ItemDrop>(); if ((Object)component != (Object)null) { return component; } _step = "attachedRigidbody"; Rigidbody attachedRigidbody = col.attachedRigidbody; if ((Object)attachedRigidbody == (Object)null) { return null; } _step = "rb.GetComponent<ItemDrop>"; component = ((Component)attachedRigidbody).GetComponent<ItemDrop>(); if ((Object)component != (Object)null) { return component; } _step = "rb.GetComponentInParent<ItemDrop>"; return ((Component)attachedRigidbody).GetComponentInParent<ItemDrop>(); } catch (Exception ex) { errors++; Fail("TryGetItemDrop", ex); return null; } } private static CapDecision ApplyCap(object inventory, ItemDrop drop, string prefab, string rawName, int cap) { _step = "Cap.TryShared"; _item = prefab; string text = TryShared(drop, prefab); _step = "Cap.TryStack"; int num = TryStack(drop, prefab); _step = "Cap.TryMaxStack"; int num2 = TryMaxStack(drop, prefab); if (string.IsNullOrEmpty(text) || num < 1) { Log($"Cap SKIP prefab='{prefab}' raw='{rawName}' shared='{text}' stack={num} maxStack={num2}"); return CapDecision.Skip; } _step = "Cap.CountHave"; _item = prefab + " shared=" + text; string method; int num3 = CountHaveReflect(inventory, text, prefab, out method); PendingPickup.TryGetValue(text, out var value); int num4 = cap - num3 - value; if (num4 <= 0) { Suppress(drop, prefab); return CapDecision.Suppress; } int num5 = num; if (num > num4) { if (!TryCapShrink(drop, prefab, num4, num - num4)) { Log($"Cap SUPPRESS prefab='{prefab}' reason=stack({num})>rem({num4}) shrink-failed"); Suppress(drop, prefab); return CapDecision.Suppress; } num5 = num4; Log($"Cap SHRINK prefab='{prefab}' take={num5} leftOnGround={num - num4}"); } PendingPickup[text] = value + num5; Log($"Cap ALLOW prefab='{prefab}' take={num5} have={num3} via={method}"); return CapDecision.Allow; } private static bool TryCapShrink(ItemDrop drop, string prefab, int take, int leave) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: 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_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Expected O, but got Unknown if (take < 1) { return false; } try { _step = "Cap.SetStack"; if (drop.m_itemData != null) { drop.m_itemData.m_stack = take; } drop.SetStack(take); } catch (Exception ex) { Fail("Cap.SetStack", ex); return false; } if (leave < 1) { return true; } if ((Object)ObjectDB.instance == (Object)null) { Log("Cap shrink: ObjectDB null — took " + take + ", lost leave " + leave); return true; } try { _step = "Cap.InstantiateLeftover"; GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefab); if ((Object)itemPrefab == (Object)null) { Log("Cap shrink: no prefab '" + prefab + "' — took " + take + ", lost leave " + leave); return true; } Vector3 val = ((Component)drop).transform.position + Vector3.up * 0.05f; Quaternion rotation = ((Component)drop).transform.rotation; GameObject val2 = Object.Instantiate<GameObject>(itemPrefab, val, rotation); ItemDrop component = val2.GetComponent<ItemDrop>(); if ((Object)component != (Object)null) { if (component.m_itemData != null) { component.m_itemData.m_stack = leave; } try { component.SetStack(leave); } catch (Exception ex2) { Fail("Cap.leftover.SetStack", ex2); } component.m_autoPickup = false; component.m_autoPickup = true; } return true; } catch (Exception ex3) { Fail("Cap.InstantiateLeftover", ex3); return true; } } private static int CountHaveReflect(object inventory, string shared, string prefab, out string method) { if (inventory == null) { method = "inv-null"; return 0; } try { _step = "Cap.CountItems.Invoke"; _item = prefab + " shared=" + shared; MethodInfo method2 = inventory.GetType().GetMethod("CountItems", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[3] { typeof(string), typeof(int), typeof(bool) }, null); if (method2 != null) { object value = method2.Invoke(inventory, new object[3] { shared, -1, true }); method = "CountItems"; return Convert.ToInt32(value); } method = "CountItems-missing"; } catch (TargetInvocationException ex) { Fail("Cap.CountItems.Invoke", ex.InnerException ?? ex); method = "CountItems-threw"; } catch (Exception ex2) { Fail("Cap.CountItems.Invoke", ex2); method = "CountItems-threw"; } try { _step = "Cap.GetAllItems.Scan"; int num = CountHaveByScan(inventory, shared); if (num >= 0) { method = "scan"; return num; } } catch (Exception ex3) { Fail("Cap.GetAllItems.Scan", ex3); method = "scan-threw"; } return 0; } private static int CountHaveByScan(object inventory, string shared) { MethodInfo method = inventory.GetType().GetMethod("GetAllItems", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); if (method == null) { return -1; } object obj = method.Invoke(inventory, null); if (obj == null) { return 0; } if (!(obj is IEnumerable enumerable)) { return -1; } int num = 0; foreach (object item in enumerable) { if (item == null) { continue; } Type type = item.GetType(); FieldInfo field = type.GetField("m_shared", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field2 = type.GetField("m_stack", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null || field2 == null) { continue; } object value = field.GetValue(item); if (value == null) { continue; } FieldInfo field3 = value.GetType().GetField("m_name", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field3 == null)) { string a = field3.GetValue(value) as string; if (string.Equals(a, shared, StringComparison.Ordinal)) { num += Math.Max(0, Convert.ToInt32(field2.GetValue(item))); } } } return num; } private static string TryShared(ItemDrop drop, string prefab) { try { _step = "Read.m_itemData"; _item = prefab; ItemData itemData = drop.m_itemData; if (itemData == null) { return string.Empty; } _step = "Read.m_shared"; SharedData shared = itemData.m_shared; if (shared == null) { return string.Empty; } _step = "Read.m_shared.m_name"; return shared.m_name ?? string.Empty; } catch (Exception ex) { Fail("TryShared", ex); return string.Empty; } } private static int TryStack(ItemDrop drop, string prefab) { try { _step = "Read.m_stack"; _item = prefab; ItemData itemData = drop.m_itemData; return (itemData != null) ? Math.Max(1, itemData.m_stack) : (-1); } catch (Exception ex) { Fail("TryStack", ex); return -1; } } private static int TryMaxStack(ItemDrop drop, string prefab) { try { _step = "Read.m_maxStackSize"; _item = prefab; ItemData itemData = drop.m_itemData; return (itemData?.m_shared != null) ? itemData.m_shared.m_maxStackSize : (-1); } catch (Exception ex) { Fail("TryMaxStack", ex); return -1; } } private static void Suppress(ItemDrop drop, string prefab) { try { _step = "Suppress.set_m_autoPickup_false"; _item = prefab; drop.m_autoPickup = false; Suppressed.Add(drop); } catch (Exception ex) { Fail("Suppress", ex); } } [HarmonyPostfix] private static void Postfix(Player __instance, float dt) { _step = "Postfix"; _item = "suppressed=" + Suppressed.Count; try { if (SonicPickupFiltersPlugin.DebugEnabled && Suppressed.Count > 0) { Log("Postfix restore count=" + Suppressed.Count); } RestoreSuppressed(); } catch (Exception ex) { Fail("Postfix", ex); Suppressed.Clear(); } PendingPickup.Clear(); _step = "Postfix.done"; } private static void RestoreSuppressed() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown for (int i = 0; i < Suppressed.Count; i++) { _step = "RestoreSuppressed[" + i + "]"; ItemDrop val = Suppressed[i]; if (!((Object)val == (Object)null)) { try { _item = ((Object)((Component)val).gameObject).name; } catch { _item = "drop#" + i; } try { val.m_autoPickup = true; } catch (Exception ex) { Fail("RestoreSuppressed.set_true", ex); } } } Suppressed.Clear(); } private static void Log(string message) { SonicPickupFiltersPlugin.DebugLog("#" + _passSeq + " [" + _step + "] " + message); } private static void Fail(string where, Exception ex) { _failLogs++; float unscaledTime = Time.unscaledTime; if (_failLogs <= 8 || !(unscaledTime < _nextFailLog)) { _nextFailLog = unscaledTime + 2f; ManualLogSource modLogger = SonicPickupFiltersPlugin.ModLogger; if (modLogger != null) { modLogger.LogWarning((object)($"#{_passSeq} FAIL where={where} step={_step} item={_item} " + $"ex={ex.GetType().Name}: {ex.Message} (fail#{_failLogs})")); } } } } [HarmonyPatch(typeof(InventoryGui), "Awake")] internal static class InventoryBarButton { [CompilerGenerated] private static class <>O { public static UnityAction <0>__TogglePanel; } private const string ButtonName = "sonic_pickupfilter_button"; private const string IconItemPrefab = "Coins"; private static readonly Vector3[] Corners = (Vector3[])(object)new Vector3[4]; [HarmonyPostfix] private static void Postfix(InventoryGui __instance) { TryInject(__instance); } internal static void TryInjectExisting() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown InventoryGui instance = InventoryGui.instance; if ((Object)instance != (Object)null) { TryInject(instance); } } internal static void DestroyInjected() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown InventoryGui instance = InventoryGui.instance; if (!((Object)instance == (Object)null) && !((Object)instance.m_pvp == (Object)null)) { Transform parent = ((Component)instance.m_pvp).transform.parent; Transform val = parent.Find("sonic_pickupfilter_button"); if ((Object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } } } internal static void TryInject(InventoryGui __instance) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Expected O, but got Unknown //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Invalid comparison between Unknown and I4 //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Expected O, but got Unknown //IL_0198: Expected O, but got Unknown if (!SonicPickupFiltersPlugin.IsModEnabled() || GUIManagerMissing() || (Object)__instance == (Object)null) { return; } Toggle pvp = __instance.m_pvp; if ((Object)pvp == (Object)null) { SonicPickupFiltersPlugin.DebugLog("m_pvp missing; skip Pickup Filter inventory button."); return; } Transform parent = ((Component)pvp).transform.parent; Transform val = parent.Find("sonic_pickupfilter_button"); if ((Object)val != (Object)null) { return; } Button val2 = FindTrophiesButton(parent, pvp); if ((Object)val2 == (Object)null) { SonicPickupFiltersPlugin.DebugLog("Trophies button not found; skip Pickup Filter inventory button."); return; } GameObject val3 = Object.Instantiate<GameObject>(((Component)val2).gameObject, parent); ((Object)val3).name = "sonic_pickupfilter_button"; Button component = val3.GetComponent<Button>(); component.onClick = new ButtonClickedEvent(); ButtonClickedEvent onClick = component.onClick; object obj = <>O.<0>__TogglePanel; if (obj == null) { UnityAction val4 = PickupFilterPanel.TogglePanel; <>O.<0>__TogglePanel = val4; obj = (object)val4; } ((UnityEvent)onClick).AddListener((UnityAction)obj); string text = ModLocalization.Translate("$sonic_pickupfilters_button", "Pickup Filter"); TMP_Text componentInChildren = val3.GetComponentInChildren<TMP_Text>(); if ((Object)componentInChildren != (Object)null) { componentInChildren.text = text; } else { Text componentInChildren2 = val3.GetComponentInChildren<Text>(); if ((Object)componentInChildren2 != (Object)null) { componentInChildren2.text = text; } } UITooltip componentInChildren3 = val3.GetComponentInChildren<UITooltip>(); if ((Object)componentInChildren3 != (Object)null) { componentInChildren3.m_topic = string.Empty; componentInChildren3.m_text = text; } Image val5 = FindIconImage(val3); if ((Object)val5 != (Object)null) { if ((int)((Selectable)component).transition == 2 && (Object)((Selectable)component).targetGraphic == (Object)val5) { ((Selectable)component).transition = (Transition)1; } ((MonoBehaviour)__instance).StartCoroutine(SwapIconWhenReady(val5)); } LayoutRow(parent, ((Component)val2).GetComponent<RectTransform>(), val3.GetComponent<RectTransform>()); SonicPickupFiltersPlugin.DebugLog("Pickup Filter inventory button injected."); } private static bool GUIManagerMissing() { try { return GUIManager.IsHeadless(); } catch { return false; } } private static Button FindTrophiesButton(Transform bar, Toggle pvpToggle) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown Button result = null; float num = float.MaxValue; float num2 = WorldLeft(((Component)pvpToggle).GetComponent<RectTransform>()); foreach (Transform item in bar) { Transform val = item; Button component = ((Component)val).GetComponent<Button>(); if (!((Object)component == (Object)null)) { if (((Object)val).name.IndexOf("Trophies", StringComparison.OrdinalIgnoreCase) >= 0) { return component; } float num3 = num2 - WorldRight((RectTransform)val); if (num3 > 0f && num3 < num) { num = num3; result = component; } } } return result; } private static Image FindIconImage(GameObject buttonGo) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0026: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown Image val = null; Image[] componentsInChildren = buttonGo.GetComponentsInChildren<Image>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)((Component)componentsInChildren[i]).gameObject != (Object)buttonGo) { val = componentsInChildren[i]; } } if (!((Object)val != (Object)null)) { return buttonGo.GetComponent<Image>(); } return val; } private static IEnumerator SwapIconWhenReady(Image iconImage) { while ((Object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_items.Count == 0) { yield return null; } if ((Object)iconImage == (Object)null) { yield break; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Coins"); Sprite val = null; if ((Object)itemPrefab != (Object)null) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)component != (Object)null && component.m_itemData != null) { val = component.m_itemData.GetIcon(); } } if ((Object)val != (Object)null) { iconImage.sprite = val; } } private static void LayoutRow(Transform bar, RectTransform trophiesRt, RectTransform insertedRt) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_0043: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Expected O, but got Unknown //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) List<RectTransform> list = new List<RectTransform>(); foreach (Transform item in bar) { Transform val = item; if (((Component)val).gameObject.activeSelf && !((Object)val == (Object)((Component)insertedRt).transform) && !((Object)((Component)val).GetComponent<Selectable>() == (Object)null)) { list.Add((RectTransform)val); } } if (list.Count != 0) { list.Sort((RectTransform a, RectTransform b) => WorldLeft(a).CompareTo(WorldLeft(b))); float num = bar.lossyScale.x; if (num <= 0f) { num = 1f; } List<float> list2 = new List<float>(); for (int num2 = 1; num2 < list.Count; num2++) { list2.Add(WorldLeft(list[num2]) - WorldRight(list[num2 - 1])); } list2.Sort(); float num3 = ((list2.Count > 0) ? list2[list2.Count / 2] : (8f * num)); int num4 = list.IndexOf(trophiesRt); list.Insert((num4 >= 0) ? (num4 + 1) : list.Count, insertedRt); float num5 = 0f; for (int num6 = 0; num6 < list.Count; num6++) { num5 += WorldRight(list[num6]) - WorldLeft(list[num6]); } RectTransform rt = (RectTransform)bar; float num7 = WorldLeft(rt); float num8 = WorldRight(rt); float num9 = num8 - num7; float num10 = Mathf.Min(8f * num, Mathf.Max(0f, (num9 - num5) * 0.5f)); float num11 = ((list.Count > 1) ? ((num9 - 2f * num10 - num5) / (float)(list.Count - 1)) : 0f); float num12 = Mathf.Max(0f, Mathf.Min(num3, num11)); float num13 = num8 - num10; if (num9 < num5) { num13 = WorldRight(list[list.Count - 1]); } for (int num14 = list.Count - 1; num14 >= 0; num14--) { float num15 = WorldRight(list[num14]) - WorldLeft(list[num14]); float num16 = num13 - num15; Vector2 anchoredPosition = list[num14].anchoredPosition; anchoredPosition.x += (num16 - WorldLeft(list[num14])) / num; list[num14].anchoredPosition = anchoredPosition; num13 = num16 - num12; } } } private static float WorldLeft(RectTransform rt) { rt.GetWorldCorners(Corners); return Corners[0].x; } private static float WorldRight(RectTransform rt) { rt.GetWorldCorners(Corners); return Corners[2].x; } } [HarmonyPatch(typeof(InventoryGui), "OnRightClickItem")] internal static class InventoryModifierClickPatch { [HarmonyPrefix] private static bool Prefix(InventoryGrid grid, ItemData item, Vector2i pos) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_004f: Expected O, but got Unknown if (!SonicPickupFiltersPlugin.IsModEnabled()) { return true; } if (!IsBlockToggleModifierHeld()) { return true; } InventoryGui instance = InventoryGui.instance; if ((Object)instance == (Object)null || (Object)instance.m_playerGrid == (Object)null || (Object)grid != (Object)instance.m_playerGrid) { return true; } if (item == null || item.m_shared == null) { return true; } string text = ResolvePrefabName(item); if (string.IsNullOrEmpty(text)) { return true; } if (PickupRuleStore.GetRule(text).Mode == PickupRuleMode.Block) { PickupRuleStore.SetRule(text, PickupRule.Allow); Message(FormatName(item) + ": auto-pickup allowed"); } else { PickupRuleStore.SetRule(text, PickupRule.Block); Message(FormatName(item) + ": auto-pickup blocked"); } PickupFilterPanel.RefreshIfOpen(); return false; } internal unsafe static bool IsBlockToggleModifierHeld() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) ConfigEntry<KeyboardShortcut> inventoryBlockModifier = SonicPickupFiltersPlugin.InventoryBlockModifier; if (inventoryBlockModifier == null) { if (!Input.GetKey((KeyCode)308)) { return Input.GetKey((KeyCode)307); } return true; } KeyboardShortcut value = inventoryBlockModifier.Value; object obj = KeyboardShortcut.Empty; if (((object)(*(KeyboardShortcut*)(&value))/*cast due to .constrained prefix*/).Equals(obj)) { return false; } return ((KeyboardShortcut)(ref value)).IsPressed(); } private static string FormatName(ItemData item) { if (Localization.instance == null || item.m_shared == null) { return item.m_shared?.m_name ?? "?"; } return Localization.instance.Localize(item.m_shared.m_name); } private static string ResolvePrefabName(ItemData item) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown if ((Object)item.m_dropPrefab != (Object)null) { return PickupRuleStore.NormalizePrefabName(((Object)item.m_dropPrefab).name); } if ((Object)ObjectDB.instance == (Object)null || item.m_shared == null) { return string.Empty; } foreach (GameObject item2 in ObjectDB.instance.m_items) { if (!((Object)item2 == (Object)null)) { ItemDrop component = item2.GetComponent<ItemDrop>(); if (!((Object)component == (Object)null) && component.m_itemData?.m_shared != null && component.m_itemData.m_shared.m_name == item.m_shared.m_name) { return PickupRuleStore.NormalizePrefabName(((Object)item2).name); } } } return string.Empty; } private static void Message(string text) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown Player localPlayer = Player.m_localPlayer; if ((Object)localPlayer != (Object)null) { ((Character)localPlayer).Message((MessageType)1, text, 0, (Sprite)null, false); } } } internal static class ItemMatch { internal static bool MatchesSearch(ItemDrop drop, string pattern) { if ((Object)(object)drop == (Object)null) { return false; } if (string.IsNullOrWhiteSpace(pattern)) { return true; } string value = PickupRuleStore.NormalizePrefabName(((Object)drop).name); string text = drop.m_itemData?.m_shared?.m_name ?? string.Empty; string localized = GetLocalized(text); if (!LocateNameMatches(value, pattern) && !LocateNameMatches(text, pattern) && !LocateNameMatches(localized, pattern)) { if (text.StartsWith("$", StringComparison.Ordinal)) { return LocateNameMatches(text.Substring(1), pattern); } return false; } return true; } internal static string GetLocalized(string sharedName) { if (string.IsNullOrEmpty(sharedName)) { return string.Empty; } if (Localization.instance != null) { return Localization.instance.Localize(sharedName); } return sharedName; } internal unsafe static string FriendlyItemTypeLabel(ItemType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected I4, but got Unknown return (int)type switch { 0 => "None", 1 => "Materials", 2 => "Food & Mead", 3 => "One-handed weapons", 14 => "Two-handed weapons", 22 => "Two-handed (left)", 4 => "Bows", 5 => "Shields", 6 => "Helmets", 7 => "Chest armor", 11 => "Leg armor", 12 => "Hands", 17 => "Capes & shoulders", 9 => "Ammo", 23 => "Thrown / ammo", 19 => "Tools", 18 => "Utility", 15 => "Torches", 13 => "Trophies", 16 => "Misc", 10 => "Customization", 20 => "Atgeir attach", 21 => "Fish", 24 => "Trinkets", _ => SpaceEnumName(((object)(*(ItemType*)(&type))/*cast due to .constrained prefix*/).ToString()), }; } private static string SpaceEnumName(string value) { if (string.IsNullOrEmpty(value)) { return value; } StringBuilder stringBuilder = new StringBuilder(value.Length + 8); for (int i = 0; i < value.Length; i++) { char c = value[i]; if (i > 0 && char.IsUpper(c) && !char.IsUpper(value[i - 1])) { stringBuilder.Append(' '); } stringBuilder.Append(c); } return stringBuilder.ToString(); } private static bool LocateNameMatches(string value, string pattern) { if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(pattern)) { return false; } if (NameMatches(value, pattern)) { return true; } string text = pattern.Replace("*", string.Empty).Trim(); if (text.Length == 0) { return false; } return value.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0; } private static bool NameMatches(string value, string pattern) { if (string.IsNullOrEmpty(pattern)) { return false; } if (pattern.IndexOf('*') < 0) { return string.Equals(value, pattern, StringComparison.OrdinalIgnoreCase); } string[] array = pattern.Split('*'); int num = 0; for (int i = 0; i < array.Length; i++) { string text = array[i]; if (text.Length == 0) { continue; } if (i == 0) { if (!value.StartsWith(text, StringComparison.OrdinalIgnoreCase)) { return false; } num = text.Length; continue; } if (i == array.Length - 1 && pattern[pattern.Length - 1] != '*') { if (!value.EndsWith(text, StringComparison.OrdinalIgnoreCase)) { return false; } return value.Length - text.Length >= num; } int num2 = value.IndexOf(text, num, StringComparison.OrdinalIgnoreCase); if (num2 < 0) { return false; } num = num2 + text.Length; } return true; } } internal static class ModLocalization { internal const string Title = "$sonic_pickupfilters_title"; internal const string Hint = "$sonic_pickupfilters_hint"; internal const string SearchPlaceholder = "$sonic_pickupfilters_search"; internal const string CategoryAll = "$sonic_pickupfilters_cat_all"; internal const string Clear = "$sonic_pickupfilters_clear"; internal const string TabAll = "$sonic_pickupfilters_tab_all"; internal const string TabBlocked = "$sonic_pickupfilters_tab_blocked"; internal const string TabCapped = "$sonic_pickupfilters_tab_capped"; internal const string Close = "$sonic_pickupfilters_close"; internal const string Button = "$sonic_pickupfilters_button"; internal const string ColItem = "$sonic_pickupfilters_col_item"; internal const string ColBlock = "$sonic_pickupfilters_col_block"; internal const string ColCap = "$sonic_pickupfilters_col_cap"; internal const string TipBlockTopic = "$sonic_pickupfilters_tip_block_topic"; internal const string TipBlockBody = "$sonic_pickupfilters_tip_block_body"; internal const string TipCapTopic = "$sonic_pickupfilters_tip_cap_topic"; internal const string TipCapBody = "$sonic_pickupfilters_tip_cap_body"; internal const string TipItemTopic = "$sonic_pickupfilters_tip_item_topic"; internal const string TipItemBody = "$sonic_pickupfilters_tip_item_body"; internal const string CapPlaceholderOff = "$sonic_pickupfilters_cap_ph_off"; internal const string CapPlaceholderOn = "$sonic_pickupfilters_cap_ph_on"; private static CustomLocalization _localization; internal static void Register() { if (LocalizationManager.Instance != null) { _localization = LocalizationManager.Instance.GetLocalization(); CustomLocalization localization = _localization; string text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "sonic_pickupfilters_title", "Pickup Filter" }, { "sonic_pickupfilters_hint", "Check Block to turn filtering on. Cap is optional — leave empty to never auto-pick, or type a max count. Cap alone (Block off) does nothing." }, { "sonic_pickupfilters_search", "Search items…" }, { "sonic_pickupfilters_cat_all", "All categories" }, { "sonic_pickupfilters_clear", "Clear" }, { "sonic_pickupfilters_tab_all", "All" }, { "sonic_pickupfilters_tab_blocked", "Blocked" }, { "sonic_pickupfilters_tab_capped", "Capped" }, { "sonic_pickupfilters_close", "Close" }, { "sonic_pickupfilters_button", "Pickup Filter" }, { "sonic_pickupfilters_col_item", "Item" }, { "sonic_pickupfilters_col_block", "Block" }, { "sonic_pickupfilters_col_cap", "Cap" }, { "sonic_pickupfilters_tip_block_topic", "Block" }, { "sonic_pickupfilters_tip_block_body", "Turns filtering on for this item.\nOff = vanilla auto-pickup (Cap ignored).\nOn + empty Cap = never auto-pick.\nOn + Cap number = auto-pick until that count." }, { "sonic_pickupfilters_tip_cap_topic", "Cap" }, { "sonic_pickupfilters_tip_cap_body", "Only works while Block is checked.\nEmpty Cap = full block (never auto-pick).\nNumber = keep auto-picking until you hold that many.\nCap with Block unchecked does nothing." }, { "sonic_pickupfilters_tip_item_topic", "Item" }, { "sonic_pickupfilters_tip_item_body", "Discovered items from your world. Use Block + Cap to control auto-pickup. Manual Use still works when blocked." }, { "sonic_pickupfilters_cap_ph_off", "need Block" }, { "sonic_pickupfilters_cap_ph_on", "∞ block" } }); } } internal static string Translate(string token, string fallback) { if (_localization != null) { string text = _localization.TryTranslate(token); if (!string.IsNullOrEmpty(text) && text[0] != '[' && text != token) { return text; } } if (LocalizationManager.Instance != null) { string text2 = LocalizationManager.Instance.TryTranslate(token); if (!string.IsNullOrEmpty(text2) && text2[0] != '[' && text2 != token) { return text2; } } return fallback; } } internal static class PickupFilterPanel { private enum ViewTab { All, Blocked, Capped } [CompilerGenerated] private static class <>O { public static UnityAction<string> <0>__OnSearchChanged; public static UnityAction <1>__ClearFilters; public static UnityAction<int> <2>__OnCategoryChanged; public static Func<ItemDrop, ItemType> <3>__GetItemType; public static UnityAction <4>__ApplyCapEditor; public static UnityAction <5>__HideCapEditor; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__55_0; public static UnityAction <>9__55_1; public static UnityAction <>9__55_2; public static UnityAction <>9__55_3; public static Func<ItemType, string> <>9__67_0; public static Func<ItemType, ItemType?> <>9__67_1; public static Func<ItemDrop, bool> <>9__71_0; public static Func<ItemDrop, bool> <>9__71_1; public static Func<ItemDrop, bool> <>9__71_2; public static Func<IGrouping<ItemType, ItemDrop>, string> <>9__71_3; public static Func<ItemDrop, string> <>9__71_6; public static Func<IGrouping<ItemType, ItemDrop>, int> <>9__71_4; public static Func<ItemDrop, string> <>9__71_7; public static Func<IGrouping<string, ItemDrop>, ItemDrop> <>9__71_8; public static Func<ItemDrop, string> <>9__71_9; public static Func<ItemDrop, string> <>9__73_0; public static UnityAction <>9__93_0; public static UnityAction <>9__93_1; public static UnityAction <>9__93_2; public static UnityAction <>9__93_3; internal void <BuildPanel>b__55_0() { SetViewTab(ViewTab.All); } internal void <BuildPanel>b__55_1() { SetViewTab(ViewTab.Blocked); } internal void <BuildPanel>b__55_2() { SetViewTab(ViewTab.Capped); } internal void <BuildPanel>b__55_3() { if (IsOpen) { TogglePanel(); } } internal string <EnsureCategoryOptions>b__67_0(ItemType t) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return ItemMatch.FriendlyItemTypeLabel(t); } internal ItemType? <EnsureCategoryOptions>b__67_1(ItemType t) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return t; } internal bool <RefreshContent>b__71_0(ItemDrop d) { return ItemMatch.MatchesSearch(d, _searchText); } internal bool <RefreshContent>b__71_1(ItemDrop d) { return PickupRuleStore.GetRule(PickupRuleStore.NormalizePrefabName(((Object)d).name)).Mode == PickupRuleMode.Block; } internal bool <RefreshContent>b__71_2(ItemDrop d) { return PickupRuleStore.GetRule(PickupRuleStore.NormalizePrefabName(((Object)d).name)).Mode == PickupRuleMode.Cap; } internal string <RefreshContent>b__71_3(IGrouping<ItemType, ItemDrop> g) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return ItemMatch.FriendlyItemTypeLabel(g.Key); } internal int <RefreshContent>b__71_4(IGrouping<ItemType, ItemDrop> g) { return g.Select((ItemDrop d) => PickupRuleStore.NormalizePrefabName(((Object)d).name)).Distinct<string>(StringComparer.OrdinalIgnoreCase).Count(); } internal string <RefreshContent>b__71_6(ItemDrop d) { return PickupRuleStore.NormalizePrefabName(((Object)d).name); } internal string <RefreshContent>b__71_7(ItemDrop d) { return PickupRuleStore.NormalizePrefabName(((Object)d).name); } internal ItemDrop <RefreshContent>b__71_8(IGrouping<string, ItemDrop> g) { return g.First(); } internal string <RefreshContent>b__71_9(ItemDrop d) { return ItemMatch.GetLocalized(d.m_itemData?.m_shared?.m_name); } internal string <EstimateContentHeight>b__73_0(ItemDrop d) { return PickupRuleStore.NormalizePrefabName(((Object)d).name); } internal void <EnsureCapEditor>b__93_0() { NudgeCap(-1); } internal void <EnsureCapEditor>b__93_1() { NudgeCap(1); } internal void <EnsureCapEditor>b__93_2() { NudgeCap(-_capEditDefault); } internal void <EnsureCapEditor>b__93_3() { NudgeCap(_capEditDefault); } } private const float PanelW = 980f; private const float PanelH = 780f; private const float RowHeight = 36f; private const float ItemRowHeight = 36f; private const float CategoryHeaderHeight = 22f; private const float ScrollH = 500f; private const float RowInnerW = 880f; private const float IconSize = 28f; private const float ToggleSize = 28f; private const float CapFieldW = 90f; private const float CapFieldH = 28f; private const float ColIconX = 8f; private const float ColNameX = 44f; private const float ColNameW = 540f; private const float ColBlockX = 620f; private const float ColCapX = 720f; private static readonly FieldInfo KnownMaterialField = AccessTools.Field(typeof(Player), "m_knownMaterial"); private static readonly Dictionary<string, Sprite> IconCache = new Dictionary<string, Sprite>(); private static readonly Color ColNormal = Color.white; private static readonly Color ColBlocked = new Color(1f, 0.25f, 0.25f, 1f); private static readonly Color ColCapped = new Color(1f, 0.85f, 0.35f, 1f); private static GameObject _panel; private static RectTransform _contentRoot; private static ScrollRect _scrollRect; private static InputField _searchInput; private static Dropdown _categoryDropdown; private static Text _tabAllLabel; private static Text _tabBlockedLabel; private static Text _tabCappedLabel; private static Button _tabAllButton; private static Button _tabBlockedButton; private static Button _tabCappedButton; private static GameObject _capEditor; private static InputField _capInput; private static Text _capEditorTitle; private static string _capEditPrefab = string.Empty; private static int _capEditDefault = 1; private static bool _guiReady; private static string _searchText = string.Empty; private static int _categoryIndex; private static ViewTab _viewTab = ViewTab.All; private static List<ItemType?> _categoryOptions = new List<ItemType?> { null }; private static List<string> _categoryLabels = new List<string>(); private static bool _suppressCategoryCallback; private static bool _refreshQueued; private static int _refreshReadyFrame; private static float _contentWidth = 900f; private static UITooltip _tooltipTemplate; internal static bool IsOpen { get { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown if ((Object)_panel != (Object)null) { return _panel.activeSelf; } return false; } } internal static void OnGuiReady() { _guiReady = GUIManager.Instance != null && (Object)(object)GUIManager.CustomGUIFront != (Object)null; } internal static void TogglePanel() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown if (!_guiReady && GUIManager.Instance != null) { _guiReady = (Object)(object)GUIManager.CustomGUIFront != (Object)null; } if (!_guiReady || GUIManager.IsHeadless()) { return; } if ((Object)_panel == (Object)null) { BuildPanel(); } else if ((Object)_contentRoot == (Object)null || (Object)_scrollRect == (Object)null) { DestroyPanel(); BuildPanel(); } if (!((Object)_panel == (Object)null)) { bool flag = !_panel.activeSelf; _panel.SetActive(flag); GUIManager.BlockInput(flag); SonicPickupFiltersPlugin.DebugLog("TogglePanel open=" + flag); if (flag) { _viewTab = ViewTab.All; EnsureCategoryOptions(); RefreshContent(); } else { _refreshQueued = false; HideCapEditor(); } } } internal static void RefreshIfOpen() { if (IsOpen) { RefreshContent(); } } internal static void ProcessQueuedRefresh() { if (_refreshQueued && Time.frameCount >= _refreshReadyFrame) { _refreshQueued = false; if (IsOpen) { RefreshContent(); } } } internal static void DestroyPanel() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown if ((Object)_panel != (Object)null) { Object.Destroy((Object)(object)_panel); } _panel = null; _contentRoot = null; _scrollRect = null; _searchInput = null; _categoryDropdown = null; _tabAllLabel = null; _tabBlockedLabel = null; _tabCappedLabel = null; _tabAllButton = null; _tabBlockedButton = null; _tabCappedButton = null; _capEditor = null; _capInput = null; _capEditorTitle = null; _capEditPrefab = string.Empty; _viewTab = ViewTab.All; _searchText = string.Empty; _categoryIndex = 0; _categoryLabels.Clear(); _suppressCategoryCallback = false; _refreshQueued = false; _refreshReadyFrame = 0; _tooltipTemplate = null; } private static void BuildPanel() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0047: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_012f: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Expected O, but got Unknown //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Expected O, but got Unknown //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Expected O, but got Unknown //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Expected O, but got Unknown //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Expected O, but got Unknown //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03b2: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_043b: Unknown result type (might be due to invalid IL or missing references) //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_047a: Unknown result type (might be due to invalid IL or missing references) //IL_0485: Expected O, but got Unknown //IL_040c: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Expected O, but got Unknown //IL_04e0: Unknown result type (might be due to invalid IL or missing references) //IL_04ea: Unknown result type (might be due to invalid IL or missing references) //IL_0521: Unknown result type (might be due to invalid IL or missing references) //IL_0537: Unknown result type (might be due to invalid IL or missing references) //IL_054d: Unknown result type (might be due to invalid IL or missing references) //IL_0563: Unknown result type (might be due to invalid IL or missing references) //IL_05aa: Unknown result type (might be due to invalid IL or missing references) //IL_05b5: Expected O, but got Unknown //IL_0620: Unknown result type (might be due to invalid IL or missing references) //IL_062b: Expected O, but got Unknown //IL_06ce: Unknown result type (might be due to invalid IL or missing references) //IL_06dd: Unknown result type (might be due to invalid IL or missing references) //IL_06ec: Unknown result type (might be due to invalid IL or missing references) //IL_0734: Unknown result type (might be due to invalid IL or missing references) //IL_0739: Unknown result type (might be due to invalid IL or missing references) //IL_073f: Expected O, but got Unknown //IL_066c: Unknown result type (might be due to invalid IL or missing references) if (GUIManager.Instance == null || (Object)GUIManager.CustomGUIFront == (Object)null) { ManualLogSource modLogger = SonicPickupFiltersPlugin.ModLogger; if (modLogger != null) { modLogger.LogError((object)"GUIManager not ready for Pickup Filter panel."); } return; } _panel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 980f, 780f, true); _panel.SetActive(false); GUIManager.Instance.CreateText(ModLocalization.Translate("$sonic_pickupfilters_title", "Pickup Filter"), _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -36f), GUIManager.Instance.AveriaSerifBold, 28, GUIManager.Instance.ValheimOrange, true, Color.black, 500f, 36f, false); GameObject val = GUIManager.Instance.CreateText(ModLocalization.Translate("$sonic_pickupfilters_hint", "Check Block to turn filtering on. Cap is optional — leave empty to never auto-pick, or type a max count. Cap alone (Block off) does nothing."), _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -78f), GUIManager.Instance.AveriaSerifBold, 12, Color.white, true, Color.black, 900f, 40f, false); Text component = val.GetComponent<Text>(); if ((Object)component != (Object)null) { component.alignment = (TextAnchor)1; component.horizontalOverflow = (HorizontalWrapMode)0; component.verticalOverflow = (VerticalWrapMode)1; } RectTransform row = CreateRow("TabRow", new Vector2(0f, -128f), 920f, 36f); object obj = <>c.<>9__55_0; if (obj == null) { UnityAction val2 = delegate { SetViewTab(ViewTab.All); }; <>c.<>9__55_0 = val2; obj = (object)val2; } _tabAllButton = AddRowButton(row, "All", 140f, (UnityAction)obj, out _tabAllLabel); object obj2 = <>c.<>9__55_1; if (obj2 == null) { UnityAction val3 = delegate { SetViewTab(ViewTab.Blocked); }; <>c.<>9__55_1 = val3; obj2 = (object)val3; } _tabBlockedButton = AddRowButton(row, "Blocked", 160f, (UnityAction)obj2, out _tabBlockedLabel); object obj3 = <>c.<>9__55_2; if (obj3 == null) { UnityAction val4 = delegate { SetViewTab(ViewTab.Capped); }; <>c.<>9__55_2 = val4; obj3 = (object)val4; } _tabCappedButton = AddRowButton(row, "Capped", 160f, (UnityAction)obj3, out _tabCappedLabel); AttachTooltip(((Component)_tabBlockedButton).gameObject, ModLocalization.Translate("$sonic_pickupfilters_tab_blocked", "Blocked"), "Items with Block on and no Cap (never auto-picked)."); AttachTooltip(((Component)_tabCappedButton).gameObject, ModLocalization.Translate("$sonic_pickupfilters_tab_capped", "Capped"), "Items with Block on and a Cap number (auto-pick until that count)."); RectTransform val5 = CreateRow("FilterRow", new Vector2(0f, -176f), 920f, 36f); GameObject val6 = GUIManager.Instance.CreateInputField((Transform)(object)val5, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, (ContentType)0, ModLocalization.Translate("$sonic_pickupfilters_search", "Search items…"), 14, 360f, 36f); PrepareLayoutChild(val6, 360f, 36f); _searchInput = val6.GetComponent<InputField>(); if ((Object)_searchInput != (Object)null) { GUIManager.Instance.ApplyInputFieldStyle(_searchInput, 14); ((UnityEvent<string>)(object)_searchInput.onValueChanged).AddListener((UnityAction<string>)OnSearchChanged); } GameObject val7 = GUIManager.Instance.CreateButton(ModLocalization.Translate("$sonic_pickupfilters_clear", "Clear"), (Transform)(object)val5, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 100f, 36f); PrepareLayoutChild(val7, 100f, 36f); Button component2 = val7.GetComponent<Button>(); GUIManager.Instance.ApplyButtonStyle(component2, 14); ButtonClickedEvent onClick = component2.onClick; object obj4 = <>O.<1>__ClearFilters; if (obj4 == null) { UnityAction val8 = ClearFilters; <>O.<1>__ClearFilters = val8; obj4 = (object)val8; } ((UnityEvent)onClick).AddListener((UnityAction)obj4); GameObject val9 = GUIManager.Instance.CreateDropDown((Transform)(object)val5, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 14, 280f, 36f); PrepareLayoutChild(val9, 280f, 36f); _categoryDropdown = val9.GetComponent<Dropdown>(); if ((Object)_categoryDropdown != (Object)null) { FixDropdownOptionHits(_categoryDropdown, 26f); ((UnityEvent<int>)(object)_categoryDropdown.onValueChanged).AddListener((UnityAction<int>)OnCategoryChanged); } GameObject val10 = GUIManager.Instance.CreateScrollView(_panel.transform, false, true, 8f, 2f, GUIManager.Instance.ValheimScrollbarHandleColorBlock, GUIManager.Instance.ValheimBeige, 920f, 500f); ((Object)val10).name = "PickupFilterScroll"; RectTransform component3 = val10.GetComponent<RectTransform>(); component3.anchorMin = new Vector2(0.5f, 1f); component3.anchorMax = new Vector2(0.5f, 1f); component3.pivot = new Vector2(0.5f, 1f); component3.anchoredPosition = new Vector2(0f, -228f); component3.SetSizeWithCurrentAnchors((Axis)0, 920f); component3.SetSizeWithCurrentAnchors((Axis)1, 500f); FixJotunnScrollFill(val10, 920f, 500f); _scrollRect = val10.GetComponentInChildren<ScrollRect>(true); if ((Object)_scrollRect == (Object)null) { ManualLogSource modLogger2 = SonicPickupFiltersPlugin.ModLogger; if (modLogger2 != null) { modLogger2.LogError((object)"ScrollRect missing."); } return; } _scrollRect.horizontal = false; _scrollRect.vertical = true; _scrollRect.movementType = (MovementType)2; _scrollRect.scrollSensitivity = 120f; _scrollRect.verticalScrollbarVisibility = (ScrollbarVisibility)1; GUIManager.Instance.ApplyScrollRectStyle(_scrollRect); if ((Object)_scrollRect.viewport != (Object)null) { Image val11 = ((Component)_scrollRect.viewport).GetComponent<Image>() ?? ((Component)_scrollRect.viewport).gameObject.AddComponent<Image>(); ((Graphic)val11).color = new Color(0f, 0f, 0f, 0.01f); ((Graphic)val11).raycastTarget = true; } _contentRoot = _scrollRect.content; _contentWidth = 908f; ConfigureContentRoot(_contentRoot, _contentWidth); GameObject val12 = GUIManager.Instance.CreateButton(ModLocalization.Translate("$sonic_pickupfilters_close", "Close"), _panel.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 40f), 200f, 48f); Button component4 = val12.GetComponent<Button>(); GUIManager.Instance.ApplyButtonStyle(component4, 16); ButtonClickedEvent onClick2 = component4.onClick; object obj5 = <>c.<>9__55_3; if (obj5 == null) { UnityAction val13 = delegate { if (IsOpen) { TogglePanel(); } }; <>c.<>9__55_3 = val13; obj5 = (object)val13; } ((UnityEvent)onClick2).AddListener((UnityAction)obj5); } private static RectTransform CreateRow(string name, Vector2 anchoredPos, float width, float height) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(HorizontalLayoutGroup) }); val.transform.SetParent(_panel.transform, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0.5f, 1f); component.anchorMax = new Vector2(0.5f, 1f); component.pivot = new Vector2(0.5f, 1f); component.anchoredPosition = anchoredPos; component.sizeDelta = new Vector2(width, height); HorizontalLayoutGroup component2 = val.GetComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component2).spacing = 10f; ((LayoutGroup)component2).padding = new RectOffset(0, 0, 0, 0); ((LayoutGroup)component2).childAlignment = (TextAnchor)3; ((HorizontalOrVerticalLayoutGroup)component2).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)component2).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = false; return component; } private static Button AddRowButton(RectTransform row, string label, float width, UnityAction onClick, out Text labelText) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //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) GameObject val = GUIManager.Instance.CreateButton(label, (Transform)(object)row, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, width, 36f); PrepareLayoutChild(val, width, 36f); Button component = val.GetComponent<Button>(); GUIManager.Instance.ApplyButtonStyle(component, 14); ((UnityEvent)component.onClick).AddListener(onClick); labelText = val.GetComponentInChildren<Text>(); return component; } private static void PrepareLayoutChild(GameObject go, float width, float height) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) RectTransform component = go.GetComponent<RectTransform>(); if ((Object)component != (Object)null) { component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.sizeDelta = new Vector2(width, height); component.anchoredPosition = Vector2.zero; ((Transform)component).localScale = Vector3.one; } LayoutElement val = go.GetComponent<LayoutElement>() ?? go.AddComponent<LayoutElement>(); val.preferredWidth = width; val.preferredHeight = height; val.minWidth = width; val.minHeight = height; val.flexibleWidth = 0f; val.flexibleHeight = 0f; } private static void FixJotunnScrollFill(GameObject scrollRoot, float width, float height) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_0096: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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) Transform val = scrollRoot.transform.Find("Scroll View"); if (!((Object)val == (Object)null)) { RectTransform component = ((Component)val).GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.pivot = new Vector2(0.5f, 0.5f); component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; component.anchoredPosition = Vector2.zero; ((Transform)component).localScale = Vector3.one; Transform val2 = val.Find("Viewport"); if ((Object)val2 != (Object)null) { RectTransform component2 = ((Component)val2).GetComponent<RectTransform>(); component2.anchorMin = Vector2.zero; component2.anchorMax = Vector2.one; component2.pivot = new Vector2(0.5f, 0.5f); component2.offsetMin = new Vector2(0f, 0f); component2.offsetMax = new Vector2(-10f, 0f); component2.anchoredPosition = Vector2.zero; } } } private static void ConfigureContentRoot(RectTransform content, float width) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Expected O, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown VerticalLayoutGroup val = ((Component)content).GetComponent<VerticalLayoutGroup>() ?? ((Component)content).gameObject.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)val).childAlignment = (TextAnchor)0; ((HorizontalOrVerticalLayoutGroup)val).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)val).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val).spacing = 4f; ((LayoutGroup)val).padding = new RectOffset(8, 8, 8, 8); ContentSizeFitter val2 = ((Component)content).GetComponent<ContentSizeFitter>() ?? ((Component)content).gameObject.AddComponent<ContentSizeFitter>(); val2.horizontalFit = (FitMode)0; val2.verticalFit = (FitMode)2; content.anchorMin = new Vector2(0f, 1f); content.anchorMax = new Vector2(0f, 1f); content.pivot = new Vector2(0f, 1f); content.anchoredPosition = Vector2.zero; content.SetSizeWithCurrentAnchors((Axis)0, width); ((Transform)content).localScale = Vector3.one; GraphicRaycaster component = ((Component)content).GetComponent<GraphicRaycaster>(); if ((Object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } Canvas component2 = ((Component)content).GetComponent<Canvas>(); if ((Object)component2 != (Object)null) { Object.DestroyImmediate((Object)(object)component2); } } private static void OnSearchChanged(string value) { _searchText = value ?? string.Empty; SonicPickupFiltersPlugin.DebugLog("Search='" + _searchText + "'"); RefreshContent(); } private static void OnCategoryChanged(int index) { if (!_suppressCategoryCallback) { _categoryIndex = index; string text = ((index >= 0 && index < _categoryLabels.Count) ? _categoryLabels[index] : "?"); SonicPickupFiltersPlugin.DebugLog("Category dropdown → " + index + " (" + text + ")"); _refreshReadyFrame = Time.frameCount + 2; _refreshQueued = true; } } private static void ClearFilters() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown _searchText = string.Empty; _categoryIndex = 0; if ((Object)_searchInput != (Object)null) { _searchInput.SetTextWithoutNotify(string.Empty); } SetCategoryDropdownValue(0); RefreshContent(); } private static void SetViewTab(ViewTab tab) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown _viewTab = tab; _categoryIndex = 0; SetCategoryDropdownValue(0); if ((Object)_searchInput != (Object)null && !string.IsNullOrEmpty(_searchText)) { SonicPickupFiltersPlugin.DebugLog("Tab " + tab.ToString() + " with search still='" + _searchText + "'"); } RefreshContent(); } private static void UpdateTabLabels() { SetTabLabel(_tabAllLabel, _tabAllButton, ViewTab.All, ModLocalization.Translate("$sonic_pickupfilters_tab_all", "All")); SetTabLabel(_tabBlockedLabel, _tabBlockedButton, ViewTab.Blocked, ModLocalization.Translate("$sonic_pickupfilters_tab_blocked", "Blocked") + " (" + PickupRuleStore.CountByMode(PickupRuleMode.Block) + ")"); SetTabLabel(_tabCappedLabel, _tabCappedButton, ViewTab.Capped, ModLocalization.Translate("$sonic_pickupfilters_tab_capped", "Capped") + " (" + PickupRuleStore.CountByMode(PickupRuleMode.Cap) + ")"); } private static void SetTabLabel(Text label, Button button, ViewTab tab, string text) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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) if ((Object)label != (Object)null) { label.text = text; ((Graphic)label).color = ((_viewTab == tab) ? GUIManager.Instance.ValheimOrange : Color.white); } if ((Object)button != (Object)null) { ColorBlock colors = ((Selectable)button).colors; ((ColorBlock)(ref colors)).normalColor = (Color)((_viewTab == tab) ? new Color(1f, 0.85f, 0.55f, 1f) : Color.white); ((Selectable)button).colors = colors; } } private static void EnsureCategoryOptions() { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown List<ItemType> list = (from t in GetKnownItems().Select(GetItemType).Distinct() orderby ItemMatch.FriendlyItemTypeLabel(t) select t).ToList(); _categoryOptions = new List<ItemType?> { null }; _categoryOptions.AddRange(((IEnumerable<ItemType>)list).Select((Func<ItemType, ItemType?>)((ItemType t) => t))); List<string> list2 = new List<string> { ModLocalization.Translate("$sonic_pickupfilters_cat_all", "All categories") }; for (int num = 0; num < list.Count; num++) { list2.Add(ItemMatch.FriendlyItemTypeLabel(list[num])); } if (_categoryIndex < 0 || _categoryIndex >= _categoryOptions.Count) { _categoryIndex = 0; } bool flag = list2.Count == _categoryLabels.Count; if (flag) { for (int num2 = 0; num2 < list2.Count; num2++) { if (!string.Equals(list2[num2], _categoryLabels[num2], StringComparison.Ordinal)) { flag = false; break; } } } if (flag) { SetCategoryDropdownValue(_categoryIndex); return; } _categoryLabels = list2; if (!((Object)_categoryDropdown == (Object)null)) { _suppressCategoryCallback = true; try { _categoryDropdown.ClearOptions(); _categoryDropdown.AddOptions(list2); _categoryDropdown.SetValueWithoutNotify(_categoryIndex); } finally { _suppressCategoryCallback = false; } SonicPickupFiltersPlugin.DebugLog("Category options rebuilt count=" + list2.Count); } } private static void SetCategoryDropdownValue(int index) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown if ((Object)_categoryDropdown == (Object)null) { return; } _suppressCategoryCallback = true; try { _categoryDropdown.SetValueWithoutNotify(index); } finally { _suppressCategoryCallback = false; } } private static void FixDropdownOptionHits(Dropdown dropdown, float optionHeight) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Expected O, but got Unknown //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Expected O, but got Unknown //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Expected O, but got Unknown //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Expected O, but got Unknown //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Expected O, but got Unknown //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) if ((Object)dropdown == (Object)null) { return; } if ((Object)dropdown.itemText != (Object)null) { RectTransform rectTransform = ((Graphic)dropdown.itemText).rectTransform; rectTransform.anchorMin = new Vector2(0f, 0f); rectTransform.anchorMax = new Vector2(1f, 1f); rectTransform.offsetMin = new Vector2(10f, 2f); rectTransform.offsetMax = new Vector2(-10f, -2f); ((Graphic)dropdown.itemText).raycastTarget = false; dropdown.itemText.alignment = (TextAnchor)3; } if ((Object)dropdown.template == (Object)null) { return; } RectTransform template = dropdown.template; template.SetSizeWithCurrentAnchors((Axis)1, Mathf.Min(280f, optionHeight * 8f)); Transform val = ((Transform)dropdown.template).Find("Viewport/Content"); if ((Object)val != (Object)null) { VerticalLayoutGroup val2 = ((Component)val).GetComponent<VerticalLayoutGroup>() ?? ((Component)val).gameObject.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)val2).childAlignment = (TextAnchor)0; ((HorizontalOrVerticalLayoutGroup)val2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val2).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)val2).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val2).spacing = 0f; ((LayoutGroup)val2).padding = new RectOffset(0, 0, 0, 0); } Transform val3 = ((Transform)dropdown.template).Find("Viewport/Content/Item"); if ((Object)val3 == (Object)null) { return; } RectTransform val4 = (RectTransform)(object)((val3 is RectTransform) ? val3 : null); if ((Object)val4 != (Object)null) { val4.SetSizeWithCurrentAnchors((Axis)1, optionHeight); } LayoutElement val5 = ((Component)val3).GetComponent<LayoutElement>() ?? ((Component)val3).gameObject.AddComponent<LayoutElement>(); val5.minHeight = optionHeight; val5.preferredHeight = optionHeight; val5.flexibleHeight = 0f; for (int i = 0; i < val3.childCount; i++) { Transform child = val3.GetChild(i); Image component = ((Component)child).GetComponent<Image>(); if ((Object)component != (Object)null) { ((Graphic)component).raycastTarget = true; RectTransform val6 = (RectTransform)(object)((child is RectTransform) ? child : null); if ((Object)val6 != (Object)null) { val6.anchorMin = Vector2.zero; val6.anchorMax = Vector2.one; val6.offsetMin = Vector2.zero; val6.offsetMax = Vector2.zero; } } Text component2 = ((Component)child).GetComponent<Text>(); if ((Object)component2 != (Object)null) { ((Graphic)component2).raycastTarget = false; } } Toggle component3 = ((Component)val3).GetComponent<Toggle>(); if ((Object)component3 != (Object)null) { component3.toggleTransition = (ToggleTransition)0; } } private static void ClearContentChildren() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown if (!((Object)_contentRoot == (Object)null)) { for (int num = ((Transform)_contentRoot).childCount - 1; num >= 0; num--) { Object.DestroyImmediate((Object)(object)((Component)((Transform)_contentRoot).GetChild(num)).gameObject); } } } private static void RefreshContent() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Unknown result type (might be due to invalid IL or missing references) //IL_046e: Unknown result type (might be due to invalid IL or missing references) //IL_0479: Expected O, but got Unknown //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_04f8: Unknown result type (might be due to invalid IL or missing references) //IL_04fd: Unknown result type (might be due to invalid IL or missing references) //IL_0510: Unknown result type (might be due to invalid IL or missing references) //IL_0515: Unknown result type (might be due to invalid IL or missing references) if ((Object)_contentRoot == (Object)null) { return; } ClearContentChildren(); List<ItemDrop> list = GetKnownItems(); if (_viewTab == ViewTab.Blocked) { list = MergeRuleItems(list, PickupRuleMode.Block); } else if (_viewTab == ViewTab.Capped) { list = MergeRuleItems(list, PickupRuleMode.Cap); } UpdateTabLabels(); IEnumerable<ItemDrop> source = list.Where((ItemDrop d) => ItemMatch.MatchesSearch(d, _searchText)); bool flag = _viewTab == ViewTab.All && _categoryIndex > 0 && _categoryIndex < _categoryOptions.Count && _categoryOptions[_categoryIndex].HasValue; if (flag) { ItemType want = _categoryOptions[_categoryIndex].Value; source = source.Where((ItemDrop d) => GetItemType(d) == want); } if (_viewTab == ViewTab.Blocked) { source = source.Where((ItemDrop d) => PickupRuleStore.GetRule(PickupRuleStore.NormalizePrefabName(((Object)d).name)).Mode == PickupRuleMode.Block); } else if (_viewTab == ViewTab.Capped) { source = source.Where((ItemDrop d) => PickupRuleStore.GetRule(PickupRuleStore.NormalizePrefabName(((Object)d).name)).Mode == PickupRuleMode.Cap); } List<IGrouping<ItemType, ItemDrop>> list2 = (from g in source.GroupBy(GetItemType) orderby ItemMatch.FriendlyItemTypeLabel(g.Key) select g).ToList(); int num = list2.Sum((IGrouping<ItemType, ItemDrop> g) => g.Select((ItemDrop d) => PickupRuleStore.NormalizePrefabName(((Object)d).name)).Distinct<string>(StringComparer.OrdinalIgnoreCase).Count()); float realtimeSinceStartup = Time.realtimeSinceStartup; SonicPickupFiltersPlugin.DebugLog($"Refresh tab={_viewTab} known={list.Count} items={num} search='{_searchText}' " + $"cat={_categoryIndex} applyCat={flag} rules={PickupRuleStore.CountByMode(PickupRuleMode.Block)}B/" + $"{PickupRuleStore.CountByMode(PickupRuleMode.Cap)}C"); if (list2.Count == 0) { string text = ((_viewTab == ViewTab.Blocked || _viewTab == ViewTab.Capped) ? (((_viewTab == ViewTab.Blocked) ? (PickupRuleStore.CountByMode(PickupRuleMode.Block) > 0) : (PickupRuleStore.CountByMode(PickupRuleMode.Cap) > 0)) ? ((!string.IsNullOrEmpty(_searchText)) ? ("No matches for search \"" + _searchText + "\". Clear search to see all.") : ((_viewTab == ViewTab.Blocked) ? "No blocked items." : "No capped items.")) : ((_viewTab == ViewTab.Blocked) ? "No blocked items." : "No capped items.")) : ((list.Count != 0) ? "No matching items." : "No known items yet — pick something up first.")); CreateContentLabel(text, 18, Color.white, 40f); } else { CreateColumnHeaderRow(); float realtimeSinceStartup2 = Time.realtimeSinceStartup; foreach (IGrouping<ItemType, ItemDrop> item in list2) { List<ItemDrop> items = (from g in item.GroupBy<ItemDrop, string>((ItemDrop d) => PickupRuleStore.NormalizePrefabName(((Object)d).name), StringComparer.OrdinalIgnoreCase) select g.First() into d orderby ItemMatch.GetLocalized(d.m_itemData?.m_shared?.m_name) select d).ToList(); CreateGroupSection(ItemMatch.FriendlyItemTypeLabel(item.Key), items); } SonicPickupFiltersPlugin.DebugLog($"Row build: {(Time.realtimeSinceStartup - realtimeSinceStartup2) * 1000f:F0}ms for {num} items"); } float realtimeSinceStartup3 = Time.realtimeSinceStartup; Canvas.ForceUpdateCanvases(); LayoutRebuilder.ForceRebuildLayoutImmediate(_contentRoot); float num2 = Mathf.Max(new float[3] { LayoutUtility.GetPreferredHeight(_contentRoot), EstimateContentHeight(list2), 80f }); _contentRoot.SetSizeWithCurrentAnchors((Axis)0, _contentWidth); _contentRoot.SetSizeWithCurrentAnchors((Axis)1, num2); _contentRoot.anchoredPosition = Vector2.zero; ((Transform)_contentRoot).localScale = Vector3.one; if ((Object)_scrollRect != (Object)null) { _scrollRect.verticalNormalizedPosition = 1f; } string[] obj = new string[5] { $"Layout: {(Time.realtimeSinceStartup - realtimeSinceStartup3) * 1000f:F0}ms; ", $"total={(Time.realtimeSinceStartup - realtimeSinceStartup) * 1000f:F0}ms; ", $"children={((Transform)_contentRoot).childCount}; ", null, null }; Rect rect = _contentRoot.rect; object arg = ((Rect)(ref rect)).width; rect = _contentRoot.rect; obj[3] = $"content={arg:F0}x{((Rect)(ref rect)).height:F0}; "; obj[4] = $"hasContentCanvas={(Object)(object)((Component)_contentRoot).GetComponent<Canvas>() != (Object)null}"; SonicPickupFiltersPlugin.DebugLog(string.Concat(obj)); } private static void CreateContentLabel(string text, int fontSize, Color color, float height) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("EmptyLabel", new Type[3] { typeof(RectTransform), typeof(Text), typeof(LayoutElement) }); val.transform.SetParent((Transform)(object)_contentRoot, false); LayoutElement component = val.GetComponent<LayoutElement>(); component.minHeight = height; component.preferredHeight = height; component.flexibleWidth = 1f; Text component2 = val.GetComponent<Text>(); component2.font = GUIManager.Instance.AveriaSerifBold; component2.fontSize = fontSize; ((Graphic)component2).color = color; component2.alignment = (TextAnchor)4; component2.text = text; GUIManager.Instance.ApplyTextStyle(component2, fontSize); } private static float EstimateContentHeight(List<IGrouping<ItemType, ItemDrop>> groups) { if (groups == null || groups.Count == 0) { return 80f; } float num = 44f; for (int i = 0; i < groups.Count; i++) { int num2 = groups[i].Select((ItemDrop d) => PickupRuleStore.NormalizePrefabName(((Object)d).name)).Distinct<string>(StringComparer.OrdinalIgnoreCase).Count(); num += 22f + (float)num2 * 36f + 8f; } return num; } private static List<ItemDrop> MergeRuleItems(List<ItemDrop> known, PickupRuleMode mode) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown Dictionary<string, ItemDrop> dictionary = new Dictionary<string, ItemDrop>(StringComparer.OrdinalIgnoreCase); for (int i = 0; i < known.Count; i++) { string key = PickupRuleStore.NormalizePrefabName(((Object)known[i]).name); if (!dictionary.ContainsKey(key)) { dictionary[key] = known[i]; } } if ((Object)ObjectDB.instance != (Object)null) { foreach (KeyValuePair<string, PickupRule> item in PickupRuleStore.EnumerateRules()) { if (item.Value.Mode != mode || dictionary.ContainsKey(item.Key)) { continue; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item.Key); if (!((Object)itemPrefab == (Object)null)) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)component != (Object)null) { dictionary[item.Key] = component; } } } } return dictionary.Values.ToList(); } private static ItemType GetItemType(ItemDrop drop) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (drop?.m_itemData?.m_shared == null) { return (ItemType)16; } return drop.m_itemData.m_shared.m_itemType; } private static List<ItemDrop> GetKnownItems() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown List<ItemDrop> list = new List<ItemDrop>(); HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); if ((Object)ObjectDB.instance == (Object)null) { return list; } HashSet<string> hashSet2 = null; if ((Object)Player.m_localPlayer != (Object)null && KnownMaterialField != null) { hashSet2 = KnownMaterialField.GetValue(Player.m_localPlayer) as HashSet<string>; } foreach (GameObject item2 in ObjectDB.instance.m_items) { if ((Object)item2 == (Object)null) { continue; } ItemDrop component = item2.GetComponent<ItemDrop>(); if ((Object)component == (Object)null || component.m_itemData?.m_shared == null) { continue; } string item = PickupRuleStor