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 TreasureMaps v1.0.4
TreasureMaps.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using ConditionalConfigSync; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Splatform; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("TreasureMaps")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("TreasureMaps")] [assembly: AssemblyTitle("TreasureMaps")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace TreasureMaps { internal sealed class BiomeDef { public Biome Biome; public string Key; public string NameToken; public int Tier; public string[] ChestKeywords; public string[] IdolKeywords; public HuntKind[] Kinds; public ConfigEntry<bool> Enabled; public ConfigEntry<int> Price; public ConfigEntry<int> ChestStock; public ConfigEntry<int> GuardianStock; public ConfigEntry<int> FishingStock; public ConfigEntry<int> ShipwreckStock; public ConfigEntry<int> BountyStock; public ConfigEntry<int> BountyReward; public ConfigEntry<string> RequiredKey; public ConfigEntry<string> Guardians; public ConfigEntry<string> ChestPrefabs; public ConfigEntry<string> DungeonLocations; public ConfigEntry<string> DungeonBosses; public ConfigEntry<string> BountyCreatures; public bool IsOcean => (int)Biome == 256; public string DisplayName => Localization.instance.Localize(NameToken); } internal static class BiomeCatalog { internal static readonly List<BiomeDef> All = new List<BiomeDef>(); private static readonly Dictionary<Biome, List<GameObject>> guardianCache = new Dictionary<Biome, List<GameObject>>(); private static readonly Dictionary<Biome, GameObject> chestCache = new Dictionary<Biome, GameObject>(); private static readonly HashSet<Faction> ExcludedFactions = new HashSet<Faction> { (Faction)0, (Faction)6, (Faction)8, (Faction)11, (Faction)12, (Faction)10 }; private static readonly Dictionary<Biome, string> FallbackGuardians = new Dictionary<Biome, string>(); internal static void BindConfig(TreasureMapsPlugin plugin) { All.Clear(); AddOcean(plugin); Add(plugin, (Biome)1, "Meadows", "$tm_biome_meadows", 1, 100, "", "TreasureChest_meadows", "Greyling,Boar,Neck", new string[1] { "meadows" }, new string[1] { "wood" }, "Boar,Neck,Greydwarf", ""); Add(plugin, (Biome)8, "BlackForest", "$tm_biome_blackforest", 2, 250, "defeated_eikthyr", "TreasureChest_blackforest", "Greydwarf_Elite,Greydwarf_Shaman,Troll,Skeleton", new string[2] { "blackforest", "forest" }, new string[1] { "bronze" }, "Greydwarf_Elite,Greydwarf_Shaman,Troll", "Skeleton_Poison,Troll,Ghost"); Add(plugin, (Biome)2, "Swamp", "$tm_biome_swamp", 3, 450, "defeated_gdking", "TreasureChest_swamp", "Draugr,Draugr_Elite,Wraith,Abomination", new string[1] { "swamp" }, new string[1] { "iron" }, "Draugr_Elite,Abomination,Wraith", "Draugr_Elite,BlobElite"); Add(plugin, (Biome)4, "Mountain", "$tm_biome_mountain", 4, 700, "defeated_bonemass", "TreasureChest_mountains", "Wolf,Fenring,StoneGolem,Ulv", new string[1] { "mountain" }, new string[1] { "silver" }, "Wolf,Fenring,StoneGolem", "Fenring_Cultist,Ulv"); Add(plugin, (Biome)16, "Plains", "$tm_biome_plains", 5, 1000, "defeated_dragon", "TreasureChest_heath,TreasureChest_plains_stone", "Goblin,GoblinBrute,GoblinShaman,Lox", new string[2] { "plains", "heath" }, new string[1] { "blackmetal" }, "GoblinBrute,GoblinShaman,Lox", ""); Add(plugin, (Biome)512, "Mistlands", "$tm_biome_mistlands", 6, 1400, "defeated_goblinking", "TreasureChest_dvergrtower,TreasureChest_dvergrtown", "Seeker,SeekerBrute", new string[2] { "mistlands", "dvergr" }, new string[2] { "blackmarble", "marble" }, "SeekerBrute,Seeker", "SeekerBrute,Seeker"); Add(plugin, (Biome)32, "AshLands", "$tm_biome_ashlands", 7, 1900, "defeated_queen", "TreasureChest_charredfortress", "Charred_Melee,Charred_Archer,Charred_Mage,Morgen,Asksvin", new string[2] { "ashland", "charred" }, new string[1] { "flametal" }, "Charred_Melee,Charred_Mage,Morgen,Asksvin", "Morgen"); Add(plugin, (Biome)64, "DeepNorth", "$tm_biome_deepnorth", 8, 2500, "defeated_fader", "", "", new string[3] { "deepnorth", "north", "jotun" }, new string[1] { "bloodgold" }, "", ""); } private static void Add(TreasureMapsPlugin plugin, Biome biome, string key, string token, int tier, int price, string bossKey, string chests, string fallbackGuardians, string[] chestKeywords, string[] idolKeywords, string bountyCreatures, string bountyDungeonCreatures) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) string section = "Biome " + tier + " - " + key; BiomeDef biomeDef = new BiomeDef(); biomeDef.Biome = biome; biomeDef.Key = key; biomeDef.NameToken = token; biomeDef.Tier = tier; biomeDef.ChestKeywords = chestKeywords; biomeDef.IdolKeywords = idolKeywords; biomeDef.Kinds = new HuntKind[3] { HuntKind.Chest, HuntKind.Guardian, HuntKind.Fishing }; BiomeDef biomeDef2 = biomeDef; biomeDef2.Enabled = plugin.Admin(section, "Enabled", value: true, "Sell treasure maps for this biome."); biomeDef2.Price = plugin.Admin(section, "Price", price, "Coin price of this biome's Treasure Chest map. Guardian Hunt and Fishing Treasure maps cost this times their price multipliers. Harder biomes cost more by default.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100000)); biomeDef2.ChestStock = plugin.Admin(section, "ChestMapStock", 1, "Treasure Chest maps of this biome Hildir has per restock period (shared by everyone). 0 = not sold.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50)); biomeDef2.GuardianStock = plugin.Admin(section, "GuardianMapStock", 1, "Guardian Hunt maps of this biome Hildir has per restock period (shared by everyone). 0 = not sold.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50)); biomeDef2.FishingStock = plugin.Admin(section, "FishingMapStock", 1, "Fishing Treasure maps of this biome Hildir has per restock period (shared by everyone). 0 = not sold.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50)); biomeDef2.RequiredKey = plugin.Admin(section, "RequiredKey", bossKey, "Global or player key needed before this map is sold, usually the previous biome's boss. Empty = always available."); biomeDef2.Guardians = plugin.Admin(section, "Guardians", "", "Comma-separated creature prefabs used as guardians. Empty = use the creatures that naturally spawn in this biome. If none are found, these are used: " + fallbackGuardians); biomeDef2.ChestPrefabs = plugin.Admin(section, "ChestPrefabs", chests, "Comma-separated chest prefabs (first one found is used). The chest's own loot table is the biome loot. Empty or missing = auto-detect a TreasureChest prefab for this biome."); biomeDef2.BountyStock = plugin.Admin(section, "BountyMapStock", 1, "Free bounties for this biome on the Bounties board per bounty refresh (shared by everyone). 0 = no bounties for this biome.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50)); biomeDef2.BountyReward = plugin.Admin(section, "BountyReward", DefaultBountyReward(tier), "Coins Hildir pays each player who turns in a killed bounty of this biome. Harder biomes pay more by default.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100000)); biomeDef2.DungeonLocations = plugin.Admin(section, "DungeonLocations", DefaultDungeons(key), "Comma-separated location name prefixes of this biome's dungeons. Bounties can lead inside one of them (see BountyDungeonChance). Empty = this biome's bounties are always outdoors."); biomeDef2.BountyCreatures = plugin.Admin(section, "BountyCreatures", bountyCreatures, "Comma-separated creature prefabs that can be this biome's bounty target outdoors. Empty = use this biome's Guardians."); biomeDef2.DungeonBosses = plugin.Admin(section, "BountyDungeonCreatures", bountyDungeonCreatures, "Comma-separated creature prefabs that can be this biome's bounty target inside a dungeon. Creatures from this list that live in the dungeon the bounty is in are picked first. Empty = the toughest creature that naturally spawns in that dungeon."); biomeDef2.Guardians.SettingChanged += delegate { ClearCaches(); }; biomeDef2.ChestPrefabs.SettingChanged += delegate { ClearCaches(); }; FallbackGuardians[biome] = fallbackGuardians; All.Add(biomeDef2); } private static void AddOcean(TreasureMapsPlugin plugin) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) BiomeDef biomeDef = new BiomeDef(); biomeDef.Biome = (Biome)256; biomeDef.Key = "Ocean"; biomeDef.NameToken = "$tm_biome_ocean"; biomeDef.Tier = 0; biomeDef.ChestKeywords = new string[1] { "shipwreck" }; biomeDef.IdolKeywords = new string[0]; biomeDef.Kinds = new HuntKind[1] { HuntKind.Shipwreck }; BiomeDef biomeDef2 = biomeDef; biomeDef2.Enabled = plugin.Admin("Biome 0 - Ocean", "Enabled", value: true, "Sell Derelict Karve maps. They're always available, no boss needed."); biomeDef2.Price = plugin.Admin("Biome 0 - Ocean", "Price", 500, "Coin price of a Derelict Karve map.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100000)); biomeDef2.ShipwreckStock = plugin.Admin("Biome 0 - Ocean", "ShipwreckMapStock", 1, "Derelict Karve maps Hildir has per restock period (shared by everyone). 0 = not sold.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 50)); biomeDef2.RequiredKey = plugin.Admin("Biome 0 - Ocean", "RequiredKey", "", "Global or player key needed before this map is sold. Empty = always available."); biomeDef2.Guardians = plugin.Admin("Biome 0 - Ocean", "Guardians", "Serpent", "Comma-separated sea creature prefabs that guard the derelict karve."); biomeDef2.Guardians.SettingChanged += delegate { ClearCaches(); }; FallbackGuardians[biomeDef2.Biome] = "Serpent"; All.Add(biomeDef2); } private static int DefaultBountyReward(int tier) { int[] array = new int[8] { 100, 200, 350, 500, 750, 1000, 1400, 1800 }; return array[Mathf.Clamp(tier, 1, array.Length) - 1]; } private static string DefaultDungeons(string key) { return key switch { "BlackForest" => "Crypt,TrollCave", "Swamp" => "SunkenCrypt", "Mountain" => "MountainCave", "Mistlands" => "Mistlands_DvergrTownEntrance", "AshLands" => "MorgenHole", _ => "", }; } internal static bool HasDungeons(BiomeDef def) { if (def != null && def.DungeonLocations != null) { return SplitList(def.DungeonLocations.Value).Count > 0; } return false; } internal static int EffectiveTier(BiomeDef def) { if (def == null) { return 1; } if (!def.IsOcean) { return def.Tier; } Player localPlayer = Player.m_localPlayer; int num = 1; foreach (BiomeDef item in All) { if (!item.IsOcean && item.Tier > num && IsUnlocked(item, localPlayer)) { num = item.Tier; } } return num; } internal static BiomeDef Get(Biome biome) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) foreach (BiomeDef item in All) { if (item.Biome == biome) { return item; } } return null; } internal static void ClearCaches() { guardianCache.Clear(); chestCache.Clear(); IdolCatalog.Clear(); GemCatalog.Clear(); } internal static List<string> SplitList(string raw) { List<string> list = new List<string>(); if (string.IsNullOrEmpty(raw)) { return list; } string[] array = raw.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0) { list.Add(text); } } return list; } internal static int PriceOf(BiomeDef def, HuntKind kind) { return kind switch { HuntKind.Guardian => Mathf.RoundToInt((float)def.Price.Value * TreasureMapsPlugin.GuardianPriceMultiplier.Value), HuntKind.Fishing => Mathf.RoundToInt((float)def.Price.Value * TreasureMapsPlugin.FishingPriceMultiplier.Value), HuntKind.Bounty => 0, _ => def.Price.Value, }; } internal static int StockOf(BiomeDef def, HuntKind kind) { switch (kind) { case HuntKind.Guardian: if (def.GuardianStock == null) { return 0; } return def.GuardianStock.Value; case HuntKind.Fishing: if (def.FishingStock == null) { return 0; } return def.FishingStock.Value; case HuntKind.Shipwreck: if (def.ShipwreckStock == null) { return 0; } return def.ShipwreckStock.Value; case HuntKind.Bounty: if (def.BountyStock == null) { return 0; } return def.BountyStock.Value; default: if (def.ChestStock == null) { return 0; } return def.ChestStock.Value; } } internal static bool Offers(BiomeDef def, HuntKind kind) { if (kind == HuntKind.Bounty) { if (!def.IsOcean && def.BountyStock != null) { return def.BountyStock.Value > 0; } return false; } return Array.IndexOf(def.Kinds, kind) >= 0; } internal static bool IsUnlocked(BiomeDef def, Player player) { string text = (def.RequiredKey.Value ?? "").Trim(); if (text.Length == 0) { return true; } if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey(text)) { return true; } if ((Object)(object)player != (Object)null) { return ((Humanoid)player).HaveUniqueKey(text); } return false; } internal static GameObject PickGuardian(Biome biome) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) List<GameObject> guardians = GetGuardians(biome); if (guardians.Count == 0) { return null; } return guardians[Random.Range(0, guardians.Count)]; } internal unsafe static List<GameObject> GetGuardians(Biome biome) { //IL_0005: 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) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) if (guardianCache.TryGetValue(biome, out var value)) { return value; } List<GameObject> list = new List<GameObject>(); BiomeDef biomeDef = Get(biome); if ((Object)(object)ZNetScene.instance == (Object)null) { return list; } if (biomeDef != null) { AddNamedCreatures(list, biomeDef.Guardians.Value); } if (list.Count == 0) { AddSpawnSystemCreatures(list, biome); } if (list.Count == 0 && FallbackGuardians.TryGetValue(biome, out var value2)) { AddNamedCreatures(list, value2); } List<string> list2 = new List<string>(); foreach (GameObject item in list) { list2.Add(((Object)item).name); } Debug.Log((object)("[TreasureMaps] Guardians for " + ((object)(*(Biome*)(&biome))/*cast due to .constrained prefix*/).ToString() + ": " + ((list2.Count > 0) ? string.Join(", ", list2.ToArray()) : "(none, chests only)"))); guardianCache[biome] = list; return list; } private static void AddNamedCreatures(List<GameObject> result, string raw) { foreach (string item in SplitList(raw)) { GameObject prefab = ZNetScene.instance.GetPrefab(item); if ((Object)(object)prefab != (Object)null && (Object)(object)prefab.GetComponent<Character>() != (Object)null && !result.Contains(prefab)) { result.Add(prefab); } } } private static void AddSpawnSystemCreatures(List<GameObject> result, Biome biome) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) HashSet<string> hashSet = new HashSet<string>(SplitList(TreasureMapsPlugin.GuardianBlacklist.Value), StringComparer.OrdinalIgnoreCase); foreach (SpawnSystemList item2 in SpawnLists()) { if ((Object)(object)item2 == (Object)null || item2.m_spawners == null) { continue; } foreach (SpawnData spawner in item2.m_spawners) { if (spawner == null || !spawner.m_enabled || spawner.m_devDisabled || (Object)(object)spawner.m_prefab == (Object)null || (spawner.m_biome & biome) == 0 || ReachesHarderBiome(spawner.m_biome, biome) || spawner.m_maxAltitude < 0f || spawner.m_minOceanDepth > 0f || !spawner.m_outsideLava || !string.IsNullOrEmpty(spawner.m_requiredPersistentEvent) || hashSet.Contains(((Object)spawner.m_prefab).name)) { continue; } Character component = spawner.m_prefab.GetComponent<Character>(); if (!((Object)(object)component == (Object)null) && !component.m_boss && !component.m_flying && !ExcludedFactions.Contains(component.m_faction) && !((Object)(object)spawner.m_prefab.GetComponent<MonsterAI>() == (Object)null)) { GameObject item = ZNetScene.instance.GetPrefab(((Object)spawner.m_prefab).name) ?? spawner.m_prefab; if (!result.Contains(item)) { result.Add(item); } } } } } private static bool ReachesHarderBiome(Biome mask, Biome biome) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_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) BiomeDef biomeDef = Get(biome); if (biomeDef == null) { return false; } foreach (BiomeDef item in All) { if (!item.IsOcean && item.Biome != biome && (mask & item.Biome) != 0 && item.Tier > biomeDef.Tier) { return true; } } return false; } private static IEnumerable<SpawnSystemList> SpawnLists() { HashSet<SpawnSystemList> seen = new HashSet<SpawnSystemList>(); ZoneSystem instance = ZoneSystem.instance; SpawnSystem val = (((Object)(object)instance != (Object)null && (Object)(object)instance.m_zoneCtrlPrefab != (Object)null) ? instance.m_zoneCtrlPrefab.GetComponent<SpawnSystem>() : null); if ((Object)(object)val != (Object)null && val.m_spawnLists != null) { foreach (SpawnSystemList spawnList in val.m_spawnLists) { if ((Object)(object)spawnList != (Object)null && seen.Add(spawnList)) { yield return spawnList; } } } if (seen.Count > 0) { yield break; } SpawnSystemList[] array = Resources.FindObjectsOfTypeAll<SpawnSystemList>(); foreach (SpawnSystemList val2 in array) { if ((Object)(object)val2 != (Object)null && seen.Add(val2)) { yield return val2; } } } internal unsafe static GameObject GetChestPrefab(Biome biome) { //IL_0005: 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_01cd: Unknown result type (might be due to invalid IL or missing references) if (chestCache.TryGetValue(biome, out var value) && (Object)(object)value != (Object)null) { return value; } if ((Object)(object)ZNetScene.instance == (Object)null) { return null; } BiomeDef biomeDef = Get(biome); GameObject val = null; if (biomeDef != null) { foreach (string item in SplitList((biomeDef.ChestPrefabs != null) ? biomeDef.ChestPrefabs.Value : "")) { GameObject prefab = ZNetScene.instance.GetPrefab(item); if ((Object)(object)prefab != (Object)null && (Object)(object)prefab.GetComponentInChildren<Container>(true) != (Object)null) { val = prefab; break; } } if ((Object)(object)val == (Object)null) { foreach (GameObject prefab2 in ZNetScene.instance.m_prefabs) { if ((Object)(object)prefab2 == (Object)null) { continue; } string text = ((Object)prefab2).name.ToLowerInvariant(); if (!text.StartsWith("treasurechest")) { continue; } bool flag = false; string[] chestKeywords = biomeDef.ChestKeywords; foreach (string value2 in chestKeywords) { if (text.Contains(value2)) { flag = true; break; } } if (flag && (Object)(object)prefab2.GetComponentInChildren<Container>(true) != (Object)null) { val = prefab2; break; } } } } if ((Object)(object)val == (Object)null) { val = ZNetScene.instance.GetPrefab("TreasureChest_meadows"); } if ((Object)(object)val == (Object)null) { val = ZNetScene.instance.GetPrefab("piece_chest_wood"); } if ((Object)(object)val != (Object)null) { Debug.Log((object)("[TreasureMaps] Chest for " + ((object)(*(Biome*)(&biome))/*cast due to .constrained prefix*/).ToString() + ": " + ((Object)val).name)); } chestCache[biome] = val; return val; } internal static Biome LootBiome(Biome biome) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) BiomeDef biomeDef = Get(biome); if (biomeDef == null || !biomeDef.IsOcean) { return biome; } int num = EffectiveTier(biomeDef); foreach (BiomeDef item in All) { if (!item.IsOcean && item.Tier == num) { return item.Biome; } } return (Biome)1; } internal static DropTable GetChestLootTable(Biome biome) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) GameObject chestPrefab = GetChestPrefab(LootBiome(biome)); Container val = (((Object)(object)chestPrefab != (Object)null) ? chestPrefab.GetComponentInChildren<Container>(true) : null); if (!((Object)(object)val != (Object)null)) { return null; } return val.m_defaultItems; } } internal static class CommandOutput { internal static void Print(string text) { if ((Object)(object)Console.instance != (Object)null) { Console.instance.Print(text); } else { Debug.Log((object)("[TreasureMaps] " + text)); } } internal static BiomeDef FindBiome(string key) { foreach (BiomeDef item in BiomeCatalog.All) { if (item.Key.Equals(key, StringComparison.OrdinalIgnoreCase)) { return item; } } return null; } internal static List<string> BiomeKeys() { List<string> list = new List<string>(); foreach (BiomeDef item in BiomeCatalog.All) { list.Add(item.Key); } return list; } } internal class ListMapsCommand : ConsoleCommand { public override string Name => "treasuremaps_list"; public override string Help => "Lists every treasure hunt in the world. * marks the ones on your map."; public override void Run(string[] args) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) TreasureHuntManager instance = TreasureHuntManager.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null || instance.Hunts.Count == 0) { CommandOutput.Print("No treasure hunts."); return; } _ = TreasureHuntManager.LocalId; for (int i = 0; i < instance.Hunts.Count; i++) { Hunt hunt = instance.Hunts[i]; CommandOutput.Print(string.Format(CultureInfo.InvariantCulture, "{0}{1}: {2} {3}, {4}, owner {5}", instance.OnMap(hunt) ? "*" : " ", i, hunt.Biome, hunt.Kind.ToString().ToLowerInvariant(), hunt.State, string.IsNullOrEmpty(hunt.OwnerName) ? "?" : hunt.OwnerName)); } } } internal class JoinMapCommand : ConsoleCommand { public override string Name => "treasuremaps_map"; public override string Help => "Adds a treasure hunt's marker to your map, or takes it off: treasuremaps_map <index> (see treasuremaps_list)"; public override void Run(string[] args) { Hunt hunt = PickHunt(args, ((ConsoleCommand)this).Help); if (hunt != null) { bool flag = !TreasureHuntManager.Instance.OnMap(hunt); TreasureHuntManager.Instance.SetOnMap(hunt, flag); CommandOutput.Print(flag ? "Marker added to your map." : "Marker removed from your map."); } } internal static Hunt PickHunt(string[] args, string help) { TreasureHuntManager instance = TreasureHuntManager.Instance; if ((Object)(object)instance == (Object)null || args.Length == 0 || !int.TryParse(args[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) || result < 0 || result >= instance.Hunts.Count) { CommandOutput.Print(help); return null; } return instance.Hunts[result]; } } internal class LeaveMapCommand : ConsoleCommand { public override string Name => "treasuremaps_abandon"; public override string Help => "Abandons a treasure map or bounty you took, removing it for everyone: treasuremaps_abandon <index|all>"; public override void Run(string[] args) { TreasureHuntManager instance = TreasureHuntManager.Instance; if ((Object)(object)instance == (Object)null) { return; } if (args.Length != 0 && args[0].Equals("all", StringComparison.OrdinalIgnoreCase)) { long localId = TreasureHuntManager.LocalId; foreach (Hunt item in new List<Hunt>(instance.Hunts)) { if (item.Owner == localId) { TreasureHuntManager.AbandonHunt(item); } } CommandOutput.Print("Abandoning all your treasure hunts."); return; } Hunt hunt = JoinMapCommand.PickHunt(args, ((ConsoleCommand)this).Help); if (hunt != null) { if (hunt.Owner != TreasureHuntManager.LocalId) { CommandOutput.Print("You can only abandon maps and bounties you took yourself."); return; } TreasureHuntManager.AbandonHunt(hunt); CommandOutput.Print("Abandoning the hunt."); } } public override List<string> CommandOptionList() { return new List<string> { "all" }; } } internal class RestockCommand : ConsoleCommand { public override string Name => "treasuremaps_restock"; public override string Help => "Refills Hildir's treasure map stock for everyone (cheat)."; public override bool IsCheat => true; public override void Run(string[] args) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write("restock"); TreasureHuntManager.SendAdmin(val); CommandOutput.Print("Treasure map stock refilled."); } } internal class ClearHuntsCommand : ConsoleCommand { public override string Name => "treasuremaps_clear"; public override string Help => "Removes every treasure hunt in the world (cheat)."; public override bool IsCheat => true; public override void Run(string[] args) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write("clear"); TreasureHuntManager.SendAdmin(val); CommandOutput.Print("All treasure hunts removed."); } } internal class GiveMapCommand : ConsoleCommand { public override string Name => "treasuremaps_give"; public override string Help => "Gives you a free treasure map (cheat): treasuremaps_give <biome> [chest|guardian|fishing|bounty|shipwreck]"; public override bool IsCheat => true; public override void Run(string[] args) { //IL_0094: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } BiomeDef biomeDef = ((args.Length != 0) ? CommandOutput.FindBiome(args[0]) : null); if (biomeDef == null) { CommandOutput.Print(((ConsoleCommand)this).Help + " Biomes: " + string.Join(", ", CommandOutput.BiomeKeys().ToArray())); return; } HuntKind kind = biomeDef.Kinds[Random.Range(0, biomeDef.Kinds.Length)]; if (args.Length > 1 && (!HuntKinds.TryParse(args[1], out kind) || !BiomeCatalog.Offers(biomeDef, kind))) { CommandOutput.Print(((ConsoleCommand)this).Help + " Ocean only has shipwreck maps; the other biomes have chest, guardian, fishing and bounty maps."); return; } ZPackage val = new ZPackage(); val.Write("give"); val.Write(biomeDef.Key); val.Write((int)kind); val.Write(localPlayer.GetPlayerID()); val.Write(localPlayer.GetPlayerName()); TreasureHuntManager.SendAdmin(val); CommandOutput.Print("Requested a " + biomeDef.Key + " " + kind.ToString().ToLowerInvariant() + " map. Use treasuremaps_list to see it."); } public override List<string> CommandOptionList() { return CommandOutput.BiomeKeys(); } } internal static class TreasureStats { private const string Prefix = "TreasureMaps_Stat_"; private const string Heading = "#ffc864"; private static string KeyFor(HuntKind kind) { return kind switch { HuntKind.Guardian => "Guardians", HuntKind.Fishing => "Fishing", HuntKind.Shipwreck => "Shipwrecks", HuntKind.Bounty => "Bounties", _ => "Chests", }; } internal static int Get(HuntKind kind) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || localPlayer.m_customData == null) { return 0; } if (!localPlayer.m_customData.TryGetValue("TreasureMaps_Stat_" + KeyFor(kind), out var value) || !int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return 0; } return result; } internal static void Add(HuntKind kind) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && localPlayer.m_customData != null) { localPlayer.m_customData["TreasureMaps_Stat_" + KeyFor(kind)] = (Get(kind) + 1).ToString(CultureInfo.InvariantCulture); } } private static string L(string token, params string[] args) { return Localization.instance.Localize(token, args); } internal static string BuildText() { StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("<color=").Append("#ffc864").Append("><b>") .Append(L("$tm_codex_stats")) .Append("</b></color>\n"); StatLine(stringBuilder, "$tm_codex_chests", HuntKind.Chest); StatLine(stringBuilder, "$tm_codex_guardians", HuntKind.Guardian); StatLine(stringBuilder, "$tm_codex_fishing", HuntKind.Fishing); StatLine(stringBuilder, "$tm_codex_shipwrecks", HuntKind.Shipwreck); StatLine(stringBuilder, "$tm_codex_bounties", HuntKind.Bounty); List<Hunt> list = new List<Hunt>(); List<Hunt> list2 = new List<Hunt>(); TreasureHuntManager instance = TreasureHuntManager.Instance; long localId = TreasureHuntManager.LocalId; if ((Object)(object)instance != (Object)null && localId != 0L) { foreach (Hunt hunt in instance.Hunts) { if (hunt.Bounty) { list2.Add(hunt); } else { list.Add(hunt); } } } HuntSection(stringBuilder, "$tm_codex_maps", "$tm_codex_none_maps", list, localId); HuntSection(stringBuilder, "$tm_codex_active_bounties", "$tm_codex_none_bounties", list2, localId); return stringBuilder.ToString(); } private static void StatLine(StringBuilder text, string token, HuntKind kind) { text.Append(L(token)).Append(": <color=orange>").Append(Get(kind).ToString(CultureInfo.InvariantCulture)) .Append("</color>\n"); } private static void HuntSection(StringBuilder text, string header, string none, List<Hunt> hunts, long localId) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) text.Append("\n<color=").Append("#ffc864").Append("><b>") .Append(L(header)) .Append("</b></color>\n"); if (hunts.Count == 0) { text.Append("<color=#a0a0a0>").Append(L(none)).Append("</color>\n"); return; } foreach (Hunt hunt in hunts) { BiomeDef biomeDef = BiomeCatalog.Get(hunt.Biome); string value = ((biomeDef != null) ? biomeDef.DisplayName : ((object)Unsafe.As<Biome, Biome>(ref hunt.Biome)/*cast due to .constrained prefix*/).ToString()); text.Append("<b>").Append(value).Append(' ') .Append(L(HuntKinds.TypeToken(hunt.Kind))) .Append("</b> - "); text.Append(StatusOf(hunt)); List<string> list = new List<string>(); if (hunt.Owner != localId && !string.IsNullOrEmpty(hunt.OwnerName)) { list.Add(L("$tm_codex_owner", hunt.OwnerName)); } if (list.Count > 0) { text.Append(" <color=#a0a0a0>(").Append(string.Join(", ", list.ToArray())).Append(")</color>"); } text.Append('\n'); } } private static string StatusOf(Hunt hunt) { if (hunt.State == HuntState.Killed) { return "<color=#78e678>" + L("$tm_codex_killed") + "</color>"; } if (hunt.State == HuntState.Spawned) { return "<color=yellow>" + L("$tm_codex_found") + "</color>"; } if (hunt.Dungeon) { return L("$tm_codex_dungeon"); } return L("$tm_codex_searching"); } } [HarmonyPatch] internal static class CompendiumTabPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(TextsDialog), "UpdateTextsList", (Type[])null, (Type[])null); } private static bool Prepare() { return TargetMethod() != null; } private static void Postfix(List<TextInfo> ___m_texts) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown if (___m_texts == null || (Object)(object)Player.m_localPlayer == (Object)null) { return; } string text = Localization.instance.Localize("$inventory_activeeffects"); int index = 0; for (int i = 0; i < ___m_texts.Count; i++) { if (___m_texts[i].m_topic == text) { index = i + 1; break; } } ___m_texts.Insert(index, new TextInfo(Localization.instance.Localize("$tm_codex_topic"), TreasureStats.BuildText())); } } internal static class ConfigSyncCompat { internal static readonly bool CompiledIn = true; private static object configSync; [MethodImpl(MethodImplOptions.NoInlining)] internal static void Initialize(string guid, string name, string version) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown configSync = (object)new ConfigSync(guid) { DisplayName = name, CurrentVersion = version, MinimumRequiredVersion = version, ModRequired = true }; } [MethodImpl(MethodImplOptions.NoInlining)] internal static void AddLockingConfigEntry(ConfigEntry<bool> entry) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) ((ConditionalConfigSync)(ConfigSync)configSync).AddLockingConfigEntry<bool>(entry); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void AddConfigEntry<T>(ConfigEntry<T> entry) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) ((ConditionalConfigSync)(ConfigSync)configSync).AddConfigEntry<T>(entry, (ConfigSyncMode)0); } } internal static class FishingTreasure { internal sealed class Tug { public string HuntId; public float TimeInZone; public float BiteAt; public bool Hooked; public string Bait; public float NextNibble; } internal static readonly Dictionary<FishingFloat, Tug> Tugs = new Dictionary<FishingFloat, Tug>(); private static readonly HashSet<string> landed = new HashSet<string>(); internal static Hunt HuntAt(Vector3 position) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) TreasureHuntManager instance = TreasureHuntManager.Instance; if ((Object)(object)instance == (Object)null) { return null; } _ = TreasureHuntManager.LocalId; float value = TreasureMapsPlugin.FishingRadius.Value; foreach (Hunt hunt in instance.Hunts) { if (hunt.Fishing && !landed.Contains(hunt.Id) && Utils.DistanceXZ(position, hunt.PinPos) <= value) { return hunt; } } return null; } internal static bool InWater(FishingFloat fishingFloat) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZoneSystem.instance == (Object)null) { return false; } return ((Component)fishingFloat).transform.position.y <= ZoneSystem.instance.m_waterLevel + 0.6f; } internal static void Land(string huntId, string bait) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) TreasureHuntManager instance = TreasureHuntManager.Instance; Player localPlayer = Player.m_localPlayer; if ((Object)(object)instance == (Object)null || (Object)(object)localPlayer == (Object)null || landed.Contains(huntId)) { return; } Hunt hunt = null; foreach (Hunt hunt2 in instance.Hunts) { if (hunt2.Id == huntId) { hunt = hunt2; } } if (hunt != null) { landed.Add(huntId); int num = Loot.BaitLevel(bait); if (num > 0) { ConsumeBait(localPlayer, bait); } Loot.GiveFishingLoot(localPlayer, hunt.Biome, num); string text = Localization.instance.Localize("$tm_msg_fish_caught"); GameObject val = ((num > 0 && (Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(bait) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 != (Object)null) { text = text + "\n" + Localization.instance.Localize("$tm_msg_fish_bait", new string[1] { Localization.instance.Localize(val2.m_itemData.m_shared.m_name) }); } ((Character)localPlayer).Message((MessageType)2, text, 0, (Sprite)null, false); TreasureHuntManager.SendComplete(huntId); } } private static void ConsumeBait(Player player, string bait) { GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(bait) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if (!((Object)(object)val2 == (Object)null)) { string name = val2.m_itemData.m_shared.m_name; if (((Humanoid)player).GetInventory().CountItems(name, -1, true) > 0) { ((Humanoid)player).GetInventory().RemoveItem(name, 1, -1, true); } } } internal static void Lost(Tug tug) { if (tug != null && tug.Hooked) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, Localization.instance.Localize("$tm_msg_fish_lost"), 0, (Sprite)null, false); } } } } [HarmonyPatch(typeof(FishingFloat), "FixedUpdate")] internal static class FishingTreasureUpdatePatch { private static void Prefix(FishingFloat __instance, ZNetView ___m_nview, out FishingTreasure.Tug __state) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: 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_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) __state = null; if ((Object)(object)___m_nview == (Object)null || !___m_nview.IsValid() || !___m_nview.IsOwner() || (Object)(object)Player.m_localPlayer == (Object)null) { return; } Hunt hunt = FishingTreasure.HuntAt(((Component)__instance).transform.position); FishingTreasure.Tugs.TryGetValue(__instance, out var value); if (value == null) { if (hunt == null) { return; } float num = Mathf.Min(TreasureMapsPlugin.FishingBiteMin.Value, TreasureMapsPlugin.FishingBiteMax.Value); float num2 = Mathf.Max(TreasureMapsPlugin.FishingBiteMin.Value, TreasureMapsPlugin.FishingBiteMax.Value); value = new FishingTreasure.Tug { HuntId = hunt.Id, BiteAt = Random.Range(num, num2) }; FishingTreasure.Tugs[__instance] = value; } else if (!value.Hooked && (hunt == null || hunt.Id != value.HuntId)) { FishingTreasure.Tugs.Remove(__instance); return; } if (!value.Hooked) { if (!FishingTreasure.InWater(__instance)) { return; } value.TimeInZone += Time.fixedDeltaTime; if (value.TimeInZone >= value.BiteAt) { value.Hooked = true; value.Bait = __instance.GetBait(); value.NextNibble = Time.time + 1.5f; __instance.m_nibbleEffect.Create(((Component)__instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); ((Character)Player.m_localPlayer).Message((MessageType)2, Localization.instance.Localize("$tm_msg_fish_bite"), 0, (Sprite)null, false); } } else if (Time.time >= value.NextNibble) { value.NextNibble = Time.time + Random.Range(1.2f, 2.5f); __instance.m_nibbleEffect.Create(((Component)__instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } __state = value; } private static void Postfix(FishingFloat __instance, ZNetView ___m_nview, float ___m_lineLength, FishingTreasure.Tug __state) { if (__state != null && __state.Hooked && (!((Object)(object)___m_nview != (Object)null) || !___m_nview.IsValid())) { FishingTreasure.Tugs.Remove(__instance); if (___m_lineLength <= 0.6f) { FishingTreasure.Land(__state.HuntId, __state.Bait); } else { FishingTreasure.Lost(__state); } } } } [HarmonyPatch(typeof(FishingFloat), "OnDestroy")] internal static class FishingTreasureDestroyPatch { private static void Postfix(FishingFloat __instance) { if (FishingTreasure.Tugs.TryGetValue(__instance, out var value)) { FishingTreasure.Tugs.Remove(__instance); FishingTreasure.Lost(value); } } } internal static class HildirMapPanel { private sealed class PanelParts { public GameObject Root; public Text Countdown; public RectTransform Fill; public float BarWidth; public RectTransform List; } private static GameObject root; private static RectTransform listContent; private static RectTransform activeRoot; private static Text restockText; private static RectTransform restockFill; private static float restockBarWidth; private static float nextCountdown; private static Text activeHeader; private static GameObject bountyRoot; private static RectTransform bountyList; private static Text bountyCountdown; private static RectTransform bountyFill; private static float bountyBarWidth; private static int lastBountyPeriod = -1; private static Trader trader; private static bool dirty = true; private static int lastCoins = -1; private static int lastPeriod = -1; private static float nextActiveRefresh; private const float RowHeight = 48f; private const float HeaderHeight = 32f; private const int MaxActiveLines = 5; private static GameObject tooltipPrefab; private const float TooltipDelay = 0.5f; private const float TooltipGap = 18f; private static GameObject tooltip; private static MapTooltipTrigger tooltipOwner; private static float tooltipShowAt; private static bool IsVisible { get { if ((Object)(object)root != (Object)null) { return root.activeSelf; } return false; } } internal static void MarkDirty() { dirty = true; } internal static void Show(StoreGui gui, Trader newTrader) { if (!IsTreasureTrader(newTrader)) { Hide(); } else if (Ensure(gui)) { trader = newTrader; root.SetActive(true); root.transform.SetAsLastSibling(); if ((Object)(object)bountyRoot != (Object)null) { bountyRoot.SetActive(true); bountyRoot.transform.SetAsLastSibling(); } PositionNextToStore(gui); dirty = true; Refresh(); } } internal static void Hide() { HideTooltip(null); trader = null; if ((Object)(object)root != (Object)null) { root.SetActive(false); } if ((Object)(object)bountyRoot != (Object)null) { bountyRoot.SetActive(false); } } internal static void Tick(StoreGui gui) { if (!IsVisible) { return; } FollowPointer(); if ((Object)(object)gui == (Object)null || (Object)(object)gui.m_rootPanel == (Object)null || !gui.m_rootPanel.activeSelf || (Object)(object)Player.m_localPlayer == (Object)null) { Hide(); return; } int num = PlayerCoins(); int num2 = TreasureHuntManager.CurrentPeriod(); int num3 = TreasureHuntManager.CurrentBountyPeriod(); if (num != lastCoins || num2 != lastPeriod || num3 != lastBountyPeriod) { dirty = true; } if (Time.time >= nextCountdown) { PositionNextToStore(gui); } if (dirty) { Refresh(); } else if (Time.time >= nextActiveRefresh) { RefreshActive(); } if (Time.time >= nextCountdown) { UpdateCountdown(); } } private static bool IsTreasureTrader(Trader candidate) { if ((Object)(object)candidate == (Object)null) { return false; } string a = ((Object)((Component)candidate).gameObject).name.Replace("(Clone)", "").Trim(); string text = candidate.m_name ?? ""; string a2 = Localization.instance.Localize(text); foreach (string item in BiomeCatalog.SplitList(TreasureMapsPlugin.TraderNames.Value)) { if (string.Equals(a, item, StringComparison.OrdinalIgnoreCase)) { return true; } if (string.Equals(a2, item, StringComparison.OrdinalIgnoreCase)) { return true; } if (text.IndexOf(item, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } private static Transform PanelParent(StoreGui store) { Canvas val = (((Object)(object)store != (Object)null && (Object)(object)store.m_rootPanel != (Object)null) ? store.m_rootPanel.GetComponentInParent<Canvas>() : null); if ((Object)(object)val != (Object)null) { return ((Component)val.rootCanvas).transform; } if (!((Object)(object)GUIManager.CustomGUIFront != (Object)null)) { return null; } return GUIManager.CustomGUIFront.transform; } private static RectTransform StorePanelRect(StoreGui store, RectTransform parent) { //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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)store == (Object)null || (Object)(object)store.m_rootPanel == (Object)null || (Object)(object)parent == (Object)null) { return null; } Transform transform = store.m_rootPanel.transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); Rect rect = parent.rect; float num = ((Rect)(ref rect)).width * 0.85f; if ((Object)(object)val != (Object)null) { rect = val.rect; if (((Rect)(ref rect)).width > 0f) { rect = val.rect; if (((Rect)(ref rect)).width < num) { return val; } } } RectTransform result = null; float num2 = 0f; Image[] componentsInChildren = store.m_rootPanel.GetComponentsInChildren<Image>(true); for (int i = 0; i < componentsInChildren.Length; i++) { RectTransform rectTransform = ((Graphic)componentsInChildren[i]).rectTransform; rect = rectTransform.rect; float width = ((Rect)(ref rect)).width; rect = rectTransform.rect; float height = ((Rect)(ref rect)).height; if (!(width < 200f) && !(width > num) && !(height < 200f) && width * height > num2) { result = rectTransform; num2 = width * height; } } return result; } private static void PositionNextToStore(StoreGui store) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: 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_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_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: 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_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return; } RectTransform val = (RectTransform)root.transform; Transform parent = ((Transform)val).parent; RectTransform val2 = (RectTransform)(object)((parent is RectTransform) ? parent : null); if ((Object)(object)val2 == (Object)null) { return; } Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0.5f, 0.5f); val.anchorMin = val3; val.anchorMax = val3; val.pivot = new Vector2(0f, 1f); float x = val.sizeDelta.x; float y = val.sizeDelta.y; Vector2 val4 = default(Vector2); ((Vector2)(ref val4))..ctor(TreasureMapsPlugin.PanelOffsetX.Value, TreasureMapsPlugin.PanelOffsetY.Value); RectTransform val5 = StorePanelRect(store, val2); if ((Object)(object)val5 == (Object)null) { val.anchoredPosition = new Vector2((0f - x) / 2f, y / 2f) + val4; PlaceBountyPanel(val); return; } Vector3[] array = (Vector3[])(object)new Vector3[4]; val5.GetWorldCorners(array); Vector3 val6 = ((Transform)val2).InverseTransformPoint(array[1]); Vector3 val7 = ((Transform)val2).InverseTransformPoint(array[2]); Rect rect = val2.rect; float num = ((Rect)(ref rect)).width / 2f; rect = val2.rect; float num2 = ((Rect)(ref rect)).height / 2f; Vector2 val8 = default(Vector2); ((Vector2)(ref val8))..ctor(val7.x + 8f, val7.y); if (val8.x + x > num) { ((Vector2)(ref val8))..ctor(val6.x - 8f - x, val6.y); } val8 += val4; val8.y = Mathf.Min(val8.y, num2); val8.y = Mathf.Max(val8.y, 0f - num2 + y); val.anchoredPosition = val8; PlaceBountyPanel(val); } private static void PlaceBountyPanel(RectTransform panel) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)bountyRoot == (Object)null) { return; } RectTransform val = (RectTransform)bountyRoot.transform; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); val.anchorMin = val2; val.anchorMax = val2; val.pivot = new Vector2(0f, 1f); val.anchoredPosition = panel.anchoredPosition + new Vector2(panel.sizeDelta.x + 8f, 0f); Transform parent = ((Transform)panel).parent; RectTransform val3 = (RectTransform)(object)((parent is RectTransform) ? parent : null); if (!((Object)(object)val3 == (Object)null)) { float num = val.anchoredPosition.x + val.sizeDelta.x; Rect rect = val3.rect; float num2 = num - ((Rect)(ref rect)).width / 2f; if (!(num2 <= 0f)) { panel.anchoredPosition -= new Vector2(num2, 0f); val.anchoredPosition -= new Vector2(num2, 0f); } } } private static PanelParts BuildPanel(Transform parent, string name, string titleToken, string subtitleToken, float width, float height, float listBottom) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Expected O, but got Unknown //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Expected O, but got Unknown //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Expected O, but got Unknown //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_032d: 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_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Unknown result type (might be due to invalid IL or missing references) //IL_03f1: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Unknown result type (might be due to invalid IL or missing references) //IL_0441: Expected O, but got Unknown GUIManager instance = GUIManager.Instance; Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(0.5f, 0.5f); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 1f); PanelParts panelParts = new PanelParts(); panelParts.Root = instance.CreateWoodpanel(parent, val, val, Vector2.zero, width, height, false); ((Object)panelParts.Root).name = name; MakeText(Localization.instance.Localize(titleToken), panelParts.Root.transform, val2, new Vector2(0f, -38f), width - 40f, 44f, 32, instance.ValheimOrange, (TextAnchor)4, instance.NorseBold); MakeText(Localization.instance.Localize(subtitleToken), panelParts.Root.transform, val2, new Vector2(0f, -72f), width - 40f, 22f, 15, instance.ValheimBeige, (TextAnchor)4, instance.AveriaSerif); panelParts.Countdown = MakeText("", panelParts.Root.transform, val2, new Vector2(0f, -94f), width - 40f, 22f, 15, instance.ValheimYellow, (TextAnchor)4, instance.AveriaSerif); panelParts.BarWidth = width - 120f; GameObject val3 = new GameObject("CountdownBar", new Type[2] { typeof(RectTransform), typeof(Image) }); val3.transform.SetParent(panelParts.Root.transform, false); RectTransform val4 = (RectTransform)val3.transform; val4.anchorMin = val2; val4.anchorMax = val2; val4.sizeDelta = new Vector2(panelParts.BarWidth, 8f); val4.anchoredPosition = new Vector2(0f, -112f); Image component = val3.GetComponent<Image>(); ((Graphic)component).color = new Color(0f, 0f, 0f, 0.55f); ((Graphic)component).raycastTarget = false; GameObject val5 = new GameObject("Fill", new Type[2] { typeof(RectTransform), typeof(Image) }); val5.transform.SetParent(val3.transform, false); panelParts.Fill = (RectTransform)val5.transform; panelParts.Fill.anchorMin = new Vector2(0f, 0f); panelParts.Fill.anchorMax = new Vector2(0f, 1f); panelParts.Fill.pivot = new Vector2(0f, 0.5f); panelParts.Fill.anchoredPosition = Vector2.zero; panelParts.Fill.sizeDelta = Vector2.zero; Image component2 = val5.GetComponent<Image>(); ((Graphic)component2).color = instance.ValheimOrange; ((Graphic)component2).raycastTarget = false; float num = Mathf.Max(120f, height - 126f - listBottom); GameObject obj = instance.CreateScrollView(panelParts.Root.transform, false, true, 8f, 6f, instance.ValheimScrollbarHandleColorBlock, new Color(0f, 0f, 0f, 0.35f), width - 40f, num); RectTransform val6 = (RectTransform)obj.transform; val6.anchorMin = val2; val6.anchorMax = val2; val6.pivot = new Vector2(0.5f, 1f); val6.anchoredPosition = new Vector2(0f, -126f); ScrollRect componentInChildren = obj.GetComponentInChildren<ScrollRect>(); panelParts.List = componentInChildren.content; panelParts.List.anchorMin = new Vector2(0f, 1f); panelParts.List.anchorMax = new Vector2(1f, 1f); panelParts.List.pivot = new Vector2(0.5f, 1f); panelParts.List.anchoredPosition = Vector2.zero; panelParts.List.sizeDelta = new Vector2(0f, panelParts.List.sizeDelta.y); VerticalLayoutGroup orAdd = GetOrAdd<VerticalLayoutGroup>(((Component)panelParts.List).gameObject); ((HorizontalOrVerticalLayoutGroup)orAdd).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)orAdd).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)orAdd).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)orAdd).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)orAdd).spacing = 4f; ((LayoutGroup)orAdd).padding = new RectOffset(4, 14, 4, 4); ContentSizeFitter orAdd2 = GetOrAdd<ContentSizeFitter>(((Component)panelParts.List).gameObject); orAdd2.horizontalFit = (FitMode)0; orAdd2.verticalFit = (FitMode)2; panelParts.Root.SetActive(false); return panelParts; } private static bool Ensure(StoreGui store) { //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Expected O, but got Unknown //IL_01b0: 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_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) Transform val = PanelParent(store); if ((Object)(object)root != (Object)null && ((Object)(object)root.transform.parent != (Object)(object)val || (Object)(object)bountyRoot == (Object)null)) { Object.Destroy((Object)(object)root); root = null; } if ((Object)(object)bountyRoot != (Object)null && ((Object)(object)root == (Object)null || (Object)(object)bountyRoot.transform.parent != (Object)(object)val)) { Object.Destroy((Object)(object)bountyRoot); bountyRoot = null; } if ((Object)(object)root != (Object)null) { return true; } GUIManager instance = GUIManager.Instance; if (instance == null || (Object)(object)val == (Object)null) { return false; } float value = TreasureMapsPlugin.PanelWidth.Value; float value2 = TreasureMapsPlugin.PanelHeight.Value; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0f); PanelParts panelParts = BuildPanel(val, "TreasureMaps_HildirPanel", "$tm_panel_title", "$tm_panel_subtitle", value, value2, 186f); root = panelParts.Root; restockText = panelParts.Countdown; restockFill = panelParts.Fill; restockBarWidth = panelParts.BarWidth; listContent = panelParts.List; activeHeader = MakeText("", root.transform, val2, new Vector2(0f, 160f), value - 40f, 26f, 19, instance.ValheimOrange, (TextAnchor)3, instance.AveriaSerifBold); activeRoot = (RectTransform)new GameObject("ActiveMaps", new Type[1] { typeof(RectTransform) }).transform; ((Transform)activeRoot).SetParent(root.transform, false); activeRoot.anchorMin = val2; activeRoot.anchorMax = val2; activeRoot.pivot = new Vector2(0.5f, 1f); activeRoot.sizeDelta = new Vector2(value - 40f, 120f); activeRoot.anchoredPosition = new Vector2(0f, 144f); PanelParts panelParts2 = BuildPanel(val, "TreasureMaps_BountyPanel", "$tm_bounty_title", "$tm_bounty_subtitle", TreasureMapsPlugin.BountyPanelWidth.Value, value2, 24f); bountyRoot = panelParts2.Root; bountyCountdown = panelParts2.Countdown; bountyFill = panelParts2.Fill; bountyBarWidth = panelParts2.BarWidth; bountyList = panelParts2.List; return true; } private static T GetOrAdd<T>(GameObject go) where T : Component { T component = go.GetComponent<T>(); if (!((Object)(object)component != (Object)null)) { return go.AddComponent<T>(); } return component; } private static Text MakeText(string text, Transform parent, Vector2 anchor, Vector2 position, float width, float height, int size, Color color, TextAnchor alignment, Font font) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) Text component = GUIManager.Instance.CreateText(text, parent, anchor, anchor, position, font, size, color, true, Color.black, width, height, false).GetComponent<Text>(); component.alignment = alignment; ((Graphic)component).raycastTarget = false; component.horizontalOverflow = (HorizontalWrapMode)0; component.verticalOverflow = (VerticalWrapMode)1; return component; } private static Button MakeButton(string text, Transform parent, Vector2 anchor, Vector2 position, float width, float height, Action onClick) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown Button component = GUIManager.Instance.CreateButton(text, parent, anchor, anchor, position, width, height).GetComponent<Button>(); ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { onClick(); }); return component; } private static GameObject TooltipPrefab() { if ((Object)(object)tooltipPrefab != (Object)null) { return tooltipPrefab; } StoreGui instance = StoreGui.instance; UITooltip val = (((Object)(object)instance != (Object)null && (Object)(object)instance.m_listElement != (Object)null) ? instance.m_listElement.GetComponent<UITooltip>() : null); if ((Object)(object)val != (Object)null && (Object)(object)val.m_tooltipPrefab != (Object)null) { return tooltipPrefab = val.m_tooltipPrefab; } UITooltip[] array = Resources.FindObjectsOfTypeAll<UITooltip>(); foreach (UITooltip val2 in array) { if ((Object)(object)val2 != (Object)null && (Object)(object)val2.m_tooltipPrefab != (Object)null) { return tooltipPrefab = val2.m_tooltipPrefab; } } return null; } private static void AddTooltip(GameObject target, string topic, string text) { Graphic component = target.GetComponent<Graphic>(); if ((Object)(object)component != (Object)null) { component.raycastTarget = true; } MapTooltipTrigger mapTooltipTrigger = target.AddComponent<MapTooltipTrigger>(); mapTooltipTrigger.Topic = topic; mapTooltipTrigger.Text = text; } internal static void ShowTooltip(MapTooltipTrigger owner) { if (!((Object)(object)root == (Object)null) && !((Object)(object)owner == (Object)null)) { tooltipOwner = owner; tooltipShowAt = Time.time + 0.5f; if ((Object)(object)tooltip != (Object)null) { tooltip.SetActive(false); } } } internal static void HideTooltip(MapTooltipTrigger owner) { if (!((Object)(object)owner != (Object)null) || !((Object)(object)owner != (Object)(object)tooltipOwner)) { tooltipOwner = null; if ((Object)(object)tooltip != (Object)null) { tooltip.SetActive(false); } } } private static bool CreateTooltip() { Transform val = (((Object)(object)root != (Object)null) ? root.transform.parent : null); GameObject val2 = TooltipPrefab(); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return false; } if ((Object)(object)tooltip != (Object)null && (Object)(object)tooltip.transform.parent == (Object)(object)val) { return true; } if ((Object)(object)tooltip != (Object)null) { Object.Destroy((Object)(object)tooltip); } tooltip = Object.Instantiate<GameObject>(val2, val); ((Object)tooltip).name = "TreasureMaps_Tooltip"; CanvasGroup orAdd = GetOrAdd<CanvasGroup>(tooltip); orAdd.blocksRaycasts = false; orAdd.interactable = false; Graphic[] componentsInChildren = tooltip.GetComponentsInChildren<Graphic>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].raycastTarget = false; } tooltip.SetActive(false); return true; } private static void SetTooltipText(string childName, string value) { Transform val = Utils.FindChild(tooltip.transform, childName, (IterativeSearchType)0); TMP_Text val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<TMP_Text>() : null); if ((Object)(object)val2 != (Object)null) { val2.text = value ?? ""; } } private static void FollowPointer() { if ((Object)(object)tooltipOwner == (Object)null || !((Component)tooltipOwner).gameObject.activeInHierarchy) { if ((Object)(object)tooltipOwner != (Object)null) { HideTooltip(null); } } else { if (Time.time < tooltipShowAt) { return; } if ((Object)(object)tooltip == (Object)null || !tooltip.activeSelf) { if (!CreateTooltip()) { return; } SetTooltipText("Topic", tooltipOwner.Topic); SetTooltipText("Text", tooltipOwner.Text); tooltip.SetActive(true); tooltip.transform.SetAsLastSibling(); } PlaceTooltip(); } } private static void PlaceTooltip() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) Vector3 pointerPosition = ZInput.pointerPosition; tooltip.transform.position = pointerPosition; RectTransform val = (RectTransform)((tooltip.transform.childCount > 0) ? /*isinst with value type is only supported in some contexts*/: null); if (!((Object)(object)val == (Object)null)) { Vector3[] array = (Vector3[])(object)new Vector3[4]; val.GetWorldCorners(array); float num = array[2].x - array[1].x; float num2 = array[1].y - array[0].y; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(pointerPosition.x - 18f - array[3].x, pointerPosition.y + 18f - array[3].y, 0f); if (pointerPosition.x - 18f - num < 0f) { val2.x = pointerPosition.x + 18f - array[0].x; } if (pointerPosition.y + 18f + num2 > (float)Screen.height) { val2.y = pointerPosition.y - 18f - array[1].y; } Transform transform = tooltip.transform; transform.position += val2; } } private static string MapTooltip(BiomeDef def, HuntKind kind) { string text; switch (kind) { case HuntKind.Fishing: text = Localization.instance.Localize("$tm_tip_fishing", new string[1] { def.DisplayName }); break; case HuntKind.Shipwreck: text = Localization.instance.Localize("$tm_tip_shipwreck"); break; case HuntKind.Bounty: return Localization.instance.Localize("$tm_tip_bounty"); case HuntKind.Guardian: { int num = Mathf.Min(TreasureMapsPlugin.GuardianMinStars.Value, TreasureMapsPlugin.GuardianMaxStars.Value); int num2 = Mathf.Max(TreasureMapsPlugin.GuardianMinStars.Value, TreasureMapsPlugin.GuardianMaxStars.Value); string text2 = ((num == num2) ? num.ToString() : (num + "-" + num2)); text = Localization.instance.Localize("$tm_tip_guardian", new string[2] { text2, def.DisplayName }); break; } default: text = Localization.instance.Localize("$tm_tip_chest", new string[1] { def.DisplayName }); break; } string text3 = text; if (kind == HuntKind.Fishing) { text3 = text3 + "\n\n" + Localization.instance.Localize("$tm_tip_fish_how") + "\n\n" + Localization.instance.Localize("$tm_tip_bait"); } return text3; } private static void ClearChildren(Transform parent) { for (int num = parent.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)parent.GetChild(num)).gameObject); } } private static void Refresh() { dirty = false; Player localPlayer = Player.m_localPlayer; if ((Object)(object)root == (Object)null || (Object)(object)localPlayer == (Object)null) { return; } GUIManager instance = GUIManager.Instance; lastCoins = PlayerCoins(); lastPeriod = TreasureHuntManager.CurrentPeriod(); lastBountyPeriod = TreasureHuntManager.CurrentBountyPeriod(); UpdateCountdown(); RefreshBounties(localPlayer, instance); ClearChildren((Transform)(object)listContent); Sprite coinIcon = CoinIcon(); foreach (BiomeDef item in BiomeCatalog.All) { if (item.Enabled.Value && BiomeCatalog.IsUnlocked(item, localPlayer)) { BuildBiome(item, localPlayer, coinIcon, instance); } } RefreshActive(); } private static GameObject MakeRow(RectTransform parent, string name, float height, float shade) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(LayoutElement), typeof(Image) }); val.transform.SetParent((Transform)(object)parent, false); LayoutElement component = val.GetComponent<LayoutElement>(); component.minHeight = height; component.preferredHeight = height; Image component2 = val.GetComponent<Image>(); ((Graphic)component2).color = new Color(0f, 0f, 0f, shade); ((Graphic)component2).raycastTarget = false; return val; } private static void BuildBiome(BiomeDef def, Player player, Sprite coinIcon, GUIManager gui) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) Vector2 anchor = default(Vector2); ((Vector2)(ref anchor))..ctor(0f, 0.5f); GameObject val = MakeRow(listContent, "Biome_" + def.Key, 32f, 0.45f); MakeText(def.DisplayName, val.transform, anchor, new Vector2(124f, 0f), 228f, 26f, 20, gui.ValheimOrange, (TextAnchor)3, gui.AveriaSerifBold); HuntKind[] kinds = def.Kinds; foreach (HuntKind huntKind in kinds) { if (BiomeCatalog.StockOf(def, huntKind) > 0 && (huntKind != HuntKind.Guardian || BiomeCatalog.GetGuardians(def.Biome).Count != 0)) { BuildMapRow(def, huntKind, player, coinIcon, gui); } } } private static void BuildMapRow(BiomeDef def, HuntKind kind, Player player, Sprite coinIcon, GUIManager gui) { //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_028f: 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_029a: Unknown result type (might be due to invalid IL or missing references) //IL_029b: 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_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) GameObject val = MakeRow(listContent, "Map_" + def.Key + "_" + kind, 48f, 0.25f); int num = TreasureHuntManager.Remaining(def, kind); int num2 = BiomeCatalog.StockOf(def, kind); int num3 = BiomeCatalog.PriceOf(def, kind); bool flag = player.NoCostCheat() || lastCoins >= num3; bool flag2 = (Object)(object)TreasureHuntManager.Instance != (Object)null && TreasureHuntManager.Instance.OwnedCount() >= TreasureMapsPlugin.MaxActiveMaps.Value; bool flag3 = (Object)(object)TreasureHuntManager.Instance != (Object)null && TreasureHuntManager.Instance.BuyPending; Vector2 anchor = default(Vector2); ((Vector2)(ref anchor))..ctor(0f, 0.5f); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(1f, 0.5f); MakeText(Localization.instance.Localize(HuntKinds.TypeToken(kind)), val.transform, anchor, new Vector2(134f, 9f), 228f, 22f, 17, gui.ValheimBeige, (TextAnchor)3, gui.AveriaSerifBold); Color color = default(Color); ((Color)(ref color))..ctor(0.8f, 0.8f, 0.75f); string text; if (num <= 0) { text = Localization.instance.Localize("$tm_soldout"); ((Color)(ref color))..ctor(0.85f, 0.4f, 0.3f); } else { text = Localization.instance.Localize("$tm_stock", new string[2] { num.ToString(), num2.ToString() }); } MakeText(text, val.transform, anchor, new Vector2(134f, -11f), 228f, 20f, 13, color, (TextAnchor)3, gui.AveriaSerif); MakeText(num3.ToString(), val.transform, val2, new Vector2(-162f, 0f), 70f, 28f, 18, flag ? gui.ValheimYellow : Color.grey, (TextAnchor)5, gui.AveriaSerifBold); if ((Object)(object)coinIcon != (Object)null) { GameObject val3 = new GameObject("Coin", new Type[2] { typeof(RectTransform), typeof(Image) }); val3.transform.SetParent(val.transform, false); RectTransform val4 = (RectTransform)val3.transform; val4.anchorMin = val2; val4.anchorMax = val2; val4.sizeDelta = new Vector2(24f, 24f); val4.anchoredPosition = new Vector2(-112f, 0f); Image component = val3.GetComponent<Image>(); component.sprite = coinIcon; component.preserveAspect = true; ((Graphic)component).raycastTarget = false; } AddTooltip(val, def.DisplayName + " - " + Localization.instance.Localize(HuntKinds.TypeToken(kind)), MapTooltip(def, kind)); ((Selectable)MakeButton(Localization.instance.Localize("$tm_buy"), val.transform, val2, new Vector2(-50f, 0f), 82f, 34f, delegate { OnBuy(def, kind); })).interactable = num > 0 && flag && !flag2 && !flag3; } private static void UpdateCountdown() { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) nextCountdown = Time.time + 0.25f; if ((Object)(object)restockText == (Object)null) { return; } double num = TreasureHuntManager.PreciseDaysUntilRestock(); int num2 = Mathf.Max(1, TreasureMapsPlugin.RestockDays.Value); restockText.text = ((num < 0.05) ? Localization.instance.Localize("$tm_restock_soon") : Localization.instance.Localize("$tm_restock", new string[1] { num.ToString((num < 1.0) ? "0.00" : "0.0", CultureInfo.InvariantCulture) })); if ((Object)(object)restockFill != (Object)null) { float num3 = Mathf.Clamp01(1f - (float)(num / (double)num2)); restockFill.sizeDelta = new Vector2(restockBarWidth * num3, 0f); } if (!((Object)(object)bountyCountdown == (Object)null)) { double num4 = TreasureHuntManager.PreciseDaysUntilBountyRefresh(); int num5 = Mathf.Max(1, TreasureMapsPlugin.BountyRefreshDays.Value); bountyCountdown.text = ((num4 < 0.05) ? Localization.instance.Localize("$tm_bounty_soon") : Localization.instance.Localize("$tm_bounty_refresh", new string[1] { num4.ToString((num4 < 1.0) ? "0.00" : "0.0", CultureInfo.InvariantCulture) })); if ((Object)(object)bountyFill != (Object)null) { float num6 = Mathf.Clamp01(1f - (float)(num4 / (double)num5)); bountyFill.sizeDelta = new Vector2(bountyBarWidth * num6, 0f); } } } private static void RefreshBounties(Player player, GUIManager gui) { //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)bountyList == (Object)null) { return; } ClearChildren((Transform)(object)bountyList); bool flag = (Object)(object)TreasureHuntManager.Instance != (Object)null && TreasureHuntManager.Instance.OwnedCount(bounties: true) >= TreasureMapsPlugin.MaxActiveBounties.Value; bool flag2 = (Object)(object)TreasureHuntManager.Instance != (Object)null && TreasureHuntManager.Instance.BuyPending; Vector2 anchor = default(Vector2); Vector2 anchor2 = default(Vector2); Vector2 position = default(Vector2); foreach (BiomeDef item in BiomeCatalog.All) { if (!item.Enabled.Value || !BiomeCatalog.Offers(item, HuntKind.Bounty)) { continue; } GameObject val = MakeRow(bountyList, "Bounty_" + item.Key, 48f, 0.3f); ((Vector2)(ref anchor))..ctor(0f, 0.5f); ((Vector2)(ref anchor2))..ctor(1f, 0.5f); float num = Mathf.Max(120f, TreasureMapsPlugin.BountyPanelWidth.Value - 180f); float num2 = 12f + num / 2f; Hunt killed = (((Object)(object)TreasureHuntManager.Instance != (Object)null) ? TreasureHuntManager.Instance.KilledBounty(item) : null); bool flag3 = killed == null && (Object)(object)TreasureHuntManager.Instance != (Object)null && TreasureHuntManager.Instance.ActiveBounty(item) != null; int num3 = TreasureHuntManager.Remaining(item, HuntKind.Bounty); bool flag4 = killed == null && !flag3 && num3 <= 0; bool flag5 = killed != null || flag3; MakeText(item.DisplayName, val.transform, anchor, new Vector2(num2, flag5 ? 9f : 0f), num, 24f, 18, gui.ValheimOrange, (TextAnchor)3, gui.AveriaSerifBold); if (killed != null) { MakeText(Localization.instance.Localize("$tm_bounty_ready"), val.transform, anchor, new Vector2(num2, -11f), num, 20f, 13, new Color(0.55f, 0.85f, 0.45f), (TextAnchor)3, gui.AveriaSerif); } else if (flag3) { MakeText(Localization.instance.Localize("$tm_bounty_taken"), val.transform, anchor, new Vector2(num2, -11f), num, 20f, 13, new Color(0.85f, 0.4f, 0.3f), (TextAnchor)3, gui.AveriaSerif); } AddTooltip(val, item.DisplayName + " - " + Localization.instance.Localize("$tm_type_bounty"), MapTooltip(item, HuntKind.Bounty)); BiomeDef captured = item; ((Vector2)(ref position))..ctor(-58f, 0f); if (killed != null) { ((Selectable)MakeButton(Localization.instance.Localize("$tm_turnin"), val.transform, anchor2, position, 100f, 34f, delegate { OnTurnIn(killed); })).interactable = !flag2; } else if (flag3 || flag4) { ((Selectable)MakeButton(Localization.instance.Localize(flag3 ? "$tm_bounty_inprogress" : "$tm_bounty_completed"), val.transform, anchor2, position, 100f, 34f, delegate { })).interactable = false; } else { ((Selectable)MakeButton(Localization.instance.Localize("$tm_accept"), val.transform, anchor2, position, 100f, 34f, delegate { OnBuy(captured, HuntKind.Bounty); })).interactable = !flag && !flag2; } } } private static void RefreshActive() { //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_0504: Unknown result type (might be due to invalid IL or missing references) //IL_0513: Unknown result type (might be due to invalid IL or missing references) //IL_0521: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_048a: Unknown result type (might be due to invalid IL or missing references) //IL_049a: Unknown result type (might be due to invalid IL or missing references) nextActiveRefresh = Time.time + 1f; TreasureHuntManager manager = TreasureHuntManager.Instance; if ((Object)(object)activeRoot == (Object)null || (Object)(object)manager == (Object)null) { return; } GUIManager instance = GUIManager.Instance; long localId = TreasureHuntManager.LocalId; activeHeader.text = Localization.instance.Localize("$tm_active_header", new string[4] { manager.OwnedCount(bounties: false).ToString(), TreasureMapsPlugin.MaxActiveMaps.Value.ToString(), manager.OwnedCount(bounties: true).ToString(), TreasureMapsPlugin.MaxActiveBounties.Value.ToString() }); List<Hunt> list = new List<Hunt>(); foreach (Hunt hunt2 in manager.Hunts) { if (hunt2.Owner == localId) { list.Add(hunt2); } } foreach (Hunt hunt3 in manager.Hunts) { if (hunt3.Owner != localId) { list.Add(hunt3); } } ClearChildren((Transform)(object)activeRoot); if (list.Count == 0) { MakeText(Localization.instance.Localize("$tm_active_none"), (Transform)(object)activeRoot, new Vector2(0.5f, 1f), new Vector2(0f, -12f), activeRoot.sizeDelta.x, 22f, 15, instance.ValheimBeige, (TextAnchor)3, instance.AveriaSerif); return; } float x = activeRoot.sizeDelta.x; for (int i = 0; i < list.Count && i < 5; i++) { Hunt hunt = list[i]; bool flag = hunt.Owner == localId; bool flag2 = manager.OnMap(hunt); bool flag3 = hunt.State != HuntState.Killed; BiomeDef biomeDef = BiomeCatalog.Get(hunt.Biome); string text = ((biomeDef != null) ? biomeDef.DisplayName : ((object)Unsafe.As<Biome, Biome>(ref hunt.Biome)/*cast due to .constrained prefix*/).ToString()); string text2 = Localization.instance.Localize(HuntKinds.TypeToken(hunt.Kind)); string text3 = ((hunt.State == HuntState.Killed) ? Localization.instance.Localize("$tm_active_killed", new string[2] { text, text2 }) : ((hunt.State == HuntState.Spawned) ? Localization.instance.Localize("$tm_active_found", new string[2] { text, text2 }) : Localization.instance.Localize(hunt.Dungeon ? "$tm_active_dungeon" : "$tm_active_entry", new string[2] { text, text2 }))); if (!flag && !string.IsNullOrEmpty(hunt.OwnerName)) { text3 = text3 + " " + Localization.instance.Localize("$tm_active_owner", new string[1] { hunt.OwnerName }); } float num = ((!flag3) ? 0f : (flag2 ? 26f : 92f)); float num2 = -12f - (float)i * 24f; Text obj = MakeText(text3, (Transform)(object)activeRoot, new Vector2(0.5f, 1f), new Vector2((0f - (num + 8f)) / 2f, num2), x - num - 8f, 22f, 15, (Color)((flag2 || !flag3) ? instance.ValheimBeige : new Color(0.75f, 0.75f, 0.7f)), (TextAnchor)3, instance.AveriaSerif); string text4 = (hunt.Bounty ? Localization.instance.Localize("$tm_tip_bounty") : ""); if (flag3) { string text5 = Localization.instance.Localize(flag2 ? "$tm_tip_onmap" : "$tm_tip_addmap"); text4 = ((text4.Length > 0) ? (text5 + "\n\n" + text4) : text5); } AddTooltip(((Component)obj).gameObject, text + " - " + text2, text4); Hunt captured = hunt; if (flag3) { string text6 = (flag2 ? "X" : Localization.instance.Localize("$tm_addmap")); bool show = !flag2; MakeButton(text6, (Transform)(object)activeRoot, new Vector2(1f, 1f), new Vector2((0f - num) / 2f, num2), num, 22f, delegate { manager.SetOnMap(captured, show); Refresh(); }); } } if (list.Count > 5) { MakeText("+" + (list.Count - 5), (Transform)(object)activeRoot, new Vector2(0.5f, 1f), new Vector2(0f, -132f), x, 22f, 14, Color.grey, (TextAnchor)3, instance.AveriaSerif); } } private static void OnTurnIn(Hunt hunt) { TreasureHuntManager.RequestTurnIn(hunt); Refresh(); } internal static void OnTurnedIn() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) StoreGui instance = StoreGui.instance; if ((Object)(object)instance != (Object)null && IsVisible) { instance.m_sellEffects.Create(((Component)instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } if ((Object)(object)trader != (Object)null) { trader.OnSold(); } } private static void OnBuy(BiomeDef def, HuntKind kind) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { string text = TreasureHuntManager.RequestBuy(def, kind); if (!string.IsNullOrEmpty(text)) { ((Character)localPlayer).Message((MessageType)2, text, 0, (Sprite)null, false); } Refresh(); } } internal static void OnPurchased() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) StoreGui instance = StoreGui.instance; if ((Object)(object)instance != (Object)null && IsVisible) { instance.m_buyEffects.Create(((Component)instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } if ((Object)(object)trader != (Object)null) { trader.OnBought((TradeItem)null); } } private static int PlayerCoins() { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer != (Object)null)) { return 0; } return ((Humanoid)localPlayer).GetInventory().CountItems(TreasureHuntManager.CoinName(), -1, true); } private static Sprite CoinIcon() { StoreGui instance = StoreGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_coinPrefab == (Object)null) { return null; } Sprite[] icons = instance.m_coinPrefab.m_itemData.m_shared.m_icons; if (icons == null || icons.Length == 0) { return null; } return icons[0]; } } internal class MapTooltipTrigger : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { public string Topic; public string Text; public void OnPointerEnter(PointerEventData eventData) { HildirMapPanel.ShowTooltip(this); } public void OnPointerExit(PointerEventData eventData) { HildirMapPanel.HideTooltip(this); } private void OnDisable() { HildirMapPanel.HideTooltip(this); } private void OnDestroy() { HildirMapPanel.HideTooltip(this); } } internal static class IdolCatalog { private sealed class IdolInfo { public GameObject Prefab; public bool Battle; public bool Protection; public int Tier; } private static List<IdolInfo> idols; private static readonly Dictionary<string, int> MaterialTiers = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase) { { "Flint", 1 }, { "LeatherScraps", 1 }, { "DeerHide", 1 }, { "Bronze", 2 }, { "Copper", 2 }, { "Tin", 2 }, { "TrollHide", 2 }, { "RoundLog", 2 }, { "Iron", 3 }, { "ElderBark", 3 }, { "Chain", 3 }, { "Silver", 4 }, { "WolfPelt", 4 }, { "WolfFang", 4 }, { "Obsidian", 4 }, { "DragonTear", 4 }, { "BlackMetal", 5 }, { "LinenThread", 5 }, { "L