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 Shopkeep v1.2.0
Shopkeep.dll
Decompiled 2 weeks agousing System; 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.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Shopkeep")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Shopkeep")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("0b261f31-75b2-4405-b7ec-25e6fade4c16")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace Shopkeep; public class BercansDestroy : MonoBehaviour { private void OnDestroy() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown foreach (Transform item in ((Component)this).transform) { Transform val = item; if (((Object)((Component)val).gameObject).name.Contains("Haldor")) { Object.Destroy((Object)(object)((Component)val).gameObject); } } } } [BepInPlugin("com.demonforge.shopkeep", "Shopkeep", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Shopkeep : BaseUnityPlugin { public const string PluginGUID = "com.demonforge.shopkeep"; public const string PluginName = "Shopkeep"; public const string PluginVersion = "1.1.0"; public static ManualLogSource Log; private readonly Harmony harmony = new Harmony("com.demonforge.shopkeep"); private void Awake() { Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"Shopkeep 1.1.0 loading..."); try { harmony.PatchAll(); } catch (Exception arg) { Log.LogError((object)$"Harmony patching failed: {arg}"); } PrefabManager.OnVanillaPrefabsAvailable += RegisterNPC; PrefabManager.OnPrefabsRegistered += ValidatePrefabNames; } private void RegisterNPC() { Log.LogInfo((object)"Registering Shopkeep NPC..."); ShopkeepNPC.Register(); PrefabManager.OnVanillaPrefabsAvailable -= RegisterNPC; } private void ValidatePrefabNames() { PrefabManager.OnPrefabsRegistered -= ValidatePrefabNames; List<string> list = new List<string>(); foreach (string prefabName in ShopUI.GetPrefabNames()) { if (!PrefabExists(prefabName)) { list.Add("shop: " + prefabName); } } foreach (string lootPrefabName in ItemEffects.GetLootPrefabNames()) { if (!PrefabExists(lootPrefabName)) { list.Add("loot: " + lootPrefabName); } } if (list.Count == 0) { Log.LogInfo((object)"Prefab check passed - all shop and loot entries resolved."); return; } Log.LogWarning((object)$"Prefab check found {list.Count} unresolved name(s):"); foreach (string item in list) { Log.LogWarning((object)(" " + item)); } } private static bool PrefabExists(string name) { if (PrefabManager.Instance != null && (Object)(object)PrefabManager.Instance.GetPrefab(name) != (Object)null) { return true; } if ((Object)(object)ZNetScene.instance != (Object)null && (Object)(object)ZNetScene.instance.GetPrefab(name) != (Object)null) { return true; } return false; } } public static class ItemEffects { public const string VitalityKey = "Shopkeep_Vitality"; public const string EnduranceKey = "Shopkeep_Endurance"; public const string BurdenKey = "Shopkeep_Burden"; public const int MaxScrollUses = 3; public const float HealthPerUse = 25f; public const float StaminaPerUse = 25f; public const float CarryPerUse = 100f; private static readonly List<(string item, int amount, float chance)> LootTable = new List<(string, int, float)> { ("Wood", 50, 30f), ("FineWood", 20, 20f), ("Coins", 500, 25f), ("Copper", 10, 15f), ("Tin", 10, 15f), ("Bronze", 10, 12f), ("Iron", 10, 12f), ("Silver", 10, 10f), ("BlackMetal", 10, 8f), ("Flametal", 5, 4f), ("Chitin", 15, 15f), ("Crystal", 10, 10f), ("Ruby", 5, 8f), ("FreezeGland", 10, 10f), ("Blueberries", 20, 20f), ("SerpentStew", 3, 10f), ("BloodPudding", 3, 10f), ("LoxPie", 3, 8f), ("CookedMeat", 10, 15f), ("CarrotSeeds", 10, 15f), ("TurnipSeeds", 10, 15f), ("OnionSeeds", 10, 12f), ("BarleySeed", 10, 10f), ("FlaxSeed", 10, 10f), ("MeadHealthMedium", 3, 10f), ("MeadStaminaMedium", 3, 10f), ("MeadPoisonResist", 2, 8f), ("AxeIron", 1, 3f), ("AxeBlackMetal", 1, 2f), ("BattleaxeBlackmetal", 1, 1f), ("PickaxeBronze", 1, 3f), ("PickaxeIron", 1, 2f), ("SwordBronze", 1, 3f), ("SwordIron", 1, 2f), ("SwordBlackmetal", 1, 1f), ("SwordMistwalker", 1, 0.5f), ("BowFineWood", 1, 3f), ("BowHuntsman", 1, 2f), ("BowDraugrFang", 1, 1f), ("APPLY_VITALITY", 1, 2f), ("APPLY_ENDURANCE", 1, 2f), ("APPLY_BURDEN", 1, 2f) }; public static IEnumerable<string> GetLootPrefabNames() { foreach (var entry in LootTable) { if (!entry.item.StartsWith("APPLY_")) { yield return entry.item; } } } public static bool CanGiveItem(Player player, string prefabName, int amount, out string error) { error = null; if ((Object)(object)player == (Object)null) { error = "No player"; return false; } GameObject val = ResolvePrefab(prefabName); if ((Object)(object)val == (Object)null) { error = "'" + prefabName + "' no longer exists in this version of Valheim"; ManualLogSource log = Shopkeep.Log; if (log != null) { log.LogError((object)("Unresolved prefab: " + prefabName)); } return false; } if ((Object)(object)val.GetComponent<ItemDrop>() == (Object)null) { error = "'" + prefabName + "' is not an item"; return false; } if (!((Humanoid)player).GetInventory().CanAddItem(val, amount)) { error = "Not enough inventory space!"; return false; } return true; } public static bool TryGiveItem(Player player, string prefabName, int amount) { GameObject val = ResolvePrefab(prefabName); if ((Object)(object)val == (Object)null) { return false; } ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { return false; } Inventory inventory = ((Humanoid)player).GetInventory(); int num = Mathf.Max(1, component.m_itemData.m_shared.m_maxStackSize); int num2 = amount; while (num2 > 0) { int num3 = Mathf.Min(num2, num); ItemData val2 = component.m_itemData.Clone(); val2.m_stack = num3; val2.m_dropPrefab = val; if (!inventory.AddItem(val2)) { ManualLogSource log = Shopkeep.Log; if (log != null) { log.LogWarning((object)$"Inventory rejected {prefabName} x{num3}"); } return num2 < amount; } num2 -= num3; } return true; } private static GameObject ResolvePrefab(string prefabName) { GameObject val = null; if (PrefabManager.Instance != null) { val = PrefabManager.Instance.GetPrefab(prefabName); } if ((Object)(object)val == (Object)null && (Object)(object)ZNetScene.instance != (Object)null) { val = ZNetScene.instance.GetPrefab(prefabName); } return val; } public static void ApplyMysteryBox(Player player) { if ((Object)(object)player == (Object)null) { return; } float num = 0f; foreach (var item in LootTable) { num += item.chance; } float num2 = Random.Range(0f, num); float num3 = 0f; foreach (var item2 in LootTable) { num3 += item2.chance; if (num2 > num3) { continue; } switch (item2.item) { case "APPLY_VITALITY": ApplyScroll(player, "Shopkeep_Vitality", "Vitality", fromBox: true); break; case "APPLY_ENDURANCE": ApplyScroll(player, "Shopkeep_Endurance", "Endurance", fromBox: true); break; case "APPLY_BURDEN": ApplyScroll(player, "Shopkeep_Burden", "Burden", fromBox: true); break; default: { if (!CanGiveItem(player, item2.item, item2.amount, out var error)) { ManualLogSource log = Shopkeep.Log; if (log != null) { log.LogWarning((object)("Mystery Box fallback (" + item2.item + "): " + error)); } if (TryGiveItem(player, "Coins", 250)) { Message("Mystery Box: 250 coins!"); } else { Message("Mystery Box: no room in your inventory!"); } } else { TryGiveItem(player, item2.item, item2.amount); Message($"Mystery Box: You found {item2.item} x{item2.amount}!"); } break; } } break; } } public static bool IsScroll(string itemName, out string key, out string label) { switch (itemName) { case "ScrollOfVitality": key = "Shopkeep_Vitality"; label = "Vitality"; return true; case "ScrollOfEndurance": key = "Shopkeep_Endurance"; label = "Endurance"; return true; case "ScrollOfBurden": key = "Shopkeep_Burden"; label = "Burden"; return true; default: key = null; label = null; return false; } } public static bool CanApplyScroll(Player player, string key) { return (Object)(object)player != (Object)null && GetScrollUses(player, key) < 3; } public static void ApplyScrollOfVitality(Player player) { ApplyScroll(player, "Shopkeep_Vitality", "Vitality", fromBox: false); } public static void ApplyScrollOfEndurance(Player player) { ApplyScroll(player, "Shopkeep_Endurance", "Endurance", fromBox: false); } public static void ApplyScrollOfBurden(Player player) { ApplyScroll(player, "Shopkeep_Burden", "Burden", fromBox: false); } private static void ApplyScroll(Player player, string key, string label, bool fromBox) { if (!((Object)(object)player == (Object)null)) { int scrollUses = GetScrollUses(player, key); if (scrollUses >= 3) { Message("You have already reached the limit for Scroll of " + label + "!"); return; } scrollUses++; player.m_customData[key] = scrollUses.ToString(); RefreshFoodStats(player); string text = (fromBox ? ("Mystery Box: You found a Scroll of " + label + "! ") : ""); string text2 = ((key == "Shopkeep_Vitality") ? $"Max health +{25f}" : ((!(key == "Shopkeep_Endurance")) ? $"Carry weight +{100f}" : $"Max stamina +{25f}")); Message($"{text}{text2} ({scrollUses}/{3})"); } } public static int GetScrollUses(Player player, string key) { if ((Object)(object)player == (Object)null || player.m_customData == null) { return 0; } if (!player.m_customData.TryGetValue(key, out var value)) { return 0; } int result; return int.TryParse(value, out result) ? result : 0; } private static void RefreshFoodStats(Player player) { try { AccessTools.Method(typeof(Player), "UpdateFood", (Type[])null, (Type[])null)?.Invoke(player, new object[2] { 0f, true }); } catch { } } private static void Message(string text) { if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, text, 0, (Sprite)null, false, true); } } } [HarmonyPatch(typeof(Player), "GetTotalFoodValue")] public static class Patch_Player_GetTotalFoodValue { private static bool Prepare() { bool flag = AccessTools.Method(typeof(Player), "GetTotalFoodValue", (Type[])null, (Type[])null) != null; if (!flag) { ManualLogSource log = Shopkeep.Log; if (log != null) { log.LogError((object)"Player.GetTotalFoodValue not found - Vitality and Endurance scrolls disabled."); } } return flag; } private static void Postfix(Player __instance, ref float hp, ref float stamina) { if (!((Object)(object)__instance == (Object)null)) { hp += (float)ItemEffects.GetScrollUses(__instance, "Shopkeep_Vitality") * 25f; stamina += (float)ItemEffects.GetScrollUses(__instance, "Shopkeep_Endurance") * 25f; } } } [HarmonyPatch(typeof(Player), "GetMaxCarryWeight")] public static class Patch_Player_GetMaxCarryWeight { private static bool Prepare() { bool flag = AccessTools.Method(typeof(Player), "GetMaxCarryWeight", (Type[])null, (Type[])null) != null; if (!flag) { ManualLogSource log = Shopkeep.Log; if (log != null) { log.LogError((object)"Player.GetMaxCarryWeight not found - Burden scroll disabled."); } } return flag; } private static void Postfix(Player __instance, ref float __result) { if (!((Object)(object)__instance == (Object)null)) { __result += (float)ItemEffects.GetScrollUses(__instance, "Shopkeep_Burden") * 100f; } } } public class ShopkeepInteract : MonoBehaviour, Interactable, Hoverable { public bool Interact(Humanoid user, bool hold, bool alt) { if (hold) { return false; } Player val = (Player)(object)((user is Player) ? user : null); if ((Object)(object)val == (Object)null) { ManualLogSource log = Shopkeep.Log; if (log != null) { log.LogWarning((object)"Interact: user was not a Player."); } return false; } ShopUI.Show(); return true; } public bool UseItem(Humanoid user, ItemData item) { return false; } public string GetHoverText() { return "Bercans\n[E] Browse Wares"; } public string GetHoverName() { return "Bercans"; } public float GetHoverOffset() { return 0f; } } public class ShopkeepNPC { private const string BasePrefab = "piece_bone_throne"; private const string VisualPrefab = "Haldor"; public static void Register() { //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Expected O, but got Unknown //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Expected O, but got Unknown GameObject val = PrefabManager.Instance.CreateClonedPrefab("Bercans", "piece_bone_throne"); if ((Object)(object)val == (Object)null) { ManualLogSource log = Shopkeep.Log; if (log != null) { log.LogError((object)"Failed to clone 'piece_bone_throne' - Bercans will not be available. The base prefab may have been renamed or removed."); } return; } Interactable[] componentsInChildren = val.GetComponentsInChildren<Interactable>(true); foreach (Interactable val2 in componentsInChildren) { Object.DestroyImmediate((Object)(object)((val2 is Object) ? val2 : null), true); } Hoverable[] componentsInChildren2 = val.GetComponentsInChildren<Hoverable>(true); foreach (Hoverable val3 in componentsInChildren2) { Object.DestroyImmediate((Object)(object)((val3 is Object) ? val3 : null), true); } GameObject prefab = PrefabManager.Instance.GetPrefab("Haldor"); if ((Object)(object)prefab == (Object)null) { ManualLogSource log2 = Shopkeep.Log; if (log2 != null) { log2.LogError((object)"Could not find 'Haldor' prefab. Bercans will register but have no visible model."); } } else { GameObject val4 = Object.Instantiate<GameObject>(prefab, val.transform); ((Object)val4).name = "BercansVisual"; val4.transform.localPosition = new Vector3(0f, 0.3f, 0.3f); val4.transform.localRotation = Quaternion.Euler(0f, 180f, 0f); val4.transform.localScale = Vector3.one; StripVisual(val4); } ShopkeepInteract shopkeepInteract = val.AddComponent<ShopkeepInteract>(); if ((Object)(object)shopkeepInteract == (Object)null) { ManualLogSource log3 = Shopkeep.Log; if (log3 != null) { log3.LogError((object)"Failed to add ShopkeepInteract component!"); } } PieceConfig val5 = new PieceConfig(); val5.Name = "Bercans"; val5.Description = "A traveling merchant with rare wares."; val5.PieceTable = "Hammer"; val5.AddRequirement(new RequirementConfig("Coins", 1000, 0, true)); PieceManager.Instance.AddPiece(new CustomPiece(val, false, val5)); DumpPrefabDiagnostics(val); ManualLogSource log4 = Shopkeep.Log; if (log4 != null) { log4.LogInfo((object)"Bercans registered."); } } private static void StripVisual(GameObject visual) { int num = 0; Collider[] componentsInChildren = visual.GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { Object.DestroyImmediate((Object)(object)val, true); num++; } Interactable[] componentsInChildren2 = visual.GetComponentsInChildren<Interactable>(true); foreach (Interactable val2 in componentsInChildren2) { Object.DestroyImmediate((Object)(object)((val2 is Object) ? val2 : null), true); } Hoverable[] componentsInChildren3 = visual.GetComponentsInChildren<Hoverable>(true); foreach (Hoverable val3 in componentsInChildren3) { Object.DestroyImmediate((Object)(object)((val3 is Object) ? val3 : null), true); } Trader component = visual.GetComponent<Trader>(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component, true); } Character component2 = visual.GetComponent<Character>(); if ((Object)(object)component2 != (Object)null) { Object.DestroyImmediate((Object)(object)component2, true); } BaseAI component3 = visual.GetComponent<BaseAI>(); if ((Object)(object)component3 != (Object)null) { Object.DestroyImmediate((Object)(object)component3, true); } ZNetView component4 = visual.GetComponent<ZNetView>(); if ((Object)(object)component4 != (Object)null) { Object.DestroyImmediate((Object)(object)component4, true); } ZSyncTransform component5 = visual.GetComponent<ZSyncTransform>(); if ((Object)(object)component5 != (Object)null) { Object.DestroyImmediate((Object)(object)component5, true); } Rigidbody component6 = visual.GetComponent<Rigidbody>(); if ((Object)(object)component6 != (Object)null) { Object.DestroyImmediate((Object)(object)component6, true); } MonoBehaviour[] componentsInChildren4 = visual.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val4 in componentsInChildren4) { if (!((Object)(object)val4 == (Object)null)) { ((Behaviour)val4).enabled = false; } } ManualLogSource log = Shopkeep.Log; if (log != null) { log.LogInfo((object)$"Visual stripped: removed {num} collider(s)."); } } private static void DumpPrefabDiagnostics(GameObject prefab) { ManualLogSource log = Shopkeep.Log; if (log != null) { log.LogInfo((object)"--- Bercans prefab diagnostics ---"); } ManualLogSource log2 = Shopkeep.Log; if (log2 != null) { log2.LogInfo((object)$" Root layer: {prefab.layer} ({LayerMask.LayerToName(prefab.layer)})"); } ManualLogSource log3 = Shopkeep.Log; if (log3 != null) { log3.LogInfo((object)$" ShopkeepInteract present: {(Object)(object)prefab.GetComponent<ShopkeepInteract>() != (Object)null}"); } ManualLogSource log4 = Shopkeep.Log; if (log4 != null) { log4.LogInfo((object)$" Piece present: {(Object)(object)prefab.GetComponent<Piece>() != (Object)null}"); } ManualLogSource log5 = Shopkeep.Log; if (log5 != null) { log5.LogInfo((object)$" ZNetView present: {(Object)(object)prefab.GetComponent<ZNetView>() != (Object)null}"); } Collider[] componentsInChildren = prefab.GetComponentsInChildren<Collider>(true); ManualLogSource log6 = Shopkeep.Log; if (log6 != null) { log6.LogInfo((object)$" Colliders: {componentsInChildren.Length}"); } Collider[] array = componentsInChildren; foreach (Collider val in array) { ManualLogSource log7 = Shopkeep.Log; if (log7 != null) { log7.LogInfo((object)(" " + ((Object)((Component)val).gameObject).name + " layer=" + LayerMask.LayerToName(((Component)val).gameObject.layer) + " " + $"trigger={val.isTrigger} " + $"enabled={val.enabled}")); } } Hoverable[] componentsInChildren2 = prefab.GetComponentsInChildren<Hoverable>(true); ManualLogSource log8 = Shopkeep.Log; if (log8 != null) { log8.LogInfo((object)$" Hoverables: {componentsInChildren2.Length}"); } Hoverable[] array2 = componentsInChildren2; foreach (Hoverable val2 in array2) { ManualLogSource log9 = Shopkeep.Log; if (log9 != null) { log9.LogInfo((object)(" " + ((object)val2).GetType().Name)); } } ManualLogSource log10 = Shopkeep.Log; if (log10 != null) { log10.LogInfo((object)"--- end diagnostics ---"); } } } public class ShopKeyListener : MonoBehaviour { private static bool warnedAboutJoyBinding; private void Update() { if (Input.GetKeyDown((KeyCode)27)) { ShopUI.Hide(); return; } try { if (ZInput.instance != null && ZInput.GetButtonDown("JoyButtonB")) { ShopUI.Hide(); } } catch (Exception ex) { if (!warnedAboutJoyBinding) { warnedAboutJoyBinding = true; ManualLogSource log = Shopkeep.Log; if (log != null) { log.LogWarning((object)("Controller close binding unavailable: " + ex.Message)); } } } } } public class ShopUI { private struct ShopItem { public string itemName; public string displayName; public int price; public int amount; public string category; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__9_0; internal void <CreateUI>b__9_0() { Hide(); } } private static GameObject shopPanel; private static GameObject coinsLabel; private static bool isOpen = false; private static List<ShopItem> shopItems = new List<ShopItem> { new ShopItem { itemName = "CookedMeat", displayName = "Cooked Meat", price = 50, amount = 5, category = "Food" }, new ShopItem { itemName = "Bread", displayName = "Bread", price = 8, amount = 5, category = "Food" }, new ShopItem { itemName = "FishCooked", displayName = "Cooked Fish", price = 60, amount = 5, category = "Food" }, new ShopItem { itemName = "SerpentStew", displayName = "Serpent Stew", price = 250, amount = 3, category = "Food" }, new ShopItem { itemName = "LoxPie", displayName = "Lox Meat Pie", price = 300, amount = 3, category = "Food" }, new ShopItem { itemName = "BloodPudding", displayName = "Blood Pudding", price = 200, amount = 3, category = "Food" }, new ShopItem { itemName = "MeadHealthMinor", displayName = "Minor Health Mead", price = 150, amount = 1, category = "Potions" }, new ShopItem { itemName = "MeadHealthMedium", displayName = "Medium Health Mead", price = 250, amount = 1, category = "Potions" }, new ShopItem { itemName = "MeadStaminaMinor", displayName = "Minor Stamina Mead", price = 150, amount = 1, category = "Potions" }, new ShopItem { itemName = "MeadStaminaMedium", displayName = "Medium Stamina Mead", price = 250, amount = 1, category = "Potions" }, new ShopItem { itemName = "MeadPoisonResist", displayName = "Poison Resistance Mead", price = 300, amount = 1, category = "Potions" }, new ShopItem { itemName = "MeadFrostResist", displayName = "Frost Resistance Mead", price = 300, amount = 1, category = "Potions" }, new ShopItem { itemName = "MysteryBox", displayName = "Mystery Box", price = 500, amount = 1, category = "Special" }, new ShopItem { itemName = "ScrollOfVitality", displayName = "Scroll of Vitality (+25 Health)", price = 2000, amount = 1, category = "Special" }, new ShopItem { itemName = "ScrollOfEndurance", displayName = "Scroll of Endurance (+25 Stamina)", price = 2000, amount = 1, category = "Special" }, new ShopItem { itemName = "ScrollOfBurden", displayName = "Scroll of Burden (+100 Carry Weight)", price = 2000, amount = 1, category = "Special" } }; public static IEnumerable<string> GetPrefabNames() { foreach (ShopItem item in shopItems) { if (!IsSpecial(item.itemName)) { yield return item.itemName; } } } private static bool IsSpecial(string itemName) { string key; string label; return itemName == "MysteryBox" || ItemEffects.IsScroll(itemName, out key, out label); } public static void Show() { if (isOpen) { Hide(); return; } CreateUI(); isOpen = true; GUIManager.BlockInput(true); } public static void Hide() { if ((Object)(object)shopPanel != (Object)null) { Object.Destroy((Object)(object)shopPanel); shopPanel = null; } coinsLabel = null; isOpen = false; GUIManager.BlockInput(false); } private static void CreateUI() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Expected O, but got Unknown //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Expected O, but got Unknown //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Expected O, but got Unknown //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_0345: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Expected O, but got Unknown //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Expected O, but got Unknown //IL_0435: Unknown result type (might be due to invalid IL or missing references) //IL_0444: Unknown result type (might be due to invalid IL or missing references) //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_0469: Unknown result type (might be due to invalid IL or missing references) //IL_046f: Unknown result type (might be due to invalid IL or missing references) shopPanel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(-400f, 0f), 1400f, 1500f, true); shopPanel.AddComponent<ShopKeyListener>(); GUIManager.Instance.CreateText("Free Gold Market", shopPanel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -60f), GUIManager.Instance.AveriaSerifBold, 36, GUIManager.Instance.ValheimOrange, true, Color.black, 1200f, 60f, false); coinsLabel = GUIManager.Instance.CreateText($"Your Coins: {GetPlayerCoins()}", shopPanel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -110f), GUIManager.Instance.AveriaSerifBold, 24, Color.yellow, true, Color.black, 1200f, 40f, false); GameObject val = GUIManager.Instance.CreateButton("X", shopPanel.transform, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-25f, -25f), 40f, 40f); ButtonClickedEvent onClick = val.GetComponent<Button>().onClick; object obj = <>c.<>9__9_0; if (obj == null) { UnityAction val2 = delegate { Hide(); }; <>c.<>9__9_0 = val2; obj = (object)val2; } ((UnityEvent)onClick).AddListener((UnityAction)obj); GameObject val3 = new GameObject("ScrollView"); val3.transform.SetParent(shopPanel.transform, false); RectTransform val4 = val3.AddComponent<RectTransform>(); val4.anchorMin = new Vector2(0.5f, 0f); val4.anchorMax = new Vector2(0.5f, 1f); val4.offsetMin = new Vector2(-670f, 10f); val4.offsetMax = new Vector2(670f, -160f); ScrollRect val5 = val3.AddComponent<ScrollRect>(); GameObject val6 = new GameObject("Viewport"); val6.transform.SetParent(val3.transform, false); RectTransform val7 = val6.AddComponent<RectTransform>(); val7.anchorMin = Vector2.zero; val7.anchorMax = Vector2.one; val7.offsetMin = Vector2.zero; val7.offsetMax = Vector2.zero; val6.AddComponent<Mask>().showMaskGraphic = false; ((Graphic)val6.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.1f); GameObject val8 = new GameObject("Content"); val8.transform.SetParent(val6.transform, false); RectTransform val9 = val8.AddComponent<RectTransform>(); val9.anchorMin = new Vector2(0f, 1f); val9.anchorMax = new Vector2(1f, 1f); val9.pivot = new Vector2(0.5f, 1f); val9.offsetMin = Vector2.zero; val9.offsetMax = Vector2.zero; VerticalLayoutGroup val10 = val8.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val10).spacing = 15f; ((LayoutGroup)val10).padding = new RectOffset(5, 5, 5, 5); ContentSizeFitter val11 = val8.AddComponent<ContentSizeFitter>(); val11.verticalFit = (FitMode)2; val5.viewport = val7; val5.content = val9; val5.horizontal = false; val5.vertical = true; string text = ""; foreach (ShopItem shopItem in shopItems) { if (shopItem.category != text) { text = shopItem.category; GUIManager.Instance.CreateText("-- " + shopItem.category + " --", val8.transform, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(10f, 0f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 1200f, 40f, false); } CreateItemRow(val8.transform, shopItem); } } private static void CreateItemRow(Transform parent, ShopItem item) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Expected O, but got Unknown GameObject val = new GameObject("Row_" + item.itemName); val.transform.SetParent(parent, false); RectTransform val2 = val.AddComponent<RectTransform>(); val2.sizeDelta = new Vector2(1300f, 60f); HorizontalLayoutGroup val3 = val.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val3).spacing = 0f; ((LayoutGroup)val3).childAlignment = (TextAnchor)3; ((LayoutGroup)val3).padding = new RectOffset(10, 10, 2, 2); ((HorizontalOrVerticalLayoutGroup)val3).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)val3).childForceExpandHeight = false; GameObject val4 = GUIManager.Instance.CreateText($"{item.displayName} x{item.amount}", val.transform, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), Vector2.zero, GUIManager.Instance.AveriaSerifBold, 22, Color.white, true, Color.black, 850f, 50f, false); LayoutElement val5 = val4.AddComponent<LayoutElement>(); val5.minWidth = 850f; val5.preferredWidth = 850f; val5.minHeight = 50f; val5.preferredHeight = 50f; GameObject val6 = GUIManager.Instance.CreateText($"{item.price} coins", val.transform, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), Vector2.zero, GUIManager.Instance.AveriaSerifBold, 22, Color.yellow, true, Color.black, 250f, 50f, false); LayoutElement val7 = val6.AddComponent<LayoutElement>(); val7.minWidth = 250f; val7.preferredWidth = 250f; val7.minHeight = 50f; val7.preferredHeight = 50f; ShopItem capturedItem = item; GameObject val8 = GUIManager.Instance.CreateButton("Buy", val.transform, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), Vector2.zero, 120f, 55f); StyleLabel(val8, Color.white, 20); LayoutElement val9 = val8.AddComponent<LayoutElement>(); val9.minWidth = 120f; val9.preferredWidth = 120f; val9.minHeight = 55f; val9.preferredHeight = 55f; ((UnityEvent)val8.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { BuyItem(capturedItem); }); } private static void StyleLabel(GameObject go, Color color, int fontSize) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)go == (Object)null) { return; } TMP_Text componentInChildren = go.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { ((Graphic)componentInChildren).color = color; componentInChildren.fontSize = fontSize; return; } Text componentInChildren2 = go.GetComponentInChildren<Text>(true); if ((Object)(object)componentInChildren2 != (Object)null) { ((Graphic)componentInChildren2).color = color; componentInChildren2.fontSize = fontSize; } } private static void SetLabel(GameObject go, string text) { if ((Object)(object)go == (Object)null) { return; } TMP_Text componentInChildren = go.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = text; return; } Text componentInChildren2 = go.GetComponentInChildren<Text>(true); if ((Object)(object)componentInChildren2 != (Object)null) { componentInChildren2.text = text; } } private static void RefreshCoins() { SetLabel(coinsLabel, $"Your Coins: {GetPlayerCoins()}"); } private static void BuyItem(ShopItem item) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } bool flag = item.itemName == "MysteryBox"; string key; string label; bool flag2 = ItemEffects.IsScroll(item.itemName, out key, out label); if (flag2 && !ItemEffects.CanApplyScroll(localPlayer, key)) { Message("You have already reached the limit for Scroll of " + label + "!"); return; } if (!flag && !flag2 && !ItemEffects.CanGiveItem(localPlayer, item.itemName, item.amount, out var error)) { Message("Cannot buy " + item.displayName + ": " + error); return; } int playerCoins = GetPlayerCoins(); if (playerCoins < item.price) { Message("Not enough coins!"); return; } if (!RemoveCoins(localPlayer, item.price)) { Message("Payment failed - nothing was charged."); return; } if (flag) { ItemEffects.ApplyMysteryBox(localPlayer); } else if (flag2) { if (key == "Shopkeep_Vitality") { ItemEffects.ApplyScrollOfVitality(localPlayer); } else if (key == "Shopkeep_Endurance") { ItemEffects.ApplyScrollOfEndurance(localPlayer); } else { ItemEffects.ApplyScrollOfBurden(localPlayer); } } else { ItemEffects.TryGiveItem(localPlayer, item.itemName, item.amount); Message("Purchased " + item.displayName + "!"); } RefreshCoins(); } private static bool RemoveCoins(Player player, int price) { Inventory inventory = ((Humanoid)player).GetInventory(); int num = price; List<ItemData> list = new List<ItemData>(); foreach (ItemData allItem in inventory.GetAllItems()) { if (num <= 0) { break; } if (IsCoins(allItem)) { if (num >= allItem.m_stack) { num -= allItem.m_stack; list.Add(allItem); } else { allItem.m_stack -= num; num = 0; } } } if (num > 0) { return false; } foreach (ItemData item in list) { inventory.RemoveItem(item); } return true; } private static bool IsCoins(ItemData item) { if (item == null) { return false; } if ((Object)(object)item.m_dropPrefab != (Object)null && ((Object)item.m_dropPrefab).name == "Coins") { return true; } if (item.m_shared != null && item.m_shared.m_name == "$item_coins") { return true; } return false; } private static int GetPlayerCoins() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return 0; } int num = 0; foreach (ItemData allItem in ((Humanoid)localPlayer).GetInventory().GetAllItems()) { if (IsCoins(allItem)) { num += allItem.m_stack; } } return num; } private static void Message(string text) { if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, text, 0, (Sprite)null, false, true); } } }