Please disclose if your mod was created primarily 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 GenesisExtraCustomSlots v1.0.0
GenesisExtraCustomSlots.dll
Decompiled 6 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using ExtraSlots; using GenesisExtraCustomSlots.AdventureBackpacksCustomSlot; using GenesisExtraCustomSlots.JudesEquipmentBackpacksCustomSlot; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using ServerSync; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("GenesisExtraCustomSlots")] [assembly: AssemblyDescription("Genesis Extra Custom Slots - Enhanced custom equipment slots for Valheim")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("GenesisProject")] [assembly: AssemblyProduct("GenesisExtraCustomSlots")] [assembly: AssemblyCopyright("Copyright © GenesisProject 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("ee3d2a93-2e64-4701-bfd2-efd5a55cfe52")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace GenesisExtraCustomSlots { public class BowsBeforeHoesSlot : CustomSlot { public const string ID = "BowsBeforeHoes"; public const string pluginID = "Azumatt.BowsBeforeHoes"; public static bool _isActive; private static Func<ItemData, bool> _isQuiver; public static bool IsActive => _isActive && GenesisExtraCustomSlots.bbhQuiverSlotEnabled.Value; public static bool IsQuiver(ItemData item) { if (_isQuiver != null && _isQuiver(item)) { return true; } if (IsRustyBagsQuiver(item)) { return true; } if (IsHunterLegacyQuiver(item)) { return true; } return false; } private static bool IsRustyBagsQuiver(ItemData item) { if (!Chainloader.PluginInfos.ContainsKey("RustyMods.RustyBags")) { return false; } if ((Object)(object)item?.m_dropPrefab == (Object)null) { return false; } string name = ((Object)item.m_dropPrefab).name; return name == "CrossbowQuiver_RS" || name == "MountainQuiver_RS" || name == "Quiver_RS"; } private static bool IsHunterLegacyQuiver(ItemData item) { if (!Chainloader.PluginInfos.ContainsKey("horemvore.HunterLegacy")) { return false; } return HunterLegacyConstants.IsHunterLegacyQuiver(item); } public BowsBeforeHoesSlot() { CustomSlot.slots.Add(this); GUID = "Azumatt.BowsBeforeHoes"; slotID = "BowsBeforeHoes"; if (!base.PluginInstalled) { return; } try { Assembly assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["Azumatt.BowsBeforeHoes"].Instance).GetType()); MethodInfo isValid = AccessTools.Method(assembly.GetType("BowsBeforeHoes.Util.Functions"), "IsQuiverSlot", (Type[])null, (Type[])null); if (isValid == null) { GenesisExtraCustomSlots.LogWarning("BowsBeforeHoes mod is loaded but BowsBeforeHoes.Util.Functions:IsQuiverSlot is not found"); return; } _isQuiver = delegate(ItemData item) { int result; if (item != null) { MethodInfo methodInfo = isValid; object[] parameters = (object[])(object)new ItemData[1] { item }; result = (((bool)methodInfo.Invoke(null, parameters)) ? 1 : 0); } else { result = 0; } return (byte)result != 0; }; itemIsValid = (ItemData item) => IsQuiver(item); getName = () => GenesisExtraCustomSlots.bbhQuiverSlotName.Value; isActive = () => CustomSlot.IsSlotActive(GenesisExtraCustomSlots.bbhQuiverSlotGlobalKey.Value, GenesisExtraCustomSlots.bbhQuiverSlotItemDiscovered.Value); initialized = true; _isActive = true; } catch (Exception ex) { GenesisExtraCustomSlots.LogWarning("Error initializing BowsBeforeHoes slot: " + ex.Message); initialized = false; } } } public static class BowsBeforeHoesCompat { [HarmonyPatch(typeof(Player), "AddKnownItem")] public static class Player_AddKnownItem_BBHQuiverType { private static void Postfix(Player __instance, ref ItemData item) { if (BowsBeforeHoesSlot.IsActive) { HashSet<string> value = Traverse.Create((object)__instance).Field("m_knownMaterial").GetValue<HashSet<string>>(); if ((value == null || !value.Contains(item.m_shared.m_name)) && BowsBeforeHoesSlot.IsQuiver(item)) { PatchBackpackItemData(item); } } } } [HarmonyPatch(typeof(Player), "OnSpawned")] public class Player_OnSpawned_BBHQuiverType { public static void Postfix(Player __instance) { if (BowsBeforeHoesSlot.IsActive && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { PatchInventory(((Humanoid)__instance).GetInventory()); } } } [HarmonyPatch(typeof(Inventory), "Load")] public class Inventory_Load_BBHQuiverType { public static void Postfix(Inventory __instance) { if (BowsBeforeHoesSlot.IsActive) { PatchInventory(__instance); } } } [HarmonyPatch(typeof(ObjectDB), "Awake")] public static class ObjectDB_Awake_ChangeBackpackItemType { [HarmonyPriority(0)] private static void Postfix(ObjectDB __instance) { if (BowsBeforeHoesSlot.IsActive && __instance.m_items.Count != 0 && !((Object)(object)__instance.GetItemPrefab("Wood") == (Object)null)) { UpdateBackpacksItemType(); } } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] public static class ObjectDB_CopyOtherDB_AddPrefab { [HarmonyPriority(0)] private static void Postfix(ObjectDB __instance) { if (BowsBeforeHoesSlot.IsActive && __instance.m_items.Count != 0 && !((Object)(object)__instance.GetItemPrefab("Wood") == (Object)null)) { UpdateBackpacksItemType(); } } } public static ItemType GetItemType() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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 (!BowsBeforeHoesSlot.IsActive) { return (ItemType)17; } return (ItemType)16; } public static void PatchBackpackItemData(ItemData itemData) { //IL_0011: 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) if (itemData != null) { itemData.m_shared.m_itemType = GetItemType(); } } public static void PatchInventory(Inventory inventory, bool force = false) { if ((!BowsBeforeHoesSlot.IsActive && !force) || inventory == null) { return; } foreach (ItemData item in from item in inventory.GetAllItems() where BowsBeforeHoesSlot.IsQuiver(item) select item) { PatchBackpackItemData(item); } } public static void PatchBackpackItemOnConfigChange() { UpdateBackpacksItemType(force: true); Player localPlayer = Player.m_localPlayer; PatchInventory((localPlayer != null) ? ((Humanoid)localPlayer).GetInventory() : null, force: true); } public static void UpdateBackpacksItemType(bool force = false) { if ((!BowsBeforeHoesSlot.IsActive && !force) || !Object.op_Implicit((Object)(object)ObjectDB.instance)) { return; } foreach (GameObject item in ObjectDB.instance.m_items) { if ((Object)(object)item != (Object)null) { ItemData val = item.GetComponent<ItemDrop>()?.m_itemData; if (val != null && BowsBeforeHoesSlot.IsQuiver(val)) { PatchBackpackItemData(val); } } } } } public static class HunterLegacyCompat { [HarmonyPatch(typeof(ItemData), "IsEquipable")] public static class ItemDropItemData_IsEquipable_HunterLegacyQuiver { private static void Postfix(ItemData __instance, ref bool __result) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 if (UnifiedQuiverSlot.IsSlotActive() && (int)__instance.m_shared.m_itemType == 16 && IsHunterLegacyQuiver(__instance)) { __result = true; } } } [HarmonyPatch(typeof(Humanoid), "EquipItem")] public static class Humanoid_EquipItem_HunterLegacyQuiver { private static void Prefix(ItemData item, ref ItemType __state) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected I4, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (UnifiedQuiverSlot.IsSlotActive() && item != null && IsHunterLegacyQuiver(item)) { __state = (ItemType)(int)item.m_shared.m_itemType; if ((int)__state == 16) { item.m_shared.m_itemType = (ItemType)17; } } } private static void Postfix(ItemData item, ItemType __state) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Invalid comparison between Unknown and I4 //IL_001f: Unknown result type (might be due to invalid IL or missing references) if ((int)__state == 16 && item != null && IsHunterLegacyQuiver(item)) { item.m_shared.m_itemType = (ItemType)16; } } } [HarmonyPatch(typeof(Humanoid), "UnequipItem")] public static class Humanoid_UnequipItem_HunterLegacyQuiver { private static void Prefix(ItemData item, ref ItemType __state) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected I4, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (UnifiedQuiverSlot.IsSlotActive() && item != null && IsHunterLegacyQuiver(item)) { __state = (ItemType)(int)item.m_shared.m_itemType; if ((int)__state == 16) { item.m_shared.m_itemType = (ItemType)17; } } } private static void Postfix(ItemData item, ItemType __state) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Invalid comparison between Unknown and I4 //IL_001f: Unknown result type (might be due to invalid IL or missing references) if ((int)__state == 16 && item != null && IsHunterLegacyQuiver(item)) { item.m_shared.m_itemType = (ItemType)16; } } } [HarmonyPatch(typeof(Player), "AddKnownItem")] public static class Player_AddKnownItem_HunterLegacyQuiverType { private static void Postfix(Player __instance, ref ItemData item) { if (UnifiedQuiverSlot.IsSlotActive()) { HashSet<string> value = Traverse.Create((object)__instance).Field("m_knownMaterial").GetValue<HashSet<string>>(); if ((value == null || !value.Contains(item.m_shared.m_name)) && IsHunterLegacyQuiver(item)) { PatchQuiverItemData(item); } } } } [HarmonyPatch(typeof(Player), "OnSpawned")] public class Player_OnSpawned_HunterLegacyQuiverType { public static void Postfix(Player __instance) { if (UnifiedQuiverSlot.IsSlotActive() && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { PatchInventory(((Humanoid)__instance).GetInventory()); } } } [HarmonyPatch(typeof(Inventory), "Load")] public class Inventory_Load_HunterLegacyQuiverType { public static void Postfix(Inventory __instance) { if (UnifiedQuiverSlot.IsSlotActive()) { PatchInventory(__instance); } } } [HarmonyPatch(typeof(ItemDrop), "Start")] public static class ItemDrop_Start_HunterLegacyQuiver { private static void Postfix(ref ItemDrop __instance) { if (UnifiedQuiverSlot.IsSlotActive() && IsHunterLegacyQuiver(__instance.m_itemData)) { PatchQuiverItemData(__instance.m_itemData); } } } [HarmonyPatch(typeof(ObjectDB), "Awake")] public static class ObjectDB_Awake_ChangeQuiverItemType { [HarmonyPriority(0)] private static void Postfix(ObjectDB __instance) { if (UnifiedQuiverSlot.IsSlotActive() && __instance.m_items.Count != 0 && !((Object)(object)__instance.GetItemPrefab("Wood") == (Object)null)) { UpdateQuiversItemType(); } } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] public static class ObjectDB_CopyOtherDB_AddPrefab { [HarmonyPriority(0)] private static void Postfix(ObjectDB __instance) { if (UnifiedQuiverSlot.IsSlotActive() && __instance.m_items.Count != 0 && !((Object)(object)__instance.GetItemPrefab("Wood") == (Object)null)) { UpdateQuiversItemType(); } } } public static bool IsHunterLegacyQuiver(ItemData item) { return HunterLegacyConstants.IsHunterLegacyQuiver(item); } public static ItemType GetItemType() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (UnifiedQuiverSlot.IsSlotActive()) { return (ItemType)16; } return (ItemType)17; } public static void PatchQuiverItemData(ItemData itemData) { //IL_0011: 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) if (itemData != null) { itemData.m_shared.m_itemType = GetItemType(); } } public static void PatchInventory(Inventory inventory, bool force = false) { if ((!UnifiedQuiverSlot.IsSlotActive() && !force) || inventory == null) { return; } foreach (ItemData item in from item in inventory.GetAllItems() where IsHunterLegacyQuiver(item) select item) { PatchQuiverItemData(item); } } public static void PatchQuiverItemOnConfigChange() { UpdateQuiversItemType(force: true); Player localPlayer = Player.m_localPlayer; PatchInventory((localPlayer != null) ? ((Humanoid)localPlayer).GetInventory() : null, force: true); } public static void UpdateQuiversItemType(bool force = false) { if ((!UnifiedQuiverSlot.IsSlotActive() && !force) || !Object.op_Implicit((Object)(object)ObjectDB.instance)) { return; } foreach (GameObject item in ObjectDB.instance.m_items) { if ((Object)(object)item != (Object)null) { ItemData val = item.GetComponent<ItemDrop>()?.m_itemData; if (val != null && IsHunterLegacyQuiver(val)) { PatchQuiverItemData(val); } } } } } public static class HunterLegacyConstants { public const string PluginID = "horemvore.HunterLegacy"; public static readonly HashSet<string> QuiverPrefabs = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "ArmorFrostpeakHarrierCapeDO", "ArmorGoldenStriderCapeDO", "ArmorSapphireFalconCapeDO", "ArmorAshenExileCapeDO", "ArmorDemonHunterCapeDO" }; public static bool IsHunterLegacyQuiver(ItemData item) { if ((Object)(object)item?.m_dropPrefab == (Object)null) { return false; } return QuiverPrefabs.Contains(((Object)item.m_dropPrefab).name); } } public class JudesEquipmentBackpackSlot : CustomSlot { public const string ID = "JudesEquipmentBackpack"; public const string pluginID = "GoldenJude_JudesEquipment"; public static Assembly assembly; public static bool IsLoaded => Chainloader.PluginInfos.ContainsKey("GoldenJude_JudesEquipment"); public static bool IsActive => IsLoaded && GenesisExtraCustomSlots.judesEquipmentBackpackSlotEnabled.Value; public JudesEquipmentBackpackSlot() { CustomSlot.slots.Add(this); GUID = "GoldenJude_JudesEquipment"; slotID = "JudesEquipmentBackpack"; if (base.PluginInstalled) { assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["GoldenJude_JudesEquipment"].Instance).GetType()); itemIsValid = (ItemData item) => item != null && (Object)(object)item.m_dropPrefab != (Object)null && (((Object)item.m_dropPrefab).name == "BackpackSimple" || ((Object)item.m_dropPrefab).name == "BackpackHeavy"); getName = () => GenesisExtraCustomSlots.judesEquipmentBackpackSlotName.Value; isActive = () => CustomSlot.IsSlotActive(GenesisExtraCustomSlots.judesEquipmentBackpackSlotGlobalKey.Value, GenesisExtraCustomSlots.judesEquipmentBackpackSlotItemDiscovered.Value); initialized = true; global::GenesisExtraCustomSlots.JudesEquipmentBackpacksCustomSlot.CustomItemType.InitBackpackFunc(itemIsValid); } } } public static class EpicLootCompat { [HarmonyPatch] public static class EpicLoot_EnchantCostsHelper_CanBeMagicItem_TreatBackpackAsShoulder { public static List<MethodBase> targets; public static List<MethodBase> GetTargets() { if ((object)assembly == null) { assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["randyknapp.mods.epicloot"].Instance).GetType()); } List<MethodBase> list = new List<MethodBase>(); MethodInfo methodInfo = AccessTools.Method(assembly.GetType("EpicLoot.Crafting.EnchantCostsHelper"), "GetSacrificeProducts", new Type[1] { typeof(ItemData) }, (Type[])null); if ((object)methodInfo != null) { GenesisExtraCustomSlots.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetSacrificeProducts method is patched to make it work with custom backpack item type"); list.Add(methodInfo); } else { GenesisExtraCustomSlots.LogWarning("EpicLoot.Crafting.EnchantCostsHelper:GetSacrificeProducts method was not found"); } MethodInfo methodInfo2 = AccessTools.Method(assembly.GetType("EpicLoot.Crafting.EnchantCostsHelper"), "GetEnchantCost", (Type[])null, (Type[])null); if ((object)methodInfo2 != null) { GenesisExtraCustomSlots.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetEnchantCost method is patched to make it work with custom backpack item type"); list.Add(methodInfo2); } else { GenesisExtraCustomSlots.LogWarning("EpicLoot.Crafting.EnchantCostsHelper:GetEnchantCost method was not found"); } MethodInfo methodInfo3 = AccessTools.Method(assembly.GetType("EpicLoot.Crafting.EnchantCostsHelper"), "GetAugmentCost", (Type[])null, (Type[])null); if ((object)methodInfo3 != null) { GenesisExtraCustomSlots.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetAugmentCost method is patched to make it work with custom backpack item type"); list.Add(methodInfo3); } else { GenesisExtraCustomSlots.LogWarning("EpicLoot.Crafting.EnchantCostsHelper:GetAugmentCost method was not found"); } MethodInfo methodInfo4 = AccessTools.Method(assembly.GetType("EpicLoot.Crafting.EnchantCostsHelper"), "GetReAugmentCost", (Type[])null, (Type[])null); if ((object)methodInfo4 != null) { GenesisExtraCustomSlots.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetReAugmentCost method is patched to make it work with custom backpack item type"); list.Add(methodInfo4); } else { GenesisExtraCustomSlots.LogWarning("EpicLoot.Crafting.EnchantCostsHelper:GetReAugmentCost method was not found"); } MethodInfo methodInfo5 = AccessTools.Method(assembly.GetType("EpicLoot.EpicLoot"), "CanBeMagicItem", (Type[])null, (Type[])null); if ((object)methodInfo5 != null) { GenesisExtraCustomSlots.LogInfo("EpicLoot.EpicLoot:CanBeMagicItem method is patched to make it work with custom backpack item type"); list.Add(methodInfo5); } else { GenesisExtraCustomSlots.LogWarning("EpicLoot.EpicLoot:CanBeMagicItem method was not found"); } return list; } public static bool Prepare() { return JudesEquipmentBackpackSlot.IsLoaded && Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot") && (targets ?? (targets = GetTargets())).Count > 0; } private static IEnumerable<MethodBase> TargetMethods() { return targets; } public static void Prefix(ItemData item, ref bool __state) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (JudesEquipmentBackpackSlot.IsActive && (__state = global::GenesisExtraCustomSlots.JudesEquipmentBackpacksCustomSlot.CustomItemType.IsBackpack(item))) { item.m_shared.m_itemType = (ItemType)17; } } public static void Postfix(ItemData item, bool __state) { if (__state) { JudesEquipmentBackpackItem.PatchBackpackItemData(item); } } } [HarmonyPatch] public static class EpicLoot_MagicItemEffectRequirements_argItemData_TreatBackpackAsShoulder { public static List<MethodBase> targets; public static List<MethodBase> GetTargets() { if ((object)assembly == null) { assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["randyknapp.mods.epicloot"].Instance).GetType()); } List<MethodBase> list = new List<MethodBase>(); MethodInfo methodInfo = AccessTools.Method(assembly.GetType("EpicLoot.MagicItemEffectRequirements"), "AllowByItemType", (Type[])null, (Type[])null); if ((object)methodInfo != null) { GenesisExtraCustomSlots.LogInfo("EpicLoot.MagicItemEffectRequirements:AllowByItemType method is patched to make it work with custom backpack item type"); list.Add(methodInfo); } else { GenesisExtraCustomSlots.LogWarning("EpicLoot.MagicItemEffectRequirements:AllowByItemType method was not found"); } MethodInfo methodInfo2 = AccessTools.Method(assembly.GetType("EpicLoot.MagicItemEffectRequirements"), "ExcludeByItemType", (Type[])null, (Type[])null); if ((object)methodInfo2 != null) { GenesisExtraCustomSlots.LogInfo("EpicLoot.MagicItemEffectRequirements:ExcludeByItemType method is patched to make it work with custom backpack item type"); list.Add(methodInfo2); } else { GenesisExtraCustomSlots.LogWarning("EpicLoot.MagicItemEffectRequirements:ExcludeByItemType method was not found"); } MethodInfo methodInfo3 = AccessTools.Method(assembly.GetType("EpicLoot.MagicItemEffectRequirements"), "CheckRequirements", (Type[])null, (Type[])null); if ((object)methodInfo3 != null) { GenesisExtraCustomSlots.LogInfo("EpicLoot.MagicItemEffectRequirements:CheckRequirements method is patched to make it work with custom backpack item type"); list.Add(methodInfo3); } else { GenesisExtraCustomSlots.LogWarning("EpicLoot.MagicItemEffectRequirements:CheckRequirements method was not found"); } return list; } public static bool Prepare() { return JudesEquipmentBackpackSlot.IsLoaded && Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot") && (targets ?? (targets = GetTargets())).Count > 0; } private static IEnumerable<MethodBase> TargetMethods() { return targets; } public static void Prefix(ItemData itemData, ref bool __state) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (JudesEquipmentBackpackSlot.IsActive && (__state = global::GenesisExtraCustomSlots.JudesEquipmentBackpacksCustomSlot.CustomItemType.IsBackpack(itemData))) { itemData.m_shared.m_itemType = (ItemType)17; } } public static void Postfix(ItemData itemData, bool __state) { if (__state) { JudesEquipmentBackpackItem.PatchBackpackItemData(itemData); } } } public const string epicLootGUID = "randyknapp.mods.epicloot"; public static Assembly assembly; } public class AdventureBackpacksSlot : CustomSlot { public const string ID = "AdventureBackpacks"; public const string pluginID = "vapok.mods.adventurebackpacks"; public static Assembly assembly; public static bool IsLoaded => Chainloader.PluginInfos.ContainsKey("vapok.mods.adventurebackpacks"); public static bool IsActive => IsLoaded && GenesisExtraCustomSlots.adventureBackpackSlotEnabled.Value; public AdventureBackpacksSlot() { CustomSlot.slots.Add(this); GUID = "vapok.mods.adventurebackpacks"; slotID = "AdventureBackpacks"; if (!base.PluginInstalled) { return; } try { assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["vapok.mods.adventurebackpacks"].Instance).GetType()); MethodInfo isValid = AccessTools.Method(assembly.GetType("AdventureBackpacks.API.ABAPI"), "IsBackpack", (Type[])null, (Type[])null); if (isValid == null) { GenesisExtraCustomSlots.LogWarning("AdventureBackpacks mod is loaded but AdventureBackpacks.API.ABAPI:IsBackpack is not found"); return; } itemIsValid = delegate(ItemData item) { int result; if (item != null) { MethodInfo methodInfo = isValid; object[] parameters = (object[])(object)new ItemData[1] { item }; if ((bool)methodInfo.Invoke(null, parameters)) { result = ((!IsAnyQuiver(item)) ? 1 : 0); goto IL_002e; } } result = 0; goto IL_002e; IL_002e: return (byte)result != 0; }; getName = () => GenesisExtraCustomSlots.adventureBackpackSlotName.Value; isActive = () => CustomSlot.IsSlotActive(GenesisExtraCustomSlots.adventureBackpackSlotGlobalKey.Value, GenesisExtraCustomSlots.adventureBackpackSlotItemDiscovered.Value); initialized = true; global::GenesisExtraCustomSlots.AdventureBackpacksCustomSlot.CustomItemType.InitBackpackFunc(itemIsValid); AdventureBackpacksPatches.UnpatchUnequip(); } catch (Exception ex) { GenesisExtraCustomSlots.LogWarning("Error initializing AdventureBackpacks slot: " + ex.Message); initialized = false; } } private static bool IsAnyQuiver(ItemData item) { if ((Object)(object)item?.m_dropPrefab == (Object)null) { return false; } string name = ((Object)item.m_dropPrefab).name; if (name == "CrossbowQuiver_RS" || name == "MountainQuiver_RS" || name == "Quiver_RS") { return true; } if (Chainloader.PluginInfos.ContainsKey("horemvore.HunterLegacy") && HunterLegacyConstants.IsHunterLegacyQuiver(item)) { return true; } if (Chainloader.PluginInfos.ContainsKey("Azumatt.BowsBeforeHoes")) { try { if (UnifiedQuiverSlot.IsQuiver(item)) { return true; } } catch { } } return false; } } public static class AdventureBackpacksPatches { [HarmonyPatch] public static class AdventureBackpacks_PlayerExtensions_CustomSlotItem { public static List<MethodBase> targets; public static List<MethodBase> GetTargets() { List<MethodBase> list = new List<MethodBase>(); if (AdventureBackpacksSlot.assembly == null) { return list; } MethodInfo methodInfo = AccessTools.Method(AdventureBackpacksSlot.assembly.GetType("AdventureBackpacks.Extensions.PlayerExtensions"), "IsBackpackEquipped", (Type[])null, (Type[])null); if ((object)methodInfo != null) { GenesisExtraCustomSlots.LogInfo("AdventureBackpacks.Extensions.PlayerExtensions:IsBackpackEquipped method is patched to make it work with custom slot"); list.Add(methodInfo); } else { GenesisExtraCustomSlots.LogWarning("AdventureBackpacks.Extensions.PlayerExtensions:IsBackpackEquipped method was not found"); } MethodInfo methodInfo2 = AccessTools.Method(AdventureBackpacksSlot.assembly.GetType("AdventureBackpacks.Extensions.PlayerExtensions"), "IsThisBackpackEquipped", (Type[])null, (Type[])null); if ((object)methodInfo2 != null) { GenesisExtraCustomSlots.LogInfo("AdventureBackpacks.Extensions.PlayerExtensions:IsThisBackpackEquipped method is patched to make it work with custom slot"); list.Add(methodInfo2); } else { GenesisExtraCustomSlots.LogWarning("AdventureBackpacks.Extensions.PlayerExtensions:IsThisBackpackEquipped method was not found"); } MethodInfo methodInfo3 = AccessTools.Method(AdventureBackpacksSlot.assembly.GetType("AdventureBackpacks.Extensions.PlayerExtensions"), "GetEquippedBackpack", (Type[])null, (Type[])null); if ((object)methodInfo3 != null) { GenesisExtraCustomSlots.LogInfo("AdventureBackpacks.Extensions.PlayerExtensions:GetEquippedBackpack method is patched to make it work with custom slot"); list.Add(methodInfo3); } else { GenesisExtraCustomSlots.LogWarning("AdventureBackpacks.Extensions.PlayerExtensions:GetEquippedBackpack method was not found"); } return list; } public static bool Prepare() { return AdventureBackpacksSlot.IsLoaded && (targets ?? (targets = GetTargets())).Count > 0; } private static IEnumerable<MethodBase> TargetMethods() { return targets; } public static void Prefix(Player player, ref ItemData __state) { if (AdventureBackpacksSlot.IsActive) { __state = Traverse.Create((object)player).Field("m_shoulderItem").GetValue<ItemData>(); Traverse.Create((object)player).Field("m_shoulderItem").SetValue((object)((Humanoid)(object)player).GetAdventureBackpack()); } } public static void Postfix(Player player, ItemData __state) { if (AdventureBackpacksSlot.IsActive) { Traverse.Create((object)player).Field("m_shoulderItem").SetValue((object)__state); } } } [HarmonyPatch(typeof(Humanoid), "UnequipItem")] public static class Humanoid_UnequipItem_CustomItemType_FirstPrefix { public static bool Prepare() { return AdventureBackpacksSlot.IsLoaded; } private static void Prefix(Humanoid __instance, ItemData item) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (!AdventureBackpacksSlot.IsActive || prefixHumanoidUnequip == null || item == null || (Object)(object)Player.m_localPlayer != (Object)(object)__instance) { return; } Scene activeScene = SceneManager.GetActiveScene(); if (!((Scene)(ref activeScene)).name.Equals("start") && global::GenesisExtraCustomSlots.AdventureBackpacksCustomSlot.CustomItemType.IsBackpack(item) && item == __instance.GetAdventureBackpack()) { ItemData value = Traverse.Create((object)__instance).Field("m_shoulderItem").GetValue<ItemData>(); if (item != value) { ItemData val = value; Traverse.Create((object)__instance).Field("m_shoulderItem").SetValue((object)item); prefixHumanoidUnequip.Invoke(null, new object[1] { item }); Traverse.Create((object)__instance).Field("m_shoulderItem").SetValue((object)val); GenesisExtraCustomSlots.LogInfo($"Shoulder item {val}"); GenesisExtraCustomSlots.LogInfo("swapped with"); GenesisExtraCustomSlots.LogInfo($"{item}"); } } } } public static class EpicLootCompat { [HarmonyPatch] public static class EpicLoot_EnchantCostsHelper_CanBeMagicItem_TreatBackpackAsShoulder { public static List<MethodBase> targets; public static List<MethodBase> GetTargets() { if ((object)assembly == null) { assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["randyknapp.mods.epicloot"].Instance).GetType()); } List<MethodBase> list = new List<MethodBase>(); MethodInfo methodInfo = AccessTools.Method(assembly.GetType("EpicLoot.Crafting.EnchantCostsHelper"), "GetSacrificeProducts", new Type[1] { typeof(ItemData) }, (Type[])null); if ((object)methodInfo != null) { GenesisExtraCustomSlots.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetSacrificeProducts method is patched to make it work with custom backpack item type"); list.Add(methodInfo); } else { GenesisExtraCustomSlots.LogWarning("EpicLoot.Crafting.EnchantCostsHelper:GetSacrificeProducts method was not found"); } MethodInfo methodInfo2 = AccessTools.Method(assembly.GetType("EpicLoot.Crafting.EnchantCostsHelper"), "GetEnchantCost", (Type[])null, (Type[])null); if ((object)methodInfo2 != null) { GenesisExtraCustomSlots.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetEnchantCost method is patched to make it work with custom backpack item type"); list.Add(methodInfo2); } else { GenesisExtraCustomSlots.LogWarning("EpicLoot.Crafting.EnchantCostsHelper:GetEnchantCost method was not found"); } MethodInfo methodInfo3 = AccessTools.Method(assembly.GetType("EpicLoot.Crafting.EnchantCostsHelper"), "GetAugmentCost", (Type[])null, (Type[])null); if ((object)methodInfo3 != null) { GenesisExtraCustomSlots.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetAugmentCost method is patched to make it work with custom backpack item type"); list.Add(methodInfo3); } else { GenesisExtraCustomSlots.LogWarning("EpicLoot.Crafting.EnchantCostsHelper:GetAugmentCost method was not found"); } MethodInfo methodInfo4 = AccessTools.Method(assembly.GetType("EpicLoot.Crafting.EnchantCostsHelper"), "GetReAugmentCost", (Type[])null, (Type[])null); if ((object)methodInfo4 != null) { GenesisExtraCustomSlots.LogInfo("EpicLoot.Crafting.EnchantCostsHelper:GetReAugmentCost method is patched to make it work with custom backpack item type"); list.Add(methodInfo4); } else { GenesisExtraCustomSlots.LogWarning("EpicLoot.Crafting.EnchantCostsHelper:GetReAugmentCost method was not found"); } MethodInfo methodInfo5 = AccessTools.Method(assembly.GetType("EpicLoot.EpicLoot"), "CanBeMagicItem", (Type[])null, (Type[])null); if ((object)methodInfo5 != null) { GenesisExtraCustomSlots.LogInfo("EpicLoot.EpicLoot:CanBeMagicItem method is patched to make it work with custom backpack item type"); list.Add(methodInfo5); } else { GenesisExtraCustomSlots.LogWarning("EpicLoot.EpicLoot:CanBeMagicItem method was not found"); } return list; } public static bool Prepare() { return AdventureBackpacksSlot.IsLoaded && Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot") && (targets ?? (targets = GetTargets())).Count > 0; } private static IEnumerable<MethodBase> TargetMethods() { return targets; } public static void Prefix(ItemData item, ref bool __state) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (AdventureBackpacksSlot.IsActive && (__state = global::GenesisExtraCustomSlots.AdventureBackpacksCustomSlot.CustomItemType.IsBackpack(item))) { item.m_shared.m_itemType = (ItemType)17; } } public static void Postfix(ItemData item, bool __state) { if (__state) { AdventureBackpackItem.PatchBackpackItemData(item); } } } [HarmonyPatch] public static class EpicLoot_MagicItemEffectRequirements_argItemData_TreatBackpackAsShoulder { public static List<MethodBase> targets; public static List<MethodBase> GetTargets() { if ((object)assembly == null) { assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["randyknapp.mods.epicloot"].Instance).GetType()); } List<MethodBase> list = new List<MethodBase>(); MethodInfo methodInfo = AccessTools.Method(assembly.GetType("EpicLoot.MagicItemEffectRequirements"), "AllowByItemType", (Type[])null, (Type[])null); if ((object)methodInfo != null) { GenesisExtraCustomSlots.LogInfo("EpicLoot.MagicItemEffectRequirements:AllowByItemType method is patched to make it work with custom backpack item type"); list.Add(methodInfo); } else { GenesisExtraCustomSlots.LogWarning("EpicLoot.MagicItemEffectRequirements:AllowByItemType method was not found"); } MethodInfo methodInfo2 = AccessTools.Method(assembly.GetType("EpicLoot.MagicItemEffectRequirements"), "ExcludeByItemType", (Type[])null, (Type[])null); if ((object)methodInfo2 != null) { GenesisExtraCustomSlots.LogInfo("EpicLoot.MagicItemEffectRequirements:ExcludeByItemType method is patched to make it work with custom backpack item type"); list.Add(methodInfo2); } else { GenesisExtraCustomSlots.LogWarning("EpicLoot.MagicItemEffectRequirements:ExcludeByItemType method was not found"); } MethodInfo methodInfo3 = AccessTools.Method(assembly.GetType("EpicLoot.MagicItemEffectRequirements"), "CheckRequirements", (Type[])null, (Type[])null); if ((object)methodInfo3 != null) { GenesisExtraCustomSlots.LogInfo("EpicLoot.MagicItemEffectRequirements:CheckRequirements method is patched to make it work with custom backpack item type"); list.Add(methodInfo3); } else { GenesisExtraCustomSlots.LogWarning("EpicLoot.MagicItemEffectRequirements:CheckRequirements method was not found"); } return list; } public static bool Prepare() { return AdventureBackpacksSlot.IsLoaded && Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot") && (targets ?? (targets = GetTargets())).Count > 0; } private static IEnumerable<MethodBase> TargetMethods() { return targets; } public static void Prefix(ItemData itemData, ref bool __state) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (AdventureBackpacksSlot.IsActive && (__state = global::GenesisExtraCustomSlots.AdventureBackpacksCustomSlot.CustomItemType.IsBackpack(itemData))) { itemData.m_shared.m_itemType = (ItemType)17; } } public static void Postfix(ItemData itemData, bool __state) { if (__state) { AdventureBackpackItem.PatchBackpackItemData(itemData); } } } public const string epicLootGUID = "randyknapp.mods.epicloot"; public static Assembly assembly; } public static MethodInfo prefixHumanoidUnequip; public static void UnpatchUnequip() { MethodInfo methodInfo = AccessTools.Method(typeof(Humanoid), "UnequipItem", (Type[])null, (Type[])null); prefixHumanoidUnequip = AccessTools.Method(AdventureBackpacksSlot.assembly.GetType("AdventureBackpacks.Patches.HumanoidPatches+HumanoidUnequipItemPatch"), "Prefix", (Type[])null, (Type[])null); if (methodInfo != null && prefixHumanoidUnequip != null) { GenesisExtraCustomSlots.instance.harmony.Unpatch((MethodBase)methodInfo, prefixHumanoidUnequip); GenesisExtraCustomSlots.LogInfo("AdventureBackpacks.Patches.HumanoidPatches+HumanoidUnequipItemPatch:Prefix was unpatched and will be called directly."); return; } if (methodInfo == null) { GenesisExtraCustomSlots.LogWarning("Humanoid:UnequipItem was not found."); } if (prefixHumanoidUnequip == null) { GenesisExtraCustomSlots.LogWarning("AdventureBackpacks.Patches.HumanoidPatches+HumanoidUnequipItemPatch:Prefix was not found."); } } } public class HipLanternSlot : CustomSlot { public const string ID = "HipLantern"; public const string pluginID = "shudnal.HipLantern"; public HipLanternSlot() { CustomSlot.slots.Add(this); GUID = "shudnal.HipLantern"; slotID = "HipLantern"; if (!base.PluginInstalled) { return; } try { Assembly assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["shudnal.HipLantern"].Instance).GetType()); MethodInfo isValid = AccessTools.Method(assembly.GetType("HipLantern.LanternItem"), "IsLanternItem", new Type[1] { typeof(ItemData) }, (Type[])null); if (isValid == null) { GenesisExtraCustomSlots.LogWarning("HipLantern mod is loaded but HipLantern.LanternItem:IsLanternItem is not found"); return; } itemIsValid = delegate(ItemData item) { int result; if (item != null) { MethodInfo methodInfo = isValid; object[] parameters = (object[])(object)new ItemData[1] { item }; result = (((bool)methodInfo.Invoke(null, parameters)) ? 1 : 0); } else { result = 0; } return (byte)result != 0; }; getName = () => GenesisExtraCustomSlots.hipLanternSlotName.Value; isActive = () => CustomSlot.IsSlotActive(GenesisExtraCustomSlots.hipLanternSlotGlobalKey.Value, GenesisExtraCustomSlots.hipLanternSlotItemDiscovered.Value); initialized = true; } catch (Exception ex) { GenesisExtraCustomSlots.LogWarning("Error initializing HipLantern slot: " + ex.Message); initialized = false; } } } public class CircletExtendedSlot : CustomSlot { public const string ID = "CircletExtended"; public const string pluginID = "shudnal.CircletExtended"; public CircletExtendedSlot() { CustomSlot.slots.Add(this); GUID = "shudnal.CircletExtended"; slotID = "CircletExtended"; if (!base.PluginInstalled) { return; } Assembly assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["shudnal.CircletExtended"].Instance).GetType()); MethodInfo isValid = AccessTools.Method(assembly.GetType("CircletExtended.CircletItem"), "IsCircletItem", new Type[1] { typeof(ItemData) }, (Type[])null); if (isValid == null) { GenesisExtraCustomSlots.LogWarning("CircletExtended mod is loaded but CircletExtended.CircletItem:IsCircletItem is not found"); return; } MethodInfo isCircletSlotKnown = AccessTools.Method(assembly.GetType("CircletExtended.CircletItem"), "IsCircletSlotKnown", (Type[])null, (Type[])null); itemIsValid = delegate(ItemData item) { int result; if (item != null) { MethodInfo methodInfo = isValid; object[] parameters = (object[])(object)new ItemData[1] { item }; result = (((bool)methodInfo.Invoke(null, parameters)) ? 1 : 0); } else { result = 0; } return (byte)result != 0; }; getName = () => GenesisExtraCustomSlots.circletExtendedSlotName.Value; isActive = () => CustomSlot.IsSlotActive(GenesisExtraCustomSlots.circletExtendedSlotGlobalKey.Value, GenesisExtraCustomSlots.circletExtendedSlotItemDiscovered.Value) && (isCircletSlotKnown == null || (bool)isCircletSlotKnown.Invoke(null, null)); initialized = true; } } public class JewelcraftingNeckSlot : CustomSlot { public const string ID = "JewelcraftingNeck"; public const string pluginID = "org.bepinex.plugins.jewelcrafting"; public JewelcraftingNeckSlot() { CustomSlot.slots.Add(this); GUID = "org.bepinex.plugins.jewelcrafting"; slotID = "JewelcraftingNeck"; if (!base.PluginInstalled) { return; } Assembly assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["org.bepinex.plugins.jewelcrafting"].Instance).GetType()); MethodInfo isValid = AccessTools.Method(assembly.GetType("Jewelcrafting.Visual"), "IsNeckItem", (Type[])null, (Type[])null); if (isValid == null) { GenesisExtraCustomSlots.LogWarning("Jewelcrafting mod is loaded but Jewelcrafting.Visual:IsNeckItem is not found"); return; } itemIsValid = delegate(ItemData item) { int result; if (item != null) { MethodInfo methodInfo = isValid; object[] parameters = (object[])(object)new ItemData[1] { item }; result = (((bool)methodInfo.Invoke(null, parameters)) ? 1 : 0); } else { result = 0; } return (byte)result != 0; }; getName = () => GenesisExtraCustomSlots.jewelcraftingNeckSlotName.Value; isActive = () => CustomSlot.IsSlotActive(GenesisExtraCustomSlots.jewelcraftingNeckSlotGlobalKey.Value, GenesisExtraCustomSlots.jewelcraftingNeckSlotItemDiscovered.Value); initialized = true; } } public class JewelcraftingRingSlot : CustomSlot { public const string ID = "JewelcraftingRing"; public const string pluginID = "org.bepinex.plugins.jewelcrafting"; public JewelcraftingRingSlot() { CustomSlot.slots.Add(this); GUID = "org.bepinex.plugins.jewelcrafting"; slotID = "JewelcraftingRing"; if (!base.PluginInstalled) { return; } Assembly assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["org.bepinex.plugins.jewelcrafting"].Instance).GetType()); MethodInfo isValid = AccessTools.Method(assembly.GetType("Jewelcrafting.Visual"), "IsFingerItem", (Type[])null, (Type[])null); if (isValid == null) { GenesisExtraCustomSlots.LogWarning("Jewelcrafting mod is loaded but Jewelcrafting.Visual:IsFingerItem is not found"); return; } itemIsValid = delegate(ItemData item) { int result; if (item != null) { MethodInfo methodInfo = isValid; object[] parameters = (object[])(object)new ItemData[1] { item }; result = (((bool)methodInfo.Invoke(null, parameters)) ? 1 : 0); } else { result = 0; } return (byte)result != 0; }; getName = () => GenesisExtraCustomSlots.jewelcraftingRingSlotName.Value; isActive = () => CustomSlot.IsSlotActive(GenesisExtraCustomSlots.jewelcraftingRingSlotGlobalKey.Value, GenesisExtraCustomSlots.jewelcraftingRingSlotItemDiscovered.Value); initialized = true; } } public class BackpacksSlot : CustomSlot { public const string ID = "Backpacks"; public const string pluginID = "org.bepinex.plugins.backpacks"; public BackpacksSlot() { CustomSlot.slots.Add(this); GUID = "org.bepinex.plugins.backpacks"; slotID = "Backpacks"; if (!base.PluginInstalled) { return; } Assembly assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["org.bepinex.plugins.backpacks"].Instance).GetType()); MethodInfo isValid = AccessTools.Method(assembly.GetType("Backpacks.Backpacks"), "validateBackpack", (Type[])null, (Type[])null); if (isValid == null) { GenesisExtraCustomSlots.LogWarning("Backpacks mod is loaded but Backpacks.Backpacks:validateBackpack is not found"); return; } itemIsValid = delegate(ItemData item) { int result; if (item != null) { MethodInfo methodInfo = isValid; object[] parameters = (object[])(object)new ItemData[1] { item }; result = (((bool)methodInfo.Invoke(null, parameters)) ? 1 : 0); } else { result = 0; } return (byte)result != 0; }; getName = () => GenesisExtraCustomSlots.backpacksSlotName.Value; isActive = () => CustomSlot.IsSlotActive(GenesisExtraCustomSlots.backpacksSlotGlobalKey.Value, GenesisExtraCustomSlots.backpacksSlotItemDiscovered.Value); initialized = true; } } internal class CustomConfigs { internal class ConfigurationManagerAttributes { [UsedImplicitly] public Action<ConfigEntryBase>? CustomDrawer; } internal static object? configManager; internal static Type? configManagerStyles; internal static GUIStyle GetStyle(GUIStyle other) { //IL_0034: 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_0051: Expected O, but got Unknown if (configManagerStyles == null) { return other; } FieldInfo fieldInfo = AccessTools.Field(configManagerStyles, "fontSize"); if (fieldInfo == null) { return other; } return new GUIStyle(other) { fontSize = (int)fieldInfo.GetValue(configManagerStyles) }; } internal static void Awake() { Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "ConfigurationManager"); Type type = assembly?.GetType("ConfigurationManager.ConfigurationManager"); configManager = ((type == null) ? null : Chainloader.ManagerObject.GetComponent(type)); configManagerStyles = assembly?.GetType("ConfigurationManager.ConfigurationManagerStyles") ?? assembly?.GetType("ConfigurationManager.Utilities.ImguiUtils"); } internal static Action<ConfigEntryBase> DrawSeparatedStrings(string splitString) { string splitString2 = splitString; return delegate(ConfigEntryBase cfg) { //IL_010a: 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_0125: Expected O, but got Unknown //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Expected O, but got Unknown bool valueOrDefault = cfg.Description.Tags.Select((object a) => (a.GetType().Name == "ConfigurationManagerAttributes") ? ((bool?)a.GetType().GetField("ReadOnly")?.GetValue(a)) : null).FirstOrDefault((bool? v) => v.HasValue).GetValueOrDefault(); bool flag = false; GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); List<string> list = new List<string>(); List<string> list2 = ((string)cfg.BoxedValue).Split(new string[1] { splitString2 }, StringSplitOptions.None).ToList(); for (int i = 0; i < list2.Count; i++) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); string text = list2[i]; string text2 = GUILayout.TextField(text, GetStyle(GUI.skin.textField), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (text2 != text && !valueOrDefault) { flag = true; } if (GUILayout.Button("x", new GUIStyle(GetStyle(GUI.skin.button)) { fixedWidth = 21f }, Array.Empty<GUILayoutOption>()) && !valueOrDefault) { flag = true; } else { list.Add(text2); } if (GUILayout.Button("+", new GUIStyle(GetStyle(GUI.skin.button)) { fixedWidth = 21f }, Array.Empty<GUILayoutOption>()) && !valueOrDefault) { flag = true; list.Add(""); } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); if (flag) { cfg.BoxedValue = string.Join(splitString2, list); } }; } internal static Action<ConfigEntryBase> DrawOrderedFixedStrings(string splitString) { string splitString2 = splitString; return delegate(ConfigEntryBase cfg) { //IL_00e4: 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) //IL_00ff: Expected O, but got Unknown //IL_015b: 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) //IL_0176: Expected O, but got Unknown bool valueOrDefault = cfg.Description.Tags.Select((object a) => (a.GetType().Name == "ConfigurationManagerAttributes") ? ((bool?)a.GetType().GetField("ReadOnly")?.GetValue(a)) : null).FirstOrDefault((bool? v) => v.HasValue).GetValueOrDefault(); bool flag = false; GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); string[] array = ((string)cfg.BoxedValue).Split(new string[1] { splitString2 }, StringSplitOptions.None).ToArray(); for (int i = 0; i < array.Length; i++) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); string text = array[i]; GUILayout.Label(text, GetStyle(GUI.skin.textField), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); if (GUILayout.Button("ʌ", new GUIStyle(GetStyle(GUI.skin.button)) { fixedWidth = 21f }, Array.Empty<GUILayoutOption>()) && !valueOrDefault && (flag = i > 0)) { ref string reference = ref array[i]; ref string reference2 = ref array[i - 1]; string text2 = array[i - 1]; string text3 = array[i]; reference = text2; reference2 = text3; } if (GUILayout.Button("v", new GUIStyle(GetStyle(GUI.skin.button)) { fixedWidth = 21f }, Array.Empty<GUILayoutOption>()) && !valueOrDefault && (flag = i < array.Length - 1)) { ref string reference = ref array[i]; ref string reference3 = ref array[i + 1]; string text3 = array[i + 1]; string text2 = array[i]; reference = text3; reference3 = text2; } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); if (flag) { cfg.BoxedValue = string.Join(splitString2, array); } }; } } public class CustomSlot { public const string slotPrefix = "GECS"; public string GUID; public bool initialized; public string slotID; public Func<ItemData, bool> itemIsValid; public Func<string> getName; public Func<bool> isActive; public static readonly List<CustomSlot> slots = new List<CustomSlot>(); public static readonly string VanillaOrder = string.Join(",", GetVanillaOrder()); public bool PluginInstalled => Chainloader.PluginInfos.ContainsKey(GUID); public bool AddSlot() { return initialized && API.AddSlot(GetSlotID(slotID), getName, itemIsValid, isActive); } public bool RemoveSlot() { return initialized && (API.RemoveSlot(GetSlotID(slotID)) || API.RemoveSlot(slotID)); } public static string GetSlotID(string slotID) { return "GECS" + slotID.ToString(); } public override string ToString() { return initialized ? slotID.ToString() : (GUID + " (inactive)"); } public static List<string> GetVanillaOrder() { List<string> list = new List<string> { "AdventureBackpacks", "Backpacks", "JudesEquipmentBackpack", "RustyBagsBag", "CircletExtended", "JewelcraftingNeck", "MagicPluginEarring", "JewelcraftingRing", "MagicPluginTome", "BowsBeforeHoes", "Hunter_Legacy", "HipLantern" }; for (int i = 0; i < 8; i++) { list.Add(UserDefinedSlot.GetSlotID(i)); } return list; } public static bool IsSlotActive(string globalKey, string itemDiscovered) { bool flag = !Utility.IsNullOrWhiteSpace(globalKey); bool flag2 = !Utility.IsNullOrWhiteSpace(itemDiscovered); if (!flag && !flag2) { return true; } if (flag && flag2) { return API.IsAnyGlobalKeyActive(globalKey) || API.IsAnyMaterialDiscovered(itemDiscovered); } return flag ? API.IsAnyGlobalKeyActive(globalKey) : API.IsAnyMaterialDiscovered(itemDiscovered); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("GenesisProject.GenesisExtraCustomSlots", "Genesis Extra Custom Slots", "1.0.0")] public class GenesisExtraCustomSlots : BaseUnityPlugin { public const string pluginID = "GenesisProject.GenesisExtraCustomSlots"; public const string pluginName = "Genesis Extra Custom Slots"; public const string pluginVersion = "1.0.0"; internal readonly Harmony harmony = new Harmony("GenesisProject.GenesisExtraCustomSlots"); internal static readonly ConfigSync configSync = new ConfigSync("GenesisProject.GenesisExtraCustomSlots") { DisplayName = "Genesis Extra Custom Slots", CurrentVersion = "1.0.0", MinimumRequiredVersion = "1.0.0" }; internal static GenesisExtraCustomSlots instance; public static ConfigEntry<bool> configLocked; public static ConfigEntry<bool> loggingEnabled; public static ConfigEntry<string> slotsOrder; public static ConfigEntry<bool> adventureBackpackSlotEnabled; public static ConfigEntry<string> adventureBackpackSlotName; public static ConfigEntry<string> adventureBackpackSlotGlobalKey; public static ConfigEntry<string> adventureBackpackSlotItemDiscovered; public static ConfigEntry<bool> backpacksSlotEnabled; public static ConfigEntry<string> backpacksSlotName; public static ConfigEntry<string> backpacksSlotGlobalKey; public static ConfigEntry<string> backpacksSlotItemDiscovered; public static ConfigEntry<bool> bbhQuiverSlotEnabled; public static ConfigEntry<string> bbhQuiverSlotName; public static ConfigEntry<string> bbhQuiverSlotGlobalKey; public static ConfigEntry<string> bbhQuiverSlotItemDiscovered; public static ConfigEntry<bool> circletExtendedSlotEnabled; public static ConfigEntry<string> circletExtendedSlotName; public static ConfigEntry<string> circletExtendedSlotGlobalKey; public static ConfigEntry<string> circletExtendedSlotItemDiscovered; public static ConfigEntry<bool> hipLanternSlotEnabled; public static ConfigEntry<string> hipLanternSlotName; public static ConfigEntry<string> hipLanternSlotGlobalKey; public static ConfigEntry<string> hipLanternSlotItemDiscovered; public static ConfigEntry<bool> jewelcraftingNeckSlotEnabled; public static ConfigEntry<string> jewelcraftingNeckSlotName; public static ConfigEntry<string> jewelcraftingNeckSlotGlobalKey; public static ConfigEntry<string> jewelcraftingNeckSlotItemDiscovered; public static ConfigEntry<bool> jewelcraftingRingSlotEnabled; public static ConfigEntry<string> jewelcraftingRingSlotName; public static ConfigEntry<string> jewelcraftingRingSlotGlobalKey; public static ConfigEntry<string> jewelcraftingRingSlotItemDiscovered; public static ConfigEntry<bool> magicPluginTomeSlotEnabled; public static ConfigEntry<string> magicPluginTomeSlotName; public static ConfigEntry<string> magicPluginTomeSlotGlobalKey; public static ConfigEntry<string> magicPluginTomeSlotItemDiscovered; public static ConfigEntry<bool> magicPluginEarringSlotEnabled; public static ConfigEntry<string> magicPluginEarringSlotName; public static ConfigEntry<string> magicPluginEarringSlotGlobalKey; public static ConfigEntry<string> magicPluginEarringSlotItemDiscovered; public static ConfigEntry<bool> judesEquipmentBackpackSlotEnabled; public static ConfigEntry<string> judesEquipmentBackpackSlotName; public static ConfigEntry<string> judesEquipmentBackpackSlotGlobalKey; public static ConfigEntry<string> judesEquipmentBackpackSlotItemDiscovered; public static ConfigEntry<bool> rustyBagsSlotEnabled; public static ConfigEntry<string> rustyBagsSlotName; public static ConfigEntry<string> rustyBagsSlotGlobalKey; public static ConfigEntry<string> rustyBagsSlotItemDiscovered; public static ConfigEntry<bool> hunterLegacyQuiverSlotEnabled; private void Awake() { instance = this; CustomConfigs.Awake(); ConfigInit(); configSync.AddLockingConfigEntry<bool>(configLocked); UpdateSlots(); harmony.PatchAll(); } private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); instance = null; Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } public void ConfigInit() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown configLocked = config("General", "Lock Configuration", defaultValue: true, "Configuration is locked and can be changed by server admins only. "); loggingEnabled = config("General", "Logging enabled", defaultValue: false, "Enable logging. [Not synced with Server]", synchronizedSetting: false); slotsOrder = config("General", "Slots order", CustomSlot.VanillaOrder, new ConfigDescription("Comma-separated slot ID order of custom slots", (AcceptableValueBase)null, new object[1] { new CustomConfigs.ConfigurationManagerAttributes { CustomDrawer = CustomConfigs.DrawOrderedFixedStrings(",") } })); slotsOrder.SettingChanged += delegate { UpdateSlots(); }; adventureBackpackSlotEnabled = config("Mod - Adventure Backpacks", "Enabled", defaultValue: true, "Enable adventure backpack slot. Restart the game after change to avoid potential issues."); adventureBackpackSlotName = config("Mod - Adventure Backpacks", "Name", "Backpack", "Slot name. Use ExtraSlots translation files to add localized string."); adventureBackpackSlotGlobalKey = config("Mod - Adventure Backpacks", "Global keys", "", "Comma-separated list of global keys and player unique keys. Slot will be active only if any key is enabled or list is not set."); adventureBackpackSlotItemDiscovered = config("Mod - Adventure Backpacks", "Items discovered", "$vapok_mod_item_backpack_meadows,$vapok_mod_item_backpack_blackforest,$vapok_mod_item_backpack_swamp,$vapok_mod_item_backpack_mountains,$vapok_mod_item_backpack_plains,$vapok_mod_item_backpack_mistlands,$vapok_mod_item_rugged_backpack,$vapok_mod_item_arctic_backpack", "Comma-separated list of items. Slot will be active only if any item is discovered or list is not set."); adventureBackpackSlotEnabled.SettingChanged += delegate { AdventureBackpackItem.PatchBackpackItemOnConfigChange(); UpdateSlots(); }; backpacksSlotEnabled = config("Mod - Backpacks", "Enabled", defaultValue: true, "Enable backpack slot"); backpacksSlotName = config("Mod - Backpacks", "Name", "$bp_backpack_slot_name", "Slot name"); backpacksSlotGlobalKey = config("Mod - Backpacks", "Global keys", "", "Comma-separated list of global keys and player unique keys. Slot will be active only if any key is enabled or list is not set."); backpacksSlotItemDiscovered = config("Mod - Backpacks", "Items discovered", "$item_explorer", "Comma-separated list of items. Slot will be active only if any item is discovered or list is not set."); backpacksSlotEnabled.SettingChanged += delegate { UpdateSlots(); }; bbhQuiverSlotEnabled = config("Mod - BowsBeforeHoes", "Enabled", defaultValue: true, "Enable quiver slot"); bbhQuiverSlotName = config("Mod - BowsBeforeHoes", "Name", "$bbh_slot_quiver", "Slot name"); bbhQuiverSlotGlobalKey = config("Mod - BowsBeforeHoes", "Global keys", "", "Comma-separated list of global keys and player unique keys. Slot will be active only if any key is enabled or list is not set."); bbhQuiverSlotItemDiscovered = config("Mod - BowsBeforeHoes", "Items discovered", "$item_quiver_blackforest,$item_quiver_seeker,$item_quiver_leather,$item_quiver_odinplus,$item_quiver_plainslox", "Comma-separated list of items. Slot will be active only if any item is discovered or list is not set."); bbhQuiverSlotEnabled.SettingChanged += delegate { UpdateSlots(); BowsBeforeHoesCompat.PatchBackpackItemOnConfigChange(); }; circletExtendedSlotEnabled = config("Mod - CircletExtended", "Enabled", defaultValue: true, "Enable circlet slot"); circletExtendedSlotName = config("Mod - CircletExtended", "Name", "Circlet", "Slot name. Use ExtraSlots translation files to add localized string."); circletExtendedSlotGlobalKey = config("Mod - CircletExtended", "Global keys", "", "Comma-separated list of global keys and player unique keys. Slot will be active only if any key is enabled or list is not set."); circletExtendedSlotItemDiscovered = config("Mod - CircletExtended", "Items discovered", "$item_helmet_dverger", "Comma-separated list of items. Slot will be active only if any item is discovered or list is not set."); circletExtendedSlotEnabled.SettingChanged += delegate { UpdateSlots(); }; hipLanternSlotEnabled = config("Mod - HipLantern", "Enabled", defaultValue: true, "Enable hip lantern slot"); hipLanternSlotName = config("Mod - HipLantern", "Name", "Lantern", "Slot name. Use ExtraSlots translation files to add localized string."); hipLanternSlotGlobalKey = config("Mod - HipLantern", "Global keys", "", "Comma-separated list of global keys and player unique keys. Slot will be active only if any key is enabled or list is not set."); hipLanternSlotItemDiscovered = config("Mod - HipLantern", "Items discovered", "$item_hiplantern", "Comma-separated list of items. Slot will be active only if any item is discovered or list is not set."); hipLanternSlotEnabled.SettingChanged += delegate { UpdateSlots(); }; jewelcraftingNeckSlotEnabled = config("Mod - Jewelcrafting - Neck", "Enabled", defaultValue: true, "Enable neck slot"); jewelcraftingNeckSlotName = config("Mod - Jewelcrafting - Neck", "Name", "Neck", "Slot name. Use ExtraSlots translation files to add localized string."); jewelcraftingNeckSlotGlobalKey = config("Mod - Jewelcrafting - Neck", "Global keys", "", "Comma-separated list of global keys and player unique keys. Slot will be active only if any key is enabled or list is not set."); jewelcraftingNeckSlotItemDiscovered = config("Mod - Jewelcrafting - Neck", "Items discovered", "$jc_necklace_red,$jc_necklace_green,$jc_necklace_blue,$jc_necklace_yellow,$jc_necklace_purple,$jc_necklace_orange,$jc_necklace_dvergrnecklace,$jc_necklace_eitrnecklace,$jc_necklace_fireresistnecklace,$jc_necklace_frostresistnecklace,$jc_necklace_poisonresistnecklace,", "Comma-separated list of items. Slot will be active only if any item is discovered or list is not set."); jewelcraftingNeckSlotEnabled.SettingChanged += delegate { UpdateSlots(); }; jewelcraftingRingSlotEnabled = config("Mod - Jewelcrafting - Ring", "Enabled", defaultValue: true, "Enable Ring slot"); jewelcraftingRingSlotName = config("Mod - Jewelcrafting - Ring", "Name", "Finger", "Slot name. Use ExtraSlots translation files to add localized string."); jewelcraftingRingSlotGlobalKey = config("Mod - Jewelcrafting - Ring", "Global keys", "", "Comma-separated list of global keys and player unique keys. Slot will be active only if any key is enabled or list is not set."); jewelcraftingRingSlotItemDiscovered = config("Mod - Jewelcrafting - Ring", "Items discovered", "$jc_ring_purple,$jc_ring_green,$jc_ring_red,$jc_ring_blue,$jc_ring_black,$jc_ring_dvergrring,$jc_ring_eitrring,$jc_ring_fireresistring,$jc_ring_frostresistring,$jc_ring_poisonresistring", "Comma-separated list of items. Slot will be active only if any item is discovered or list is not set."); jewelcraftingRingSlotEnabled.SettingChanged += delegate { UpdateSlots(); }; magicPluginTomeSlotEnabled = config("Mod - Magic Plugin - Tome", "Enabled", defaultValue: true, "Enable tome slot"); magicPluginTomeSlotName = config("Mod - Magic Plugin - Tome", "Name", "$bmp_tomeslot", "Slot name"); magicPluginTomeSlotGlobalKey = config("Mod - Magic Plugin - Tome", "Global keys", "", "Comma-separated list of global keys and player unique keys. Slot will be active only if any key is enabled or list is not set."); magicPluginTomeSlotItemDiscovered = config("Mod - Magic Plugin - Tome", "Items discovered", "$bmp_advance_magicbook,$bmp_beginners_magicbook", "Comma-separated list of items. Slot will be active only if any item is discovered or list is not set."); magicPluginTomeSlotEnabled.SettingChanged += delegate { UpdateSlots(); }; magicPluginEarringSlotEnabled = config("Mod - Magic Plugin - Earring", "Enabled", defaultValue: true, "Enable earring slot"); magicPluginEarringSlotName = config("Mod - Magic Plugin - Earring", "Name", "$bmp_earringslot", "Slot name"); magicPluginEarringSlotGlobalKey = config("Mod - Magic Plugin - Earring", "Global keys", "", "Comma-separated list of global keys and player unique keys. Slot will be active only if any key is enabled or list is not set."); magicPluginEarringSlotItemDiscovered = config("Mod - Magic Plugin - Earring", "Items discovered", "$bmp_dvergr_earring,$bmp_fireresist_earring,$bmp_frostresist_earring,$bmp_poisonresist_earring,$bmp_eitr_earring", "Comma-separated list of items. Slot will be active only if any item is discovered or list is not set."); magicPluginEarringSlotEnabled.SettingChanged += delegate { UpdateSlots(); }; judesEquipmentBackpackSlotEnabled = config("Mod - Judes Equipment", "Enabled", defaultValue: true, "Enable Judes Equipment backpack slot. Restart the game after change to avoid potential issues."); judesEquipmentBackpackSlotName = config("Mod - Judes Equipment", "Name", "Backpack", "Slot name. Use ExtraSlots translation files to add localized string."); judesEquipmentBackpackSlotGlobalKey = config("Mod - Judes Equipment", "Global keys", "", "Comma-separated list of global keys and player unique keys. Slot will be active only if any key is enabled or list is not set."); judesEquipmentBackpackSlotItemDiscovered = config("Mod - Judes Equipment", "Items discovered", "$BackpackSimple,$BackpackHeavy", "Comma-separated list of items. Slot will be active only if any item is discovered or list is not set."); judesEquipmentBackpackSlotEnabled.SettingChanged += delegate { JudesEquipmentBackpackItem.PatchBackpackItemOnConfigChange(); UpdateSlots(); }; rustyBagsSlotEnabled = config("Mod - Rusty Bags", "Enabled", defaultValue: true, "Enable Rusty Bags backpack slot."); rustyBagsSlotName = config("Mod - Rusty Bags", "Name", "Bag", "Slot name. Use ExtraSlots translation files to add localized string."); rustyBagsSlotGlobalKey = config("Mod - Rusty Bags", "Global keys", "", "Comma-separated list of global keys and player unique keys. Slot will be active only if any key is enabled or list is not set."); rustyBagsSlotItemDiscovered = config("Mod - Rusty Bags", "Items discovered", "$item_BarrelBag_RS,$item_DvergerBag_RS,$item_LeatherBag_RS,$item_UnbjornBag_RS", "Comma-separated list of items. Slot will be active only if any item is discovered or list is not set."); rustyBagsSlotEnabled.SettingChanged += delegate { UpdateSlots(); }; hunterLegacyQuiverSlotEnabled = config("Mod - Hunter Legacy Quiver", "Enabled", defaultValue: false, "Enable Hunter Legacy quiver slot (shares with BowsBeforeHoes and Rusty Bags quiver slot). DEPRECATED: Hunter Legacy quivers now automatically use the BowsBeforeHoes quiver slot."); hunterLegacyQuiverSlotEnabled.SettingChanged += delegate { UpdateSlots(); }; for (int i = 0; i < 8; i++) { new UserDefinedSlot(i); } } public static bool AnyBackpackModInstalled() { return Chainloader.PluginInfos.ContainsKey("vapok.mods.adventurebackpacks") || Chainloader.PluginInfos.ContainsKey("org.bepinex.plugins.backpacks") || Chainloader.PluginInfos.ContainsKey("GoldenJude_JudesEquipment") || Chainloader.PluginInfos.ContainsKey("RustyMods.RustyBags"); } public static bool AnyQuiverModInstalled() { return Chainloader.PluginInfos.ContainsKey("Azumatt.BowsBeforeHoes") || Chainloader.PluginInfos.ContainsKey("RustyMods.RustyBags") || Chainloader.PluginInfos.ContainsKey("horemvore.HunterLegacy"); } public static void UpdateSlots() { CollectionExtensions.Do<CustomSlot>((IEnumerable<CustomSlot>)CustomSlot.slots, (Action<CustomSlot>)delegate(CustomSlot slot) { slot.RemoveSlot(); }); CustomSlot.slots.Clear(); CollectionExtensions.Do<string>(from s in slotsOrder.Value.Split(new char[1] { ',' }) select s.Trim() into s where !Utility.IsNullOrWhiteSpace(s) select s, (Action<string>)InitSlot); List<string> vanillaSlots = CustomSlot.VanillaOrder.Split(new char[1] { ',' }).ToList(); CollectionExtensions.Do<CustomSlot>((IEnumerable<CustomSlot>)CustomSlot.slots, (Action<CustomSlot>)delegate(CustomSlot slot) { vanillaSlots.Remove(slot.slotID); }); CollectionExtensions.Do<string>((IEnumerable<string>)vanillaSlots, (Action<string>)InitSlot); CollectionExtensions.Do<CustomSlot>((IEnumerable<CustomSlot>)CustomSlot.slots, (Action<CustomSlot>)TryAddSlot); } public static void TryAddSlot(CustomSlot slot) { if (slot.RemoveSlot()) { LogInfo($"Slot {slot} was removed"); } if (slot.AddSlot()) { LogInfo($"Slot {slot} was added"); } else if (slot.initialized) { LogWarning($"Error while trying to add new slot {slot}."); } } public static void InitSlot(string slotID) { switch (slotID) { case "Backpacks": if (!backpacksSlotEnabled.Value || !Chainloader.PluginInfos.ContainsKey("org.bepinex.plugins.backpacks")) { break; } goto IL_024d; case "AdventureBackpacks": if (!adventureBackpackSlotEnabled.Value || !Chainloader.PluginInfos.ContainsKey("vapok.mods.adventurebackpacks")) { break; } goto IL_024d; case "JudesEquipmentBackpack": if (!judesEquipmentBackpackSlotEnabled.Value || !Chainloader.PluginInfos.ContainsKey("GoldenJude_JudesEquipment")) { break; } goto IL_024d; case "RustyBagsBag": if (rustyBagsSlotEnabled.Value && Chainloader.PluginInfos.ContainsKey("RustyMods.RustyBags")) { goto IL_024d; } if (!rustyBagsSlotEnabled.Value) { break; } goto IL_02bf; case "BowsBeforeHoes": if (!bbhQuiverSlotEnabled.Value) { if (!bbhQuiverSlotEnabled.Value) { break; } new BowsBeforeHoesSlot(); return; } goto IL_02bf; case "Hunter_Legacy": if (!hunterLegacyQuiverSlotEnabled.Value) { if (!hunterLegacyQuiverSlotEnabled.Value) { break; } Type type = Type.GetType("ExtraSlotsCustomSlots.HunterLegacyQuiverSlot"); if (type != null) { Activator.CreateInstance(type); } return; } goto IL_02bf; case "MagicPluginTome": if (!magicPluginTomeSlotEnabled.Value) { break; } new MagicPluginTomeSlot(); return; case "MagicPluginEarring": if (!magicPluginEarringSlotEnabled.Value) { break; } new MagicPluginEarringSlot(); return; case "JewelcraftingNeck": if (!jewelcraftingNeckSlotEnabled.Value) { break; } new JewelcraftingNeckSlot(); return; case "JewelcraftingRing": if (!jewelcraftingRingSlotEnabled.Value) { break; } new JewelcraftingRingSlot(); return; case "CircletExtended": if (!circletExtendedSlotEnabled.Value) { break; } new CircletExtendedSlot(); return; case "HipLantern": { if (!hipLanternSlotEnabled.Value) { break; } new HipLanternSlot(); return; } IL_024d: if (!CustomSlot.slots.Any((CustomSlot s) => s is UnifiedBackpackSlot)) { new UnifiedBackpackSlot(); } return; IL_02bf: if (!CustomSlot.slots.Any((CustomSlot s) => s is UnifiedQuiverSlot)) { new UnifiedQuiverSlot(); } return; } if (UserDefinedSlot.IsUserDefinedSlot(slotID)) { UserDefinedSlot.UpdateSlot(slotID); } } public static void LogInfo(object data) { if (loggingEnabled.Value) { ((BaseUnityPlugin)instance).Logger.LogInfo(data); } } public static void LogMessage(object data) { ((BaseUnityPlugin)instance).Logger.LogMessage(data); } public static void LogWarning(object data) { ((BaseUnityPlugin)instance).Logger.LogWarning(data); } internal ConfigEntry<T> config<T>(string group, string name, T defaultValue, ConfigDescription description, bool synchronizedSetting = true) { ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, defaultValue, description); SyncedConfigEntry<T> syncedConfigEntry = configSync.AddConfigEntry<T>(val); syncedConfigEntry.SynchronizedConfig = synchronizedSetting; return val; } internal ConfigEntry<T> config<T>(string group, string name, T defaultValue, string description, bool synchronizedSetting = true) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown return config(group, name, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()), synchronizedSetting); } } public class RustyBagsSlot : CustomSlot { public const string ID = "RustyBagsBag"; public const string pluginID = "RustyMods.RustyBags"; public RustyBagsSlot() { CustomSlot.slots.Add(this); GUID = "RustyMods.RustyBags"; slotID = "RustyBagsBag"; if (!base.PluginInstalled) { return; } Assembly assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["RustyMods.RustyBags"].Instance).GetType()); Type bag = AccessTools.GetTypesFromAssembly(assembly).FirstOrDefault((Type type) => type.FullName == "RustyBags.Bag"); if (bag == null) { GenesisExtraCustomSlots.LogWarning("RustyBags mod is loaded but RustyBags.Bag type is not found"); return; } itemIsValid = (ItemData item) => item != null && bag.IsInstanceOfType(item) && !IsRustyBagsQuiver(item); getName = () => GenesisExtraCustomSlots.rustyBagsSlotName.Value; isActive = () => CustomSlot.IsSlotActive(GenesisExtraCustomSlots.rustyBagsSlotGlobalKey.Value, GenesisExtraCustomSlots.rustyBagsSlotItemDiscovered.Value); initialized = true; } public static bool IsRustyBagsQuiver(ItemData item) { if ((Object)(object)item?.m_dropPrefab == (Object)null) { return false; } string name = ((Object)item.m_dropPrefab).name; return name == "CrossbowQuiver_RS" || name == "MountainQuiver_RS" || name == "Quiver_RS"; } } public class MagicPluginTomeSlot : CustomSlot { public const string ID = "MagicPluginTome"; public const string pluginID = "blacks7ar.MagicPlugin"; public MagicPluginTomeSlot() { CustomSlot.slots.Add(this); GUID = "blacks7ar.MagicPlugin"; slotID = "MagicPluginTome"; if (!base.PluginInstalled) { return; } Assembly assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["blacks7ar.MagicPlugin"].Instance).GetType()); MethodInfo isValid = AccessTools.Method(assembly.GetType("MagicPlugin.Functions.MagicSlot"), "IsTomeItem", (Type[])null, (Type[])null); if (isValid == null) { GenesisExtraCustomSlots.LogWarning("MagicPlugin mod is loaded but MagicPlugin.Functions.MagicSlot:IsTomeItem is not found"); return; } itemIsValid = delegate(ItemData item) { int result; if (item != null) { MethodInfo methodInfo = isValid; object[] parameters = (object[])(object)new ItemData[1] { item }; result = (((bool)methodInfo.Invoke(null, parameters)) ? 1 : 0); } else { result = 0; } return (byte)result != 0; }; getName = () => GenesisExtraCustomSlots.magicPluginTomeSlotName.Value; isActive = () => CustomSlot.IsSlotActive(GenesisExtraCustomSlots.magicPluginTomeSlotGlobalKey.Value, GenesisExtraCustomSlots.magicPluginTomeSlotItemDiscovered.Value); initialized = true; } } public class MagicPluginEarringSlot : CustomSlot { public const string ID = "MagicPluginEarring"; public const string pluginID = "blacks7ar.MagicPlugin"; public MagicPluginEarringSlot() { CustomSlot.slots.Add(this); GUID = "blacks7ar.MagicPlugin"; slotID = "MagicPluginEarring"; if (!base.PluginInstalled) { return; } Assembly assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["blacks7ar.MagicPlugin"].Instance).GetType()); MethodInfo isValid = AccessTools.Method(assembly.GetType("MagicPlugin.Functions.MagicSlot"), "IsEarringItem", (Type[])null, (Type[])null); if (isValid == null) { GenesisExtraCustomSlots.LogWarning("MagicPlugin mod is loaded but MagicPlugin.Functions.MagicSlot:IsEarringItem is not found"); return; } itemIsValid = delegate(ItemData item) { int result; if (item != null) { MethodInfo methodInfo = isValid; object[] parameters = (object[])(object)new ItemData[1] { item }; result = (((bool)methodInfo.Invoke(null, parameters)) ? 1 : 0); } else { result = 0; } return (byte)result != 0; }; getName = () => GenesisExtraCustomSlots.magicPluginEarringSlotName.Value; isActive = () => CustomSlot.IsSlotActive(GenesisExtraCustomSlots.magicPluginEarringSlotGlobalKey.Value, GenesisExtraCustomSlots.magicPluginEarringSlotItemDiscovered.Value); initialized = true; } } [HarmonyPatch] public static class MagicPlugin_MagicSlot_AddCustomSlot_PreventCustomSlotAddition { public static MethodBase target; public static bool Prepare(MethodBase original) { if (!Chainloader.PluginInfos.TryGetValue("blacks7ar.MagicPlugin", out var value)) { return false; } if ((object)target == null) { target = AccessTools.Method(Assembly.GetAssembly(((object)value.Instance).GetType()).GetType("MagicPlugin.Functions.MagicSlot"), "AddCustomSlot", (Type[])null, (Type[])null); } if (target == null) { return false; } if (original == null) { GenesisExtraCustomSlots.LogInfo("MagicPlugin.Functions.MagicSlot:AddCustomSlot method is patched to prevent adding custom slot call"); } return true; } public static MethodBase TargetMethod() { return target; } public static bool Prefix() { return false; } } [HarmonyPatch] public static class MagicPlugin_AzuEPI_IsLoaded_CustomSlotHandle { public static MethodBase target; public static bool Prepare(MethodBase original) { if (!Chainloader.PluginInfos.TryGetValue("blacks7ar.MagicPlugin", out var value)) { return false; } if ((object)target == null) { target = AccessTools.Method(Assembly.GetAssembly(((object)value.Instance).GetType()).GetType("AzuExtendedPlayerInventory.API"), "IsLoaded", (Type[])null, (Type[])null); } if (target == null) { return false; } if (original == null) { GenesisExtraCustomSlots.LogInfo("MagicPlugin.AzuExtendedPlayerInventory.API:IsLoaded method is patched to enable custom slot handling"); } return true; } public static MethodBase TargetMethod() { return target; } public static void Postfix(ref bool __result) { __result = true; } } public class UnifiedBackpackSlot : CustomSlot { public const string ID = "UnifiedBackpack"; private static Func<ItemData, bool> _adventureBackpacksValidator; private static Func<ItemData, bool> _backpacksValidator; private static Func<ItemData, bool> _judesEquipmentValidator; private static Func<ItemData, bool> _rustyBagsValidator; public UnifiedBackpackSlot() { CustomSlot.slots.Add(this); if (Chainloader.PluginInfos.ContainsKey("vapok.mods.adventurebackpacks")) { GUID = "vapok.mods.adventurebackpacks"; slotID = "AdventureBackpacks"; } else if (Chainloader.PluginInfos.ContainsKey("org.bepinex.plugins.backpacks")) { GUID = "org.bepinex.plugins.backpacks"; slotID = "Backpacks"; } else if (Chainloader.PluginInfos.ContainsKey("GoldenJude_JudesEquipment")) { GUID = "GoldenJude_JudesEquipment"; slotID = "JudesEquipmentBackpack"; } else { if (!Chainloader.PluginInfos.ContainsKey("RustyMods.RustyBags")) { GenesisExtraCustomSlots.LogWarning("UnifiedBackpackSlot created but no backpack mod is installed"); return; } GUID = "RustyMods.RustyBags"; slotID = "RustyBagsBag"; } InitializeValidators(); itemIsValid = delegate(ItemData item) { if (item == null) { return false; } if (IsQuiverItem(item)) { return false; } bool flag2 = false; if (_adventureBackpacksValidator != null) { flag2 |= _adventureBackpacksValidator(item); } if (_backpacksValidator != null) { flag2 |= _backpacksValidator(item); } if (_judesEquipmentValidator != null) { flag2 |= _judesEquipmentValidator(item); } if (_rustyBagsValidator != null) { flag2 |= _rustyBagsValidator(item); } return flag2; }; getName = delegate { if (Chainloader.PluginInfos.ContainsKey("vapok.mods.adventurebackpacks") && GenesisExtraCustomSlots.adventureBackpackSlotEnabled.Value) { return GenesisExtraCustomSlots.adventureBackpackSlotName.Value; } if (Chainloader.PluginInfos.ContainsKey("org.bepinex.plugins.backpacks") && GenesisExtraCustomSlots.backpacksSlotEnabled.Value) { return GenesisExtraCustomSlots.backpacksSlotName.Value; } if (Chainloader.PluginInfos.ContainsKey("GoldenJude_JudesEquipment") && GenesisExtraCustomSlots.judesEquipmentBackpackSlotEnabled.Value) { return GenesisExtraCustomSlots.judesEquipmentBackpackSlotName.Value; } return (Chainloader.PluginInfos.ContainsKey("RustyMods.RustyBags") && GenesisExtraCustomSlots.rustyBagsSlotEnabled.Value) ? GenesisExtraCustomSlots.rustyBagsSlotName.Value : "Backpack"; }; isActive = delegate { bool flag = false; if (Chainloader.PluginInfos.ContainsKey("vapok.mods.adventurebackpacks") && GenesisExtraCustomSlots.adventureBackpackSlotEnabled.Value) { flag |= CustomSlot.IsSlotActive(GenesisExtraCustomSlots.adventureBackpackSlotGlobalKey.Value, GenesisExtraCustomSlots.adventureBackpackSlotItemDiscovered.Value); } if (Chainloader.PluginInfos.ContainsKey("org.bepinex.plugins.backpacks") && GenesisExtraCustomSlots.backpacksSlotEnabled.Value) { flag |= CustomSlot.IsSlotActive(GenesisExtraCustomSlots.backpacksSlotGlobalKey.Value, GenesisExtraCustomSlots.backpacksSlotItemDiscovered.Value); } if (Chainloader.PluginInfos.ContainsKey("GoldenJude_JudesEquipment") && GenesisExtraCustomSlots.judesEquipmentBackpackSlotEnabled.Value) { flag |= CustomSlot.IsSlotActive(GenesisExtraCustomSlots.judesEquipmentBackpackSlotGlobalKey.Value, GenesisExtraCustomSlots.judesEquipmentBackpackSlotItemDiscovered.Value); } if (Chainloader.PluginInfos.ContainsKey("RustyMods.RustyBags") && GenesisExtraCustomSlots.rustyBagsSlotEnabled.Value) { flag |= CustomSlot.IsSlotActive(GenesisExtraCustomSlots.rustyBagsSlotGlobalKey.Value, GenesisExtraCustomSlots.rustyBagsSlotItemDiscovered.Value); } return flag; }; initialized = true; } private static void InitializeValidators() { if (Chainloader.PluginInfos.ContainsKey("vapok.mods.adventurebackpacks")) { try { _adventureBackpacksValidator = global::GenesisExtraCustomSlots.AdventureBackpacksCustomSlot.CustomItemType.IsBackpack; } catch (Exception ex) { GenesisExtraCustomSlots.LogWarning("Failed to initialize Adventure Backpacks validator: " + ex.Message); } } if (Chainloader.PluginInfos.ContainsKey("org.bepinex.plugins.backpacks")) { try { Assembly assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["org.bepinex.plugins.backpacks"].Instance).GetType()); MethodInfo isValid = AccessTools.Method(assembly.GetType("Backpacks.Backpacks"), "validateBackpack", (Type[])null, (Type[])null); if (isValid != null) { _backpacksValidator = delegate(ItemData item) { int result; if (item != null) { MethodInfo methodInfo = isValid; object[] parameters = (object[])(object)new ItemData[1] { item }; result = (((bool)methodInfo.Invoke(null, parameters)) ? 1 : 0); } else { result = 0; } return (byte)result != 0; }; } } catch (Exception ex2) { GenesisExtraCustomSlots.LogWarning("Failed to initialize Backpacks validator: " + ex2.Message); } } if (Chainloader.PluginInfos.ContainsKey("GoldenJude_JudesEquipment")) { try { _judesEquipmentValidator = (ItemData item) => item != null && (Object)(object)item.m_dropPrefab != (Object)null && (((Object)item.m_dropPrefab).name == "BackpackSimple" || ((Object)item.m_dropPrefab).name == "BackpackHeavy"); } catch (Exception ex3) { GenesisExtraCustomSlots.LogWarning("Failed to initialize Judes Equipment validator: " + ex3.Message); } } if (!Chainloader.PluginInfos.ContainsKey("RustyMods.RustyBags")) { return; } try { Assembly assembly2 = Assembly.GetAssembly(((object)Chainloader.PluginInfos["RustyMods.RustyBags"].Instance).GetType()); Type bag = AccessTools.GetTypesFromAssembly(assembly2).FirstOrDefault((Type type) => type.FullName == "RustyBags.Bag"); if (bag != null) { _rustyBagsValidator = (ItemData item) => item != null && bag.IsInstanceOfType(item) && !RustyBagsSlot.IsRustyBagsQuiver(item); } } catch (Exception ex4) { GenesisExtraCustomSlots.LogWarning("Failed to initialize Rusty Bags validator: " + ex4.Message); } } private static bool IsQuiverItem(ItemData item) { if ((Object)(object)item?.m_dropPrefab == (Object)null) { return false; } try { if (UnifiedQuiverSlot.IsQuiver(item)) { return true; } } catch { } return HunterLegacyConstants.IsHunterLegacyQuiver(item); } } public class UnifiedQuiverSlot : CustomSlot { public const string ID = "UnifiedQuiver"; private static List<Func<ItemData, bool>> validators; private static bool initializedStatic; public UnifiedQuiverSlot() { CustomSlot.slots.Add(this); GUID = "Azumatt.BowsBeforeHoes"; slotID = "BowsBeforeHoes"; EnsureInitialized(); itemIsValid = (ItemData item) => IsQuiver(item); getName = delegate { if (Chainloader.PluginInfos.ContainsKey("Azumatt.BowsBeforeHoes") && GenesisExtraCustomSlots.bbhQuiverSlotEnabled.Value) { return GenesisExtraCustomSlots.bbhQuiverSlotName.Value; } return (Chainloader.PluginInfos.ContainsKey("RustyMods.RustyBags") && GenesisExtraCustomSlots.rustyBagsSlotEnabled.Value) ? GenesisExtraCustomSlots.rustyBagsSlotName.Value : "Quiver"; }; isActive = delegate { bool flag = false; if (Chainloader.PluginInfos.ContainsKey("Azumatt.BowsBeforeHoes") && GenesisExtraCustomSlots.bbhQuiverSlotEnabled.Value) { flag |= CustomSlot.IsSlotActive(GenesisExtraCustomSlots.bbhQuiverSlotGlobalKey.Value, GenesisExtraCustomSlots.bbhQuiverSlotItemDiscovered.Value); } if (Chainloader.PluginInfos.ContainsKey("RustyMods.RustyBags") && GenesisExtraCustomSlots.rustyBagsSlotEnabled.Value) { flag |= CustomSlot.IsSlotActive(GenesisExtraCustomSlots.rustyBagsSlotGlobalKey.Value, GenesisExtraCustomSlots.rustyBagsSlotItemDiscovered.Value); } if (Chainloader.PluginInfos.ContainsKey("horemvore.HunterLegacy")) { flag |= GenesisExtraCustomSlots.hunterLegacyQuiverSlotEnabled.Value; } return flag; }; initialized = validators != null && validators.Count > 0; } public static bool IsSlotActive() { bool flag = false; if (Chainloader.PluginInfos.ContainsKey("Azumatt.BowsBeforeHoes") && GenesisExtraCustomSlots.bbhQuiverSlotEnabled.Value) { flag |= CustomSlot.IsSlotActive(GenesisExtraCustomSlots.bbhQuiverSlotGlobalKey.Value, GenesisExtraCustomSlots.bbhQuiverSlotItemDiscovered.Value); } if (Chainloader.PluginInfos.ContainsKey("RustyMods.RustyBags") && GenesisExtraCustomSlots.rustyBagsSlotEnabled.Value) { flag |= CustomSlot.IsSlotActive(GenesisExtraCustomSlots.rustyBagsSlotGlobalKey.Value, GenesisExtraCustomSlots.rustyBagsSlotItemDiscovered.Value); } if (Chainloader.PluginInfos.ContainsKey("horemvore.HunterLegacy")) { flag |= GenesisExtraCustomSlots.hunterLegacyQuiverSlotEnabled.Value; } return flag; } private static void EnsureInitialized() { if (initializedStatic) { return; } validators = new List<Func<ItemData, bool>>(); if (Chainloader.PluginInfos.ContainsKey("Azumatt.BowsBeforeHoes")) { try { Assembly assembly = Assembly.GetAssembly(((object)Chainloader.PluginInfos["Azumatt.BowsBeforeHoes"].Instance).GetType()); MethodInfo isValid = AccessTools.Method(assembly.GetType("BowsBeforeHoes.Util.Functions"), "IsQuiverSlot", (Type[])null, (Type[])null); if (isValid != null) { validators.Add(delegate(ItemData item) { int result; if (item != null) { MethodInfo methodInfo = isValid; object[] parameters = (object[])(object)new ItemData[1] { item }; result = (((bool)methodInfo.Invoke(null, parameters)) ? 1 : 0); } else { result = 0; } return (byte)result != 0; }); GenesisExtraCustomSlots.LogInfo("UnifiedQuiverSlot: BowsBeforeHoes validator registered"); } else { GenesisExtraCustomSlots.LogWarning("BowsBeforeHoes mod is loaded but IsQuiverSlot not found via reflection"); } } catch (Exception ex) { GenesisExtraCustomSlots.LogWarning("Failed to initialize BowsBeforeHoes validator: " + ex.Message); } } if (Chainloader.PluginInfos.ContainsKey("RustyMods.RustyBags")) { try { validators.Add((ItemData item) => RustyBagsSlot.IsRustyBagsQuiver(item)); GenesisExtraCustomSlots.LogInfo("UnifiedQuiverSlot: RustyBags validator registered"); } catch (Exception ex2) { GenesisExtraCustomSlots.LogWarning("Failed to initialize RustyBags validator: " + ex2.Message); } } try { validators.Add((ItemData item) => HunterLegacyConstants.IsHunterLegacyQuiver(item)); GenesisExtraCustomSlots.LogInfo("UnifiedQuiverSlot: HunterLegacy validator registered"); } catch (Exception ex3) { GenesisExtraCustomSlots.LogWarning("Failed to initialize HunterLegacy validator: " + ex3.Message); } initializedStatic = true; } public static bool IsQuiver(ItemData item) { EnsureInitialized(); if (validators == null) { return false; } foreach (Func<ItemData, bool> validator in validators) { try { if (validator(item)) { return true; } } catch (Exception ex) { if (GenesisExtraCustomSlots.loggingEnabled.Value) { GenesisExtraCustomSlots.LogWarning("UnifiedQuiverSlot: validator threw exception: " + ex.Message); } } } try { string text = item?.m_shared?.m_name ?? ""; if (!string.IsNullOrEmpty(text) && text.IndexOf("quiver", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } catch { } return false; } } public class UserDefinedSlot : CustomSlot { public ConfigEntry<bool> slotEnabled; public ConfigEntry<string> slotName; public ConfigEntry<string> slotGlobalKey; public ConfigEntry<string> slotItemList; public ConfigEntry<bool> itemIsVisible; public string groupName; public List<string> itemList = new List<string>(); public const int maxAmount = 8; public static UserDefinedSlot[] userDefinedSlots = new UserDefinedSlot[8]; public const string UserDefinedSlotID = "CustomSlot"; public void UpdateItemList() { itemList.Clear(); CollectionExtensions.Do<string>(from s in slotItemList.Value.Split(new char[1] { ',' }) select s.Trim() into s where !Utility.IsNullOrWhiteSpace(s) select s, (Action<string>)itemList.Add); } public UserDefinedSlot(int index) { userDefinedSlots[index] = this; groupName = $"User defined - Custom slot {index + 1}"; slotEnabled = GenesisExtraCustomSlots.instance.config(groupName, "Enabled", defaultValue: false, "Enable custom slot."); slotName = GenesisExtraCustomSlots.instance.config(groupName, "Name", "Slot", "Slot name. Use ExtraSlots translation files to add localized string."); slotGlobalKey = GenesisExtraCustomSlots.instance.config(groupName, "Global keys", "", "Comma-separated list of global keys and player unique keys. Slot will be active only if any key is enabled or list is not set."); slotItemList = GenesisExtraCustomSlots.instance.config(groupName, "Item list", "", "Comma-separated list of items. Slot will be active only if any item is discovered."); itemIsVisible = GenesisExtraCustomSlots.instance.config(groupName, "Item is visible", defaultValue: true, "Make item in that slot visible on player model (if supported by an item itself)."); slotEnabled.SettingChanged += delegate { GenesisExtraCustomSlots.UpdateSlots(); }; slotItemList.SettingChanged += delegate { UpdateItemList(); }; itemIsVisible.SettingChanged += delegate { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Humanoid)localPlayer).SetupEquipment(); } }; UpdateItemList(); GUID = GetSlotID(index); slotID = GUID; itemIsValid = (ItemData item) => item != null && ((item.m_shared != null && itemList.Contains(item.m_shared.m_name)) || ((Object)(object)item.m_dropPrefab != (Object)null && itemList.Contains(((Object)item.m_dropPrefab).name))); getName = () => slotName.Value; isActive = () => CustomSlot.IsSlotActive(slotGlobalKey.Value, slotItemList.Value); initialized = true; } public static void UpdateSlot(string slotID) { UserDefinedSlot userDefinedSlot = userDefinedSlots.FirstOrDefault((UserDefinedSlot slot) => slot.slotID == slotID); if (userDefinedSlot != null && userDefinedSlot.slotEnabled.Value) { CustomSlot.slots.Add(userDefinedSlot); } } public static bool IsUserDefinedSlot(string slotID) { return slotID.StartsWith("CustomSlot"); } public static string GetSlotID(int index) { return string.Format("{0}{1}", "CustomSlot", index + 1); } public static bool IsItemInSlotVisible(int index) { UserDefinedSlot userDefinedSlot = userDefinedSlots[index]; return userDefinedSlot != null && userDefinedSlot.slotEnabled.Value && userDefinedSlot.itemIsVisible.Value; } } } namespace GenesisExtraCustomSlots.UserDefinedCustomSlots { [Serializable] public class HumanoidCustomItemSlots { public ItemData customItem1; public ItemData customItem2; public ItemData customItem3; public ItemData customItem4; public ItemData customItem5; public ItemData customItem6; public ItemData customItem7; public ItemData customItem8; } public static class HumanoidExtension { private static readonly ConditionalWeakTable<Humanoid, HumanoidCustomItemSlots> data = new ConditionalWeakTable<Humanoid, HumanoidCustomItemSlots>(); public static HumanoidCustomItemSlots GetCustomItemData(this Humanoid humanoid) { return data.GetOrCreateValue(humanoid); } public static ItemData GetCustomItem(this Humanoid humanoid, int index) { if (1 == 0) { } ItemData result = (ItemData)(index switch { 0 => humanoid.GetCustomItemData().customItem1, 1 => humanoid.GetCustomItemData().customItem2, 2 => humanoid.GetCustomItemData().customItem3, 3 => humanoid.GetCustomItemData().customItem4, 4 => humanoid.GetCustomItemData().customItem5, 5 => humanoid.GetCustomItemData().customItem6, 6 => humanoid.GetCustomItemData().customItem7, 7 => humanoid.GetCustomItemData().customItem8, _ => null, }); if (1 == 0) { } return result; } public static ItemData SetCustomItem(this Humanoid humanoid, int index, ItemData item) { if (1 == 0) { } ItemData result = (ItemData)(index switch { 0 => humanoid.GetCustomItemData().customItem1 = item, 1 => humanoid.GetCustomItemData().customItem2 = item, 2 => humanoid.GetCustomItemData().customItem3 = item, 3 => humanoid.GetCustomItemData().customItem4 = item, 4 => humanoid.GetCustomItemData().customItem5 = item, 5 => humanoid.GetCustomItemData().customItem6 = item, 6 => humanoid.GetCustomItemData().customItem7 = item, 7 => humanoid.GetCustomItemData().customItem8 = item, _ => null, }); if (1 == 0) { } return result; } } [Serializable] public class VisEquipmentCustomItemState { public string m_item = ""; public List<GameObject> m_instances; public int m_hash = 0; } [Serializable] public class VisEquipmentCustomItem { public VisEquipmentCustomItemState customItem1 = new VisEquipmentCustomItemState(); public VisEquipmentCustomItemState customItem2 = new VisEquipmentCustomItemState(); public VisEquipmentCustomItemState customItem3 = new VisEquipmentCustomItemState(); public VisEquipmentCustomItemState customItem4 = new VisEquipmentCustomItemState(); public VisEquipmentCustomItemState customItem5 = new VisEquipmentCustomItemState(); public VisEquipmentCustomItemState customItem6 = new VisEquipmentCustomItemState(); public VisEquipmentCustomItemState customItem7 = new VisEquipmentCustomItemState(); public VisEquipmentCustomItemState customItem8 = new VisEquipmentCustomItemState(); } public static class VisEquipmentExtension { [HarmonyPatch(typeof(VisEquipment), "UpdateEquipmentVisuals")] public static class VisEquipment_UpdateEquipmentVisuals_CustomItemType { public static VisEquipment visEq; public static bool updateLodGroup; private static void Prefix(VisEquipment __instance) { ZNetView nView = GetNView(__instance); ZDO val = ((nView != null) ? nView.GetZ