Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of EndosCryptKeySlotMod v1.0.0
SwampKeyBundle.dll
Decompiled 5 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("SwampKeyBundle")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("FSOS-X R10 EXP")] [assembly: AssemblyProduct("SwampKeyBundle")] [assembly: AssemblyCopyright("Copyright © FSOS-X R10 EXP 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("4e3c96f9-75e1-43a1-a13d-36cda88fc6ad")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace ValheimCryptKeySlotHUD; [HarmonyPatch(typeof(Door), "Interact")] public static class DoorInteractKeyInjectionPatch { public static void Prefix(Door __instance, Humanoid character, bool hold, bool alt) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown if ((Object)(object)character != (Object)null && ((Character)character).IsPlayer() && (Object)(object)__instance.m_keyItem != (Object)null && __instance.m_keyItem.m_itemData.m_shared.m_name == "$item_cryptkey") { Player val = (Player)character; if (CryptKeySlotHUDMod.VirtualKeyInventory != null && !((Humanoid)val).GetInventory().ContainsItem(__instance.m_keyItem.m_itemData) && CryptKeySlotHUDMod.VirtualKeyInventory.GetItem("$item_cryptkey", -1, false) != null) { ((Humanoid)val).GetInventory().AddItem(((Component)__instance.m_keyItem).gameObject, 1); ((MonoBehaviour)val).StartCoroutine(RemoveKeyNextFrame(val)); } } } private static IEnumerator RemoveKeyNextFrame(Player player) { yield return null; if ((Object)(object)player != (Object)null && ((Humanoid)player).GetInventory() != null) { ItemData item = ((Humanoid)player).GetInventory().GetItem("$item_cryptkey", -1, false); if (item != null) { ((Humanoid)player).GetInventory().RemoveItem(item); } } } } [HarmonyPatch(typeof(Door), "GetHoverText")] public static class DoorHoverTextPatch { public static void Postfix(Door __instance, ref string __result) { if ((Object)(object)__instance.m_keyItem != (Object)null && __instance.m_keyItem.m_itemData.m_shared.m_name == "$item_cryptkey" && (Object)(object)Player.m_localPlayer != (Object)null && CryptKeySlotHUDMod.VirtualKeyInventory != null && CryptKeySlotHUDMod.VirtualKeyInventory.GetItem("$item_cryptkey", -1, false) != null && (__result.Contains("$piece_dungeon_cryptkey_required") || __result.Contains("Swamp Key") || __result.Contains("Need key"))) { __result = __instance.m_name + "\n[<color=yellow><b>E</b></color>] Open"; } } } public class CryptKeyClickComponent : MonoBehaviour, IPointerClickHandler, IEventSystemHandler, IPointerEnterHandler, IPointerExitHandler { public void OnPointerEnter(PointerEventData eventData) { } public void OnPointerExit(PointerEventData eventData) { } public void OnPointerClick(PointerEventData eventData) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; InventoryGui instance = InventoryGui.instance; if ((Object)(object)localPlayer == (Object)null || (Object)(object)instance == (Object)null) { return; } if ((int)eventData.button == 0) { FieldInfo field = typeof(InventoryGui).GetField("m_dragItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field2 = typeof(InventoryGui).GetField("m_dragInventory", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); MethodInfo method = typeof(InventoryGui).GetMethod("SetupDragItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { field = typeof(InventoryGui).GetField("dragItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (field2 == null) { field2 = typeof(InventoryGui).GetField("dragInventory", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (method == null) { method = typeof(InventoryGui).GetMethod("SetDragItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } ItemData val = ((!(field != null)) ? ((ItemData)null) : ((ItemData)field.GetValue(instance))); Inventory val2 = ((!(field2 != null)) ? ((Inventory)null) : ((Inventory)field2.GetValue(instance))); if (val != null) { if (val.m_shared.m_name == "$item_cryptkey" && CryptKeySlotHUDMod.VirtualKeyInventory.GetItem("$item_cryptkey", -1, false) == null) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("CryptKey"); if ((Object)(object)itemPrefab != (Object)null) { CryptKeySlotHUDMod.VirtualKeyInventory.AddItem(itemPrefab, 1); if (val2 != null) { if (val.m_stack > 1) { val.m_stack--; } else { val2.RemoveItem(val); } } ClearDragItem(method, instance); if ((Object)(object)itemPrefab.GetComponent<ItemDrop>() != (Object)null) { itemPrefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_itemType = (ItemType)1; } if ((Object)(object)CryptKeySlotHUDMod.KeyPanel != (Object)null) { CryptKeySlotHUDMod.KeyPanel.GetComponent<MonoBehaviour>().StartCoroutine(CryptKeySlotHUDMod.FlashGreenGlow()); } } } } else if (val == null) { ItemData item = CryptKeySlotHUDMod.VirtualKeyInventory.GetItem("$item_cryptkey", -1, false); if (item != null) { GameObject itemPrefab2 = ObjectDB.instance.GetItemPrefab("CryptKey"); if ((Object)(object)itemPrefab2 != (Object)null) { ItemData val3 = ((Humanoid)localPlayer).PickupPrefab(itemPrefab2, 1, true); if (val3 != null) { CryptKeySlotHUDMod.VirtualKeyInventory.RemoveItem(item); if (method != null) { try { method.Invoke(instance, new object[3] { val3, ((Humanoid)localPlayer).GetInventory(), 1 }); } catch { method.Invoke(instance, new object[2] { val3, ((Humanoid)localPlayer).GetInventory() }); } } } } } } } CryptKeySlotHUDMod.UpdateSlotVisuals(); instance.m_playerGrid.UpdateInventory(((Humanoid)localPlayer).GetInventory(), localPlayer, (ItemData)null); } private void ClearDragItem(MethodInfo setupDragMethod, InventoryGui gui) { if (setupDragMethod != null) { try { setupDragMethod.Invoke(gui, new object[3] { null, null, 0 }); } catch { setupDragMethod.Invoke(gui, null); } } } } [BepInPlugin("EndosCryptKeySlot", "EndosCryptKeySlotMod", "1.0.0")] public class CryptKeySlotHUDMod : BaseUnityPlugin { public static Image GlowIconImage; public const string ModGUID = "EndosCryptKeySlot"; public const string ModName = "EndosCryptKeySlotMod"; public const string ModVersion = "1.0.0"; private Harmony harmony; public static GameObject KeyPanel; public static Text SlotText; public static Image SlotIconImage; public static Inventory VirtualKeyInventory; public static ConfigEntry<float> ConfigPosX; public static ConfigEntry<float> ConfigPosY; public static void CreateKeySlotUI(InventoryGui gui) { if ((Object)(object)gui != (Object)null && ((Component)gui).gameObject.activeInHierarchy) { CryptKeySlotHUDMod cryptKeySlotHUDMod = Object.FindAnyObjectByType<CryptKeySlotHUDMod>(); if ((Object)(object)cryptKeySlotHUDMod != (Object)null) { ((MonoBehaviour)cryptKeySlotHUDMod).StartCoroutine(DelayedCreateUI(gui)); } } } private static IEnumerator DelayedCreateUI(InventoryGui gui) { yield return (object)new WaitForSecondsRealtime(0.15f); if ((Object)(object)gui == (Object)null || (Object)(object)KeyPanel != (Object)null) { yield break; } GameObject val = GameObject.Find("ArmorSlots") ?? GameObject.Find("EquipmentAndQuickSlots") ?? GameObject.Find("EquipmentPanel") ?? GameObject.Find("EquipmentGui"); if ((Object)(object)val == (Object)null && (Object)(object)((Component)gui).transform.parent != (Object)null) { Transform[] componentsInChildren = ((Component)((Component)gui).transform.parent).GetComponentsInChildren<Transform>(true); foreach (Transform val2 in componentsInChildren) { if ((((Object)((Component)val2).gameObject).name.Contains("Equipment") || ((Object)((Component)val2).gameObject).name.Contains("ArmorSlots")) && ((Component)val2).gameObject.activeInHierarchy) { val = ((Component)val2).gameObject; break; } } } Transform val3 = (((Object)(object)val != (Object)null) ? val.transform : ((Component)gui.m_playerGrid).transform.parent); if ((Object)(object)val3 == (Object)null) { yield break; } KeyPanel = new GameObject("CryptKeySlotHUD", new Type[4] { typeof(RectTransform), typeof(Image), typeof(CanvasGroup), typeof(CryptKeyClickComponent) }); KeyPanel.transform.SetParent(val3, false); Image component = KeyPanel.GetComponent<Image>(); ((Graphic)component).raycastTarget = true; Sprite val4 = null; Image[] array = Resources.FindObjectsOfTypeAll<Image>(); foreach (Image val5 in array) { if ((Object)(object)val5 != (Object)null && (Object)(object)val5.sprite != (Object)null) { switch (((Object)val5.sprite).name.ToLower()) { case "ac_bkg": case "stat_bkg": case "bkg": case "damage_bkg": case "armor_bkg": break; default: continue; } val4 = val5.sprite; ((Graphic)component).material = ((Graphic)val5).material; ((Graphic)component).color = ((Graphic)val5).color; break; } } if ((Object)(object)val4 == (Object)null) { GameObject val6 = GameObject.Find("ac") ?? GameObject.Find("ac_bkg") ?? GameObject.Find("Armor") ?? GameObject.Find("ac_icon"); if ((Object)(object)val6 != (Object)null) { Image val7 = val6.GetComponent<Image>() ?? val6.GetComponentInChildren<Image>(true); if ((Object)(object)val7 != (Object)null && (Object)(object)val7.sprite != (Object)null) { val4 = val7.sprite; ((Graphic)component).material = ((Graphic)val7).material; ((Graphic)component).color = ((Graphic)val7).color; } } } if ((Object)(object)val4 != (Object)null) { component.sprite = val4; component.type = (Type)0; ((Graphic)component).color = Color.white; } else { ((Graphic)component).color = new Color(0f, 0f, 0f, 0.4f); } RectTransform component2 = KeyPanel.GetComponent<RectTransform>(); component2.anchorMin = new Vector2(0f, 1f); component2.anchorMax = new Vector2(0f, 1f); component2.pivot = new Vector2(0.5f, 0.5f); component2.sizeDelta = new Vector2(54f, 60f); UpdateSlotPosition(); GameObject val8 = new GameObject("SlotGlow", new Type[2] { typeof(RectTransform), typeof(Image) }); val8.transform.SetParent(KeyPanel.transform, false); GlowIconImage = val8.GetComponent<Image>(); ((Graphic)GlowIconImage).raycastTarget = false; GlowIconImage.sprite = component.sprite; ((Graphic)GlowIconImage).material = ((Graphic)component).material; GlowIconImage.type = (Type)0; ((Graphic)GlowIconImage).color = new Color(0f, 1f, 0.2f, 0f); RectTransform component3 = val8.GetComponent<RectTransform>(); component3.anchorMin = new Vector2(0f, 0f); component3.anchorMax = new Vector2(1f, 1f); component3.offsetMin = new Vector2(0f, 0f); component3.offsetMax = new Vector2(0f, 0f); GameObject val9 = new GameObject("SlotInside", new Type[2] { typeof(RectTransform), typeof(Image) }); val9.transform.SetParent(KeyPanel.transform, false); Image component4 = val9.GetComponent<Image>(); ((Graphic)component4).raycastTarget = false; ((Graphic)component4).color = new Color(0f, 0f, 0f, 0f); RectTransform component5 = val9.GetComponent<RectTransform>(); component5.anchorMin = new Vector2(0f, 0f); component5.anchorMax = new Vector2(1f, 1f); component5.offsetMin = new Vector2(0f, 0f); component5.offsetMax = new Vector2(0f, 0f); GameObject val10 = new GameObject("KeyIcon", new Type[2] { typeof(RectTransform), typeof(Image) }); val10.transform.SetParent(val9.transform, false); SlotIconImage = val10.GetComponent<Image>(); ((Graphic)SlotIconImage).raycastTarget = false; RectTransform component6 = val10.GetComponent<RectTransform>(); component6.anchorMin = new Vector2(0.5f, 0.5f); component6.anchorMax = new Vector2(0.5f, 0.5f); component6.pivot = new Vector2(0.5f, 0.5f); component6.sizeDelta = new Vector2(40f, 40f); component6.anchoredPosition = new Vector2(0f, 4f); GameObject val11 = new GameObject("KeySlotText", new Type[2] { typeof(RectTransform), typeof(Text) }); val11.transform.SetParent(val9.transform, false); SlotText = val11.GetComponent<Text>(); ((Graphic)SlotText).raycastTarget = false; Font[] array2 = Resources.FindObjectsOfTypeAll<Font>(); foreach (Font val12 in array2) { if (((Object)val12).name.Contains("Averia")) { SlotText.font = val12; break; } } if ((Object)(object)SlotText.font == (Object)null) { ? val13 = SlotText; Object builtinResource = Resources.GetBuiltinResource(typeof(Font), "Arial.ttf"); ((Text)val13).font = (Font)(object)((builtinResource is Font) ? builtinResource : null); } SlotText.fontSize = 10; ((Graphic)SlotText).color = new Color(1f, 0.85f, 0.4f, 0.8f); SlotText.alignment = (TextAnchor)7; Shadow obj = val11.AddComponent<Shadow>(); obj.effectColor = Color.black; obj.effectDistance = new Vector2(1f, -1f); RectTransform component7 = val11.GetComponent<RectTransform>(); component7.anchorMin = new Vector2(0f, 0f); component7.anchorMax = new Vector2(1f, 1f); component7.offsetMin = new Vector2(0f, 4f); component7.offsetMax = new Vector2(0f, 0f); UpdateSlotVisuals(); } public static IEnumerator FlashGreenGlow() { if (!((Object)(object)GlowIconImage == (Object)null)) { float duration = 0.4f; float elapsed = 0f; while (elapsed < duration) { elapsed += Time.unscaledDeltaTime; float num = Mathf.Lerp(0f, 0.75f, elapsed / duration); ((Graphic)GlowIconImage).color = new Color(0.1f, 1f, 0.3f, num); yield return null; } elapsed = 0f; while (elapsed < duration) { elapsed += Time.unscaledDeltaTime; float num2 = Mathf.Lerp(0.75f, 0f, elapsed / duration); ((Graphic)GlowIconImage).color = new Color(0.1f, 1f, 0.3f, num2); yield return null; } ((Graphic)GlowIconImage).color = new Color(0.1f, 1f, 0.3f, 0f); } } private void Awake() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown harmony = new Harmony("EndosCryptKeySlot"); harmony.PatchAll(); ConfigPosX = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "Slot X Position", 160f, "The horizontal position relative to the equipment panel."); ConfigPosY = ((BaseUnityPlugin)this).Config.Bind<float>("Position", "Slot Y Position", -72f, "The vertical position relative to the equipment panel."); ConfigPosX.SettingChanged += delegate { UpdateSlotPosition(); }; ConfigPosY.SettingChanged += delegate { UpdateSlotPosition(); }; VirtualKeyInventory = new Inventory("VirtualCryptKeyInv", (Sprite)null, 1, 1); Inventory virtualKeyInventory = VirtualKeyInventory; virtualKeyInventory.m_onChanged = (Action)Delegate.Combine(virtualKeyInventory.m_onChanged, new Action(UpdateSlotVisuals)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"=== EndosCryptKeySlot successfully loaded! ==="); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } public static void UpdateSlotPosition() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)KeyPanel != (Object)null) { RectTransform component = KeyPanel.GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null) { component.anchoredPosition = new Vector2(ConfigPosX.Value, ConfigPosY.Value); } } } public static void UpdateSlotVisuals() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) if (VirtualKeyInventory == null || (Object)(object)SlotIconImage == (Object)null) { return; } ItemData item = VirtualKeyInventory.GetItem("$item_cryptkey", -1, false); if (item != null && item.m_shared.m_icons != null && item.m_shared.m_icons.Length != 0) { SlotIconImage.sprite = item.m_shared.m_icons[0]; ((Graphic)SlotIconImage).color = Color.white; if ((Object)(object)SlotText != (Object)null) { SlotText.text = ""; } return; } if ((Object)(object)ObjectDB.instance != (Object)null) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("CryptKey"); if ((Object)(object)itemPrefab != (Object)null) { ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null && component.m_itemData.m_shared.m_icons != null && component.m_itemData.m_shared.m_icons.Length != 0) { SlotIconImage.sprite = component.m_itemData.m_shared.m_icons[0]; ((Graphic)SlotIconImage).color = new Color(0f, 0f, 0f, 0.4f); } } } if ((Object)(object)SlotText != (Object)null) { SlotText.text = "Key"; } } public static void EmptySlot() { if (VirtualKeyInventory == null) { return; } foreach (ItemData item in new List<ItemData>(VirtualKeyInventory.GetAllItems())) { VirtualKeyInventory.RemoveItem(item); } } } [HarmonyPatch(typeof(InventoryGui), "Show")] public static class InventoryGuiShowPatch { private static void Postfix(InventoryGui __instance) { if ((Object)(object)CryptKeySlotHUDMod.KeyPanel == (Object)null) { CryptKeySlotHUDMod.CreateKeySlotUI(__instance); } if ((Object)(object)CryptKeySlotHUDMod.KeyPanel != (Object)null) { CryptKeySlotHUDMod.KeyPanel.SetActive(true); CryptKeySlotHUDMod.UpdateSlotPosition(); CryptKeySlotHUDMod.UpdateSlotVisuals(); } } } [HarmonyPatch(typeof(InventoryGui), "Hide")] public static class InventoryGuiHidePatch { private static void Postfix() { if ((Object)(object)CryptKeySlotHUDMod.KeyPanel != (Object)null) { CryptKeySlotHUDMod.KeyPanel.SetActive(false); } } } [HarmonyPatch(typeof(Player), "Save")] public static class PlayerSavePatch { public static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { bool flag = CryptKeySlotHUDMod.VirtualKeyInventory.GetItem("$item_cryptkey", -1, false) != null; __instance.m_customData["cryptkey_slot_has_key"] = (flag ? "1" : "0"); } } } [HarmonyPatch(typeof(Player), "Load")] public static class PlayerLoadPatch { public static void Postfix(Player __instance) { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return; } CryptKeySlotHUDMod.EmptySlot(); if (__instance.m_customData.TryGetValue("cryptkey_slot_has_key", out var value) && value == "1" && (Object)(object)ObjectDB.instance != (Object)null) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("CryptKey"); if ((Object)(object)itemPrefab != (Object)null) { CryptKeySlotHUDMod.VirtualKeyInventory.AddItem(itemPrefab, 1); } } CryptKeySlotHUDMod.UpdateSlotVisuals(); } } [HarmonyPatch(typeof(Player), "OnDeath")] public static class PlayerCreateTombStonePatch { private static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { bool flag = CryptKeySlotHUDMod.VirtualKeyInventory.GetItem("$item_cryptkey", -1, false) != null; __instance.m_customData["cryptkey_slot_has_key"] = (flag ? "1" : "0"); } } } [HarmonyPatch(typeof(Game), "Logout")] public static class GameLogoutPatch { private static void Prefix() { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && CryptKeySlotHUDMod.VirtualKeyInventory != null) { bool flag = CryptKeySlotHUDMod.VirtualKeyInventory.GetItem("$item_cryptkey", -1, false) != null; localPlayer.m_customData["cryptkey_slot_has_key"] = (flag ? "1" : "0"); CryptKeySlotHUDMod.EmptySlot(); CryptKeySlotHUDMod.UpdateSlotVisuals(); } } }