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 DadsEPI v1.4.11
DadsEPI.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("DadsEPI")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.4.11.0")] [assembly: AssemblyInformationalVersion("1.4.11+ddddd6244dbffd0cb45f333fab804fa19841936a")] [assembly: AssemblyProduct("DadsEPI")] [assembly: AssemblyTitle("DadsEPI")] [assembly: AssemblyVersion("1.4.11.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 DadsEPI { [BepInPlugin("com.dadisbored.dadsepi", "DadsEPI", "1.4.11")] [BepInProcess("valheim.exe")] public sealed class DadsEPIPlugin : BaseUnityPlugin { public const string PluginGuid = "com.dadisbored.dadsepi"; public const string PluginName = "DadsEPI"; public const string PluginVersion = "1.4.11"; internal static ConfigEntry<bool> ModEnabled; internal static ConfigEntry<int> ExtraRows; internal static ConfigEntry<bool> EquipmentRowEnabled; internal static ConfigEntry<bool> SeparateEquipmentPanel; internal static ConfigEntry<bool> AutoEquip; internal static ConfigEntry<int> QuickSlotCount; internal static ConfigEntry<bool> ShowQuickSlots; internal static ConfigEntry<bool> AlwaysShowQuickSlots; internal static ConfigEntry<int> QuickSlotsPerRow; internal static ConfigEntry<bool> WisplightSlot; internal static ConfigEntry<bool> WishboneSlot; internal static ConfigEntry<bool> CryptKeySlot; internal static ConfigEntry<bool> ArrowsSlot; internal static ConfigEntry<bool> TrinketSlot; internal static ConfigEntry<bool> ShieldSlot; internal static ConfigEntry<bool> UtilitySlot; internal static ConfigEntry<string> RemovedEquipmentSlots; internal static readonly ConfigEntry<string>[] CustomSlotNames = new ConfigEntry<string>[10]; internal static readonly ConfigEntry<string>[] CustomSlotItems = new ConfigEntry<string>[10]; internal static ConfigEntry<string> HeadLabel; internal static ConfigEntry<string> ChestLabel; internal static ConfigEntry<string> LegsLabel; internal static ConfigEntry<string> BackLabel; internal static ConfigEntry<string> UtilityLabel; internal static ConfigEntry<float> HudScale; internal static ConfigEntry<Vector2> HudPosition; internal static ConfigEntry<KeyboardShortcut> HudDragKeys; internal static readonly ConfigEntry<KeyboardShortcut>[] QuickHotkeys = new ConfigEntry<KeyboardShortcut>[8]; internal static readonly ConfigEntry<string>[] QuickHotkeyLabels = new ConfigEntry<string>[8]; internal static ManualLogSource ModLogger; private Harmony _harmony; private float _nextLayoutCheck; private static int _configEditDepth; private static bool _layoutChangePending; private static bool _displayChangePending; internal static bool ConfigEditActive => _configEditDepth > 0; public static void BeginConfigEdit() { _configEditDepth++; } public static void EndConfigEdit() { if (_configEditDepth != 0 && --_configEditDepth <= 0) { bool layoutChangePending = _layoutChangePending; bool displayChangePending = _displayChangePending; _layoutChangePending = false; _displayChangePending = false; if (layoutChangePending) { OnLayoutSettingChanged(null, EventArgs.Empty); } else if (displayChangePending) { OnDisplaySettingChanged(null, EventArgs.Empty); } } } private void Awake() { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_044b: 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_0467: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0483: Unknown result type (might be due to invalid IL or missing references) //IL_0488: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Unknown result type (might be due to invalid IL or missing references) //IL_04a4: Unknown result type (might be due to invalid IL or missing references) //IL_04bb: Unknown result type (might be due to invalid IL or missing references) //IL_04c0: Unknown result type (might be due to invalid IL or missing references) //IL_04d7: Unknown result type (might be due to invalid IL or missing references) //IL_04dc: Unknown result type (might be due to invalid IL or missing references) //IL_04f3: 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_052e: Unknown result type (might be due to invalid IL or missing references) //IL_0578: Unknown result type (might be due to invalid IL or missing references) //IL_057d: Unknown result type (might be due to invalid IL or missing references) //IL_09c1: Unknown result type (might be due to invalid IL or missing references) //IL_09cb: Expected O, but got Unknown ModLogger = ((BaseUnityPlugin)this).Logger; ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - Server & Sync", "Mod Enabled", true, "Enable DadsEPI."); ExtraRows = ((BaseUnityPlugin)this).Config.Bind<int>("2 - Inventory", "Extra Inventory Rows", 0, new ConfigDescription("Additional ordinary rows; zero retains the native inventory size.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 5), Array.Empty<object>())); EquipmentRowEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Inventory", "Enable Equipment Row", true, "Add dedicated equipment and quick slots."); SeparateEquipmentPanel = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Inventory", "Display Equipment in Separate Panel", true, "Render dedicated slots in a labeled side panel."); AutoEquip = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Inventory", "Auto-Equip Items", true, "Equip items placed in equipment slots."); QuickSlotCount = ((BaseUnityPlugin)this).Config.Bind<int>("3 - Quick Slots", "Number of Quick Slots", 3, new ConfigDescription("Number of quick slots.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 8), Array.Empty<object>())); ShowQuickSlots = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Quick Slots", "Show Quick Slots on HUD", true, "Display quick slots during gameplay."); AlwaysShowQuickSlots = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Quick Slots", "Always Show All Slots", true, "Display empty quick slots on the HUD."); QuickSlotsPerRow = ((BaseUnityPlugin)this).Config.Bind<int>("3 - Quick Slots", "Slots Per Row", 8, new ConfigDescription("Maximum quick slots per HUD row.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), Array.Empty<object>())); WisplightSlot = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Special Equipment Slots", "Enable Wisplight Slot", true, "Add a Wisplight-only slot."); WishboneSlot = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Special Equipment Slots", "Enable Wishbone Slot", true, "Add a Wishbone-only slot."); CryptKeySlot = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Special Equipment Slots", "Enable Crypt Key Slot", true, "Add a Crypt Key-only slot."); ArrowsSlot = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Special Equipment Slots", "Enable Arrows Slot", true, "Add an arrow and bolt ammunition slot."); TrinketSlot = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Special Equipment Slots", "Enable Trinket Slot", true, "Add a slot for the listed trinket prefabs."); ShieldSlot = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Special Equipment Slots", "Enable Shield Slot", true, "Add a shield-only slot."); UtilitySlot = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Special Equipment Slots", "Enable Utility Slot", true, "Add a utility-item slot."); RemovedEquipmentSlots = ((BaseUnityPlugin)this).Config.Bind<string>("4.5 - Equipment Slot Management", "Removed Equipment Slots", "", "Comma or semicolon separated slot names."); for (int i = 0; i < CustomSlotNames.Length; i++) { int num = i + 1; CustomSlotNames[i] = ((BaseUnityPlugin)this).Config.Bind<string>("4.5 - Equipment Slot Management", $"Custom Slot {num} Name", "", "Visible name for this custom equipment slot. Leave blank to disable it."); CustomSlotItems[i] = ((BaseUnityPlugin)this).Config.Bind<string>("4.5 - Equipment Slot Management", $"Custom Slot {num} Items", "", "Comma-separated exact in-game prefab names accepted by this slot."); } HeadLabel = ((BaseUnityPlugin)this).Config.Bind<string>("6 - Equipment Slot Labels", "Head Slot Label", "Head", "Helmet slot label."); ChestLabel = ((BaseUnityPlugin)this).Config.Bind<string>("6 - Equipment Slot Labels", "Chest Slot Label", "Chest", "Chest slot label."); LegsLabel = ((BaseUnityPlugin)this).Config.Bind<string>("6 - Equipment Slot Labels", "Legs Slot Label", "Legs", "Leg slot label."); BackLabel = ((BaseUnityPlugin)this).Config.Bind<string>("6 - Equipment Slot Labels", "Back Slot Label", "Back", "Shoulder slot label."); UtilityLabel = ((BaseUnityPlugin)this).Config.Bind<string>("6 - Equipment Slot Labels", "Utility Slot Label", "Utility", "Utility slot label."); HudScale = ((BaseUnityPlugin)this).Config.Bind<float>("7 - Quick Slots Customization", "HUD Size", 1f, "Quick-slot HUD scale."); HudPosition = ((BaseUnityPlugin)this).Config.Bind<Vector2>("7 - Quick Slots Customization", "HUD Position", new Vector2(47f, -115f), "Legacy setting; quick slots stay anchored directly below the hotbar."); HudDragKeys = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("7 - Quick Slots Customization", "Drag to Reposition Keys", new KeyboardShortcut((KeyCode)323, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Legacy setting; quick-slot dragging is disabled."); KeyboardShortcut[] array = (KeyboardShortcut[])(object)new KeyboardShortcut[8] { new KeyboardShortcut((KeyCode)122, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), new KeyboardShortcut((KeyCode)120, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), new KeyboardShortcut((KeyCode)99, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), new KeyboardShortcut((KeyCode)118, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), new KeyboardShortcut((KeyCode)98, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), new KeyboardShortcut((KeyCode)110, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), new KeyboardShortcut((KeyCode)49, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), new KeyboardShortcut((KeyCode)50, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }) }; for (int j = 0; j < 8; j++) { int num2 = j + 1; QuickHotkeys[j] = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("8 - Quick Slot Hotkeys", $"Hotkey {num2}", array[j], $"Shortcut for quick slot {num2}."); QuickHotkeyLabels[j] = ((BaseUnityPlugin)this).Config.Bind<string>("8 - Quick Slot Hotkeys", $"Hotkey {num2} Display Text", "Alt + " + ((object)((KeyboardShortcut)(ref array[j])).MainKey/*cast due to .constrained prefix*/).ToString().Replace("Alpha", ""), $"HUD text for quick slot {num2}."); } Watch<bool>(ModEnabled, OnDisplaySettingChanged); Watch<int>(ExtraRows, OnLayoutSettingChanged); Watch<bool>(EquipmentRowEnabled, OnLayoutSettingChanged); Watch<bool>(SeparateEquipmentPanel, OnDisplaySettingChanged); Watch<bool>(AutoEquip, OnDisplaySettingChanged); Watch<int>(QuickSlotCount, OnLayoutSettingChanged); Watch<bool>(ShowQuickSlots, OnDisplaySettingChanged); Watch<bool>(AlwaysShowQuickSlots, OnDisplaySettingChanged); Watch<int>(QuickSlotsPerRow, OnDisplaySettingChanged); Watch<bool>(WisplightSlot, OnLayoutSettingChanged); Watch<bool>(WishboneSlot, OnLayoutSettingChanged); Watch<bool>(CryptKeySlot, OnLayoutSettingChanged); Watch<bool>(ArrowsSlot, OnLayoutSettingChanged); Watch<bool>(TrinketSlot, OnLayoutSettingChanged); Watch<bool>(ShieldSlot, OnLayoutSettingChanged); Watch<bool>(UtilitySlot, OnLayoutSettingChanged); Watch<string>(RemovedEquipmentSlots, OnLayoutSettingChanged); for (int k = 0; k < CustomSlotNames.Length; k++) { Watch<string>(CustomSlotNames[k], OnLayoutSettingChanged); Watch<string>(CustomSlotItems[k], OnLayoutSettingChanged); } Watch<string>(HeadLabel, OnLayoutSettingChanged); Watch<string>(ChestLabel, OnLayoutSettingChanged); Watch<string>(LegsLabel, OnLayoutSettingChanged); Watch<string>(BackLabel, OnLayoutSettingChanged); Watch<string>(UtilityLabel, OnLayoutSettingChanged); for (int l = 0; l < 8; l++) { Watch<KeyboardShortcut>(QuickHotkeys[l], OnDisplaySettingChanged); Watch<string>(QuickHotkeyLabels[l], OnDisplaySettingChanged); } InventoryLayout.RebuildSlots(); _harmony = new Harmony("com.dadisbored.dadsepi"); _harmony.PatchAll(typeof(DadsEPIPlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"DadsEPI 1.4.11 initialized with separate equipment and quick-slot compartments."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private static void Watch<T>(ConfigEntry<T> entry, EventHandler handler) { entry.SettingChanged += handler; } private static void OnLayoutSettingChanged(object sender, EventArgs args) { if (ConfigEditActive) { _layoutChangePending = true; return; } InventoryLayout.RebuildForConfigChange(Player.m_localPlayer); SlotVisuals.Reset(); QuickSlotHud.Reset(); } private static void OnDisplaySettingChanged(object sender, EventArgs args) { if (ConfigEditActive) { _displayChangePending = true; return; } InventoryLayout.RebuildSlots(); if ((Object)(object)Player.m_localPlayer != (Object)null) { InventoryLayout.Apply(Player.m_localPlayer, normalizeItems: false); } SlotVisuals.Reset(); QuickSlotHud.Reset(); } private void Update() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) if (ConfigEditActive) { return; } ConfigEntry<bool> modEnabled = ModEnabled; if (modEnabled == null || !modEnabled.Value || (Object)(object)Player.m_localPlayer == (Object)null) { return; } if (Time.unscaledTime >= _nextLayoutCheck) { _nextLayoutCheck = Time.unscaledTime + 0.5f; InventoryLayout.Apply(Player.m_localPlayer, normalizeItems: false); } if (InputBlocked()) { return; } for (int i = 0; i < InventoryLayout.EnabledQuickSlots; i++) { if (ShortcutPressed(QuickHotkeys[i].Value)) { InventoryLayout.UseQuickSlot(i); } } } private static bool ShortcutPressed(KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0 || !Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { if (!Input.GetKey(modifier)) { return false; } } return true; } private static bool InputBlocked() { if (!Console.IsVisible() && !TextInput.IsVisible() && !Menu.IsVisible() && !InventoryGui.IsVisible() && !Minimap.IsOpen()) { if ((Object)(object)Chat.instance != (Object)null) { return Chat.instance.HasFocus(); } return false; } return true; } } internal sealed class DedicatedSlot { internal string Id; internal string Label; internal bool Quick; internal Func<ItemData, bool> Accepts; } internal static class InventoryLayout { internal const int BaseVanillaRows = 4; internal const int MaximumVanillaRows = 9; internal static readonly List<DedicatedSlot> Slots = new List<DedicatedSlot>(); private static bool _normalizing; private static ItemData _pendingAutoItem; private static int _equipmentSlotCount; private static int _layoutNormalRows = 4; private static InventoryGui _lastGui; private static int _lastDisplayedRows = -1; private static bool _lastSeparatePanel; private static readonly HashSet<string> DefaultAmmoPrefabs = new HashSet<string>(StringComparer.Ordinal) { "ArrowWood", "ArrowFlint", "ArrowBronze", "ArrowFire", "ArrowIron", "ArrowPoison", "ArrowObsidian", "ArrowFrost", "ArrowSilver", "ArrowNeedle", "ArrowCarapace", "ArrowCharred", "ArrowBloodGold", "BoltBone", "BoltIron", "BoltBlackmetal", "BoltCarapace", "BoltCharred", "BoltBloodGold" }; private static readonly HashSet<string> TrinketPrefabs = new HashSet<string>(StringComparer.Ordinal) { "TrinketBlackDamageHealth", "TrinketBlackStamina", "TrinketBloodGoldHealth", "TrinketBloodGoldStamina", "TrinketBronzeHealth", "TrinketBronzeStamina", "TrinketCarapaceEitr", "TrinketChitinSwim", "TrinketFlametalEitr", "TrinketFlametalStaminaHealth", "TrinketIronHealth", "TrinketIronStamina", "TrinketScaleStaminaDamage", "TrinketSilverDamage", "TrinketSilverResist" }; internal static int VanillaRows { get; private set; } = 4; internal static int NormalRows { get { if (!DadsEPIPlugin.ConfigEditActive) { return Mathf.Clamp(VanillaRows, 4, 9) + Mathf.Clamp(DadsEPIPlugin.ExtraRows.Value, 0, 5); } return _layoutNormalRows; } } internal static int EquipmentSlotCount => _equipmentSlotCount; internal static int EnabledQuickSlots { get { if (!DadsEPIPlugin.ConfigEditActive) { if (!DadsEPIPlugin.EquipmentRowEnabled.Value) { return 0; } return Mathf.Clamp(DadsEPIPlugin.QuickSlotCount.Value, 0, 8); } return Slots.Count - _equipmentSlotCount; } } internal static int StorageRows(int width) { if (!DadsEPIPlugin.ConfigEditActive && !DadsEPIPlugin.EquipmentRowEnabled.Value) { return 0; } return Mathf.CeilToInt((float)Slots.Count / (float)Mathf.Max(1, width)); } internal static int TotalRows(int width) { return NormalRows + StorageRows(width); } internal static void RebuildSlots() { Slots.Clear(); _equipmentSlotCount = 0; _layoutNormalRows = NormalRows; _lastDisplayedRows = -1; ConfigEntry<bool> equipmentRowEnabled = DadsEPIPlugin.EquipmentRowEnabled; if (equipmentRowEnabled == null || !equipmentRowEnabled.Value) { return; } AddEquipment("Head", DadsEPIPlugin.HeadLabel.Value, (ItemData item) => (int)item.m_shared.m_itemType == 6); AddEquipment("Chest", DadsEPIPlugin.ChestLabel.Value, (ItemData item) => (int)item.m_shared.m_itemType == 7); AddEquipment("Legs", DadsEPIPlugin.LegsLabel.Value, (ItemData item) => (int)item.m_shared.m_itemType == 11); AddEquipment("Back", DadsEPIPlugin.BackLabel.Value, (ItemData item) => (int)item.m_shared.m_itemType == 17); if (DadsEPIPlugin.WisplightSlot.Value) { AddEquipment("Wisplight", "Wisplight", IsWisplight); } if (DadsEPIPlugin.WishboneSlot.Value) { AddEquipment("Wishbone", "Wishbone", (ItemData item) => IsPrefab(item, "Wishbone")); } if (DadsEPIPlugin.CryptKeySlot.Value) { AddEquipment("Crypt Key", "Crypt Key", (ItemData item) => IsPrefab(item, "CryptKey")); } if (DadsEPIPlugin.ArrowsSlot.Value) { AddEquipment("Arrows", "Arrows", IsArrow); } if (DadsEPIPlugin.TrinketSlot.Value) { AddEquipment("Trinket", "Trinket", (ItemData item) => TrinketPrefabs.Contains(PrefabName(item))); } if (DadsEPIPlugin.ShieldSlot.Value) { AddEquipment("Shield", "Shield", (ItemData item) => (int)item.m_shared.m_itemType == 5); } if (DadsEPIPlugin.UtilitySlot.Value) { AddEquipment("Utility", DadsEPIPlugin.UtilityLabel.Value, (ItemData item) => (int)item.m_shared.m_itemType == 18 && (!DadsEPIPlugin.WishboneSlot.Value || !IsPrefab(item, "Wishbone")) && (!DadsEPIPlugin.WisplightSlot.Value || !IsWisplight(item))); } for (int num = 0; num < DadsEPIPlugin.CustomSlotNames.Length; num++) { string text = (DadsEPIPlugin.CustomSlotNames[num].Value ?? string.Empty).Trim(); HashSet<string> prefabs = new HashSet<string>(from value in (DadsEPIPlugin.CustomSlotItems[num].Value ?? string.Empty).Split(new char[1] { ',' }) select value.Trim() into value where value.Length > 0 select value, StringComparer.Ordinal); if (text.Length > 0 && prefabs.Count > 0) { AddEquipment(text, text, (ItemData item) => prefabs.Contains(PrefabName(item))); } } _equipmentSlotCount = Slots.Count; for (int num2 = 0; num2 < Mathf.Clamp(DadsEPIPlugin.QuickSlotCount.Value, 0, 8); num2++) { int num3 = num2; Slots.Add(new DedicatedSlot { Id = $"Quick{num3 + 1}", Label = QuickLabel(num3), Quick = true, Accepts = (ItemData item) => true }); } } internal static void RebuildForConfigChange(Player player) { int layoutNormalRows = _layoutNormalRows; DedicatedSlot[] array = Slots.ToArray(); RebuildSlots(); if ((Object)(object)player == (Object)null) { return; } ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; if (modEnabled == null || !modEnabled.Value) { return; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory != null) { bool flag = layoutNormalRows != NormalRows || array.Length != Slots.Count; int num = 0; while (!flag && num < array.Length) { flag = array[num].Id != Slots[num].Id || array[num].Quick != Slots[num].Quick; num++; } if (flag) { MigrateSlots(inventory, layoutNormalRows, array); } Apply(player, normalizeItems: false); } } private static void MigrateSlots(Inventory inventory, int previousRows, DedicatedSlot[] previousSlots) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0176: 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_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) int width = inventory.GetWidth(); if (width <= 0) { return; } List<ItemData> list = new List<ItemData>(inventory.GetAllItems()); Dictionary<ItemData, Vector2i> dictionary = new Dictionary<ItemData, Vector2i>(); HashSet<long> hashSet = new HashSet<long>(); HashSet<int> hashSet2 = new HashSet<int>(); Vector2i val = default(Vector2i); for (int i = 0; i < previousSlots.Length; i++) { ((Vector2i)(ref val))..ctor(i % width, previousRows + i / width); ItemData itemAt = inventory.GetItemAt(val.x, val.y); if (itemAt == null) { continue; } for (int j = 0; j < Slots.Count; j++) { if (!hashSet2.Contains(j) && !(previousSlots[i].Id != Slots[j].Id) && previousSlots[i].Quick == Slots[j].Quick && Slots[j].Accepts(itemAt)) { Vector2i position = (dictionary[itemAt] = SlotPosition(j, width)); hashSet.Add(PositionKey(position, width)); hashSet2.Add(j); break; } } } foreach (ItemData item2 in list) { if (!dictionary.ContainsKey(item2)) { Vector2i gridPos = item2.m_gridPos; int num = (gridPos.y - previousRows) * width + gridPos.x; bool flag = num >= 0 && num < previousSlots.Length; bool flag2 = gridPos.y >= 0 && gridPos.y < NormalRows; bool flag3 = gridPos.y >= NormalRows && SlotIndex(gridPos, width) < 0 && !flag; long item = PositionKey(gridPos, width); if (gridPos.x >= 0 && gridPos.x < width && (flag2 || flag3) && hashSet.Add(item)) { dictionary[item2] = gridPos; } } } int k = Math.Max(TotalRows(width), inventory.GetHeight()); Vector2i val3 = default(Vector2i); foreach (ItemData item3 in list) { if (dictionary.ContainsKey(item3)) { continue; } ((Vector2i)(ref val3))..ctor(-1, -1); for (int l = 0; l < NormalRows; l++) { if (val3.x >= 0) { break; } for (int m = 0; m < width; m++) { if (hashSet.Add(PositionKey(new Vector2i(m, l), width))) { ((Vector2i)(ref val3))..ctor(m, l); break; } } } if (val3.x < 0) { for (; hashSet.Contains(PositionKey(new Vector2i(0, k), width)); k++) { } ((Vector2i)(ref val3))..ctor(0, k++); hashSet.Add(PositionKey(val3, width)); ManualLogSource modLogger = DadsEPIPlugin.ModLogger; if (modLogger != null) { modLogger.LogWarning((object)"Inventory capacity decreased; an item was retained in an overflow row."); } } dictionary[item3] = val3; } bool flag4 = false; foreach (ItemData item4 in list) { Vector2i val4 = dictionary[item4]; if (!(item4.m_gridPos == val4)) { item4.m_gridPos = val4; flag4 = true; } } if (flag4) { inventory.m_onChanged?.Invoke(); } } private static long PositionKey(Vector2i position, int width) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) return (long)position.y * (long)width + position.x; } internal static void SetVanillaRows(int rows) { VanillaRows = Mathf.Clamp(rows, 4, 9); } internal static void ReadVanillaRows(Player player) { string s = default(string); if ((Object)(object)player != (Object)null && player.TryGetUniqueKeyValue("invrows", ref s) && int.TryParse(s, out var result)) { SetVanillaRows(result); } else { SetVanillaRows(4); } } internal static void Apply(Player player, bool normalizeItems) { if ((Object)(object)player == (Object)null) { return; } ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; if (modEnabled == null || !modEnabled.Value) { return; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return; } ReadVanillaRows(player); int num = TotalRows(inventory.GetWidth()); if (inventory.GetHeight() < num) { inventory.SetHeight(num); } if (normalizeItems) { Normalize(player, inventory); } int num2 = 0; foreach (ItemData allItem in inventory.GetAllItems()) { num2 = Math.Max(num2, allItem.m_gridPos.y + 1); } int num3 = Mathf.Max(num, num2); if (inventory.GetHeight() != num3) { inventory.SetHeight(num3); } _layoutNormalRows = NormalRows; InventoryGui instance = InventoryGui.instance; bool value = DadsEPIPlugin.SeparateEquipmentPanel.Value; int num4 = (value ? NormalRows : num3); if ((Object)(object)instance != (Object)null && ((Object)(object)instance != (Object)(object)_lastGui || num4 != _lastDisplayedRows || value != _lastSeparatePanel || normalizeItems)) { instance.SetInventorySize(num4); _lastGui = instance; _lastDisplayedRows = num4; _lastSeparatePanel = value; } if ((Object)(object)player.m_tombstone != (Object)null) { Container component = player.m_tombstone.GetComponent<Container>(); if ((Object)(object)component != (Object)null) { component.m_height = num3; } } } internal static bool IsPlayerInventory(Inventory inventory) { if (inventory != null && (Object)(object)Player.m_localPlayer != (Object)null) { return inventory == ((Humanoid)Player.m_localPlayer).GetInventory(); } return false; } internal static int SlotIndex(Vector2i position, int width) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) int num = position.y * width + position.x - NormalRows * width; if (num < 0 || num >= Slots.Count) { return -1; } return num; } internal static Vector2i SlotPosition(int slotIndex, int width) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) int num = NormalRows * width + slotIndex; return new Vector2i(num % width, num / width); } internal static bool IsReserved(Vector2i position, int width) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return SlotIndex(position, width) >= 0; } internal static bool IsInEquipmentSlot(Inventory inventory, ItemData item) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (inventory == null || item == null) { return false; } int num = SlotIndex(item.m_gridPos, inventory.GetWidth()); if (num < 0 || num >= EquipmentSlotCount || !Slots[num].Accepts(item)) { return false; } return inventory.GetItemAt(item.m_gridPos.x, item.m_gridPos.y) == item; } internal static bool UsesSeparateEquipmentSlot(Inventory inventory, ItemData item, ItemData equippedItem) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (inventory == null || item == null || equippedItem == null) { return false; } int num = FindEquipmentSlot(item); int num2 = SlotIndex(equippedItem.m_gridPos, inventory.GetWidth()); if (num >= 0 && num2 >= 0 && num2 < EquipmentSlotCount) { return num != num2; } return false; } internal static bool CanPlace(ItemData item, Vector2i position, int width) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) int num = SlotIndex(position, width); if (num < 0) { return position.y < NormalRows; } if (item != null) { return Slots[num].Accepts(item); } return true; } internal static Vector2i FindGeneralEmpty(Inventory inventory, bool topFirst) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (topFirst) { for (int i = 0; i < NormalRows; i++) { for (int j = 0; j < inventory.GetWidth(); j++) { if (inventory.GetItemAt(j, i) == null) { return new Vector2i(j, i); } } } } else { for (int num = NormalRows - 1; num >= 0; num--) { for (int k = 0; k < inventory.GetWidth(); k++) { if (inventory.GetItemAt(k, num) == null) { return new Vector2i(k, num); } } } } return new Vector2i(-1, -1); } internal static void BeginAutoAdd(Inventory inventory, ItemData item) { ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; object pendingAutoItem; if (modEnabled != null && modEnabled.Value) { ConfigEntry<bool> autoEquip = DadsEPIPlugin.AutoEquip; if (autoEquip != null && autoEquip.Value && IsPlayerInventory(inventory)) { pendingAutoItem = item; goto IL_0032; } } pendingAutoItem = null; goto IL_0032; IL_0032: _pendingAutoItem = (ItemData)pendingAutoItem; } internal static void EndAutoAdd() { _pendingAutoItem = null; } internal static Vector2i FindPreferredEmpty(Inventory inventory, bool topFirst) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0037: Unknown result type (might be due to invalid IL or missing references) if (_pendingAutoItem != null) { int num = FindEquipmentSlot(_pendingAutoItem); if (num >= 0) { Vector2i val = SlotPosition(num, inventory.GetWidth()); if (inventory.GetItemAt(val.x, val.y) == null) { return val; } } } return FindGeneralEmpty(inventory, topFirst); } internal static int CountGeneralEmpty(Inventory inventory) { int num = 0; for (int i = 0; i < NormalRows; i++) { for (int j = 0; j < inventory.GetWidth(); j++) { if (inventory.GetItemAt(j, i) == null) { num++; } } } return num; } internal static void UseQuickSlot(int index) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && index >= 0 && index < EnabledQuickSlots) { int slotIndex = EquipmentSlotCount + index; ItemData itemAt = ((Humanoid)localPlayer).GetInventory().GetItemAt(SlotPosition(slotIndex, ((Humanoid)localPlayer).GetInventory().GetWidth()).x, SlotPosition(slotIndex, ((Humanoid)localPlayer).GetInventory().GetWidth()).y); if (itemAt != null) { ((Humanoid)localPlayer).UseItem(((Humanoid)localPlayer).GetInventory(), itemAt, false); } } } internal static void MoveEquippedItemToDedicatedSlot(Player player, ItemData item) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (!_normalizing && !((Object)(object)player == (Object)null) && item != null) { int num = FindEquipmentSlot(item); if (num >= 0) { MoveItem(player, ((Humanoid)player).GetInventory(), item, SlotPosition(num, ((Humanoid)player).GetInventory().GetWidth())); } } } internal static void AutoPlaceNewItem(Player player, Inventory inventory, ItemData item) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) if (_normalizing || (Object)(object)player == (Object)null || inventory == null || item == null) { return; } ConfigEntry<bool> autoEquip = DadsEPIPlugin.AutoEquip; if (autoEquip == null || !autoEquip.Value || inventory != ((Humanoid)player).GetInventory()) { return; } int slot = FindEquipmentSlot(item); if (slot < 0) { return; } Vector2i val = SlotPosition(slot, inventory.GetWidth()); ItemData itemAt = inventory.GetItemAt(val.x, val.y); if (itemAt != null) { if (itemAt == item && itemAt.IsEquipable() && !itemAt.m_equipped) { ((Humanoid)player).EquipItem(itemAt, true); } return; } ItemData val2 = (ItemData)(inventory.GetAllItems().Contains(item) ? ((object)item) : ((object)((IEnumerable<ItemData>)inventory.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData candidate) => Slots[slot].Accepts(candidate) && string.Equals(PrefabName(candidate), PrefabName(item), StringComparison.Ordinal))))); if (val2 != null) { MoveItem(player, inventory, val2, val); if (val2.IsEquipable() && !val2.m_equipped) { ((Humanoid)player).EquipItem(val2, true); } } } internal static void AutoEquipDedicatedItems(Player player) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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) if (_normalizing || (Object)(object)player == (Object)null) { return; } ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; if (modEnabled == null || !modEnabled.Value) { return; } ConfigEntry<bool> autoEquip = DadsEPIPlugin.AutoEquip; if (autoEquip == null || !autoEquip.Value) { return; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return; } for (int i = 0; i < EquipmentSlotCount; i++) { Vector2i val = SlotPosition(i, inventory.GetWidth()); ItemData itemAt = inventory.GetItemAt(val.x, val.y); if (itemAt != null && Slots[i].Accepts(itemAt) && itemAt.IsEquipable() && !itemAt.m_equipped) { ((Humanoid)player).EquipItem(itemAt, true); } } } internal static int FindEquipmentSlot(ItemData item) { for (int i = 0; i < EquipmentSlotCount; i++) { if (Slots[i].Accepts(item)) { return i; } } return -1; } private static void Normalize(Player player, Inventory inventory) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0225: 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 (_normalizing) { return; } _normalizing = true; try { foreach (ItemData item in new List<ItemData>(inventory.GetAllItems())) { if (!item.m_equipped) { continue; } int num = SlotIndex(item.m_gridPos, inventory.GetWidth()); if (num < 0 || !Slots[num].Accepts(item)) { int num2 = FindEquipmentSlot(item); if (num2 >= 0) { MoveItem(player, inventory, item, SlotPosition(num2, inventory.GetWidth())); } } } int slot; for (slot = 0; slot < EquipmentSlotCount; slot++) { Vector2i val = SlotPosition(slot, inventory.GetWidth()); if (inventory.GetItemAt(val.x, val.y) == null) { ItemData val2 = ((IEnumerable<ItemData>)inventory.GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData item) => item != null && SlotIndex(item.m_gridPos, inventory.GetWidth()) < 0 && Slots[slot].Accepts(item))); if (val2 != null) { MoveItem(player, inventory, val2, val); } } } foreach (ItemData item2 in new List<ItemData>(inventory.GetAllItems())) { if (item2.m_gridPos.y >= NormalRows && !CanPlace(item2, item2.m_gridPos, inventory.GetWidth())) { Vector2i val3 = FindGeneralEmpty(inventory, topFirst: true); if (val3.x >= 0) { MoveItem(player, inventory, item2, val3); } } } ConfigEntry<bool> autoEquip = DadsEPIPlugin.AutoEquip; if (autoEquip == null || !autoEquip.Value) { return; } for (int num3 = 0; num3 < EquipmentSlotCount; num3++) { Vector2i val4 = SlotPosition(num3, inventory.GetWidth()); ItemData itemAt = inventory.GetItemAt(val4.x, val4.y); if (itemAt != null && Slots[num3].Accepts(itemAt) && itemAt.IsEquipable() && !itemAt.m_equipped) { ((Humanoid)player).EquipItem(itemAt, true); } } } finally { _normalizing = false; } } private static void MoveItem(Player player, Inventory inventory, ItemData item, Vector2i destination) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (!(item.m_gridPos == destination)) { ItemData itemAt = inventory.GetItemAt(destination.x, destination.y); Vector2i gridPos = item.m_gridPos; if (itemAt != null && itemAt != item) { Vector2i val = FindGeneralEmpty(inventory, topFirst: true); itemAt.m_gridPos = ((val.x >= 0) ? val : gridPos); } item.m_gridPos = destination; inventory.m_onChanged?.Invoke(); } } private static void AddEquipment(string id, string label, Func<ItemData, bool> accepts) { HashSet<string> hashSet = new HashSet<string>(from value in (DadsEPIPlugin.RemovedEquipmentSlots.Value ?? string.Empty).Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries) select value.Trim(), StringComparer.OrdinalIgnoreCase); if (!hashSet.Contains(id) && !hashSet.Contains(label)) { Slots.Add(new DedicatedSlot { Id = id, Label = label, Accepts = accepts }); } } private static string QuickLabel(int index) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) string value = DadsEPIPlugin.QuickHotkeyLabels[index].Value; if (!string.IsNullOrWhiteSpace(value)) { return value; } return ((object)DadsEPIPlugin.QuickHotkeys[index].Value/*cast due to .constrained prefix*/).ToString(); } private static string PrefabName(ItemData item) { if (!((Object)(object)item?.m_dropPrefab != (Object)null)) { return string.Empty; } return Utils.GetPrefabName(item.m_dropPrefab); } private static bool IsPrefab(ItemData item, string prefab) { return string.Equals(PrefabName(item), prefab, StringComparison.Ordinal); } private static bool IsWisplight(ItemData item) { if (!IsPrefab(item, "Demister")) { return IsPrefab(item, "Wisplight"); } return true; } private static bool IsArrow(ItemData item) { return DefaultAmmoPrefabs.Contains(PrefabName(item)); } } [HarmonyPatch(typeof(Player), "Load", new Type[] { typeof(ZPackage) })] internal static class PlayerLoadPatch { private static void Prefix(Player __instance) { ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; if (modEnabled != null && modEnabled.Value) { Inventory inventory = ((Humanoid)__instance).GetInventory(); if (inventory != null) { inventory.SetHeight(Math.Max(inventory.GetHeight(), InventoryLayout.TotalRows(inventory.GetWidth()))); } } } private static void Postfix(Player __instance) { InventoryLayout.Apply(__instance, normalizeItems: true); } } [HarmonyPatch(typeof(Player), "OnSpawned", new Type[] { typeof(bool) })] internal static class PlayerSpawnedPatch { private static void Postfix(Player __instance) { InventoryLayout.Apply(__instance, normalizeItems: true); } } [HarmonyPatch(typeof(Player), "EquipInventoryItems")] internal static class EquipInventoryItemsPatch { private static bool Prefix(Player __instance) { UtilityEquipment.BeginInventoryRestore(); Inventory val = ((__instance != null) ? ((Humanoid)__instance).GetInventory() : null); if (val == null) { return false; } foreach (ItemData item in new List<ItemData>(val.GetAllItems())) { if (item == null || !item.m_equipped) { continue; } if (item.m_shared == null) { item.m_equipped = false; ManualLogSource modLogger = DadsEPIPlugin.ModLogger; if (modLogger != null) { modLogger.LogWarning((object)"Skipped an equipped inventory record with no shared item data while loading the character."); } continue; } try { if (!((Humanoid)__instance).EquipItem(item, false)) { item.m_equipped = false; } } catch (Exception ex) { item.m_equipped = false; string text = ((!string.IsNullOrEmpty(item.m_shared.m_name)) ? item.m_shared.m_name : "unknown item"); ManualLogSource modLogger2 = DadsEPIPlugin.ModLogger; if (modLogger2 != null) { modLogger2.LogError((object)("Could not restore equipped item '" + text + "'; it was left in the inventory unequipped. " + ex.GetType().Name + ": " + ex.Message)); } } } return false; } private static Exception Finalizer(Exception __exception) { UtilityEquipment.EndInventoryRestore(); return __exception; } } [HarmonyPatch(typeof(Player), "SetInventorySize")] internal static class NativeInventorySizePatch { private static bool Prefix(Player __instance, int rows) { ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; if (modEnabled == null || !modEnabled.Value) { return true; } rows = Mathf.Clamp(rows, 4, 9); InventoryLayout.SetVanillaRows(rows); __instance.AddUniqueKeyValue("invrows", rows.ToString()); Inventory inventory = ((Humanoid)__instance).GetInventory(); inventory.SetHeight(InventoryLayout.TotalRows(inventory.GetWidth())); InventoryLayout.Apply(__instance, normalizeItems: true); ((Humanoid)__instance).DropInvalidItems(); return false; } } [HarmonyPatch(typeof(Inventory), "FindEmptySlot")] internal static class FindEmptySlotPatch { private static bool Prefix(Inventory __instance, bool __0, ref Vector2i __result) { //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) ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; if (modEnabled == null || !modEnabled.Value || !InventoryLayout.IsPlayerInventory(__instance)) { return true; } __result = InventoryLayout.FindPreferredEmpty(__instance, __0); return false; } } [HarmonyPatch(typeof(Inventory), "GetEmptySlots")] internal static class GetEmptySlotsPatch { private static void Postfix(Inventory __instance, ref int __result) { ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; if (modEnabled != null && modEnabled.Value && InventoryLayout.IsPlayerInventory(__instance)) { __result = InventoryLayout.CountGeneralEmpty(__instance); } } } [HarmonyPatch(typeof(Inventory), "HaveEmptySlot")] internal static class HaveEmptySlotPatch { private static void Postfix(Inventory __instance, ref bool __result) { ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; if (modEnabled != null && modEnabled.Value && InventoryLayout.IsPlayerInventory(__instance)) { __result = InventoryLayout.CountGeneralEmpty(__instance) > 0; } } } [HarmonyPatch(typeof(Inventory), "CanAddItem", new Type[] { typeof(ItemData), typeof(int) })] internal static class CanAddItemPatch { private static void Postfix(Inventory __instance, ItemData item, int stack, ref bool __result) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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) ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; if (modEnabled == null || !modEnabled.Value || !InventoryLayout.IsPlayerInventory(__instance) || item?.m_shared == null || !__result) { return; } int num = ((stack > 0) ? stack : item.m_stack); if (num <= item.m_shared.m_maxStackSize && InventoryLayout.FindGeneralEmpty(__instance, topFirst: true).x >= 0) { return; } ConfigEntry<bool> autoEquip = DadsEPIPlugin.AutoEquip; int num2 = ((autoEquip != null && autoEquip.Value) ? InventoryLayout.FindEquipmentSlot(item) : (-1)); bool flag = false; if (num2 >= 0) { Vector2i val = InventoryLayout.SlotPosition(num2, __instance.GetWidth()); flag = __instance.GetItemAt(val.x, val.y) == null; if (flag && num <= item.m_shared.m_maxStackSize) { return; } } int num3 = 0; foreach (ItemData allItem in __instance.GetAllItems()) { if (allItem.m_shared.m_name == item.m_shared.m_name && allItem.m_quality == item.m_quality && allItem.m_worldLevel == item.m_worldLevel) { num3 += Math.Max(0, allItem.m_shared.m_maxStackSize - allItem.m_stack); } } int num4 = InventoryLayout.CountGeneralEmpty(__instance); if (flag) { num4++; } __result = num3 + num4 * item.m_shared.m_maxStackSize >= num; } } [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })] internal static class AddItemAutoEquipmentPatch { private static void Prefix(Inventory __instance, ItemData item) { InventoryLayout.BeginAutoAdd(__instance, item); } private static void Postfix(Inventory __instance, ItemData item, bool __result) { InventoryLayout.EndAutoAdd(); if (__result) { ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; if (modEnabled != null && modEnabled.Value && !((Object)(object)Player.m_localPlayer == (Object)null)) { InventoryLayout.AutoPlaceNewItem(Player.m_localPlayer, __instance, item); } } } private static Exception Finalizer(Exception __exception) { InventoryLayout.EndAutoAdd(); return __exception; } } [HarmonyPatch(typeof(TombStone), "OnTakeAllSuccess")] internal static class TombStoneAutoEquipPatch { private static void Postfix() { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; if (modEnabled != null && modEnabled.Value) { InventoryLayout.Apply(localPlayer, normalizeItems: true); InventoryLayout.AutoEquipDedicatedItems(localPlayer); } } } } [HarmonyPatch(typeof(InventoryGrid), "DropItem", new Type[] { typeof(Inventory), typeof(ItemData), typeof(int), typeof(Vector2i) })] internal static class InventoryGridDropPatch { private sealed class DropState { internal Vector2i Source; internal bool SourceInPlayerInventory; internal bool SourceEquipment; internal bool TargetEquipment; } private static readonly HashSet<ItemData> SuppressedEquipItems = new HashSet<ItemData>(); private static int _suppressionFrame = -1; private static bool Prefix(InventoryGrid __instance, Inventory __0, ItemData item, Vector2i pos, ref bool __result, out DropState __state) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) __state = null; Inventory inventory = __instance.GetInventory(); ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; if (modEnabled == null || !modEnabled.Value || !InventoryLayout.IsPlayerInventory(inventory)) { return true; } if (!InventoryLayout.CanPlace(item, pos, inventory.GetWidth())) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, "This item does not match that dedicated slot.", 0, (Sprite)null, false); } __result = false; return false; } bool flag = item != null && __0 == inventory && inventory.GetItemAt(item.m_gridPos.x, item.m_gridPos.y) == item; int num = (flag ? InventoryLayout.SlotIndex(item.m_gridPos, inventory.GetWidth()) : (-1)); int num2 = InventoryLayout.SlotIndex(pos, inventory.GetWidth()); __state = new DropState { Source = (Vector2i)(((??)item?.m_gridPos) ?? new Vector2i(-1, -1)), SourceInPlayerInventory = flag, SourceEquipment = (num >= 0 && num < InventoryLayout.EquipmentSlotCount), TargetEquipment = (num2 >= 0 && num2 < InventoryLayout.EquipmentSlotCount) }; if (item != null && num >= 0 && num < InventoryLayout.EquipmentSlotCount && (num2 < 0 || num2 >= InventoryLayout.EquipmentSlotCount) && flag) { ItemData itemAt = inventory.GetItemAt(pos.x, pos.y); if (itemAt != null && !InventoryLayout.CanPlace(itemAt, item.m_gridPos, inventory.GetWidth())) { __result = false; return false; } } if (item != null && item.m_equipped && num >= 0 && num2 < 0) { Player localPlayer2 = Player.m_localPlayer; if (localPlayer2 != null) { ((Humanoid)localPlayer2).UnequipItem(item, true); } } if (item != null && num2 >= 0 && num2 < InventoryLayout.EquipmentSlotCount) { ItemData itemAt2 = inventory.GetItemAt(pos.x, pos.y); if (itemAt2 != null && itemAt2 != item && itemAt2.m_equipped) { Player localPlayer3 = Player.m_localPlayer; if (localPlayer3 != null) { ((Humanoid)localPlayer3).UnequipItem(itemAt2, true); } } } return true; } private static void Postfix(InventoryGrid __instance, Vector2i pos, bool __result, DropState __state) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) if (!__result || __state == null || (Object)(object)Player.m_localPlayer == (Object)null) { return; } Inventory inventory = __instance.GetInventory(); if (!InventoryLayout.IsPlayerInventory(inventory)) { return; } if (__state.SourceEquipment && !__state.TargetEquipment) { Suppress(inventory.GetItemAt(pos.x, pos.y)); } if (__state.SourceInPlayerInventory && !__state.SourceEquipment && __state.TargetEquipment) { Suppress(inventory.GetItemAt(__state.Source.x, __state.Source.y)); } ConfigEntry<bool> autoEquip = DadsEPIPlugin.AutoEquip; if (autoEquip == null || !autoEquip.Value) { return; } Vector2i val = (Vector2i)(__state.TargetEquipment ? pos : (__state.SourceEquipment ? __state.Source : new Vector2i(-1, -1))); if (val.x >= 0) { ItemData itemAt = inventory.GetItemAt(val.x, val.y); if (itemAt != null && !itemAt.m_equipped && itemAt.IsEquipable() && InventoryLayout.CanPlace(itemAt, val, inventory.GetWidth())) { ((Humanoid)Player.m_localPlayer).EquipItem(itemAt, true); } } } private static void Suppress(ItemData item) { if (item != null) { if (_suppressionFrame != Time.frameCount) { SuppressedEquipItems.Clear(); _suppressionFrame = Time.frameCount; } SuppressedEquipItems.Add(item); } } internal static bool IsSuppressed(ItemData item) { if (item != null && _suppressionFrame == Time.frameCount) { return SuppressedEquipItems.Contains(item); } return false; } } [HarmonyPatch(typeof(Humanoid), "EquipItem", new Type[] { typeof(ItemData), typeof(bool) })] internal static class EquipItemPatch { private static bool Prefix(Humanoid __instance, ItemData item, ref bool __result, out ItemData __state) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && InventoryGridDropPatch.IsSuppressed(item)) { __state = null; __result = false; return false; } __state = UtilityEquipment.BeginEquip(__instance, item); return true; } private static void Postfix(Humanoid __instance, ItemData item, bool __result, ItemData __state) { UtilityEquipment.EndEquip(__instance, __state, __result); if (!__result || UtilityEquipment.IsRestoringInventoryEquipment) { return; } ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; if (modEnabled != null && modEnabled.Value) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer) { InventoryLayout.MoveEquippedItemToDedicatedSlot(val, item); } } } private static Exception Finalizer(Exception __exception, Humanoid __instance, ItemData __state) { if (__exception != null) { UtilityEquipment.EndEquip(__instance, __state, equipped: false); } return __exception; } } [HarmonyPatch(typeof(Humanoid), "IsItemEquiped")] internal static class IsItemEquippedPatch { private static void Postfix(Humanoid __instance, ItemData item, ref bool __result) { if (!__result && UtilityEquipment.IsManagedUtility(__instance, item)) { __result = true; } } } [HarmonyPatch(typeof(Humanoid), "IsItemTypeEquiped")] internal static class IsItemTypeEquippedPatch { private static void Postfix(Humanoid __instance, ItemData item, ref bool __result) { if (!__result && UtilityEquipment.HasEquippedUtilityType(__instance, item)) { __result = true; } } } [HarmonyPatch(typeof(Humanoid), "UpdateEquipmentStatusEffects")] internal static class EquipmentStatusEffectsPatch { private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown List<CodeInstruction> list = new List<CodeInstruction>(instructions); FieldInfo objB = AccessTools.Field(typeof(Humanoid), "m_equipmentStatusEffects"); MethodInfo methodInfo = AccessTools.Method(typeof(UtilityEquipment), "AddStatusEffects", (Type[])null, (Type[])null); for (int i = 1; i < list.Count; i++) { if (!(list[i].opcode != OpCodes.Ldfld) && object.Equals(list[i].operand, objB) && !(list[i - 1].opcode != OpCodes.Ldarg_0)) { int index = i - 1; CodeInstruction val = new CodeInstruction(OpCodes.Ldarg_0, (object)null); val.labels.AddRange(list[index].labels); val.blocks.AddRange(list[index].blocks); list[index].labels.Clear(); list[index].blocks.Clear(); list.InsertRange(index, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[3] { val, new CodeInstruction(OpCodes.Ldloc_0, (object)null), new CodeInstruction(OpCodes.Call, (object)methodInfo) }); return list; } } ManualLogSource modLogger = DadsEPIPlugin.ModLogger; if (modLogger != null) { modLogger.LogError((object)"Could not patch utility status-effect collection."); } return list; } } [HarmonyPatch(typeof(Humanoid), "UnequipAllItems")] internal static class UnequipAllItemsPatch { private static void Postfix(Humanoid __instance) { UtilityEquipment.UnequipAdditionalUtilities(__instance); } } [HarmonyPatch(typeof(InventoryGui), "DoCrafting")] internal static class CraftingAutoEquipPatch { private static void Postfix(Player __0) { InventoryLayout.AutoEquipDedicatedItems(__0); } } [HarmonyPatch(typeof(InventoryGrid), "UpdateInventory")] internal static class InventoryGridUpdatePatch { private static void Postfix(InventoryGrid __instance) { ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; if (modEnabled != null && modEnabled.Value && InventoryLayout.IsPlayerInventory(__instance.GetInventory())) { SlotVisuals.Refresh(__instance); } } } [HarmonyPatch(typeof(Hud), "Update")] internal static class HudUpdatePatch { private static void Postfix(Hud __instance) { QuickSlotHud.Refresh(__instance); } } [HarmonyPatch(typeof(Hud), "OnDestroy")] internal static class HudDestroyPatch { private static void Prefix() { QuickSlotHud.Reset(); } } internal static class QuickSlotHud { private const string RootName = "DadsEPI_QuickSlots"; private const float HotbarGap = 10f; private static RectTransform _root; private static readonly List<GameObject> Elements = new List<GameObject>(); private static readonly string[] HiddenChildren = new string[3] { "equiped", "queued", "selected" }; private static readonly Vector3[] Corners = (Vector3[])(object)new Vector3[4]; private static float _nextRefresh; private static RectTransform _messageTextRect; private static RectTransform _messageIconRect; private static Vector2 _messageTextPosition; private static Vector2 _messageIconPosition; internal static void Reset() { RestorePickupMessagePosition(); if ((Object)(object)_root != (Object)null) { Object.Destroy((Object)(object)((Component)_root).gameObject); } _root = null; Elements.Clear(); _nextRefresh = 0f; } internal static void Refresh(Hud hud) { //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_021b: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_015f: 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_0189: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)hud == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { return; } ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; if (modEnabled == null || !modEnabled.Value) { return; } Ensure(hud); if ((Object)(object)_root == (Object)null) { return; } HotkeyBar componentInChildren = hud.m_rootObject.GetComponentInChildren<HotkeyBar>(true); if (Time.unscaledTime < _nextRefresh) { if (((Component)_root).gameObject.activeSelf) { AlignWithHotbar(componentInChildren); } return; } _nextRefresh = Time.unscaledTime + 0.1f; bool flag = DadsEPIPlugin.ShowQuickSlots.Value && InventoryLayout.EnabledQuickSlots > 0; ((Component)_root).gameObject.SetActive(flag); if (!flag) { PositionPickupMessage(belowSlots: false); return; } int num = VisibleSlotCount(); EnsureElementCount(componentInChildren, num); int num2 = Mathf.Clamp(DadsEPIPlugin.QuickSlotsPerRow.Value, 1, 8); float num3 = (((Object)(object)componentInChildren != (Object)null) ? ((Transform)_root).InverseTransformVector(((Component)componentInChildren).transform.TransformVector(new Vector3(componentInChildren.m_elementSpace, 0f, 0f))).x : 70f); Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory(); for (int i = 0; i < Elements.Count; i++) { GameObject val = Elements[i]; bool flag2 = i < num; val.SetActive(flag2); if (flag2) { RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = new Vector2((float)(i % num2) * num3, (float)(-(i / num2)) * num3); Vector2i val2 = InventoryLayout.SlotPosition(InventoryLayout.EquipmentSlotCount + i, inventory.GetWidth()); ItemData itemAt = inventory.GetItemAt(val2.x, val2.y); SetElement(val, itemAt, i); } } _root.sizeDelta = new Vector2((float)Mathf.Min(num, num2) * num3, (float)Mathf.CeilToInt((float)num / (float)num2) * num3); ((Transform)_root).localScale = Vector3.one * Mathf.Clamp(DadsEPIPlugin.HudScale.Value, 0.25f, 3f); AlignWithHotbar(componentInChildren); PositionPickupMessage(num > 0); } private static int VisibleSlotCount() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) int enabledQuickSlots = InventoryLayout.EnabledQuickSlots; if (DadsEPIPlugin.AlwaysShowQuickSlots.Value) { return enabledQuickSlots; } Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory(); int result = 0; for (int i = 0; i < enabledQuickSlots; i++) { Vector2i val = InventoryLayout.SlotPosition(InventoryLayout.EquipmentSlotCount + i, inventory.GetWidth()); if (inventory.GetItemAt(val.x, val.y) != null) { result = i + 1; } } return result; } private static void Ensure(Hud hud) { //IL_0026: 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) //IL_005b: 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_008d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_root != (Object)null)) { GameObject val = new GameObject("DadsEPI_QuickSlots", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(hud.m_rootObject.transform, false); _root = val.GetComponent<RectTransform>(); _root.anchorMin = new Vector2(0f, 1f); _root.anchorMax = new Vector2(0f, 1f); _root.pivot = new Vector2(0f, 1f); } } private static void EnsureElementCount(HotkeyBar sourceBar, int count) { if (Elements.Count < count && !((Object)(object)sourceBar == (Object)null) && !((Object)(object)sourceBar.m_elementPrefab == (Object)null)) { while (Elements.Count < count) { GameObject val = Object.Instantiate<GameObject>(sourceBar.m_elementPrefab, (Transform)(object)_root, false); ((Object)val).name = $"DadsEPI_QuickSlot_{Elements.Count + 1}"; Elements.Add(val); } } } private static void AlignWithHotbar(HotkeyBar sourceBar) { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)sourceBar == (Object)null) && ((Component)sourceBar).transform.childCount != 0 && Elements.Count != 0) { Transform child = ((Component)sourceBar).transform.GetChild(0); RectTransform val = (RectTransform)(object)((child is RectTransform) ? child : null); Transform transform = Elements[0].transform; RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null)) { val.GetWorldCorners(Corners); float x = Corners[0].x; float y = Corners[0].y; val2.GetWorldCorners(Corners); float num = Mathf.Abs(((Component)sourceBar).transform.TransformVector(new Vector3(0f, 10f, 0f)).y); RectTransform root = _root; ((Transform)root).position = ((Transform)root).position + new Vector3(x - Corners[0].x, y - num - Corners[1].y, 0f); } } } private static void SetElement(GameObject element, ItemData item, int index) { //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) Transform val = element.transform.Find("icon"); if ((Object)(object)val != (Object)null) { Image component = ((Component)val).GetComponent<Image>(); ((Component)component).gameObject.SetActive(item != null); if (item != null) { component.sprite = item.GetIcon(); } } Transform val2 = element.transform.Find("amount"); if ((Object)(object)val2 != (Object)null) { TMP_Text component2 = ((Component)val2).GetComponent<TMP_Text>(); ((Component)component2).gameObject.SetActive(item != null && item.m_shared.m_maxStackSize > 1); if (item != null) { component2.text = item.m_stack.ToString(); } } Transform val3 = element.transform.Find("binding"); if ((Object)(object)val3 != (Object)null) { TMP_Text component3 = ((Component)val3).GetComponent<TMP_Text>(); if ((Object)(object)component3 != (Object)null) { component3.text = InventoryLayout.Slots[InventoryLayout.EquipmentSlotCount + index].Label; component3.enableAutoSizing = false; component3.textWrappingMode = (TextWrappingModes)0; component3.overflowMode = (TextOverflowModes)0; component3.fontSize = 11f; component3.alignment = (TextAlignmentOptions)514; RectTransform rectTransform = component3.rectTransform; rectTransform.anchorMin = new Vector2(0f, 1f); rectTransform.anchorMax = new Vector2(1f, 1f); rectTransform.pivot = new Vector2(0.5f, 1f); rectTransform.offsetMin = new Vector2(2f, -18f); rectTransform.offsetMax = new Vector2(-2f, -2f); } } string[] hiddenChildren = HiddenChildren; foreach (string text in hiddenChildren) { Transform val4 = element.transform.Find(text); if ((Object)(object)val4 != (Object)null) { ((Component)val4).gameObject.SetActive(false); } } GuiBar[] componentsInChildren = element.GetComponentsInChildren<GuiBar>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.SetActive(false); } } private static void PositionPickupMessage(bool belowSlots) { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) MessageHud instance = MessageHud.instance; RectTransform textRect = (((Object)(object)instance != (Object)null && (Object)(object)instance.m_messageText != (Object)null) ? instance.m_messageText.rectTransform : null); RectTransform iconRect = (((Object)(object)instance != (Object)null && (Object)(object)instance.m_messageIcon != (Object)null) ? ((Graphic)instance.m_messageIcon).rectTransform : null); CapturePickupMessagePosition(textRect, iconRect); RestorePickupMessagePosition(); if (!belowSlots || (Object)(object)_root == (Object)null) { return; } float num = WorldEdge(_root, top: false); float num2 = Mathf.Max(WorldEdge(_messageTextRect, top: true), WorldEdge(_messageIconRect, top: true)); float num3 = Mathf.Abs(((Transform)_root).TransformVector(new Vector3(0f, 10f, 0f)).y); float num4 = num - num3 - num2; if (!(num4 >= 0f)) { MoveVertically(_messageTextRect, _messageTextPosition, num4); if ((Object)(object)_messageIconRect != (Object)null && ((Object)(object)_messageTextRect == (Object)null || !((Transform)_messageIconRect).IsChildOf((Transform)(object)_messageTextRect))) { MoveVertically(_messageIconRect, _messageIconPosition, num4); } } } private static void CapturePickupMessagePosition(RectTransform textRect, RectTransform iconRect) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_messageTextRect != (Object)(object)textRect) { _messageTextRect = textRect; if ((Object)(object)_messageTextRect != (Object)null) { _messageTextPosition = _messageTextRect.anchoredPosition; } } if ((Object)(object)_messageIconRect != (Object)(object)iconRect) { _messageIconRect = iconRect; if ((Object)(object)_messageIconRect != (Object)null) { _messageIconPosition = _messageIconRect.anchoredPosition; } } } private static void RestorePickupMessagePosition() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_messageTextRect != (Object)null) { _messageTextRect.anchoredPosition = _messageTextPosition; } if ((Object)(object)_messageIconRect != (Object)null) { _messageIconRect.anchoredPosition = _messageIconPosition; } } private static float WorldEdge(RectTransform rect, bool top) { if ((Object)(object)rect == (Object)null) { if (!top) { return float.PositiveInfinity; } return float.NegativeInfinity; } rect.GetWorldCorners(Corners); float num = Corners[0].y; for (int i = 1; i < Corners.Length; i++) { num = (top ? Mathf.Max(num, Corners[i].y) : Mathf.Min(num, Corners[i].y)); } return num; } private static void MoveVertically(RectTransform rect, Vector2 originalPosition, float worldOffset) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)rect == (Object)null) && !((Object)(object)((Transform)rect).parent == (Object)null)) { float y = ((Transform)rect).parent.InverseTransformVector(new Vector3(0f, worldOffset, 0f)).y; rect.anchoredPosition = originalPosition + new Vector2(0f, y); } } } internal static class SlotVisuals { private const string PanelName = "DadsEPI_EquipmentPanel"; private const string LabelName = "DadsEPI_SlotLabel"; private const int EquipmentColumns = 3; private static readonly Dictionary<int, Transform> OriginalParents = new Dictionary<int, Transform>(); private static readonly Dictionary<int, Vector2> OriginalPositions = new Dictionary<int, Vector2>(); private static RectTransform _panel; internal static void Reset() { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) List<InventoryElement> list = new List<InventoryElement>(); if ((Object)(object)InventoryGui.instance != (Object)null && (Object)(object)InventoryGui.instance.m_playerGrid != (Object)null) { list.AddRange(((Component)InventoryGui.instance.m_playerGrid).GetComponentsInChildren<InventoryElement>(true)); } if ((Object)(object)_panel != (Object)null) { list.AddRange(((Component)_panel).GetComponentsInChildren<InventoryElement>(true)); } foreach (InventoryElement item in list) { if ((Object)(object)item == (Object)null) { continue; } int instanceID = ((Object)item).GetInstanceID(); Transform transform = ((Component)item).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if ((Object)(object)val != (Object)null && OriginalParents.TryGetValue(instanceID, out var value) && (Object)(object)value != (Object)null) { ((Transform)val).SetParent(value, false); if (OriginalPositions.TryGetValue(instanceID, out var value2)) { val.anchoredPosition = value2; } } ((Component)item).gameObject.SetActive(true); Transform val2 = ((Component)item).transform.Find("DadsEPI_SlotLabel"); if ((Object)(object)val2 != (Object)null) { ((Component)val2).gameObject.SetActive(false); } } if ((Object)(object)_panel != (Object)null) { Object.Destroy((Object)(object)((Component)_panel).gameObject); } _panel = null; OriginalParents.Clear(); OriginalPositions.Clear(); } internal static void Refresh(InventoryGrid grid) { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)grid == (Object)null || !InventoryLayout.IsPlayerInventory(grid.GetInventory())) { return; } EnsurePanel(grid); List<InventoryElement> list = new List<InventoryElement>(((Component)grid).GetComponentsInChildren<InventoryElement>(true)); if ((Object)(object)_panel != (Object)null) { list.AddRange(((Component)_panel).GetComponentsInChildren<InventoryElement>(true)); } foreach (InventoryElement item in list) { if ((Object)(object)item == (Object)null) { continue; } Transform transform = ((Component)item).transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if ((Object)(object)val == (Object)null) { continue; } int instanceID = ((Object)item).GetInstanceID(); if (!OriginalParents.ContainsKey(instanceID)) { OriginalParents[instanceID] = ((Transform)val).parent; OriginalPositions[instanceID] = val.anchoredPosition; } int num = InventoryLayout.SlotIndex(item.Position, grid.GetInventory().GetWidth()); if (num < 0 && item.Position.y >= InventoryLayout.NormalRows) { ((Component)val).gameObject.SetActive(false); continue; } ((Component)val).gameObject.SetActive(true); TMP_Text orCreateLabel = GetOrCreateLabel(item); if (num < 0 || !DadsEPIPlugin.SeparateEquipmentPanel.Value) { if (OriginalParents.TryGetValue(instanceID, out var value) && (Object)(object)((Transform)val).parent != (Object)(object)value) { ((Transform)val).SetParent(value, false); if (OriginalPositions.TryGetValue(instanceID, out var value2)) { val.anchoredPosition = value2; } } ((Component)orCreateLabel).gameObject.SetActive(num >= 0); if (num >= 0) { orCreateLabel.text = InventoryLayout.Slots[num].Label; } } else { ((Transform)val).SetParent((Transform)(object)_panel, false); val.anchorMin = new Vector2(0f, 1f); val.anchorMax = new Vector2(0f, 1f); val.pivot = new Vector2(0f, 1f); val.anchoredPosition = PanelPosition(num, grid.m_elementSpace); orCreateLabel.text = InventoryLayout.Slots[num].Label; ((Component)orCreateLabel).gameObject.SetActive(true); orCreateLabel.transform.SetAsLastSibling(); } } if ((Object)(object)_panel != (Object)null) { UpdatePanelLayout(grid); ((Component)_panel).gameObject.SetActive(DadsEPIPlugin.SeparateEquipmentPanel.Value && InventoryLayout.Slots.Count > 0); } } private static Vector2 PanelPosition(int slotIndex, float space) { //IL_007f: 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) if (slotIndex < InventoryLayout.EquipmentSlotCount) { int num = slotIndex % 3; int num2 = slotIndex / 3; return new Vector2(10f + (float)num * space, -10f - (float)num2 * space); } int num3 = slotIndex - InventoryLayout.EquipmentSlotCount; int num4 = Mathf.Min(3, Mathf.Max(1, InventoryLayout.EnabledQuickSlots)); int num5 = num3 / num4; int num6 = num3 % num4; int num7 = Mathf.CeilToInt((float)InventoryLayout.EquipmentSlotCount / 3f); return new Vector2(10f + (float)num6 * space, -10f - ((float)num7 + 0.35f) * space - (float)num5 * space); } private static void EnsurePanel(InventoryGrid grid) { //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_panel != (Object)null) { return; } RectTransform val = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_player : null); Transform val2 = (((Object)(object)val != (Object)null && (Object)(object)((Transform)val).parent != (Object)null) ? ((Transform)val).parent : ((Component)grid).transform.parent); Transform val3 = val2.Find("DadsEPI_EquipmentPanel"); if ((Object)(object)val3 != (Object)null) { _panel = ((Component)val3).GetComponent<RectTransform>(); if ((Object)(object)val != (Object)null && (Object)(object)_panel != (Object)null) { ((Transform)_panel).SetSiblingIndex(((Transform)val).GetSiblingIndex() + 1); } return; } Transform val4 = (((Object)(object)InventoryGui.instance != (Object)null && (Object)(object)InventoryGui.instance.m_crafting != (Object)null) ? ((Transform)InventoryGui.instance.m_crafting).Find("Bkg") : null); if ((Object)(object)val4 == (Object)null && (Object)(object)val != (Object)null) { val4 = ((Transform)val).Find("Bkg"); } GameObject val5; if ((Object)(object)val4 != (Object)null) { val5 = Object.Instantiate<GameObject>(((Component)val4).gameObject, val2, false); ((Object)val5).name = "DadsEPI_EquipmentPanel"; val5.SetActive(true); } else { val5 = new GameObject("DadsEPI_EquipmentPanel", new Type[2] { typeof(RectTransform), typeof(Image) }); val5.transform.SetParent(val2, false); } _panel = val5.GetComponent<RectTransform>(); _panel.anchorMin = (Vector2)(((Object)(object)val != (Object)null) ? val.anchorMin : new Vector2(0f, 1f)); _panel.anchorMax = _panel.anchorMin; _panel.pivot = new Vector2(0f, 1f); Image component = val5.GetComponent<Image>(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = true; ((Graphic)component).raycastTarget = false; } if ((Object)(object)val != (Object)null && (Object)(object)((Transform)_panel).parent == (Object)(object)((Transform)val).parent) { ((Transform)_panel).SetSiblingIndex(((Transform)val).GetSiblingIndex() + 1); } UpdatePanelLayout(grid); } private static void UpdatePanelLayout(InventoryGrid grid) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: 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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_panel == (Object)null)) { RectTransform val = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_player : null); if ((Object)(object)val != (Object)null) { _panel.anchorMin = val.anchorMin; _panel.anchorMax = val.anchorMin; Vector3[] array = (Vector3[])(object)new Vector3[4]; val.GetWorldCorners(array); float rightEdge = Mathf.Max(array[2].x, array[3].x); float num = Mathf.Max(array[1].y, array[2].y); IncludeRightEdge(((Object)(object)InventoryGui.instance.m_weight != (Object)null) ? InventoryGui.instance.m_weight.rectTransform : null, val, ref rightEdge); IncludeRightEdge(((Object)(object)InventoryGui.instance.m_armor != (Object)null) ? InventoryGui.instance.m_armor.rectTransform : null, val, ref rightEdge); float num2 = Mathf.Abs(((Transform)val).TransformVector(new Vector3(12f, 0f, 0f)).x); ((Transform)_panel).position = new Vector3(rightEdge + num2, num, ((Transform)val).position.z); } int num3 = Mathf.CeilToInt((float)InventoryLayout.EquipmentSlotCount / 3f); int num4 = Mathf.Min(3, Mathf.Max(1, InventoryLayout.EnabledQuickSlots)); int num5 = Mathf.CeilToInt((float)InventoryLayout.EnabledQuickSlots / (float)num4); int num6 = Mathf.Max(3, num4); float num7 = (float)num3 + ((num5 > 0) ? (0.35f + (float)num5) : 0f); _panel.sizeDelta = new Vector2((float)num6 * grid.m_elementSpace + 20f, num7 * grid.m_elementSpace + 20f); } } private static void IncludeRightEdge(RectTransform rect, RectTransform playerPanel, ref float rightEdge) { if (!((Object)(object)rect == (Object)null)) { Vector3[] array = (Vector3[])(object)new Vector3[4]; rect.GetWorldCorners(array); rightEdge = Mathf.Max(rightEdge, Mathf.Max(array[2].x, array[3].x)); Transform parent = ((Transform)rect).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)playerPanel) && !((Object)(object)val == (Object)(object)((Transform)_panel).parent)) { val.GetWorldCorners(array); rightEdge = Mathf.Max(rightEdge, Mathf.Max(array[2].x, array[3].x)); } } } private static TMP_Text GetOrCreateLabel(InventoryElement element) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)element).transform.Find("DadsEPI_SlotLabel"); if ((Object)(object)val != (Object)null) { return ((Component)val).GetComponent<TMP_Text>(); } GameObject val2 = new GameObject("DadsEPI_SlotLabel", new Type[1] { typeof(RectTransform) }); val2.SetActive(false); val2.transform.SetParent(((Component)element).transform, false); RectTransform component = val2.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = new Vector2(2f, 2f); component.offsetMax = new Vector2(-2f, -2f); TextMeshProUGUI val3 = val2.AddComponent<TextMeshProUGUI>(); TMP_Text val4 = (((Object)(object)element.m_amount != (Object)null && (Object)(object)element.m_amount.font != (Object)null) ? element.m_amount : null); if ((Object)(object)val4 == (Object)null && (Object)(object)InventoryGui.instance != (Object)null) { TMP_Text[] componentsInChildren = ((Component)InventoryGui.instance).GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val5 in componentsInChildren) { if (!((Object)(object)val5.font == (Object)null)) { val4 = val5; break; } } } if ((Object)(object)val4 != (Object)null) { ((TMP_Text)val3).font = val4.font; ((TMP_Text)val3).fontSharedMaterial = val4.fontSharedMaterial; } ((Behaviour)val3).enabled = true; ((TMP_Text)val3).alignment = (TextAlignmentOptions)258; ((TMP_Text)val3).fontSize = 11f; ((TMP_Text)val3).fontStyle = (FontStyles)1; ((Graphic)val3).color = new Color(0.95f, 0.84f, 0.6f, 1f); ((Graphic)val3).raycastTarget = false; val2.SetActive(true); return (TMP_Text)(object)val3; } } internal static class UtilityEquipment { private static readonly FieldRef<Humanoid, ItemData> UtilityItem = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_utilityItem"); private static bool _restoringInventoryEquipment; internal static bool IsRestoringInventoryEquipment => _restoringInventoryEquipment; internal static void BeginInventoryRestore() { _restoringInventoryEquipment = true; } internal static void EndInventoryRestore() { _restoringInventoryEquipment = false; } internal static ItemData BeginEquip(Humanoid humanoid, ItemData item) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown if (!IsLocalUtilityItem(humanoid, item) || (item.m_equipped && !_restoringInventoryEquipment)) { return null; } ItemData val = UtilityItem.Invoke(humanoid); if (val == null || val == item || !val.m_equipped) { return null; } Player val2 = (Player)humanoid; if (!InventoryLayout.IsInEquipmentSlot(((Humanoid)val2).GetInventory(), val)) { return null; } if (!InventoryLayout.UsesSeparateEquipmentSlot(((Humanoid)val2).GetInventory(), item, val)) { return null; } UtilityItem.Invoke(humanoid) = null; return val; } internal static void EndEquip(Humanoid humanoid, ItemData previous, bool equipped) { if (previous != null) { previous.m_equipped = true; if (!equipped && UtilityItem.Invoke(humanoid) == null) { UtilityItem.Invoke(humanoid) = previous; } } } internal static bool IsManagedUtility(Humanoid humanoid, ItemData item) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (_restoringInventoryEquipment || !IsLocalUtilityItem(humanoid, item) || !item.m_equipped) { return false; } return InventoryLayout.IsInEquipmentSlot(((Humanoid)(Player)humanoid).GetInventory(), item); } internal static bool HasEquippedUtilityType(Humanoid humanoid, ItemData item) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown if (!IsLocalUtilityItem(humanoid, item)) { return false; } foreach (ItemData managedUtility in GetManagedUtilities((Player)humanoid)) { if (managedUtility.m_shared.m_name == item.m_shared.m_name) { return true; } } return false; } internal static void AddStatusEffects(Humanoid humanoid, HashSet<StatusEffect> effects) { Player val = (Player)(object)((humanoid is Player) ? humanoid : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return; } ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; if (modEnabled == null || !modEnabled.Value) { return; } foreach (ItemData managedUtility in GetManagedUtilities(val)) { StatusEffect equipStatusEffect = managedUtility.m_shared.m_equipStatusEffect; if ((Object)(object)equipStatusEffect != (Object)null) { effects.Add(equipStatusEffect); } } } internal static void UnequipAdditionalUtilities(Humanoid humanoid) { Player val = (Player)(object)((humanoid is Player) ? humanoid : null); if (val == null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return; } ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; if (modEnabled == null || !modEnabled.Value) { return; } foreach (ItemData item in new List<ItemData>(GetManagedUtilities(val))) { if (item.m_equipped) { humanoid.UnequipItem(item, false); } } } private static IEnumerable<ItemData> GetManagedUtilities(Player player) { Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { yield break; } foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem?.m_shared != null && allItem.m_equipped && (int)allItem.m_shared.m_itemType == 18 && InventoryLayout.IsInEquipmentSlot(inventory, allItem)) { yield return allItem; } } } private static bool IsLocalUtilityItem(Humanoid humanoid, ItemData item) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 ConfigEntry<bool> modEnabled = DadsEPIPlugin.ModEnabled; if (modEnabled == null || !modEnabled.Value || item?.m_shared == null || (int)item.m_shared.m_itemType != 18) { return false; } Player val = (Player)(object)((humanoid is Player) ? humanoid : null); if (val != null) { return (Object)(object)val == (Object)(object)Player.m_localPlayer; } return false; } } }