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 SakeysMyKvastur v1.0.7
BepInEx/plugins/Sakey's My Kvastur/Sakey's My Kvastur.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using UnityEngine; [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("Sakey's My Kvastur")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Sakey's My Kvastur")] [assembly: AssemblyTitle("Sakey's My Kvastur")] [assembly: AssemblyVersion("1.0.0.0")] namespace SakeysMyKvastur; [BepInPlugin("com.sakey.my.kvastur", "Sakeys My Kvastur", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string PluginGUID = "com.sakey.my.kvastur"; public const string PluginName = "Sakeys My Kvastur"; public const string PluginVersion = "1.0.0"; public const string CONTRACT_PREFAB = "SakeysMyKvasturContract"; public const string KVASTUR_PREFAB = "SakeysMyKvastur"; public const string VANILLA_KVASTUR_PREFAB = "BogWitchKvastur"; public const string BROKEN_BROOM_PREFAB = "SakeysMyKvastur_BrokenBroom"; public const string BROKEN_BROOM_NAME = "$SakeysMyKvastur_BrokenBroomName"; public const string BROKEN_BROOM_DESC = "$SakeysMyKvastur_BrokenBroomDesc"; public const string TROPHY_PREFAB = "TrophyKvastur"; public const string BOGWITCH_PREFAB = "BogWitch"; public const string CONTRACT_NAME = "$SakeysMyKvastur_Name"; public const string CONTRACT_DESC = "$SakeysMyKvastur_Desc"; public const string TRADE_TEXT = "$SakeysMyKvastur_Trade"; public const string MENU_TRADE = "$SakeysMyKvastur_MenuTrade"; public const string MENU_FOLLOW = "$SakeysMyKvastur_MenuFollow"; public const string MENU_STAY = "$SakeysMyKvastur_MenuStay"; public const string MENU_RETRIEVE = "$SakeysMyKvastur_MenuRetrieve"; public const string COMMAND_FOLLOW_STAY = "$SakeysMyKvastur_CommandFollowStay"; public const string COMMAND_FOLLOW = "$SakeysMyKvastur_CommandFollow"; public const string COMMAND_STAY = "$SakeysMyKvastur_CommandStay"; public const string COMMAND_RETRIEVE = "$SakeysMyKvastur_CommandRetrieve"; public const string COMMAND_RENAME = "$SakeysMyKvastur_CommandRename"; public const string COMMAND_SWEEP = "$SakeysMyKvastur_CommandSweep"; public const string COMMAND_FOREST = "$SakeysMyKvastur_CommandForest"; public const string COMMAND_MEADOWS = "$SakeysMyKvastur_CommandMeadows"; public const string COMMAND_SWAMP = "$SakeysMyKvastur_CommandSwamp"; public const string COMMAND_KVASTUR = "$SakeysMyKvastur_CommandKvastur"; public const string FOLLOW_ON = "$SakeysMyKvastur_FollowOn"; public const string FOLLOW_OFF = "$SakeysMyKvastur_FollowOff"; public const string STAY_TEXT = "$SakeysMyKvastur_Stay"; public const string RETRIEVED_TEXT = "$SakeysMyKvastur_Retrieved"; public const string RENAME_TITLE = "$SakeysMyKvastur_RenameTitle"; public const string RENAMED_TEXT = "$SakeysMyKvastur_Renamed"; public const string NOT_OWNER = "$SakeysMyKvastur_NotOwner"; public const string NO_KVASTUR = "$SakeysMyKvastur_NoKvastur"; public const string INVENTORY_FULL = "$SakeysMyKvastur_InventoryFull"; public const string NOT_ENOUGH_ITEM = "$SakeysMyKvastur_NotEnoughItem"; public const string SOLD_TEXT = "$SakeysMyKvastur_Sold"; public const string ALREADY_OWNED = "$SakeysMyKvastur_AlreadyOwned"; public const string DEATH_TEXT = "$SakeysMyKvastur_Death"; internal static ConfigEntry<int> ContractPrice; internal static ConfigEntry<float> PatrolRadius; internal static ConfigEntry<float> ReturnDistance; internal static ConfigEntry<bool> EnableBlackForestShop; internal static ConfigEntry<bool> EnableMeadowsShop; internal static ConfigEntry<bool> EnableSwampShop; internal static ConfigEntry<KeyboardShortcut> CommandKey; internal static ConfigFile ConfigInstance; private Harmony harmony; private int GetKvasturDefaultPrice(string prefabName) { switch (prefabName) { case "Sap": return 1; case "SurtlingCore": return 10; case "MoltenCore": return 20; case "Bloodbag": return 10; case "Entrails": return 10; case "MushroomMagecap": return 10; case "AncientSeed": return 20; case "Iron": return 10; case "DvergrNeedle": return 500; case "FlametalNew": return 150; case "GemstoneBlue": case "GemstoneRed": case "GemstoneGreen": return 200; case "BlackCore": return 600; case "FrostCore": return 1000; case "Gold": return 1000; default: return 10; } } private static void OnContractPriceChanged(object sender, EventArgs e) { if (ContractPrice == null) { return; } int num = Mathf.Max(0, ContractPrice.Value); try { Trader[] array = Object.FindObjectsOfType<Trader>(); foreach (Trader val in array) { if ((Object)(object)val == (Object)null || val.m_items == null) { continue; } foreach (TradeItem item in val.m_items) { if (item != null && !((Object)(object)item.m_prefab == (Object)null) && string.Equals(((Object)((Component)item.m_prefab).gameObject).name.Replace("(Clone)", "").Trim(), "SakeysMyKvasturContract", StringComparison.OrdinalIgnoreCase)) { item.m_price = num; } } } } catch (Exception ex) { Logger.LogWarning((object)("Failed to refresh Kvastur contract price: " + ex.Message)); } Logger.LogInfo((object)$"Kvastur contract price changed to {num}."); } private void Awake() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown SetupConfig(); SetupLocalization(); harmony = new Harmony("com.sakey.my.kvastur"); harmony.PatchAll(); PrefabManager.OnVanillaPrefabsAvailable += RegisterKvasturCreature; PrefabManager.OnVanillaPrefabsAvailable += RegisterContractItem; PrefabManager.OnVanillaPrefabsAvailable += RegisterBrokenBroomItem; Logger.LogInfo((object)"Sakeys My Kvastur 1.0.0 loaded."); } private void SetupConfig() { //IL_0107: Unknown result type (might be due to invalid IL or missing references) ConfigInstance = ((BaseUnityPlugin)this).Config; ContractPrice = ((BaseUnityPlugin)this).Config.Bind<int>("General", "ContractPrice", 1000, "Price of the Kvastur contract at the Bog Witch."); ContractPrice.SettingChanged += OnContractPriceChanged; PatrolRadius = ((BaseUnityPlugin)this).Config.Bind<float>("AI", "PatrolRadius", 10f, "Normal roaming radius around Kvastur's home position."); ReturnDistance = ((BaseUnityPlugin)this).Config.Bind<float>("AI", "ReturnDistance", 20f, "Distance from home before Kvastur returns."); EnableBlackForestShop = ((BaseUnityPlugin)this).Config.Bind<bool>("Shop - Black Forest", "EnableBlackForestShop", false, "Add the Black Forest (Haldor) shop to the F4 selection cycle."); EnableMeadowsShop = ((BaseUnityPlugin)this).Config.Bind<bool>("Shop - Meadows", "EnableMeadowsShop", false, "Add the Meadows (Hildir) shop to the F4 selection cycle."); EnableSwampShop = ((BaseUnityPlugin)this).Config.Bind<bool>("Shop - Swamp", "EnableSwampShop", true, "Add the Swamp (Bog Witch) shop to the F4 selection cycle."); CommandKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "CommandKey", new KeyboardShortcut((KeyCode)285, Array.Empty<KeyCode>()), "Kvastur command selection key. F4 cycles through enabled commands and shops. Press Use/E near your Kvastur to execute. Default: F4."); } private void SetupLocalization() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown CustomLocalization val = new CustomLocalization(); string text = "English"; val.AddTranslation(ref text, new Dictionary<string, string> { { "SakeysMyKvastur_Name", "My Kvastur" }, { "SakeysMyKvastur_Desc", "While it sweeps, it can also use magic to place orders with the Bog Witch. You may keep several, but only one can be magically active at a time. If it breaks, it becomes just an ordinary broom. Take good care of it." }, { "SakeysMyKvastur_BrokenBroomName", "Ordinary Broom" }, { "SakeysMyKvastur_BrokenBroomDesc", "Just an ordinary broom now. Let’s fix it up." }, { "SakeysMyKvastur_MenuTrade", "Trade" }, { "SakeysMyKvastur_MenuFollow", "Follow" }, { "SakeysMyKvastur_MenuStay", "Stay" }, { "SakeysMyKvastur_MenuRetrieve", "Retrieve" }, { "SakeysMyKvastur_CommandFollowStay", "My Kvastur: Follow / Stay" }, { "SakeysMyKvastur_CommandFollow", "My Kvastur: Follow" }, { "SakeysMyKvastur_CommandStay", "My Kvastur: Stay" }, { "SakeysMyKvastur_CommandRetrieve", "My Kvastur: Retrieve" }, { "SakeysMyKvastur_CommandRename", "My Kvastur: Rename" }, { "SakeysMyKvastur_CommandSweep", "My Kvastur: Sweep" }, { "SakeysMyKvastur_CommandForest", "Black Forest Magic Shop" }, { "SakeysMyKvastur_CommandMeadows", "Meadows Magic Shop" }, { "SakeysMyKvastur_CommandSwamp", "Swamp Magic Shop" }, { "SakeysMyKvastur_CommandKvastur", "Kvastur Shop" }, { "SakeysMyKvastur_Trade", "Trade" }, { "SakeysMyKvastur_FollowOn", "My Kvastur will follow you." }, { "SakeysMyKvastur_FollowOff", "My Kvastur will stay here." }, { "SakeysMyKvastur_Stay", "My Kvastur will stay here." }, { "SakeysMyKvastur_Retrieved", "The Kvastur was stored in your inventory." }, { "SakeysMyKvastur_RenameTitle", "Rename Kvastur" }, { "SakeysMyKvastur_Renamed", "The Kvastur's name has been changed." }, { "SakeysMyKvastur_NotOwner", "This Kvastur does not belong to you." }, { "SakeysMyKvastur_NoKvastur", "You do not have a Kvastur nearby." }, { "SakeysMyKvastur_InventoryFull", "Your inventory is full." }, { "SakeysMyKvastur_NotEnoughItem", "You do not have that item." }, { "SakeysMyKvastur_Sold", "Sold for" }, { "SakeysMyKvastur_AlreadyOwned", "You already have a magical Kvastur. This broom remains as a spare." }, { "SakeysMyKvastur_Death", "Your Kvastur was destroyed and its magic was lost. Use a spare broom to make a new contract." }, { "SakeysMyKvastur_Talk1", "Hmm." }, { "SakeysMyKvastur_Talk2", "What do you need?" }, { "SakeysMyKvastur_Greet", "Come closer." }, { "SakeysMyKvastur_Goodbye", "Until next time." }, { "SakeysMyKvastur_StartTrade", "Take a look." }, { "SakeysMyKvastur_Buy", "It’s here!" }, { "SakeysMyKvastur_Delivered", "It’s here!" }, { "SakeysMyKvastur_Sell", "I can use that." }, { "SakeysMyKvastur_SellButton", "Sell" }, { "SakeysMyKvastur_FollowLabel", "Follow" }, { "SakeysMyKvastur_StayLabel", "Stay" }, { "SakeysMyKvastur_RetrieveLabel", "Retrieve Contract" } }); text = "Japanese"; val.AddTranslation(ref text, new Dictionary<string, string> { { "SakeysMyKvastur_Name", "ボグウィッチのほうき" }, { "SakeysMyKvastur_Desc", "魔法のほうき。魔法の力でアイテムをお取り寄せしてくれる。魔女から授かったものなので、怒らせてはいけない。壊れたらただのほうきになる。大事に使おう。" }, { "SakeysMyKvastur_BrokenBroomName", "ただのほうき" }, { "SakeysMyKvastur_BrokenBroomDesc", "ただのほうきになってしまった。修理してあげよう。" }, { "SakeysMyKvastur_Trade", "取引" }, { "SakeysMyKvastur_FollowOn", "ボグウィッチのほうきはついてきます。" }, { "SakeysMyKvastur_FollowOff", "ボグウィッチのほうきはここに留まります。" }, { "SakeysMyKvastur_Stay", "ボグウィッチのほうきはここに留まります。" }, { "SakeysMyKvastur_Retrieved", "クヴァシルを荷物に収納しました。" }, { "SakeysMyKvastur_CommandSweep", "ボグウィッチのほうき:お掃除" }, { "SakeysMyKvastur_CommandForest", "森の魔法通販" }, { "SakeysMyKvastur_CommandMeadows", "草原の魔法通販" }, { "SakeysMyKvastur_CommandSwamp", "沼の魔法通販" }, { "SakeysMyKvastur_CommandKvastur", "クヴァシルのお取り寄せ" }, { "SakeysMyKvastur_NotOwner", "このクヴァシルはあなたのものではありません。" }, { "SakeysMyKvastur_NoKvastur", "近くにあなたのクヴァシルはいません。" }, { "SakeysMyKvastur_InventoryFull", "インベントリがいっぱいです。" }, { "SakeysMyKvastur_NotEnoughItem", "そのアイテムを持っていません。" }, { "SakeysMyKvastur_Sold", "売却しました:" }, { "SakeysMyKvastur_AlreadyOwned", "すでに魔法のクヴァシルを持っています。このほうきは予備として残ります。" }, { "SakeysMyKvastur_Death", "クヴァシルが壊れ、魔力を失いました。予備のほうきがあれば、もう一度契約できます。" }, { "SakeysMyKvastur_MenuTrade", "取引" }, { "SakeysMyKvastur_MenuFollow", "ついてくる" }, { "SakeysMyKvastur_MenuStay", "待機" }, { "SakeysMyKvastur_MenuRetrieve", "回収" }, { "SakeysMyKvastur_CommandFollowStay", "ボグウィッチのほうき:追従/待機" }, { "SakeysMyKvastur_CommandFollow", "ボグウィッチのほうき:追従" }, { "SakeysMyKvastur_CommandStay", "ボグウィッチのほうき:待機" }, { "SakeysMyKvastur_CommandRetrieve", "ボグウィッチのほうき:回収" }, { "SakeysMyKvastur_CommandRename", "クヴァシル:名前変更" }, { "SakeysMyKvastur_RenameTitle", "クヴァシルの名前" }, { "SakeysMyKvastur_Renamed", "クヴァシルの名前を変更しました。" }, { "SakeysMyKvastur_Talk1", "ふむ。" }, { "SakeysMyKvastur_Talk2", "何か用か?" }, { "SakeysMyKvastur_Greet", "近くへどうぞ。" }, { "SakeysMyKvastur_Goodbye", "また会おう。" }, { "SakeysMyKvastur_StartTrade", "見ていってくれ。" }, { "SakeysMyKvastur_Buy", "届いたよ" }, { "SakeysMyKvastur_Delivered", "届いたよ" }, { "SakeysMyKvastur_Sell", "これは使えそうだ。" }, { "SakeysMyKvastur_SellButton", "売る" }, { "SakeysMyKvastur_FollowLabel", "追従" }, { "SakeysMyKvastur_StayLabel", "待機" }, { "SakeysMyKvastur_RetrieveLabel", "荷物に収納" } }); LocalizationManager.Instance.AddLocalization(val); } private void RegisterKvasturCreature() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)PrefabManager.Instance.GetPrefab("BogWitchKvastur") == (Object)null) { Logger.LogError((object)"Base Kvastur prefab 'BogWitchKvastur' was not found."); return; } if ((Object)(object)PrefabManager.Instance.GetPrefab("SakeysMyKvastur") != (Object)null) { Logger.LogInfo((object)"Custom Kvastur prefab 'SakeysMyKvastur' is already registered."); return; } GameObject val = PrefabManager.Instance.CreateClonedPrefab("SakeysMyKvastur", "BogWitchKvastur"); if ((Object)(object)val == (Object)null) { Logger.LogError((object)"Failed to clone 'BogWitchKvastur' into 'SakeysMyKvastur'."); return; } CustomPrefab val2 = new CustomPrefab(val, true); Humanoid component = val.GetComponent<Humanoid>(); if ((Object)(object)component != (Object)null) { ((Character)component).m_name = "$SakeysMyKvastur_Name"; ((Character)component).m_faction = (Faction)0; } MonsterAI component2 = val.GetComponent<MonsterAI>(); if ((Object)(object)component2 != (Object)null) { ((BaseAI)component2).m_idleSound = null; ((BaseAI)component2).m_idleSoundChance = 0f; ((BaseAI)component2).m_idleSoundInterval = 0f; } Character component3 = val.GetComponent<Character>(); if ((Object)(object)component3 != (Object)null) { component3.m_faction = (Faction)0; } RemoveKvasturTrophyDrop(val); if ((Object)(object)val.GetComponent<KvasturCompanion>() == (Object)null) { val.AddComponent<KvasturCompanion>(); } if ((Object)(object)val.GetComponent<KvasturInteractable>() == (Object)null) { val.AddComponent<KvasturInteractable>(); } PrefabManager.Instance.AddPrefab(val2); try { PrefabManager.Instance.RegisterToZNetScene(val); } catch (Exception ex) { Logger.LogDebug((object)("Kvastur current ZNetScene registration skipped/failed: " + ex.Message)); } Logger.LogInfo((object)"Registered custom Kvastur prefab 'SakeysMyKvastur' as a separate clone of 'BogWitchKvastur'. No vanilla Kvastur was modified."); } catch (Exception arg) { Logger.LogError((object)$"Kvastur prefab registration failed: {arg}"); } PrefabManager.OnVanillaPrefabsAvailable -= RegisterKvasturCreature; } private void RemoveKvasturTrophyDrop(GameObject prefab) { try { CharacterDrop component = prefab.GetComponent<CharacterDrop>(); if (!((Object)(object)component == (Object)null) && component.m_drops != null) { component.m_drops.Clear(); } } catch (Exception ex) { Logger.LogWarning((object)("Failed to remove Kvastur Trophy drop: " + ex.Message)); } } private void ConfigureKvasturDeathDrop() { //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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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_00cc: Expected O, but got Unknown try { GameObject prefab = PrefabManager.Instance.GetPrefab("SakeysMyKvastur"); if (!((Object)(object)prefab == (Object)null)) { CharacterDrop val = prefab.GetComponent<CharacterDrop>(); if ((Object)(object)val == (Object)null) { val = prefab.AddComponent<CharacterDrop>(); } GameObject val2 = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab("SakeysMyKvastur_BrokenBroom") : null); if ((Object)(object)val2 == (Object)null) { val2 = PrefabManager.Instance.GetPrefab("SakeysMyKvastur_BrokenBroom"); } if ((Object)(object)val2 == (Object)null) { Logger.LogWarning((object)"Broken broom prefab was not available while configuring Kvastur drops."); return; } val.m_drops.Clear(); val.m_drops.Add(new Drop { m_prefab = val2, m_amountMin = 1, m_amountMax = 1, m_chance = 1f, m_onePerPlayer = false, m_levelMultiplier = false }); Logger.LogInfo((object)"Configured My Kvastur death drop: 1x Broken Broom only."); } } catch (Exception arg) { Logger.LogWarning((object)$"Failed to configure Kvastur death drop: {arg}"); } } private void RegisterContractItem() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) try { CustomItem val = new CustomItem("SakeysMyKvasturContract", "TrophyKvastur"); ItemDrop itemDrop = val.ItemDrop; if ((Object)(object)itemDrop == (Object)null) { Logger.LogError((object)"Kvastur contract ItemDrop could not be created."); return; } itemDrop.m_itemData.m_shared.m_name = "$SakeysMyKvastur_Name"; itemDrop.m_itemData.m_shared.m_description = "$SakeysMyKvastur_Desc"; itemDrop.m_itemData.m_shared.m_itemType = (ItemType)16; itemDrop.m_itemData.m_shared.m_trophyPos = Vector2Int.zero; itemDrop.m_itemData.m_shared.m_questItem = false; itemDrop.m_itemData.m_shared.m_maxStackSize = 1; itemDrop.m_itemData.m_dropPrefab = val.ItemPrefab; if ((Object)(object)val.ItemPrefab.GetComponent<KvasturContractDrop>() == (Object)null) { val.ItemPrefab.AddComponent<KvasturContractDrop>(); } if (!ItemManager.Instance.AddItem(val)) { Logger.LogError((object)"Failed to register Kvastur contract."); } else { Logger.LogInfo((object)"Kvastur contract registered."); } } catch (Exception arg) { Logger.LogError((object)$"Kvastur contract registration failed: {arg}"); } PrefabManager.OnVanillaPrefabsAvailable -= RegisterContractItem; } private void RegisterBrokenBroomItem() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) try { CustomItem val = new CustomItem("SakeysMyKvastur_BrokenBroom", "TrophyKvastur"); ItemDrop itemDrop = val.ItemDrop; if ((Object)(object)itemDrop == (Object)null) { Logger.LogError((object)"Broken broom ItemDrop could not be created."); return; } itemDrop.m_itemData.m_shared.m_name = "$SakeysMyKvastur_BrokenBroomName"; itemDrop.m_itemData.m_shared.m_description = "$SakeysMyKvastur_BrokenBroomDesc"; itemDrop.m_itemData.m_shared.m_itemType = (ItemType)16; itemDrop.m_itemData.m_shared.m_trophyPos = Vector2Int.zero; itemDrop.m_itemData.m_shared.m_questItem = false; itemDrop.m_itemData.m_shared.m_maxStackSize = 20; itemDrop.m_itemData.m_dropPrefab = val.ItemPrefab; if (!ItemManager.Instance.AddItem(val)) { Logger.LogError((object)"Failed to register broken broom item."); } else { Logger.LogInfo((object)"Broken broom item registered."); RegisterRepairRecipe(); ConfigureKvasturDeathDrop(); } } catch (Exception arg) { Logger.LogError((object)$"Broken broom registration failed: {arg}"); } PrefabManager.OnVanillaPrefabsAvailable -= RegisterBrokenBroomItem; } private void RegisterRepairRecipe() { //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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown try { RecipeConfig val = new RecipeConfig { Name = "SakeysMyKvastur_Repair", Item = "SakeysMyKvasturContract", Amount = 1, CraftingStation = "piece_workbench", MinStationLevel = 1 }; val.AddRequirement("SakeysMyKvastur_BrokenBroom", 1, 0); val.AddRequirement("MeadEitrMinor", 1, 0); val.AddRequirement("LeatherScraps", 10, 0); val.AddRequirement("FineWood", 10, 0); bool flag = ItemManager.Instance.AddRecipe(new CustomRecipe(val)); Logger.LogInfo((object)$"Kvastur repair recipe registered: {flag}"); } catch (Exception arg) { Logger.LogError((object)$"Kvastur repair recipe registration failed: {arg}"); } } private void OnDestroy() { PrefabManager.OnVanillaPrefabsAvailable -= RegisterKvasturCreature; PrefabManager.OnVanillaPrefabsAvailable -= RegisterContractItem; PrefabManager.OnVanillaPrefabsAvailable -= RegisterBrokenBroomItem; Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } } public class KvasturContractDrop : MonoBehaviour { private bool processed; private void Start() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) if (processed) { return; } processed = true; if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { Logger.LogWarning((object)"Kvastur contract dropped, but local player was not found."); } else if ((Object)(object)KvasturCompanion.FindOwned(localPlayer.GetPlayerID()) != (Object)null) { ((Character)localPlayer).Message((MessageType)2, "$SakeysMyKvastur_AlreadyOwned", 0, (Sprite)null, false); Logger.LogInfo((object)"Player already owns a Kvastur; spare contract was left untouched."); } else if (SpawnKvastur(((Component)this).transform.position, localPlayer)) { if ((Object)(object)ZNetScene.instance != (Object)null) { ZNetScene.instance.Destroy(((Component)this).gameObject); } else { Object.Destroy((Object)(object)((Component)this).gameObject); } } } private bool SpawnKvastur(Vector3 position, Player owner) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)owner == (Object)null) { return false; } GameObject prefab = PrefabManager.Instance.GetPrefab("SakeysMyKvastur"); if ((Object)(object)prefab == (Object)null) { Logger.LogError((object)"Custom Kvastur prefab 'SakeysMyKvastur' was not found. No broom was spawned."); return false; } GameObject val = Object.Instantiate<GameObject>(prefab, position, ((Component)owner).transform.rotation); if ((Object)(object)val == (Object)null) { return false; } ZNetView component = val.GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { Logger.LogError((object)"Spawned SakeysMyKvastur has no valid ZNetView."); Object.Destroy((Object)(object)val); return false; } ZDO zDO = component.GetZDO(); if (zDO == null) { Logger.LogError((object)"Spawned SakeysMyKvastur has no ZDO."); Object.Destroy((Object)(object)val); return false; } zDO.Set("SakeysMyKvastur_Owner", owner.GetPlayerID()); zDO.Set("SakeysMyKvastur_HomeX", position.x); zDO.Set("SakeysMyKvastur_HomeY", position.y); zDO.Set("SakeysMyKvastur_HomeZ", position.z); zDO.Set("SakeysMyKvastur_Follow", false); KvasturCompanion kvasturCompanion = val.GetComponent<KvasturCompanion>(); if ((Object)(object)kvasturCompanion == (Object)null) { kvasturCompanion = val.AddComponent<KvasturCompanion>(); } kvasturCompanion.Initialize(owner.GetPlayerID(), position); KvasturInteractable kvasturInteractable = val.GetComponent<KvasturInteractable>(); if ((Object)(object)kvasturInteractable == (Object)null) { kvasturInteractable = val.AddComponent<KvasturInteractable>(); } kvasturInteractable.Initialize(); Humanoid component2 = val.GetComponent<Humanoid>(); if ((Object)(object)component2 != (Object)null) { ((Character)component2).m_faction = (Faction)0; kvasturCompanion.ApplyCustomName(); } Logger.LogInfo((object)string.Format("Spawned custom {0} at {1} for player {2}. Vanilla {3} was not touched.", "SakeysMyKvastur", position, owner.GetPlayerID(), "BogWitchKvastur")); return true; } } public class KvasturCompanion : MonoBehaviour { public static class KvasturPetEffect { private static object petEffect; private static MethodInfo createMethod; private static FieldInfo effectPrefabsField; public static void Create(Vector3 position, Quaternion rotation) { //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_017a: 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) try { if (petEffect == null || createMethod == null) { Initialize(); } if (petEffect == null || createMethod == null || effectPrefabsField == null || !(effectPrefabsField.GetValue(petEffect) is Array { Length: not 0 } array)) { return; } List<(AudioSource, bool, bool, float)> list = new List<(AudioSource, bool, bool, float)>(); foreach (object item in array) { if (item == null) { continue; } FieldInfo fieldInfo = AccessTools.Field(item.GetType(), "m_prefab"); if (fieldInfo == null) { continue; } object? value = fieldInfo.GetValue(item); GameObject val = (GameObject)((value is GameObject) ? value : null); if ((Object)(object)val == (Object)null) { continue; } AudioSource[] componentsInChildren = val.GetComponentsInChildren<AudioSource>(true); foreach (AudioSource val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null)) { list.Add((val2, ((Behaviour)val2).enabled, val2.mute, val2.volume)); val2.mute = true; val2.volume = 0f; } } } try { createMethod.Invoke(petEffect, new object[6] { position, rotation, null, 1f, -1, (object)default(ZDOID) }); } finally { foreach (var item2 in list) { if (!((Object)(object)item2.Item1 == (Object)null)) { ((Behaviour)item2.Item1).enabled = item2.Item2; item2.Item1.mute = item2.Item3; item2.Item1.volume = item2.Item4; } } } } catch (Exception ex) { Logger.LogDebug((object)("Kvastur pet effect failed: " + ex.Message)); } } private static void Initialize() { GameObject val = null; if ((Object)(object)ZNetScene.instance != (Object)null) { val = ZNetScene.instance.GetPrefab("Boar"); } if ((Object)(object)val == (Object)null) { val = PrefabManager.Instance.GetPrefab("Boar"); } if ((Object)(object)val == (Object)null) { return; } Component component = val.GetComponent("Tameable"); if ((Object)(object)component == (Object)null) { return; } FieldInfo fieldInfo = AccessTools.Field(((object)component).GetType(), "m_petEffect"); if (fieldInfo == null) { return; } petEffect = fieldInfo.GetValue(component); if (petEffect != null) { effectPrefabsField = AccessTools.Field(petEffect.GetType(), "m_effectPrefabs"); if (!(effectPrefabsField == null)) { createMethod = AccessTools.Method(petEffect.GetType(), "Create", new Type[6] { typeof(Vector3), typeof(Quaternion), typeof(Transform), typeof(float), typeof(int), typeof(ZDOID) }, (Type[])null); } } } } private static readonly FieldInfo ZNetSceneInstancesField = AccessTools.Field(typeof(ZNetScene), "m_instances"); private const string OWNER_KEY = "SakeysMyKvastur_Owner"; private const string HOME_X_KEY = "SakeysMyKvastur_HomeX"; private const string HOME_Y_KEY = "SakeysMyKvastur_HomeY"; private const string HOME_Z_KEY = "SakeysMyKvastur_HomeZ"; private const string FOLLOW_KEY = "SakeysMyKvastur_Follow"; private const string ORIGINAL_VANILLA_KEY = "SakeysMyKvastur_OriginalVanilla"; private const string DEAD_KEY = "SakeysMyKvastur_Dead"; private const string NAME_KEY = "SakeysMyKvastur_Name"; private const string PLAYER_NAME_KEY = "SakeysMyKvastur_PlayerName"; private ZNetView nview; private MonsterAI monsterAI; private BaseAI baseAI; private Humanoid humanoid; private Vector3 homePosition; private bool initialized; private bool trading; private bool deathHandled; private float nextNetworkDiagnostic; private int networkDiagnosticCount; private bool destroyLogged; private float nextAIUpdate; private static readonly MethodInfo MoveToMethod = AccessTools.Method(typeof(BaseAI), "MoveTo", new Type[4] { typeof(float), typeof(Vector3), typeof(float), typeof(bool) }, (Type[])null); private static readonly MethodInfo RandomMovementAroundPointMethod = AccessTools.Method(typeof(BaseAI), "RandomMovementArroundPoint", new Type[4] { typeof(float), typeof(Vector3), typeof(float), typeof(bool) }, (Type[])null); private static readonly MethodInfo StopMovingMethod = AccessTools.Method(typeof(BaseAI), "StopMoving", Type.EmptyTypes, (Type[])null); private void Awake() { nview = ((Component)this).GetComponent<ZNetView>(); monsterAI = ((Component)this).GetComponent<MonsterAI>(); baseAI = ((Component)this).GetComponent<BaseAI>(); humanoid = ((Component)this).GetComponent<Humanoid>(); LoadState(); ApplyCustomName(); initialized = true; Logger.LogInfo((object)($"[Kvastur NET-DIAG] Awake: GO='{((Object)((Component)this).gameObject).name}', active={((Component)this).gameObject.activeInHierarchy}, " + "ZNetView=" + (((Object)(object)nview != (Object)null) ? "OK" : "NULL") + ", " + $"valid={(Object)(object)nview != (Object)null && nview.IsValid()}, " + "ZDO=" + (((Object)(object)nview != (Object)null && nview.GetZDO() != null) ? "OK" : "NULL"))); nextNetworkDiagnostic = Time.unscaledTime + 1f; } private void FixedUpdate() { if (!initialized) { return; } if (networkDiagnosticCount < 3 && Time.unscaledTime >= nextNetworkDiagnostic) { networkDiagnosticCount++; LogNetworkDiagnostic($"periodic#{networkDiagnosticCount}"); nextNetworkDiagnostic = Time.unscaledTime + 5f; } if (trading) { if (StoreGui.IsVisible()) { StopKvasturMovement(); if ((Object)(object)monsterAI != (Object)null) { monsterAI.SetFollowTarget((GameObject)null); } return; } trading = false; } if (!((Object)(object)nview == (Object)null) && nview.IsValid() && nview.IsOwner() && !(Time.time < nextAIUpdate)) { nextAIUpdate = Time.time + 0.1f; UpdateAI(); } } public void Initialize(long ownerID, Vector3 home) { //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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) nview = ((Component)this).GetComponent<ZNetView>(); monsterAI = ((Component)this).GetComponent<MonsterAI>(); baseAI = ((Component)this).GetComponent<BaseAI>(); humanoid = ((Component)this).GetComponent<Humanoid>(); homePosition = home; initialized = true; if ((Object)(object)nview != (Object)null && nview.IsValid() && nview.IsOwner()) { ZDO zDO = nview.GetZDO(); zDO.Set("SakeysMyKvastur_Owner", ownerID); SaveHome(home); zDO.Set("SakeysMyKvastur_Follow", false); } if ((Object)(object)baseAI != (Object)null) { baseAI.m_randomMoveRange = Plugin.PatrolRadius.Value; baseAI.m_randomMoveInterval = 20f; } if ((Object)(object)humanoid != (Object)null) { ((Character)humanoid).m_faction = (Faction)0; } } public string GetCustomName() { string text = string.Empty; try { if ((Object)(object)nview != (Object)null && nview.IsValid()) { ZDO zDO = nview.GetZDO(); if (zDO != null) { text = zDO.GetString("SakeysMyKvastur_Name", string.Empty); } } } catch { text = string.Empty; } if (!string.IsNullOrWhiteSpace(text)) { return text; } Player val = FindOwner(); if ((Object)(object)val != (Object)null && val.m_customData != null && val.m_customData.TryGetValue("SakeysMyKvastur_PlayerName", out var value)) { return value ?? string.Empty; } return string.Empty; } public void ApplyCustomName() { if ((Object)(object)humanoid == (Object)null) { humanoid = ((Component)this).GetComponent<Humanoid>(); } if (!((Object)(object)humanoid == (Object)null)) { string customName = GetCustomName(); ((Character)humanoid).m_name = (string.IsNullOrWhiteSpace(customName) ? "$SakeysMyKvastur_Name" : customName); } } public bool SetCustomName(string text) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || !IsOwner(localPlayer)) { return false; } string text2 = text ?? string.Empty; text2 = text2.Trim(); text2 = new string(text2.Where((char c) => !char.IsControl(c)).ToArray()); if (text2.Length > 24) { text2 = text2.Substring(0, 24); } if ((Object)(object)nview == (Object)null || !nview.IsValid() || !nview.IsOwner()) { return false; } ZDO zDO = nview.GetZDO(); if (zDO == null) { return false; } zDO.Set("SakeysMyKvastur_Name", text2); if (localPlayer.m_customData != null) { if (string.IsNullOrEmpty(text2)) { localPlayer.m_customData.Remove("SakeysMyKvastur_PlayerName"); } else { localPlayer.m_customData["SakeysMyKvastur_PlayerName"] = text2; } try { Game instance = Game.instance; if ((Object)(object)instance != (Object)null) { PlayerProfile playerProfile = instance.GetPlayerProfile(); if (playerProfile != null) { playerProfile.SavePlayerData(localPlayer); } } } catch (Exception ex) { Logger.LogDebug((object)("Kvastur custom name player-data save failed: " + ex.Message)); } } ApplyCustomName(); return true; } private void LogNetworkDiagnostic(string reason) { try { ZNetScene instance = ZNetScene.instance; bool flag = (Object)(object)instance != (Object)null; bool flag2 = (Object)(object)nview != (Object)null; bool flag3 = flag2 && nview.IsValid(); ZDO val = (flag3 ? nview.GetZDO() : null); bool flag4 = val != null; bool flag5 = false; bool flag6 = false; string arg = "(unknown)"; IDictionary<ZDO, ZNetView> dictionary = null; if (flag && ZNetSceneInstancesField != null) { dictionary = ZNetSceneInstancesField.GetValue(instance) as IDictionary<ZDO, ZNetView>; } if (flag && flag4 && dictionary != null) { flag5 = dictionary.ContainsKey(val); if (dictionary.TryGetValue(val, out var value)) { flag6 = (Object)(object)value == (Object)(object)nview; } try { GameObject prefab = instance.GetPrefab(val.GetPrefab()); arg = (((Object)(object)prefab != (Object)null) ? ((Object)prefab).name : $"(hash:{val.GetPrefab()})"); } catch { arg = "(prefab lookup failed)"; } } Logger.LogInfo((object)("[Kvastur NET-DIAG] " + reason + ": GO='" + (((Object)(object)((Component)this).gameObject != (Object)null) ? ((Object)((Component)this).gameObject).name : "<null>") + "', " + $"GOActive={(Object)(object)((Component)this).gameObject != (Object)null && ((Component)this).gameObject.activeInHierarchy}, " + $"ZNetScene={flag}, ZNetView={flag2}, Valid={flag3}, ZDO={flag4}, " + "instancesField=" + ((ZNetSceneInstancesField != null) ? "OK" : "MISSING") + ", instancesRead=" + ((dictionary != null) ? "OK" : "FAILED") + ", " + $"m_instances.ContainsZDO={flag5}, mappedToThisView={flag6}, " + $"prefab='{arg}', IsOwner={flag3 && nview.IsOwner()}")); } catch (Exception arg2) { Logger.LogWarning((object)$"[Kvastur NET-DIAG] {reason}: diagnostic itself failed: {arg2}"); } } private void OnDisable() { LogNetworkDiagnostic("OnDisable"); } private void OnDestroy() { if (!destroyLogged) { destroyLogged = true; LogNetworkDiagnostic("OnDestroy"); } } private void LoadState() { //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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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) if ((Object)(object)nview == (Object)null || !nview.IsValid()) { homePosition = ((Component)this).transform.position; return; } ZDO zDO = nview.GetZDO(); if (zDO == null) { homePosition = ((Component)this).transform.position; return; } float num = zDO.GetFloat("SakeysMyKvastur_HomeX", ((Component)this).transform.position.x); float num2 = zDO.GetFloat("SakeysMyKvastur_HomeY", ((Component)this).transform.position.y); float num3 = zDO.GetFloat("SakeysMyKvastur_HomeZ", ((Component)this).transform.position.z); homePosition = new Vector3(num, num2, num3); } private void StopKvasturMovement() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)baseAI == (Object)null) { return; } try { if (StopMovingMethod != null) { StopMovingMethod.Invoke(baseAI, null); } else if (MoveToMethod != null) { MoveToMethod.Invoke(baseAI, new object[4] { 0.1f, ((Component)this).transform.position, 0f, false }); } } catch (Exception ex) { Logger.LogDebug((object)("Kvastur stop movement failed: " + ex.Message)); } } private void UpdateAI() { if (!((Object)(object)baseAI == (Object)null)) { if (IsFollowing()) { UpdateFollow(); } else { UpdatePatrol(); } } } private void UpdateFollow() { Player val = FindOwner(); if (!((Object)(object)val == (Object)null) && !((Object)(object)monsterAI == (Object)null)) { baseAI.m_randomMoveRange = 0f; monsterAI.SetFollowTarget(((Component)val).gameObject); } } private void UpdatePatrol() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)baseAI != (Object)null) { baseAI.m_randomMoveRange = Plugin.PatrolRadius.Value; } if ((Object)(object)monsterAI != (Object)null) { monsterAI.SetFollowTarget((GameObject)null); } if (Vector3.Distance(((Component)this).transform.position, homePosition) > Plugin.ReturnDistance.Value) { MoveToHome(); } else if (RandomMovementAroundPointMethod != null) { try { RandomMovementAroundPointMethod.Invoke(baseAI, new object[4] { 0.5f, homePosition, Plugin.PatrolRadius.Value, false }); } catch (Exception ex) { Logger.LogDebug((object)("Kvastur random movement failed: " + ex.Message)); } } } private void MoveToHome() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (MoveToMethod == null || (Object)(object)baseAI == (Object)null) { return; } try { MoveToMethod.Invoke(baseAI, new object[4] { 0.5f, homePosition, 2f, true }); } catch (Exception ex) { Logger.LogDebug((object)("Kvastur return movement failed: " + ex.Message)); } } public long GetOwnerID() { if ((Object)(object)nview == (Object)null || !nview.IsValid()) { return 0L; } ZDO zDO = nview.GetZDO(); if (zDO == null) { return 0L; } return zDO.GetLong("SakeysMyKvastur_Owner", 0L); } public bool IsOwner(Player player) { if ((Object)(object)player == (Object)null) { return false; } return GetOwnerID() == player.GetPlayerID(); } public bool IsFollowing() { if ((Object)(object)nview == (Object)null || !nview.IsValid()) { return false; } ZDO zDO = nview.GetZDO(); if (zDO == null) { return false; } return zDO.GetBool("SakeysMyKvastur_Follow", false); } public void StopForCommand() { StopKvasturMovement(); if ((Object)(object)monsterAI != (Object)null) { monsterAI.SetFollowTarget((GameObject)null); } } public void Follow() { if (!((Object)(object)nview == (Object)null) && nview.IsValid() && nview.IsOwner()) { nview.GetZDO().Set("SakeysMyKvastur_Follow", true); } } public void StayHere() { //IL_002f: 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_004c: 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_0054: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)nview == (Object)null) && nview.IsValid() && nview.IsOwner()) { Vector3 position = ((Component)this).transform.position; nview.GetZDO().Set("SakeysMyKvastur_Follow", false); SaveHome(position); homePosition = position; if ((Object)(object)monsterAI != (Object)null) { monsterAI.SetFollowTarget((GameObject)null); } } } private void SaveHome(Vector3 position) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)nview == (Object)null) && nview.IsValid() && nview.IsOwner()) { ZDO zDO = nview.GetZDO(); if (zDO != null) { zDO.Set("SakeysMyKvastur_HomeX", position.x); zDO.Set("SakeysMyKvastur_HomeY", position.y); zDO.Set("SakeysMyKvastur_HomeZ", position.z); } } } public void BeginTrading() { trading = true; StopKvasturMovement(); if ((Object)(object)monsterAI != (Object)null) { monsterAI.SetFollowTarget((GameObject)null); } } public void EndTrading() { trading = false; } public bool IsTrading() { return trading; } public void HandleDeath() { if (deathHandled) { return; } deathHandled = true; Player val = FindOwner(); if ((Object)(object)nview != (Object)null && nview.IsValid() && nview.IsOwner()) { ZDO zDO = nview.GetZDO(); if (zDO != null) { zDO.Set("SakeysMyKvastur_Dead", true); zDO.Set("SakeysMyKvastur_Owner", 0L); zDO.Set("SakeysMyKvastur_Follow", false); } } if ((Object)(object)val != (Object)null && (Object)(object)val == (Object)(object)Player.m_localPlayer) { ((Character)val).Message((MessageType)2, "$SakeysMyKvastur_Death", 0, (Sprite)null, false); } Logger.LogInfo((object)"Kvastur companion died; magical ownership cleared."); } public void Retrieve() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } if (!IsOwner(localPlayer)) { ((Character)localPlayer).Message((MessageType)2, "$SakeysMyKvastur_NotOwner", 0, (Sprite)null, false); } else { if ((Object)(object)nview == (Object)null || !nview.IsValid() || !nview.IsOwner()) { return; } GameObject val = ObjectDB.instance.GetItemPrefab("SakeysMyKvasturContract"); if ((Object)(object)val == (Object)null) { val = PrefabManager.Instance.GetPrefab("SakeysMyKvasturContract"); } if ((Object)(object)val == (Object)null) { Logger.LogError((object)"Kvastur contract prefab not found."); return; } Inventory inventory = ((Humanoid)localPlayer).GetInventory(); if (inventory != null) { if (!inventory.AddItem(val, 1)) { ((Character)localPlayer).Message((MessageType)2, "$SakeysMyKvastur_InventoryFull", 0, (Sprite)null, false); return; } ((Character)localPlayer).Message((MessageType)2, "$SakeysMyKvastur_Retrieved", 0, (Sprite)null, false); ZNetScene.instance.Destroy(((Component)this).gameObject); } } } private Player FindOwner() { long ownerID = GetOwnerID(); if (ownerID == 0L) { return null; } foreach (Player allPlayer in Player.GetAllPlayers()) { if ((Object)(object)allPlayer != (Object)null && allPlayer.GetPlayerID() == ownerID) { return allPlayer; } } return null; } public static KvasturCompanion FindOwned(long ownerID) { KvasturCompanion[] array = Object.FindObjectsOfType<KvasturCompanion>(); foreach (KvasturCompanion kvasturCompanion in array) { if ((Object)(object)kvasturCompanion != (Object)null && kvasturCompanion.GetOwnerID() == ownerID) { return kvasturCompanion; } } return null; } } [HarmonyPatch(typeof(Character), "OnDeath")] public static class KvasturDeathPatch { [HarmonyPrefix] private static void Prefix(Character __instance) { if (!((Object)(object)__instance == (Object)null)) { KvasturCompanion component = ((Component)__instance).GetComponent<KvasturCompanion>(); if (!((Object)(object)component == (Object)null)) { component.HandleDeath(); } } } } [HarmonyPatch(typeof(Character), "Message", new Type[] { typeof(MessageType), typeof(string), typeof(int), typeof(Sprite), typeof(bool) })] public static class KvasturCharacterMessagePatch { [HarmonyPrefix] private static bool Prefix(Character __instance) { if ((Object)(object)__instance == (Object)null) { return true; } return (Object)(object)((Component)__instance).GetComponent<KvasturCompanion>() == (Object)null; } } [HarmonyPatch(typeof(Trader), "Say", new Type[] { typeof(string), typeof(string) })] public static class KvasturTraderSayStringPatch { [HarmonyPrefix] private static bool Prefix(Trader __instance) { if ((Object)(object)__instance == (Object)null) { return true; } return (Object)(object)((Component)__instance).GetComponent<KvasturCompanion>() == (Object)null; } } [HarmonyPatch(typeof(Trader), "Say", new Type[] { typeof(List<string>), typeof(string) })] public static class KvasturTraderSayListPatch { [HarmonyPrefix] private static bool Prefix(Trader __instance) { if ((Object)(object)__instance == (Object)null) { return true; } return (Object)(object)((Component)__instance).GetComponent<KvasturCompanion>() == (Object)null; } } [HarmonyPatch(typeof(Trader), "OnBought")] public static class KvasturBoughtEffectPatch { [HarmonyPostfix] private static void Postfix(Trader __instance, TradeItem item) { if (!((Object)(object)__instance == (Object)null) && item != null && !((Object)(object)item.m_prefab == (Object)null) && !((Object)(object)((Component)__instance).GetComponent<KvasturCompanion>() == (Object)null)) { KvasturPurchaseFeedback kvasturPurchaseFeedback = ((Component)__instance).GetComponent<KvasturPurchaseFeedback>(); if ((Object)(object)kvasturPurchaseFeedback == (Object)null) { kvasturPurchaseFeedback = ((Component)__instance).gameObject.AddComponent<KvasturPurchaseFeedback>(); } kvasturPurchaseFeedback.Queue(); } } } public class KvasturPurchaseFeedback : MonoBehaviour { private bool queued; public void Queue() { queued = true; } private void LateUpdate() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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) //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (queued) { queued = false; KvasturCompanion component = ((Component)this).GetComponent<KvasturCompanion>(); if (!((Object)(object)component == (Object)null)) { KvasturCompanion.KvasturPetEffect.Create(((Component)component).transform.position + Vector3.up * 0.5f, ((Component)component).transform.rotation); } } } } [HarmonyPatch(typeof(KvasturInteractable), "Interact")] public static class KvasturControllerCyclePatch { [HarmonyPrefix] private static bool Prefix(Humanoid user) { if ((Object)(object)user == (Object)null || (Object)(object)user != (Object)(object)Player.m_localPlayer) { return true; } return !KvasturInputController.SuppressInteractThisFrame(); } } public sealed class KvasturNameReceiver : TextReceiver { private readonly KvasturCompanion companion; public KvasturNameReceiver(KvasturCompanion companion) { this.companion = companion; } public string GetText() { if (!((Object)(object)companion != (Object)null)) { return string.Empty; } return companion.GetCustomName(); } public void SetText(string text) { if (!((Object)(object)companion == (Object)null) && companion.SetCustomName(text)) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { ((Character)localPlayer).Message((MessageType)2, "$SakeysMyKvastur_Renamed", 0, (Sprite)null, false); } } } } public class KvasturInteractable : MonoBehaviour, Interactable { private enum ShopCategory { BlackForest, Meadows, Swamp, Kvastur } private KvasturCompanion companion; private Trader trader; private static readonly List<GameObject> temporaryTraderProbeObjects = new List<GameObject>(); private void Awake() { Initialize(); } public void Initialize() { companion = ((Component)this).GetComponent<KvasturCompanion>(); trader = ((Component)this).GetComponent<Trader>(); if ((Object)(object)trader == (Object)null) { trader = ((Component)this).gameObject.AddComponent<Trader>(); } ((Behaviour)trader).enabled = false; ConfigureTrader(); } private void ConfigureTrader() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown if (!((Object)(object)trader == (Object)null)) { trader.m_name = "$SakeysMyKvastur_Name"; trader.m_standRange = 3.5f; trader.m_greetRange = 7f; trader.m_byeRange = 8f; trader.m_randomTalkInterval = 18f; trader.m_randomTalkFX = new EffectList(); trader.m_randomGreetFX = new EffectList(); trader.m_randomGoodbyeFX = new EffectList(); trader.m_randomStartTradeFX = new EffectList(); trader.m_randomBuyFX = new EffectList(); trader.m_randomSellFX = new EffectList(); trader.m_randomTalk = new List<string>(); trader.m_randomGreets = new List<string>(); trader.m_randomGoodbye = new List<string>(); trader.m_randomStartTrade = new List<string>(); trader.m_randomBuy = new List<string>(); trader.m_randomSell = new List<string>(); trader.m_items = new List<TradeItem>(); trader.m_useItems = new List<TraderUseItem>(); } } public string GetHoverText() { return LocalizationManager.Instance.GetLocalization().TryTranslate("$SakeysMyKvastur_Name") + "\n[<color=yellow><b>$KEY_Use</b></color>] " + LocalizationManager.Instance.GetLocalization().TryTranslate("$SakeysMyKvastur_Trade"); } public string GetHoverName() { if ((Object)(object)companion == (Object)null) { Initialize(); } string text = (((Object)(object)companion != (Object)null) ? companion.GetCustomName() : string.Empty); if (!string.IsNullOrWhiteSpace(text)) { return text; } return LocalizationManager.Instance.GetLocalization().TryTranslate("$SakeysMyKvastur_Name"); } public bool Interact(Humanoid user, bool hold, bool alt) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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) if ((Object)(object)companion == (Object)null || (Object)(object)trader == (Object)null) { Initialize(); } if (hold || (Object)(object)companion == (Object)null) { return false; } if (StoreGui.IsVisible() || InventoryGui.IsVisible() || Menu.IsVisible()) { return false; } Player val = (Player)(object)((user is Player) ? user : null); if ((Object)(object)val == (Object)null) { return false; } if (!companion.IsOwner(val)) { ((Character)val).Message((MessageType)2, "$SakeysMyKvastur_NotOwner", 0, (Sprite)null, false); return true; } KvasturCompanion.KvasturPetEffect.Create(((Component)companion).transform.position + Vector3.up * 0.5f, ((Component)companion).transform.rotation); Logger.LogInfo((object)$"Kvastur command executed: index={KvasturCommandMenu.SelectedIndex}."); KvasturCommandMenu.Execute(companion, val); return true; } private ShopCategory ToShopCategory(KvasturCommandMenu.ShopMode mode) { return mode switch { KvasturCommandMenu.ShopMode.BlackForest => ShopCategory.BlackForest, KvasturCommandMenu.ShopMode.Meadows => ShopCategory.Meadows, KvasturCommandMenu.ShopMode.Swamp => ShopCategory.Swamp, _ => ShopCategory.Kvastur, }; } public void OpenTrade(KvasturCommandMenu.ShopMode mode) { if ((Object)(object)companion == (Object)null || (Object)(object)trader == (Object)null) { Initialize(); } EnsureTraderItems(ToShopCategory(mode)); if ((Object)(object)StoreGui.instance == (Object)null || (Object)(object)trader == (Object)null) { Logger.LogWarning((object)"Kvastur trade UI could not open: StoreGui or Trader is null."); return; } companion.BeginTrading(); ((Behaviour)trader).enabled = false; try { StoreGui.instance.Show(trader); Logger.LogInfo((object)"Kvastur trade UI opened."); } catch (Exception arg) { ((Behaviour)trader).enabled = false; companion.EndTrading(); Logger.LogError((object)$"Kvastur StoreGui.Show failed: {arg}"); } } public void OpenRename() { if ((Object)(object)companion == (Object)null) { Initialize(); } Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)companion == (Object)null) && companion.IsOwner(localPlayer) && !((Object)(object)TextInput.instance == (Object)null)) { TextInput.instance.RequestText((TextReceiver)(object)new KvasturNameReceiver(companion), LocalizationManager.Instance.GetLocalization().TryTranslate("$SakeysMyKvastur_RenameTitle"), 24); } } public void DoFollow(Player player) { companion.Follow(); if ((Object)(object)player != (Object)null) { ((Character)player).Message((MessageType)2, "$SakeysMyKvastur_FollowOn", 0, (Sprite)null, false); } } public void DoStay(Player player) { companion.StopForCommand(); companion.StayHere(); if ((Object)(object)player != (Object)null) { ((Character)player).Message((MessageType)2, "$SakeysMyKvastur_Stay", 0, (Sprite)null, false); } } public void DoRetrieve() { companion.Retrieve(); } public bool UseItem(Humanoid user, ItemData item) { return false; } private void EnsureTraderItems(ShopCategory category) { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown if (!((Object)(object)trader == (Object)null)) { trader.m_items = new List<TradeItem>(); switch (category) { case ShopCategory.BlackForest: AddTraderItemsFromSource(trader.m_items, FindTraderPrefab("Haldor"), ShopCategory.BlackForest); break; case ShopCategory.Meadows: AddTraderItemsFromSource(trader.m_items, FindTraderPrefab("Hildir"), ShopCategory.Meadows); break; case ShopCategory.Swamp: AddTraderItemsFromSource(trader.m_items, FindTraderPrefab("BogWitch"), ShopCategory.Swamp); AddKvasturContractToShop(trader.m_items, ShopCategory.Swamp); break; case ShopCategory.Kvastur: AddKvasturShopItems(trader.m_items); break; } FindLiveTrader(category switch { ShopCategory.Meadows => "Hildir", ShopCategory.BlackForest => "Haldor", _ => "BogWitch", }); trader.m_randomTalkFX = new EffectList(); trader.m_randomGreetFX = new EffectList(); trader.m_randomGoodbyeFX = new EffectList(); trader.m_randomStartTradeFX = new EffectList(); trader.m_randomBuyFX = new EffectList(); trader.m_randomSellFX = new EffectList(); trader.m_name = GetShopDisplayName(category); } } private void AddTraderItemsFromSource(List<TradeItem> target, Trader source, ShopCategory category) { if (target == null || (Object)(object)source == (Object)null) { return; } foreach (TradeItem item in (source.m_items != null) ? new List<TradeItem>(source.m_items) : new List<TradeItem>()) { if (item != null && (!((Object)(object)item.m_prefab == (Object)null) || IsInventoryUpgradeTradeItem(item)) && (!string.Equals(((Object)(object)item.m_prefab != (Object)null) ? ((Object)((Component)item.m_prefab).gameObject).name.Replace("(Clone)", "").Trim() : GetInventoryUpgradeConfigName(item), "SakeysMyKvasturContract", StringComparison.OrdinalIgnoreCase) || category == ShopCategory.Swamp || category == ShopCategory.Kvastur)) { AddSourceShopItem(target, item, category); } } try { Trader[] array = Object.FindObjectsOfType<Trader>(); foreach (Trader val in array) { if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)source) { continue; } string a = ((Object)((Component)val).gameObject).name.Replace("(Clone)", "").Trim(); string b = ((Object)((Component)source).gameObject).name.Replace("(Clone)", "").Trim(); if (!string.Equals(a, b, StringComparison.OrdinalIgnoreCase) || val.m_items == null) { continue; } foreach (TradeItem item2 in new List<TradeItem>(val.m_items)) { if (item2 != null && (!((Object)(object)item2.m_prefab == (Object)null) || IsInventoryUpgradeTradeItem(item2)) && (!string.Equals(((Object)(object)item2.m_prefab != (Object)null) ? ((Object)((Component)item2.m_prefab).gameObject).name.Replace("(Clone)", "").Trim() : GetInventoryUpgradeConfigName(item2), "SakeysMyKvasturContract", StringComparison.OrdinalIgnoreCase) || category == ShopCategory.Swamp || category == ShopCategory.Kvastur)) { AddSourceShopItem(target, item2, category); } } } } catch (Exception ex) { Logger.LogDebug((object)$"Failed to read {category} trader m_items: {ex.Message}"); } finally { CleanupTemporaryTraderProbes(); } } private static void CleanupTemporaryTraderProbes() { if (temporaryTraderProbeObjects.Count == 0) { return; } foreach (GameObject temporaryTraderProbeObject in temporaryTraderProbeObjects) { if ((Object)(object)temporaryTraderProbeObject != (Object)null) { Object.Destroy((Object)(object)temporaryTraderProbeObject); } } temporaryTraderProbeObjects.Clear(); } private Trader FindLiveTrader(string prefabName) { if (string.IsNullOrEmpty(prefabName)) { return null; } try { Trader[] array = Object.FindObjectsOfType<Trader>(); foreach (Trader val in array) { if (!((Object)(object)val == (Object)null) && string.Equals(((Object)((Component)val).gameObject).name.Replace("(Clone)", "").Trim(), prefabName, StringComparison.OrdinalIgnoreCase)) { return val; } } } catch { } return null; } private Trader FindTraderPrefab(string prefabName) { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown if (string.IsNullOrEmpty(prefabName)) { return null; } try { Trader[] array = Object.FindObjectsOfType<Trader>(); foreach (Trader val in array) { if (!((Object)(object)val == (Object)null) && string.Equals(((Object)((Component)val).gameObject).name.Replace("(Clone)", "").Trim(), prefabName, StringComparison.OrdinalIgnoreCase)) { return val; } } } catch { } GameObject val2 = null; try { if ((Object)(object)ZNetScene.instance != (Object)null) { val2 = ZNetScene.instance.GetPrefab(prefabName); } } catch { } if ((Object)(object)val2 == (Object)null) { try { val2 = PrefabManager.Instance.GetPrefab(prefabName); } catch { } } if ((Object)(object)val2 == (Object)null) { return null; } try { GameObject val3 = new GameObject(prefabName); ((Object)val3).hideFlags = (HideFlags)61; val3.SetActive(false); Trader val4 = val3.AddComponent<Trader>(); Trader component = val2.GetComponent<Trader>(); val4.m_items = (((Object)(object)component != (Object)null && component.m_items != null) ? new List<TradeItem>(component.m_items) : new List<TradeItem>()); MethodInfo methodInfo = AccessTools.Method(typeof(Trader), "Start", (Type[])null, (Type[])null); if (methodInfo != null) { methodInfo.Invoke(val4, null); } temporaryTraderProbeObjects.Add(val3); return val4; } catch (Exception ex) { Logger.LogDebug((object)("Kvastur trader probe failed for " + prefabName + ": " + ex.Message)); return null; } } private bool IsTradeItemAvailable(TradeItem item) { if (item != null) { return (Object)(object)item.m_prefab != (Object)null; } return false; } private bool IsInventoryUpgradeTradeItem(TradeItem item) { if (item == null) { return false; } string text = item.m_name ?? string.Empty; string text2 = item.m_tooltip ?? string.Empty; if (text.IndexOf("hud_extrainvslot1", StringComparison.OrdinalIgnoreCase) < 0 && text.IndexOf("hud_extrainvslot2", StringComparison.OrdinalIgnoreCase) < 0 && text2.IndexOf("hud_extrainvslot1", StringComparison.OrdinalIgnoreCase) < 0) { return text2.IndexOf("hud_extrainvslot2", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private string GetInventoryUpgradeConfigName(TradeItem item) { string text = item?.m_name ?? string.Empty; string text2 = item?.m_tooltip ?? string.Empty; if (text.IndexOf("hud_extrainvslot1", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("hud_extrainvslot1", StringComparison.OrdinalIgnoreCase) >= 0) { return "WiderPockets"; } if (text.IndexOf("hud_extrainvslot2", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("hud_extrainvslot2", StringComparison.OrdinalIgnoreCase) >= 0) { return "DeeperPockets"; } return "InventoryUpgrade"; } private void AddSourceShopItem(List<TradeItem> target, TradeItem sourceItem, ShopCategory category) { //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_018d: 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_01b3: Expected O, but got Unknown if (target == null || sourceItem == null) { return; } bool flag = IsInventoryUpgradeTradeItem(sourceItem); if ((Object)(object)sourceItem.m_prefab == (Object)null && !flag) { return; } foreach (TradeItem item in target) { if (item != null && (((Object)(object)sourceItem.m_prefab != (Object)null && (Object)(object)item.m_prefab == (Object)(object)sourceItem.m_prefab) || (flag && IsInventoryUpgradeTradeItem(item) && string.Equals(GetInventoryUpgradeConfigName(item), GetInventoryUpgradeConfigName(sourceItem), StringComparison.OrdinalIgnoreCase)))) { return; } } string text = (((Object)(object)sourceItem.m_prefab != (Object)null) ? ((Object)((Component)sourceItem.m_prefab).gameObject).name.Replace("(Clone)", "").Trim() : GetInventoryUpgradeConfigName(sourceItem)); int shopPrice = GetShopPrice(category, text, sourceItem.m_price); target.Add(new TradeItem { m_prefab = sourceItem.m_prefab, m_stack = sourceItem.m_stack, m_price = Mathf.Max(0, shopPrice), m_requiredGlobalKey = string.Empty, m_levelUpEffect = sourceItem.m_levelUpEffect, m_buyPlayerEffects = (EffectList)(((object)sourceItem.m_buyPlayerEffects) ?? ((object)new EffectList())), m_icon = sourceItem.m_icon, m_name = (sourceItem.m_name ?? string.Empty), m_tooltip = (sourceItem.m_tooltip ?? string.Empty), m_buyKey = (sourceItem.m_buyKey ?? string.Empty), m_incrementKey = (sourceItem.m_incrementKey ?? string.Empty), m_incrementAmount = sourceItem.m_incrementAmount }); Logger.LogInfo((object)($"Kvastur: added {(flag ? text : text)} from {category} shop. " + "prefab=" + (((Object)(object)sourceItem.m_prefab != (Object)null) ? ((Object)((Component)sourceItem.m_prefab).gameObject).name : "<special>") + ", " + $"buyKey={sourceItem.m_buyKey}, incrementKey={sourceItem.m_incrementKey}, incrementAmount={sourceItem.m_incrementAmount}, " + $"price={shopPrice}.")); } private void AddKvasturContractToShop(List<TradeItem> target, ShopCategory category) { if (target == null) { return; } GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab("SakeysMyKvasturContract") : null); if ((Object)(object)val == (Object)null) { val = PrefabManager.Instance.GetPrefab("SakeysMyKvasturContract"); } if (!((Object)(object)val == (Object)null)) { ItemDrop component = val.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null)) { int defaultPrice = ((Plugin.ContractPrice != null) ? Mathf.Max(0, Plugin.ContractPrice.Value) : 1000); AddPricedShopItem(target, component, category, defaultPrice); } } } private void AddKvasturShopItems(List<TradeItem> target) { AddKvasturContractToShop(target, ShopCategory.Kvastur); string[] array = new string[37] { "Sap", "SurtlingCore", "MoltenCore", "Bloodbag", "Entrails", "MushroomMagecap", "AncientSeed", "Iron", "DvergrNeedle", "FlametalNew", "GemstoneRed", "GemstoneBlue", "GemstoneGreen", "BlackCore", "FrostCore", "Gold", "BarleyWine", "MeadBugRepellent", "MeadBzerker", "MeadEitrLingering", "MeadEitrMinor", "MeadFrostResist", "MeadHasty", "MeadHealthLingering", "MeadHealthMajor", "MeadHealthMedium", "MeadHealthMinor", "MeadLightfoot", "MeadPoisonResist", "MeadStaminaLingering", "MeadStaminaMedium", "MeadStaminaMinor", "MeadStrength", "MeadSwimmer", "MeadTamer", "MeadTasty", "MeadTrollPheromones" }; foreach (string text in array) { GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(text) : null); if ((Object)(object)val == (Object)null) { val = PrefabManager.Instance.GetPrefab(text); } if (!((Object)(object)val == (Object)null)) { ItemDrop component = val.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null)) { int kvasturDefaultPrice = GetKvasturDefaultPrice(text); AddPricedShopItem(target, component, ShopCategory.Kvastur, kvasturDefaultPrice); } } } } private int GetKvasturDefaultPrice(string prefabName) { switch (prefabName) { case "Sap": return 1; case "SurtlingCore": return 10; case "MoltenCore": return 20; case "Bloodbag": return 10; case "Entrails": return 10; case "MushroomMagecap": return 10; case "AncientSeed": return 20; case "Iron": return 10; case "DvergrNeedle": return 500; case "FlametalNew": return 150; case "GemstoneBlue": case "GemstoneRed": case "GemstoneGreen": return 200; case "BlackCore": return 600; case "FrostCore": return 1000; case "Gold": return 1000; default: return 10; } } private void AddPricedShopItem(List<TradeItem> target, ItemDrop prefab, ShopCategory category, int defaultPrice) { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012f: 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) //IL_0146: Expected O, but got Unknown if (target == null || (Object)(object)prefab == (Object)null) { return; } foreach (TradeItem item in target) { if (item != null && (Object)(object)item.m_prefab == (Object)(object)prefab) { return; } } string prefabName = ((Object)((Component)prefab).gameObject).name.Replace("(Clone)", "").Trim(); int shopPrice = GetShopPrice(category, prefabName, defaultPrice); string name = string.Empty; string tooltip = string.Empty; if (prefab.m_itemData != null && prefab.m_itemData.m_shared != null) { name = prefab.m_itemData.m_shared.m_name ?? string.Empty; tooltip = prefab.m_itemData.m_shared.m_description ?? string.Empty; } target.Add(new TradeItem { m_prefab = prefab, m_stack = 1, m_price = Mathf.Max(0, shopPrice), m_requiredGlobalKey = string.Empty, m_levelUpEffect = false, m_buyPlayerEffects = new EffectList(), m_icon = null, m_name = name, m_tooltip = tooltip, m_buyKey = string.Empty, m_incrementKey = string.Empty, m_incrementAmount = 0 }); } private int GetShopPrice(ShopCategory category, string prefabName, int defaultPrice) { return KvasturPriceBridge.GetPrice(category.ToString(), prefabName, defaultPrice); } private string GetShopDisplayName(ShopCategory category) { return category switch { ShopCategory.BlackForest => "$SakeysMyKvastur_CommandForest", ShopCategory.Meadows => "$SakeysMyKvastur_CommandMeadows", ShopCategory.Swamp => "$SakeysMyKvastur_CommandSwamp", _ => "$SakeysMyKvastur_CommandKvastur", }; } private static void CopyTraderEffects(Trader source, Trader target) { if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null)) { target.m_randomTalkFX = source.m_randomTalkFX; target.m_randomGreetFX = source.m_randomGreetFX; target.m_randomGoodbyeFX = source.m_randomGoodbyeFX; target.m_randomStartTradeFX = source.m_randomStartTradeFX; target.m_randomBuyFX = source.m_randomBuyFX; target.m_randomSellFX = source.m_randomSellFX; } } private Trader FindBogWitchTrader() { Trader[] array = Object.FindObjectsOfType<Trader>(); foreach (Trader val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)trader) && string.Equals(((Object)((Component)val).gameObject).name.Replace("(Clone)", "").Trim(), "BogWitch", StringComparison.OrdinalIgnoreCase)) { return val; } } try { GameObject val2 = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("BogWitch") : null); if ((Object)(object)val2 != (Object)null) { Trader component = val2.GetComponent<Trader>(); if ((Object)(object)component != (Object)null) { return component; } } } catch (Exception ex) { Logger.LogDebug((object)("Failed to read Bog Witch prefab trader: " + ex.Message)); } try { GameObject prefab = PrefabManager.Instance.GetPrefab("BogWitch"); Trader val3 = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Trader>() : null); if ((Object)(object)val3 != (Object)null) { return val3; } } catch (Exception ex2) { Logger.LogDebug((object)("Failed to read Bog Witch registered prefab trader: " + ex2.Message)); } return null; } } [HarmonyPatch(typeof(Trader), "Start")] public static class BogWitchTraderPatch { [HarmonyPostfix] private static void Postfix(Trader __instance) { //IL_0179: 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_0185: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Expected O, but got Unknown //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: 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_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Expected O, but got Unknown if ((Object)(object)__instance == (Object)null || __instance.m_items == null || !string.Equals((((Object)((Component)__instance).gameObject).name ?? "").Replace("(Clone)", "").Trim(), "BogWitch", StringComparison.OrdinalIgnoreCase)) { return; } GameObject val = ObjectDB.instance.GetItemPrefab("SakeysMyKvasturContract"); if ((Object)(object)val == (Object)null) { val = PrefabManager.Instance.GetPrefab("SakeysMyKvasturContract"); } if ((Object)(object)val == (Object)null) { Logger.LogWarning((object)"Kvastur contract prefab not ready at Bog Witch Trader.Start."); return; } ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { return; } if (component.m_itemData != null && component.m_itemData.m_shared != null) { component.m_itemData.m_shared.m_name = "$SakeysMyKvastur_Name"; component.m_itemData.m_shared.m_description = "$SakeysMyKvastur_Desc"; } foreach (TradeItem item in __instance.m_items) { if (item != null && (Object)(object)item.m_prefab == (Object)(object)component) { return; } } string name = string.Empty; string tooltip = string.Empty; if (component.m_itemData != null && component.m_itemData.m_shared != null) { name = component.m_itemData.m_shared.m_name ?? string.Empty; tooltip = component.m_itemData.m_shared.m_description ?? string.Empty; } __instance.m_items.Add(new TradeItem { m_prefab = component, m_price = ((Plugin.ContractPrice != null) ? Mathf.Max(0, Plugin.ContractPrice.Value) : 1000), m_stack = 1, m_requiredGlobalKey = string.Empty, m_levelUpEffect = false, m_buyPlayerEffects = new EffectList(), m_icon = null, m_name = name, m_tooltip = tooltip, m_buyKey = string.Empty, m_incrementKey = string.Empty, m_incrementAmount = 0 }); Logger.LogInfo((object)"Added Kvastur contract to Bog Witch."); } } [HarmonyPatch(typeof(Player), "OnSpawned")] public static class PlayerSpawnPatch { [HarmonyPostfix] private static void Postfix(Player __instance) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && (Object)(object)((Component)__instance).GetComponent<KvasturInputController>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<KvasturInputController>(); } } } public static class KvasturCommandMenu { public enum ShopMode { Follow, Retrieve, Rename, BlackForest, Meadows, Swamp, Kvastur } private static readonly List<ShopMode> CurrentModes = new List<ShopMode>(); public static int SelectedIndex { get; private set; } = -1; public static void RebuildModes() { CurrentModes.Clear(); CurrentModes.Add(ShopMode.Follow); CurrentModes.Add(ShopMode.Retrieve); CurrentModes.Add(ShopMode.Rename); if (Plugin.EnableBlackForestShop != null && Plugin.EnableBlackForestShop.Value) { CurrentModes.Add(ShopMode.BlackForest); } if (Plugin.EnableMeadowsShop != null && Plugin.EnableMeadowsShop.Value) { CurrentModes.Add(ShopMode.Meadows); } if (Plugin.EnableSwampShop != null && Plugin.EnableSwampShop.Value) { CurrentModes.Add(ShopMode.Swamp); } CurrentModes.Add(ShopMode.Kvastur); if (SelectedIndex >= CurrentModes.Count) { SelectedIndex = 0; } } public static void Cycle() { RebuildModes(); SelectedIndex = (SelectedIndex + 1) % CurrentModes.Count; ShowSelectedMessage(); } public static void Reset() { SelectedIndex = -1; } private static void ShowSelectedMessage() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } RebuildModes(); if (CurrentModes.Count == 0) { return; } string text = CurrentModes[SelectedIndex] switch { ShopMode.Follow => "$SakeysMyKvastur_CommandFollow", ShopMode.Retrieve => "$SakeysMyKvastur_CommandRetrieve", ShopMode.Rename => "$SakeysMyKvastur_CommandRename", ShopMode.BlackForest => "$SakeysMyKvastur_CommandForest", ShopMode.Meadows => "$SakeysMyKvastur_CommandMeadows", ShopMode.Swamp => "$SakeysMyKvastur_CommandSwamp", _ => "$SakeysMyKvastur_CommandKvastur", }; string text2 = text; try { if (LocalizationManager.Instance != null) { text2 = LocalizationManager.Instance.GetLocalization().TryTranslate(text); } } catch { } ((Character)localPlayer).Message((MessageType)2, text2, 0, (Sprite)null, false); } public static void ExecuteFollow(KvasturCompanion companion, Player player) { if ((Object)(object)companion == (Object)null || (Object)(object)player == (Object)null) { return; } KvasturInteractable component = ((Component)companion).GetComponent<KvasturInteractable>(); if (!((Object)(object)component == (Object)null)) { if (companion.IsFollowing()) { component.DoStay(player); } else { component.DoFollow(player); } } } public static void ExecuteRetrieve(KvasturCompanion companion) { if (!((Object)(object)companion == (Object)null)) { KvasturInteractable component = ((Component)companion).GetComponent<KvasturInteractable>(); if (!((Object)(object)component == (Object)null)) { component.DoRetrieve(); } } } public static void ExecuteRename(KvasturCompanion companion) { if (!((Object)(object)companion == (Object)null)) { KvasturInteractable component = ((Component)companion).GetComponent<KvasturInteractable>(); if (!((Object)(object)component == (Object)null)) { component.OpenRename(); } } } public static void ExecuteShop(KvasturCompanion companion, ShopMode mode) { if (!((Object)(object)companion == (Object)null)) { KvasturInteractable component = ((Component)companion).GetComponent<KvasturInteractable>(); if (!((Object)(object)component == (Object)null)) { component.OpenTrade(mode); } } } public static void Execute(KvasturCompanion companion, Player player) { if (!((Object)(object)companion == (Object)null) && !((Object)(object)player == (Object)null)) { RebuildModes(); if (SelectedIndex < 0 || SelectedIndex >= CurrentModes.Count) { SelectedIndex = 0; } switch (CurrentModes[SelectedIndex]) { case ShopMode.Follow: ExecuteFollow(companion, player); break; case ShopMode.Retrieve: ExecuteRetrieve(companion); break; case ShopMode.Rename: ExecuteRename(companion); break; default: ExecuteShop(companion, CurrentModes[SelectedIndex]); break; } } } } public class KvasturInputController : MonoBehaviour { private static int suppressInteractFrame = -1; public static bool SuppressInteractThisFrame() { if (suppressInteractFrame == Time.frameCount) { suppressInteractFrame = -1; return true; } return false; } private void Update() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || Console.IsVisible() || Menu.IsVisible()) { return; } if (ZInput.GetButton("JoyLBumper") && ZInput.GetButtonDown("JoyUse")) { Character hoverCreature = localPlayer.GetHoverCreature(); if ((Object)(object)hoverCreature != (Object)null) { KvasturCompanion component = ((Component)hoverCreature).GetComponent<KvasturCompanion>(); if ((Object)(object)component != (Object)null && component.IsOwner(localPlayer)) { KvasturCommandMenu.Cycle(); suppressInteractFrame = Time.frameCount; } } } if (WasPressed(Plugin.CommandKey.Value)) { if ((Object)(object)KvasturCompanion.FindOwned(localPlayer.GetPlayerID()) != (Object)null) { KvasturCommandMenu.Cycle(); } else { KvasturCommandMenu.Reset(); } } } private static bool WasPressed(KeyboardShortcut shortcut) { //IL_0002: 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_002b: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0) { return false; } if (!Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { if (!Input.GetKey(modifier)) { return false; } } return true; } } [HarmonyPatch] public static class KvasturStoreGuiPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(StoreGui), "Hide", (Type[])null, (Type[])null); } private static bool Prepare() { return TargetMethod() != null; } [HarmonyPostfix] private static void Postfix(StoreGui __instance) { if ((Object)(object)__instance == (Object)null) { return; } Trader value = Traverse.Create((object)__instance).Field("m_trader").GetValue<Trader>(); if ((Object)(object)value == (Object)null) { return; } KvasturCompanion component = ((Component)value).GetComponent<KvasturCompanion>(); if ((Object)(object)component != (Object)null) { component.EndTrading(); Trader component2 = ((Component)value).GetComponent<Trader>(); if ((Object)(object)component2 != (Object)null) { ((Behaviour)component2).enabled = false; } } } public static bool IsKvasturStoreOpen(KvasturCompanion companion) { if ((Object)(object)companion == (Object)null || (Object)(object)StoreGui.instance == (Object)null) { return false; } Trader value = Traverse.Create((object)StoreGui.instance).Field("m_trader").GetValue<Trader>(); if ((Object)(object)value != (Object)null) { return (Object)(object)((Component)value).GetComponent<KvasturCompanion>() == (Object)(object)companion; } return false; } } [HarmonyPatch(typeof(StoreGui), "BuySelectedItem")] public static class KvasturContractPurchaseNamePatch { [HarmonyPrefix] private static void Prefix(StoreGui __instance) { if ((Object)(object)__instance == (Object)null) { return; } try { Trader value = Traverse.Create((object)__instance).Field("m_trader").GetValue<Trader>(); if ((Object)(object)value == (Object)null || (Object)(object)((Component)value).GetComponent<KvasturCompanion>() != (Object)null) { return; } TradeItem value2 = Traverse.Create((object)__instance).Field("m_selectedItem").GetValue<TradeItem>(); if (value2 != null && !((Object)(object)value2.m_prefab == (Object)null) && ((Object)((Component)value2.m_prefab).gameObject).name.Replace("(Clone)", "").Trim().Equals("SakeysMyKvasturContract", StringComparison.OrdinalIgnoreCase)) { ItemData itemData = value2.m_prefab.m_itemData; if (itemData != null && itemData.m_shared != null) { itemData.m_shared.m_name = "$SakeysMyKvastur_Name"; itemData.m_shared.m_description = "$SakeysMyKvastur_Desc"; itemData.m_dropPrefab = ((Component)value2.m_prefab).gameObject; } } } catch { } } } internal sealed class ConfigurationManagerAttributes { public bool? Browsable; public bool? HideDefaultButton; public bool? IsAdvanced; public int? Order; public string DispName; public string Description; public string Category; public bool? ReadOnly; } internal static class KvasturPriceBridge { public static int GetPrice(string category, string prefabName, int defaultPrice) { return category switch { "BlackForest" => KvasturHaldorPrices.Get(prefabName, defaultPrice), "Meadows" => KvasturHildirPrices.Get(prefabName, defaultPrice), "Swamp" => KvasturBogWitchPrices.Get(prefabName, defaultPrice), _ => KvasturShopPrices.Get(prefabName, defaultPrice), }; } } internal abstract class KvasturPricePluginBase : BaseUnityPlugin { protected readonly Dictionary<string, ConfigEntry<int>> Prices = new Dictionary<string, ConfigEntry<int>>(StringComparer.OrdinalIgnoreCase); protected ConfigEntry<int> BindPrice(string section, string prefabName, int defaultPrice, string description) { if (Prices.TryGetValue(prefabName, out var value)) { return value; } ConfigEntry<int> val = ((BaseUnityPlugin)this).Config.Bind<int>(section, prefabName + "Price", defaultPrice, description); Prices[prefabName] = val; return val; } protected int LegacyDefault(string section, string prefabName, int fallback) { return fallback; } protected static string CleanPrefabName(GameObject prefab) { if (!((Object)(object)prefab == (Object)null)) { return ((Object)prefab).name.Replace("(Clone)", "").Trim(); } return string.Empty; } } [BepInPlugin("com.sakey.my.kvastur.haldorprices", "Sakey's My Kvastur - Haldor Prices", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal sealed class KvasturHaldorPrices : KvasturPricePluginBase { private static readonly Dictionary<string, ConfigEntry<int>> Bound = new Dictionary<string, ConfigEntry<int>>(StringComparer.OrdinalIgnoreCase); private void Awake() { PrefabManager.OnVanillaPrefabsAvailable += BindPrices; } private void BindPrices() { BindTrader("Haldor", "Shop - Black Forest"); } private void BindTrader(string traderPrefabName, string section) { GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(traderPrefabName) : null); if ((Object)(object)val == (Object)null) { val = PrefabManager.Instance.GetPrefab(traderPrefabName); } Trader val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Trader>() : null); if ((Object)(object)val2 == (Object)null || val2.m_items == null) { return; } foreach (TradeItem item in val2.m_items) { if (item != null && !((Object)(object)item.m_prefab == (Object)null)) { string text = KvasturPricePluginBase.CleanPrefabName(((Component)item.m_prefab).gameObject); if (!Bound.ContainsKey(text)) { Bound[text] = BindPrice(section, text, LegacyDefault(section, text, Mathf.Max(0, item.m_price)), "Haldor purchase price for one item."); } } } if (!Bound.ContainsKey("WiderPockets")) { Bound["WiderPockets"] = BindPrice(section, "WiderPockets", 1000, "Kvastur Black Forest shop price for Wider Pockets."); } if (!Bound.ContainsKey("DeeperPockets")) { Bound["DeeperPockets"] = BindPrice(section, "DeeperPockets", 2000, "Kvastur Black Forest shop price for Deeper Pockets."); } } public static int Get(string prefabName, int fallback) { if (!Bound.TryGetValue(prefabName, out var value)) { return fallback; } return value.Value; } } [BepInPlugin("com.sakey.my.kvastur.hildirprices", "Sakey's My Kvastur - Hildir Prices", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal sealed class KvasturHildirPrices : KvasturPricePluginBase { private static readonly Dictionary<string, ConfigEntry<int>> Bound = new Dictionary<string, ConfigEntry<int>>(StringComparer.OrdinalIgnoreCase); private void Awake() { PrefabManager.OnVanillaPrefabsAvailable += BindPrices; } private void BindPrices() { GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("Hildir") : null); if ((Object)(object)val == (Object)null) { val = PrefabManager.Instance.GetPrefab("Hildir"); } Trader val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Trader>() : null); if ((Object)(object)val2 == (Object)null || val2.m_items == null) { return; } foreach (TradeItem item in val2.m_items) { if (item != null && !((Object)(object)item.m_prefab == (Object)null)) { string text = KvasturPricePluginBase.CleanPrefabName(((Component)item.m_prefab).gameObject); if (!Bound.ContainsKey(text)) { Bound[text] = BindPrice("Shop - Meadows", text, LegacyDefault("Shop - Meadows", text, Mathf.Max(0, item.m_price)), "Hildir purchase price for one item."); } } } } public static int Get(string prefabName, int fallback) { if (!Bound.TryGetValue(prefabName, out var value)) { return fallback; } return value.Value; } } [BepInPlugin("com.sakey.my.kvastur.bogwitchprices", "Sakey's My Kvastur - Bog Witch Prices", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal sealed class KvasturBogWitchPrices : KvasturPricePluginBase { private static readonly Dictionary<string, ConfigEntry<int>> Bound = new Dictionary<string, ConfigEntry<int>>(StringComparer.OrdinalIgnoreCase); private void Awake() { PrefabManager.OnVanillaPrefabsAvailable += BindPrices; } private void BindPrices() { GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("BogWitch") : null); if ((Object)(object)val == (Object)null) { val = PrefabManager.Instance.GetPrefab("BogWitch"); } Trader val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Trader>() : null); if ((Object)(object)val2 != (Object)null && val2.m_items != null) { foreach (TradeItem item in val2.m_items) { if (item != null && !((Object)(object)item.m_prefab == (Object)null)) { string text = KvasturPricePluginBase.CleanPrefabName(((Component)item.m_prefab).gameObject); if (!Bound.ContainsKey(text)) { Bound[text] = BindPrice("Shop - Swamp", text, LegacyDefault("Shop - Swamp", text, Mathf.Max(0, item.m_price)), "Bog Witch purchase price for one item."); } } } } if (!Bound.ContainsKey("WiderPockets")) { Bound["WiderPockets"] = BindPrice("Shop - Swamp", "WiderPockets", 1, "Kvastur magic mail-order price for Wider Pockets."); } if (!Bound.ContainsKey("DeeperPockets")) { Bound["DeeperPockets"] = BindPrice("Shop - Swamp", "DeeperPockets", 1, "Kvastur magic mail-order price for Deeper Pockets."); } } public static int Get(string prefabName, int fallback) { if (!Bound.TryGetValue(prefabName, out var value)) { return fallback; } return value.Value; } } [BepInPlugin("com.sakey.my.kvastur.kvasturprices", "Sakey's My Kvastur - Kvastur Shop Prices", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal sealed class KvasturShopPrices : KvasturPricePluginBase { private static readonly Dictionary<string, ConfigEntry<int>> Bound = new Dictionary<string, ConfigEntry<int>>(StringComparer.OrdinalIgnoreCase); private static readonly string[] Prefabs = new string[37] { "Sap", "SurtlingCore", "MoltenCore", "Bloodbag", "Entrails", "MushroomMagecap", "AncientSeed", "Iron", "DvergrNeedle", "FlametalNew", "GemstoneRed", "GemstoneBlue", "GemstoneGreen", "BlackCore", "FrostCore", "Gold", "BarleyWine", "MeadBugRepellent", "MeadBzerker", "MeadEitrLingering", "MeadEitrMinor", "MeadFrostResist", "MeadHasty", "MeadHealthLingering", "MeadHealthMajor", "MeadHealthMedium", "MeadHealthMinor", "MeadLightfoot", "MeadPoisonResist", "MeadStaminaLingering", "MeadStaminaMedium", "MeadStaminaMinor", "MeadStrength", "MeadSwimmer", "MeadTamer", "MeadTasty", "MeadTrollPheromones" }; private void Awake() { string[] prefabs = Prefabs; foreach (string text in prefabs) { Bound[text] = BindPrice("Shop - Kvastur", text, LegacyDefault("Shop - Kvastur", text, GetDefault(text)), "Kvastur purchase price for one item."); } } private static int GetDefault(string prefabName) { switch (prefabName) { case "Sap": return 1; case "SurtlingCore": return 10; case "MoltenCore": return 20; case "Bloodbag": return 10; case "Entrails": return 10; case "MushroomMagecap": return 10; case "AncientSeed": return 20; case "Iron": return 10; case "DvergrNeedle": return 500; case "FlametalNew": return 150; case "GemstoneBlue": case "GemstoneRed": case "GemstoneGreen": return 200; case "BlackCore": return 600; case "FrostCore": return 1000; case "Gold": return 1000; default: return 10; } } public static int Get(string prefabName, int fallback) { if (!Bound.TryGetValue(prefabName, out var value)) { return fallback; } return value.Value; } }