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 Clanheim Treasure Table v1.0.5
ClanheimTreasureTable.dll
Decompiled 3 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("ClanheimTreasureTable")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ClanheimTreasureTable")] [assembly: AssemblyTitle("ClanheimTreasureTable")] [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 ClanheimTreasureTable { [BepInPlugin("com.clanheim.treasuretable", "Clanheim Treasure Table", "1.0.5")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class ClanheimTreasureTablePlugin : BaseUnityPlugin { public const string PluginGuid = "com.clanheim.treasuretable"; public const string PluginName = "Clanheim Treasure Table"; public const string PluginVersion = "1.0.5"; internal static ClanheimTreasureTablePlugin Instance; internal static void LogInfo(string message) { ClanheimTreasureTablePlugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogInfo((object)message); } } internal static void LogWarning(string message) { ClanheimTreasureTablePlugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogWarning((object)message); } } private void Awake() { Instance = this; PrefabManager.OnVanillaPrefabsAvailable += RegisterContent; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Clanheim Treasure Table 1.0.5 loading."); } private void RegisterContent() { try { RegisterTable(); RegisterLocalization(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Clanheim Treasure Table registered."); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Registration failed: {arg}"); } finally { PrefabManager.OnVanillaPrefabsAvailable -= RegisterContent; } } private void RegisterTable() { //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_001b: 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) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown PieceConfig val = new PieceConfig { Name = "$clanheim_tt_name", Description = "$clanheim_tt_desc", PieceTable = "_HammerPieceTable", Category = "Misc", CraftingStation = "piece_workbench" }; val.AddRequirement(new RequirementConfig("FineWood", 20, 0, true)); val.AddRequirement(new RequirementConfig("Bronze", 10, 0, true)); val.AddRequirement(new RequirementConfig("SurtlingCore", 5, 0, true)); val.AddRequirement(new RequirementConfig("DeerHide", 10, 0, true)); val.AddRequirement(new RequirementConfig("AncientSeed", 1, 0, true)); CustomPiece val2 = new CustomPiece("piece_clanheim_treasure_table", "piece_cartographytable", val); GameObject piecePrefab = val2.PiecePrefab; if ((Object)(object)piecePrefab != (Object)null) { MapTable[] componentsInChildren = piecePrefab.GetComponentsInChildren<MapTable>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.Destroy((Object)(object)componentsInChildren[i]); } if ((Object)(object)piecePrefab.GetComponent<TreasureTableBehaviour>() == (Object)null) { piecePrefab.AddComponent<TreasureTableBehaviour>(); } } PieceManager.Instance.AddPiece(val2); } private void RegisterLocalization() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown LocalizationConfig val = new LocalizationConfig("English"); val.Translations["clanheim_tt_name"] = "Clanheim Treasure Table"; val.Translations["clanheim_tt_desc"] = "A Viking war table that binds its treasure hunt to the Viking who placed it."; LocalizationManager.Instance.AddLocalization(val); } } public sealed class TreasureTableBehaviour : MonoBehaviour, Hoverable, Interactable { private ZNetView _nview; private Piece _piece; private const string OwnerIdKey = "ctt_owner_id"; private const string OwnerNameKey = "ctt_owner_name"; private const string StageKey = "ctt_stage"; private const string CompleteKey = "ctt_complete"; private void Awake() { _nview = ((Component)this).GetComponent<ZNetView>(); _piece = ((Component)this).GetComponent<Piece>(); } private void Start() { TryBindToCreator(); } private ZDO GetZdo() { if (!((Object)(object)_nview != (Object)null) || !_nview.IsValid()) { return null; } return _nview.GetZDO(); } private void TryBindToCreator() { ZDO zdo = GetZdo(); if (zdo == null || !string.IsNullOrEmpty(zdo.GetString("ctt_owner_id", ""))) { return; } long num = 0L; try { if ((Object)(object)_piece != (Object)null) { MethodInfo method = typeof(Piece).GetMethod("GetCreator"); if (method != null) { object obj = method.Invoke(_piece, null); if (obj != null) { num = Convert.ToInt64(obj); } } } } catch (Exception ex) { ClanheimTreasureTablePlugin.LogWarning("Could not read table creator yet: " + ex.Message); } if (num != 0L) { zdo.Set("ctt_owner_id", num.ToString()); zdo.Set("ctt_stage", 1); zdo.Set("ctt_complete", false); if ((Object)(object)Player.m_localPlayer != (Object)null && GetLocalPlayerId() == num.ToString()) { zdo.Set("ctt_owner_name", Player.m_localPlayer.GetPlayerName()); } } } public string GetHoverName() { return "$clanheim_tt_name"; } public float GetHoverOffset() { return 1.2f; } public string GetHoverText() { ZDO zdo = GetZdo(); if (zdo == null) { return ""; } TryBindToCreator(); string text = zdo.GetString("ctt_owner_name", ""); string text2 = zdo.GetString("ctt_owner_id", ""); int num = Math.Max(1, zdo.GetInt("ctt_stage", 1)); if (text2 == GetLocalPlayerId() && string.IsNullOrEmpty(text) && (Object)(object)Player.m_localPlayer != (Object)null) { text = Player.m_localPlayer.GetPlayerName(); zdo.Set("ctt_owner_name", text); } string text3 = (string.IsNullOrEmpty(text) ? "Unknown Viking" : text); if (zdo.GetBool("ctt_complete", false)) { return "Clanheim Treasure Table\nOwner: " + text3 + "\nTreasure Hunt Complete"; } if (text2 == GetLocalPlayerId()) { return $"Clanheim Treasure Table\nOwner: {text3}\nStage {num}/8\n" + "[<color=yellow><b>$KEY_Use</b></color>] View quest\n[<color=yellow><b>Alt + $KEY_Use</b></color>] Submit quest"; } return "Clanheim Treasure Table\nOwner: " + text3; } public bool Interact(Humanoid user, bool hold, bool alt) { if (!hold) { Player val = (Player)(object)((user is Player) ? user : null); if (val != null) { ZDO zdo = GetZdo(); if (zdo == null) { return false; } TryBindToCreator(); string localPlayerId = GetLocalPlayerId(); string text = zdo.GetString("ctt_owner_id", ""); if (string.IsNullOrEmpty(text)) { text = localPlayerId; zdo.Set("ctt_owner_id", text); zdo.Set("ctt_owner_name", val.GetPlayerName()); zdo.Set("ctt_stage", 1); } if (text != localPlayerId) { MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)2, "This Treasure Table belongs to " + zdo.GetString("ctt_owner_name", "another Viking") + ".", 0, (Sprite)null, false, true); } return true; } if (string.IsNullOrEmpty(zdo.GetString("ctt_owner_name", ""))) { zdo.Set("ctt_owner_name", val.GetPlayerName()); } if (zdo.GetBool("ctt_complete", false)) { MessageHud instance2 = MessageHud.instance; if (instance2 != null) { instance2.ShowMessage((MessageType)1, "CLANHEIM TREASURE HUNT\n\nComplete.\nThe old hoard has yielded to you.", 0, (Sprite)null, false, true); } return true; } if (alt) { TrySubmit(val, zdo); } else { ShowQuest(val, zdo); } return true; } } return false; } public bool UseItem(Humanoid user, ItemData item) { return false; } private void ShowQuest(Player player, ZDO zdo) { int num = Math.Max(1, zdo.GetInt("ctt_stage", 1)); TreasureQuest treasureQuest = QuestDatabase.Get(num); if (treasureQuest != null) { string text = "CLANHEIM TREASURE HUNT\n" + $"Stage {num}/8 — {treasureQuest.Title}\n\n" + treasureQuest.Lore + "\n\nREQUIRED OFFERINGS\n" + treasureQuest.ProgressText(player) + "\n\nREWARD\n" + treasureQuest.RewardText + "\n\n" + treasureQuest.Clue + "\n\nAlt + Use to submit the complete offering."; MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)1, text, 0, (Sprite)null, false, true); } } } private void TrySubmit(Player player, ZDO zdo) { int num = Math.Max(1, zdo.GetInt("ctt_stage", 1)); TreasureQuest treasureQuest = QuestDatabase.Get(num); if (treasureQuest == null) { return; } List<string> list = new List<string>(); foreach (QuestRequirement requirement in treasureQuest.Requirements) { int num2 = InventoryUtil.Count(((Humanoid)player).GetInventory(), requirement.Prefab); if (num2 < requirement.Amount) { list.Add($"{requirement.Display}: {num2}/{requirement.Amount}"); } } if (list.Count > 0) { MessageHud instance = MessageHud.instance; if (instance != null) { instance.ShowMessage((MessageType)1, $"STAGE {num} INCOMPLETE\n\nMissing:\n- " + string.Join("\n- ", list.ToArray()), 0, (Sprite)null, false, true); } return; } foreach (QuestRequirement requirement2 in treasureQuest.Requirements) { InventoryUtil.Remove(((Humanoid)player).GetInventory(), requirement2.Prefab, requirement2.Amount); } foreach (QuestReward reward in treasureQuest.Rewards) { RewardUtil.Give(player, reward.Prefab, reward.Amount); } if (num >= 8) { zdo.Set("ctt_complete", true); MessageHud instance2 = MessageHud.instance; if (instance2 != null) { instance2.ShowMessage((MessageType)1, "THE HOARD OF CLANHEIM — COMPLETE\n\nEvery mark has been followed and every offering made.\nYou have completed the Clanheim Treasure Hunt.\n\n" + treasureQuest.RewardText, 0, (Sprite)null, false, true); } } else { zdo.Set("ctt_stage", num + 1); TreasureQuest treasureQuest2 = QuestDatabase.Get(num + 1); MessageHud instance3 = MessageHud.instance; if (instance3 != null) { instance3.ShowMessage((MessageType)1, "QUEST COMPLETE — " + treasureQuest.Title + "\n\nReward:\n" + treasureQuest.RewardText + "\n\n" + treasureQuest.Clue + "\n\n" + $"Stage {num + 1} unlocked: {treasureQuest2?.Title}", 0, (Sprite)null, false, true); } } ClanheimTreasureTablePlugin.LogInfo($"Treasure Table: {player.GetPlayerName()} completed Stage {num}."); } private static string GetLocalPlayerId() { if ((Object)(object)Player.m_localPlayer == (Object)null) { return ""; } try { return Player.m_localPlayer.GetPlayerID().ToString(); } catch { return Player.m_localPlayer.GetPlayerName(); } } } public static class InventoryUtil { public static int Count(Inventory inventory, string prefabName) { if (inventory == null) { return 0; } int num = 0; foreach (ItemData allItem in inventory.GetAllItems()) { if ((Object)(object)allItem?.m_dropPrefab != (Object)null && string.Equals(((Object)allItem.m_dropPrefab).name, prefabName, StringComparison.OrdinalIgnoreCase)) { num += allItem.m_stack; } } return num; } public static bool Remove(Inventory inventory, string prefabName, int amount) { if (inventory == null || amount <= 0) { return false; } int num = amount; foreach (ItemData item in new List<ItemData>(inventory.GetAllItems())) { if (num <= 0) { break; } if (!((Object)(object)item?.m_dropPrefab == (Object)null) && string.Equals(((Object)item.m_dropPrefab).name, prefabName, StringComparison.OrdinalIgnoreCase)) { int num2 = Math.Min(item.m_stack, num); inventory.RemoveItem(item, num2); num -= num2; } } return num <= 0; } } public static class RewardUtil { public static void Give(Player player, string prefabName, int amount) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || amount <= 0 || (Object)(object)ObjectDB.instance == (Object)null) { return; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefabName); if ((Object)(object)itemPrefab == (Object)null) { ClanheimTreasureTablePlugin.LogWarning("Reward prefab not found: " + prefabName); return; } ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { return; } int val = Math.Max(1, component.m_itemData.m_shared.m_maxStackSize); int num = amount; int num2 = 0; while (num > 0) { int num3 = Math.Min(val, num); Vector3 val2 = ((Component)player).transform.forward * (1f + (float)num2 * 0.15f) + Vector3.up * 0.8f; ItemDrop component2 = Object.Instantiate<GameObject>(itemPrefab, ((Component)player).transform.position + val2, Quaternion.identity).GetComponent<ItemDrop>(); if ((Object)(object)component2 != (Object)null) { component2.m_itemData.m_stack = num3; } num -= num3; num2++; } } } public sealed class QuestRequirement { public string Prefab; public string Display; public int Amount; public QuestRequirement(string prefab, string display, int amount) { Prefab = prefab; Display = display; Amount = amount; } } public sealed class QuestReward { public string Prefab; public int Amount; public QuestReward(string prefab, int amount) { Prefab = prefab; Amount = amount; } } public sealed class TreasureQuest { public int Stage; public string Title; public string Lore; public string Clue; public string RewardText; public List<QuestRequirement> Requirements = new List<QuestRequirement>(); public List<QuestReward> Rewards = new List<QuestReward>(); public string ProgressText(Player player) { List<string> list = new List<string>(); foreach (QuestRequirement requirement in Requirements) { int num = InventoryUtil.Count(((Humanoid)player).GetInventory(), requirement.Prefab); list.Add(string.Format("{0} {1}: {2}/{3}", (num >= requirement.Amount) ? "✓" : "•", requirement.Display, num, requirement.Amount)); } return string.Join("\n", list.ToArray()); } } public static class QuestDatabase { private static readonly Dictionary<int, TreasureQuest> Q = new Dictionary<int, TreasureQuest> { [1] = new TreasureQuest { Stage = 1, Title = "The First Mark", Lore = "Before the old paths open, the table demands proof that its owner can survive beyond the firelight.", Clue = "The next mark lies where the pines swallow the sun.", RewardText = "150 Coins\n10 Fine Wood\n1 Amber", Requirements = new List<QuestRequirement> { R("DeerHide", "Deer Hide", 20), R("RawMeat", "Raw Meat", 15), R("TrophyEikthyr", "Eikthyr Trophy", 1) }, Rewards = new List<QuestReward> { G("Coins", 150), G("FineWood", 10), G("Amber", 1) } }, [2] = new TreasureQuest { Stage = 2, Title = "Whispers Beneath the Pines", Lore = "The first mark points beneath the Black Forest canopy, where bronze and ancient roots guard the second secret.", Clue = "The dead keep what the living have forgotten.", RewardText = "250 Coins\n10 Bronze\n1 AmberPearl", Requirements = new List<QuestRequirement> { R("Copper", "Copper", 20), R("Tin", "Tin", 20), R("TrollHide", "Troll Hide", 10), R("TrophyTheElder", "The Elder Trophy", 1) }, Rewards = new List<QuestReward> { G("Coins", 250), G("Bronze", 10), G("AmberPearl", 1) } }, [3] = new TreasureQuest { Stage = 3, Title = "The Drowned Warrior", Lore = "A drowned warrior carried the third mark into the Swamp. Only an offering from the dead will call it back.", Clue = "Where stone reaches toward the frozen sky, the fourth mark waits beneath the silver.", RewardText = "350 Coins\n10 Iron\n1 Ruby", Requirements = new List<QuestRequirement> { R("Iron", "Iron", 25), R("Bloodbag", "Bloodbag", 15), R("Guck", "Guck", 10), R("TrophyBonemass", "Bonemass Trophy", 1) }, Rewards = new List<QuestReward> { G("Coins", 350), G("Iron", 10), G("Ruby", 1) } }, [4] = new TreasureQuest { Stage = 4, Title = "Silver Under Snow", Lore = "The fourth rune was carried above the clouds. Wolves, drakes and silver guard the mountain path.", Clue = "Beyond the mountains lies a field where even kings burn.", RewardText = "450 Coins\n10 Silver\n5 Crystal", Requirements = new List<QuestRequirement> { R("Silver", "Silver", 25), R("WolfPelt", "Wolf Pelt", 15), R("FreezeGland", "Freeze Gland", 10), R("TrophyDragonQueen", "Moder Trophy", 1) }, Rewards = new List<QuestReward> { G("Coins", 450), G("Silver", 10), G("Crystal", 5) } }, [5] = new TreasureQuest { Stage = 5, Title = "The Fallen Banner", Lore = "A king's broken banner marks the fifth road. The Plains demand black metal and proof of a fallen ruler.", Clue = "Mist hides the road, but not from those who carry light.", RewardText = "550 Coins\n10 Black Metal\n10 Needle", Requirements = new List<QuestRequirement> { R("BlackMetal", "Black Metal", 30), R("LoxPelt", "Lox Pelt", 15), R("Tar", "Tar", 15), R("TrophyGoblinKing", "Yagluth Trophy", 1) }, Rewards = new List<QuestReward> { G("Coins", 550), G("BlackMetal", 10), G("Needle", 10) } }, [6] = new TreasureQuest { Stage = 6, Title = "Eyes in the Mist", Lore = "The sixth mark is hidden where the world itself disappears. Bring the things that only Mistlands travellers know.", Clue = "The fragments form a key, but an old debt still remains.", RewardText = "700 Coins\n10 Black Marble\n10 Royal Jelly", Requirements = new List<QuestRequirement> { R("BlackMarble", "Black Marble", 30), R("Softtissue", "Soft Tissue", 15), R("Carapace", "Carapace", 20), R("TrophySeekerQueen", "Seeker Queen Trophy", 1) }, Rewards = new List<QuestReward> { G("Coins", 700), G("BlackMarble", 10), G("RoyalJelly", 10) } }, [7] = new TreasureQuest { Stage = 7, Title = "The Seven Seals", Lore = "Seven seals once guarded the hoard. The final seal is not won by one biome, but by proving every road behind you was truly walked.", Clue = "Return the trophies of the old rulers. Only then will the final path reveal itself.", RewardText = "900 Coins\n20 Yggdrasil Wood\n20 Black Marble", Requirements = new List<QuestRequirement> { R("TrophyEikthyr", "Eikthyr Trophy", 1), R("TrophyTheElder", "The Elder Trophy", 1), R("TrophyBonemass", "Bonemass Trophy", 1), R("TrophyDragonQueen", "Moder Trophy", 1), R("TrophyGoblinKing", "Yagluth Trophy", 1), R("TrophySeekerQueen", "Seeker Queen Trophy", 1) }, Rewards = new List<QuestReward> { G("Coins", 900), G("YggdrasilWood", 20), G("BlackMarble", 20) } }, [8] = new TreasureQuest { Stage = 8, Title = "The Hoard of Clanheim", Lore = "Every fragment points home. The last offering is not wealth, but the materials of every age laid together before the old table.", Clue = "The old hoard recognises its keeper.", RewardText = "2000 Coins\n30 Iron\n30 Silver\n30 Black Metal\n10 Ruby\nCompletion prestige", Requirements = new List<QuestRequirement> { R("FineWood", "Fine Wood", 50), R("Bronze", "Bronze", 20), R("Iron", "Iron", 30), R("Silver", "Silver", 30), R("BlackMetal", "Black Metal", 30), R("BlackMarble", "Black Marble", 30) }, Rewards = new List<QuestReward> { G("Coins", 2000), G("Iron", 30), G("Silver", 30), G("BlackMetal", 30), G("Ruby", 10) } } }; private static QuestRequirement R(string prefab, string display, int amount) { return new QuestRequirement(prefab, display, amount); } private static QuestReward G(string prefab, int amount) { return new QuestReward(prefab, amount); } public static TreasureQuest Get(int stage) { if (!Q.TryGetValue(stage, out var value)) { return null; } return value; } } }