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 ForesightForge v1.0.0
ForesightForge.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; using ValheimShared.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace ForesightForge { [BepInPlugin("com.drakosdj.foresightforge", "ForesightForge", "1.0.0")] public class ForesightForgePlugin : BaseUnityPlugin { public const string PluginGUID = "com.drakosdj.foresightforge"; public const string PluginName = "ForesightForge"; public const string PluginVersion = "1.0.0"; public static ConfigEntry<bool> ConfigModEnabled; public static ConfigEntry<UpgradeSimulator.OutcomeMode> ConfigOutcomeMode; public static ConfigEntry<bool> ConfigEnableAltarEffects; public static ConfigEntry<bool> ConfigEnableIdolTransmutation; public static ConfigEntry<int> ConfigIdolUpgradeRatio; private static bool s_serverHasMod = false; private static UpgradeSimulator.OutcomeMode s_serverOutcomeMode = UpgradeSimulator.OutcomeMode.Vanilla; private static bool s_serverEnableTransmutation = false; private static int s_serverRatio = 3; private Harmony m_harmony; private static MethodInfo s_updateKnownRecipesMethod = typeof(Player).GetMethod("UpdateKnownRecipesList", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static FieldInfo s_knownRecipesField = AccessTools.Field(typeof(Player), "m_knownRecipes"); public static UpgradeSimulator.OutcomeMode EffectiveOutcomeMode { get { if (ConfigModEnabled != null && !ConfigModEnabled.Value) { return UpgradeSimulator.OutcomeMode.Vanilla; } if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer()) { return (ConfigOutcomeMode == null) ? UpgradeSimulator.OutcomeMode.TierScaled : ConfigOutcomeMode.Value; } if (s_serverHasMod) { return s_serverOutcomeMode; } return UpgradeSimulator.OutcomeMode.Vanilla; } } public static bool EffectiveEnableIdolTransmutation { get { if (ConfigModEnabled != null && !ConfigModEnabled.Value) { return false; } if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer()) { return ConfigEnableIdolTransmutation != null && ConfigEnableIdolTransmutation.Value; } if (s_serverHasMod) { return s_serverEnableTransmutation; } return false; } } public static void CleanInvalidIdolRecipes(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)ObjectDB.instance == (Object)null || s_knownRecipesField == null) { return; } try { if (!(s_knownRecipesField.GetValue(player) is HashSet<string> hashSet) || ObjectDB.instance.m_recipes == null) { return; } for (int i = 0; i < ObjectDB.instance.m_recipes.Count; i++) { Recipe val = ObjectDB.instance.m_recipes[i]; if (!((Object)(object)val != (Object)null) || ((Object)val).name == null || !((Object)val).name.StartsWith("Recipe_Transmute_Upgrader") || !((Object)(object)val.m_item != (Object)null) || val.m_item.m_itemData == null || val.m_item.m_itemData.m_shared == null) { continue; } string name = val.m_item.m_itemData.m_shared.m_name; if (val.m_resources != null && val.m_resources.Length > 0 && (Object)(object)val.m_resources[0].m_resItem != (Object)null && val.m_resources[0].m_resItem.m_itemData != null && val.m_resources[0].m_resItem.m_itemData.m_shared != null) { string name2 = val.m_resources[0].m_resItem.m_itemData.m_shared.m_name; if (!player.IsKnownMaterial(name2)) { hashSet.Remove(name); } } } } catch { } } public static void SafeUpdateKnownRecipes(Player player) { if ((Object)(object)player == (Object)null) { return; } CleanInvalidIdolRecipes(player); if (!(s_updateKnownRecipesMethod != null)) { return; } try { s_updateKnownRecipesMethod.Invoke(player, null); } catch { } } private void Awake() { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown ConfigModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ModEnabled", true, "Master toggle for ForesightForge. When disabled, all features and prediction banners are turned off."); ConfigOutcomeMode = ((BaseUnityPlugin)this).Config.Bind<UpgradeSimulator.OutcomeMode>("Mechanics", "OutcomeMode", UpgradeSimulator.OutcomeMode.TierScaled, "Refinement failure outcome behavior. Vanilla = 100% item break on failure. TierScaled = 4-way dynamic risk vs. reward (Break/Downgrade/No Change) based on biome tier."); ConfigEnableAltarEffects = ((BaseUnityPlugin)this).Config.Bind<bool>("Visuals", "EnableAltarEffects", true, "Replicates the authentic thunder, lightning, and sound effects from the world altar on /openforge."); ConfigEnableIdolTransmutation = ((BaseUnityPlugin)this).Config.Bind<bool>("Transmutation", "EnableIdolTransmutation", true, "Enables the Craft tab on the Altar of Potential and registers recipes allowing lower-tier Idols to be transmuted into higher-tier Idols."); ConfigIdolUpgradeRatio = ((BaseUnityPlugin)this).Config.Bind<int>("Transmutation", "IdolUpgradeRatio", 3, new ConfigDescription("Number of lower-tier Idols required to transmute into 1 higher-tier Idol at the Altar of Potential.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), new object[0])); ConfigEnableIdolTransmutation.SettingChanged += delegate { IdolRecipes.SetRecipesEnabled(EffectiveEnableIdolTransmutation); }; ConfigIdolUpgradeRatio.SettingChanged += delegate { IdolRecipes.UpdateRecipeRatios(ConfigIdolUpgradeRatio.Value); }; m_harmony = new Harmony("com.drakosdj.foresightforge"); m_harmony.PatchAll(); TerminalPatches.RegisterCommands(); ZLog.Log((object)string.Format("[{0}] Loaded v{1} — Völva's Eye initialized. Mode: {2}, Transmutation: {3}, Ratio: {4}:1", "ForesightForge", "1.0.0", ConfigOutcomeMode.Value, ConfigEnableIdolTransmutation.Value, ConfigIdolUpgradeRatio.Value)); } private void OnDestroy() { if (m_harmony != null) { m_harmony.UnpatchSelf(); } } public static void SetServerConfig(bool serverHasMod, UpgradeSimulator.OutcomeMode mode, bool enableTransmute, int ratio) { s_serverHasMod = serverHasMod; s_serverOutcomeMode = mode; s_serverEnableTransmutation = enableTransmute; s_serverRatio = ratio; ZLog.Log((object)$"[ForesightForge] Server handshake updated: ServerHasMod={s_serverHasMod}, Mode={s_serverOutcomeMode}, Transmute={s_serverEnableTransmutation}, Ratio={s_serverRatio}:1"); IdolRecipes.SetRecipesEnabled(EffectiveEnableIdolTransmutation); IdolRecipes.UpdateRecipeRatios(s_serverRatio); } } [HarmonyPatch(typeof(Game))] public static class GameNetworkingPatches { [HarmonyPatch("Start")] [HarmonyPostfix] public static void Game_Start() { try { if (ZRoutedRpc.instance != null) { ZRoutedRpc.instance.Register<int, bool, int>("ForesightForge_SyncConfig", (Action<long, int, bool, int>)RPC_SyncConfig); } } catch (Exception arg) { ZLog.LogWarning((object)$"[ForesightForge] Failed to register ZRoutedRpc: {arg}"); } } public static void RPC_SyncConfig(long sender, int mode, bool enableTransmute, int ratio) { ForesightForgePlugin.SetServerConfig(serverHasMod: true, (UpgradeSimulator.OutcomeMode)mode, enableTransmute, ratio); } } [HarmonyPatch(typeof(ZNet))] public static class ZNetNetworkingPatches { [HarmonyPostfix] [HarmonyPatch("OnNewConnection")] public static void OnNewConnection_Postfix(ZNet __instance, ZNetPeer peer) { try { if ((Object)(object)__instance != (Object)null && __instance.IsServer() && peer != null && ZRoutedRpc.instance != null) { int num = (int)((ForesightForgePlugin.ConfigOutcomeMode == null) ? UpgradeSimulator.OutcomeMode.TierScaled : ForesightForgePlugin.ConfigOutcomeMode.Value); bool flag = ForesightForgePlugin.ConfigEnableIdolTransmutation != null && ForesightForgePlugin.ConfigEnableIdolTransmutation.Value; int num2 = ((ForesightForgePlugin.ConfigIdolUpgradeRatio != null) ? ForesightForgePlugin.ConfigIdolUpgradeRatio.Value : 3); ZRoutedRpc.instance.InvokeRoutedRPC(peer.m_uid, "ForesightForge_SyncConfig", new object[3] { num, flag, num2 }); } } catch (Exception arg) { ZLog.LogWarning((object)$"[ForesightForge] Failed to send server config: {arg}"); } } [HarmonyPatch("Shutdown")] [HarmonyPostfix] public static void Shutdown_Postfix() { ForesightForgePlugin.SetServerConfig(serverHasMod: false, UpgradeSimulator.OutcomeMode.Vanilla, enableTransmute: false, 3); } } [HarmonyPatch(typeof(InventoryGui))] public static class InventoryGuiPatches { private static FieldInfo s_selectedRecipeField = typeof(InventoryGui).GetField("m_selectedRecipe", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static MethodInfo s_updateCraftingPanelMethod = typeof(InventoryGui).GetMethod("UpdateCraftingPanel", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static MethodInfo s_cheatUtilsMethod = null; public static void GetSelectedRecipeAndItem(InventoryGui gui, out Recipe recipe, out ItemData upgradeItem) { recipe = null; upgradeItem = null; if ((Object)(object)gui == (Object)null || s_selectedRecipeField == null) { return; } object value = s_selectedRecipeField.GetValue(gui); if (value != null) { Type type = value.GetType(); PropertyInfo property = type.GetProperty("Recipe", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); PropertyInfo property2 = type.GetProperty("ItemData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { object? value2 = property.GetValue(value, null); recipe = (Recipe)((value2 is Recipe) ? value2 : null); } if (property2 != null) { object? value3 = property2.GetValue(value, null); upgradeItem = (ItemData)((value3 is ItemData) ? value3 : null); } } } [HarmonyPatch("Awake")] [HarmonyPostfix] public static void Awake_Postfix(InventoryGui __instance) { try { if (!((Object)(object)__instance == (Object)null)) { VolvaEyeBanner.Initialize(__instance); } } catch (Exception arg) { ZLog.LogWarning((object)$"[ForesightForge] Failed to initialize VolvaEyeBanner: {arg}"); } } [HarmonyPatch("CanRepair")] [HarmonyPrefix] public static bool CanRepair_Prefix(ref bool __result) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { CraftingStation currentCraftingStation = localPlayer.GetCurrentCraftingStation(); if ((Object)(object)currentCraftingStation != (Object)null && currentCraftingStation.m_upgrader) { __result = false; return false; } } return true; } [HarmonyPrefix] [HarmonyPatch("AddRecipeToList")] public static bool AddRecipeToList_Prefix(Player player, Recipe recipe, ItemData item, bool canCraft) { if ((Object)(object)player != (Object)null) { CraftingStation currentCraftingStation = player.GetCurrentCraftingStation(); bool flag = ((Object)(object)recipe != (Object)null && (Object)(object)recipe.m_item != (Object)null && (((Object)recipe.m_item).name.StartsWith("Upgrader") || ((Object)(object)((Component)recipe.m_item).gameObject != (Object)null && ((Object)((Component)recipe.m_item).gameObject).name.StartsWith("Upgrader")))) || ((Object)(object)recipe != (Object)null && ((Object)recipe).name != null && ((Object)recipe).name.StartsWith("Recipe_Transmute_Upgrader")); if ((Object)(object)currentCraftingStation != (Object)null && currentCraftingStation.m_upgrader) { if (item == null) { if (!flag) { return false; } if ((Object)(object)recipe != (Object)null && recipe.m_resources != null && recipe.m_resources.Length > 0 && (Object)(object)recipe.m_resources[0].m_resItem != (Object)null && recipe.m_resources[0].m_resItem.m_itemData != null && recipe.m_resources[0].m_resItem.m_itemData.m_shared != null) { string name = recipe.m_resources[0].m_resItem.m_itemData.m_shared.m_name; if (!player.IsKnownMaterial(name)) { return false; } } } } else if (flag) { return false; } } return true; } [HarmonyPostfix] [HarmonyPatch("UpdateRecipe")] public static void UpdateRecipe_Postfix(InventoryGui __instance, Player player, float dt) { try { if ((Object)(object)__instance == (Object)null || (Object)(object)player == (Object)null) { return; } if (ForesightForgePlugin.ConfigModEnabled != null && !ForesightForgePlugin.ConfigModEnabled.Value) { if ((Object)(object)VolvaEyeBanner.Instance != (Object)null) { VolvaEyeBanner.Instance.SetVisible(visible: false); } return; } CraftingStation currentCraftingStation = player.GetCurrentCraftingStation(); bool flag = (Object)(object)currentCraftingStation != (Object)null && currentCraftingStation.m_upgrader; GetSelectedRecipeAndItem(__instance, out var recipe, out var upgradeItem); if (!flag || upgradeItem == null || (Object)(object)recipe == (Object)null) { if ((Object)(object)VolvaEyeBanner.Instance != (Object)null) { VolvaEyeBanner.Instance.SetVisible(visible: false); } return; } UpgradeSimulator.OutcomeMode effectiveOutcomeMode = ForesightForgePlugin.EffectiveOutcomeMode; UpgradeSimulator.Prediction prediction = UpgradeSimulator.Predict(player, recipe, upgradeItem, 25, effectiveOutcomeMode); if ((Object)(object)VolvaEyeBanner.Instance != (Object)null) { VolvaEyeBanner.Instance.UpdateDisplay(prediction, upgradeItem.m_shared.m_name); } if (!((Object)(object)__instance.m_itemCraftType != (Object)null)) { return; } ((Component)__instance.m_itemCraftType).gameObject.SetActive(true); if (prediction.SuccessCount > 0) { string arg = ((prediction.SuccessCount > 1) ? "s" : ""); if (effectiveOutcomeMode == UpgradeSimulator.OutcomeMode.TierScaled) { if (prediction.NextFailure == UpgradeSimulator.NextFailureType.NoChange) { __instance.m_itemCraftType.text = $"<color=#55FF55><b>Völva's Eye:</b> Sees <b>{prediction.SuccessCount}</b> upgrade{arg}! <color=#70C0FF>(Next failure will RESIST safely)</color></color>"; } else if (prediction.NextFailure == UpgradeSimulator.NextFailureType.Downgrade) { __instance.m_itemCraftType.text = $"<color=#55FF55><b>Völva's Eye:</b> Sees <b>{prediction.SuccessCount}</b> upgrade{arg}! <color=#FFAA00>(Caution: Will DOWNGRADE on failure)</color></color>"; } else { __instance.m_itemCraftType.text = $"<color=#55FF55><b>Völva's Eye:</b> Sees <b>{prediction.SuccessCount}</b> upgrade{arg}! <color=#FF4444>(Warning: Will SHATTER on failure)</color></color>"; } } else { __instance.m_itemCraftType.text = $"<color=#55FF55><b>Völva's Eye:</b> Sees <b>{prediction.SuccessCount}</b> upgrade{arg} in this item's future!</color>"; } } else if (prediction.NextFailure == UpgradeSimulator.NextFailureType.NoChange) { __instance.m_itemCraftType.text = "<color=#70C0FF><b>Völva's Eye:</b> The thread holds firm! 0 upgrades (Will <b>RESIST / NO CHANGE</b>)</color>"; } else if (prediction.NextFailure == UpgradeSimulator.NextFailureType.Downgrade) { __instance.m_itemCraftType.text = "<color=#FFAA00><b>Völva's Eye:</b> The thread frays! 0 upgrades remaining (Will <b>DOWNGRADE</b>)</color>"; } else if (prediction.NextFailure == UpgradeSimulator.NextFailureType.Break) { __instance.m_itemCraftType.text = "<color=#FF3333><b>Völva's Eye:</b> Doom awaits! Item will <b>SHATTER</b> on next attempt!</color>"; } } catch (Exception arg2) { ZLog.LogWarning((object)$"[ForesightForge] Error in UpdateRecipe_Postfix: {arg2}"); } } [HarmonyPostfix] [HarmonyPatch("Hide")] public static void Hide_Postfix() { try { if ((Object)(object)VolvaEyeBanner.Instance != (Object)null) { VolvaEyeBanner.Instance.SetVisible(visible: false); } } catch { } } [HarmonyPrefix] [HarmonyPatch("DoCrafting")] public static bool DoCrafting_Prefix(InventoryGui __instance, Player player) { if (ForesightForgePlugin.ConfigModEnabled != null && !ForesightForgePlugin.ConfigModEnabled.Value) { return true; } CraftingStation currentCraftingStation = player.GetCurrentCraftingStation(); if ((Object)(object)currentCraftingStation == (Object)null || !currentCraftingStation.m_upgrader) { return true; } GetSelectedRecipeAndItem(__instance, out var recipe, out var upgradeItem); if (upgradeItem == null) { if ((Object)(object)recipe != (Object)null && ((Object)recipe).name != null && ((Object)recipe).name.StartsWith("Recipe_Transmute_Upgrader")) { ExecuteIdolTransmutation(__instance, player, currentCraftingStation, recipe); return false; } return true; } UpgradeSimulator.OutcomeMode effectiveOutcomeMode = ForesightForgePlugin.EffectiveOutcomeMode; if (effectiveOutcomeMode != UpgradeSimulator.OutcomeMode.TierScaled) { return true; } if ((Object)(object)recipe == (Object)null) { return true; } int num = upgradeItem.m_quality + 1; if (!player.HaveRequirements(recipe, false, num, 1) && !player.NoCostCheat() && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)25)) { return true; } ItemDrop val = null; if (recipe.m_resources != null) { for (int i = 0; i < recipe.m_resources.Length; i++) { Requirement val2 = recipe.m_resources[i]; if (val2 != null && val2.m_upgraderResource && (Object)(object)val2.m_resItem != (Object)null) { val = val2.m_resItem; break; } } } if ((Object)(object)val == (Object)null || val.m_itemData == null || val.m_itemData.m_shared == null) { return true; } ItemData itemData = val.m_itemData; int idolTier = UpgradeSimulator.GetIdolTier(val); ExecuteTierScaledRefinement(__instance, player, currentCraftingStation, recipe, upgradeItem, itemData, idolTier, num); return false; } private static void ExecuteIdolTransmutation(InventoryGui gui, Player player, CraftingStation station, Recipe recipe) { //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)recipe == (Object)null || (Object)(object)recipe.m_item == (Object)null || recipe.m_resources == null || recipe.m_resources.Length == 0) { return; } Requirement val = recipe.m_resources[0]; if (val == null || (Object)(object)val.m_resItem == (Object)null) { return; } int amount = val.m_amount; string text = ((val.m_resItem.m_itemData != null && val.m_resItem.m_itemData.m_shared != null) ? val.m_resItem.m_itemData.m_shared.m_name : ((Object)val.m_resItem).name); string text2 = (((Object)(object)((Component)val.m_resItem).gameObject != (Object)null) ? ((Object)((Component)val.m_resItem).gameObject).name : ((Object)val.m_resItem).name); if (!player.NoCostCheat() && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)25)) { int num = ((Humanoid)player).GetInventory().CountItems(text, -1, false); if (num < amount) { num = Math.Max(num, ((Humanoid)player).GetInventory().CountItems(text2, -1, false)); } if (num < amount) { ((Character)player).Message((MessageType)2, "$msg_missingrequirement", 0, (Sprite)null, false); return; } ((Humanoid)player).GetInventory().RemoveItem(text, amount, -1, false); } string text3 = (((Object)(object)((Component)recipe.m_item).gameObject != (Object)null) ? ((Object)((Component)recipe.m_item).gameObject).name : ((Object)recipe.m_item).name); ((Humanoid)player).GetInventory().AddItem(text3, recipe.m_amount, 1, 0, player.GetPlayerID(), player.GetPlayerName(), new Vector2i(-1, -1), false, false, false); if ((Object)(object)station != (Object)null && station.m_craftItemDoneEffects != null) { station.m_craftItemDoneEffects.Create(((Component)station).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } else if ((Object)(object)station != (Object)null && station.m_craftItemEffects != null) { station.m_craftItemEffects.Create(((Component)station).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } string text4 = ((recipe.m_item.m_itemData != null && recipe.m_item.m_itemData.m_shared != null) ? recipe.m_item.m_itemData.m_shared.m_name : ((Object)recipe.m_item).name); string arg = ((Localization.instance != null) ? Localization.instance.Localize(text4) : text4); ((Character)player).Message((MessageType)2, $"Transmuted {arg}", 0, (Sprite)null, true); if (s_updateCraftingPanelMethod != null) { s_updateCraftingPanelMethod.Invoke(gui, new object[1] { false }); } } private static void ExecuteTierScaledRefinement(InventoryGui gui, Player player, CraftingStation station, Recipe recipe, ItemData upgradeItem, ItemData idolData, int idolTier, int targetQuality) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_0566: Unknown result type (might be due to invalid IL or missing references) string text = (((Object)(object)recipe.m_item != (Object)null) ? ((Object)((Component)recipe.m_item).gameObject).name : ""); int num = StringExtensionMethods.GetStableHashCode(text) + targetQuality; string text2 = (((Object)(object)upgradeItem.m_dropPrefab != (Object)null) ? ((Object)upgradeItem.m_dropPrefab).name : ((Object)recipe.m_item).name); int quality = upgradeItem.m_quality; int variant = upgradeItem.m_variant; float durability = upgradeItem.m_durability; Vector2i gridPos = upgradeItem.m_gridPos; bool equipped = upgradeItem.m_equipped; Dictionary<string, string> dictionary = ((upgradeItem.m_customData != null) ? new Dictionary<string, string>(upgradeItem.m_customData) : null); long crafterID = upgradeItem.m_crafterID; string crafterName = upgradeItem.m_crafterName; player.ConsumeResources(recipe.m_resources, targetQuality, 1, 1); ((Humanoid)player).GetInventory().RemoveItem(upgradeItem); float itemUpgradeChance = player.GetItemUpgradeChance(num); float upgradeChance = idolData.m_shared.m_upgradeChance; float breakChance = idolData.m_shared.m_breakChance; if (itemUpgradeChance <= upgradeChance) { ItemData val = ((Humanoid)player).GetInventory().AddItem(text2, 1, targetQuality, variant, crafterID, crafterName, gridPos, equipped, false, false); if (val != null) { val.m_durability = val.GetMaxDurability(); if (dictionary != null) { val.m_customData = dictionary; } } if (station.m_craftItemDoneEffects != null) { station.m_craftItemDoneEffects.Create(((Component)station).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } string name = recipe.m_item.m_itemData.m_shared.m_name; string text3 = ((Localization.instance != null) ? Localization.instance.Localize(name) : name); ((Character)player).Message((MessageType)2, (Localization.instance != null) ? Localization.instance.Localize("$msg_upgrader_success", new string[2] { text3, targetQuality.ToString() }) : $"{text3} refined successfully to level {targetQuality}", 0, (Sprite)null, true); ZLog.Log((object)$"Upgrader <color=yellow>succeeded</color> on {text3} level {targetQuality}!"); } else { UpgradeSimulator.NextFailureType nextFailureType = UpgradeSimulator.EvaluateFailure(itemUpgradeChance, upgradeChance, breakChance, idolTier, UpgradeSimulator.OutcomeMode.TierScaled); if (station.m_craftItemDoneFailEffects != null) { station.m_craftItemDoneFailEffects.Create(((Component)station).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } string name = recipe.m_item.m_itemData.m_shared.m_name; string text3 = ((Localization.instance != null) ? Localization.instance.Localize(name) : name); switch (nextFailureType) { case UpgradeSimulator.NextFailureType.NoChange: { ItemData val3 = ((Humanoid)player).GetInventory().AddItem(text2, 1, quality, variant, crafterID, crafterName, gridPos, equipped, false, false); if (val3 != null) { val3.m_durability = durability; if (dictionary != null) { val3.m_customData = dictionary; } } ((Character)player).Message((MessageType)2, $"Refining of {text3} was unstable, but the item held firm (level unchanged)", 0, (Sprite)null, true); string text4 = $"<color=#70C0FF>Upgrader UNSTABLE on {text3} level {quality}, no change in quality!</color>"; ZLog.Log((object)text4); if ((Object)(object)Chat.instance != (Object)null) { ((Terminal)Chat.instance).AddString(text4); } break; } case UpgradeSimulator.NextFailureType.Downgrade: { int num3 = Mathf.Max(1, targetQuality - 2); ItemData val4 = ((Humanoid)player).GetInventory().AddItem(text2, 1, num3, variant, crafterID, crafterName, gridPos, equipped, false, false); if (val4 != null) { val4.m_durability = val4.GetMaxDurability(); if (dictionary != null) { val4.m_customData = dictionary; } } ((Character)player).Message((MessageType)2, (Localization.instance != null) ? Localization.instance.Localize("$msg_upgrader_failed", new string[2] { text3, num3.ToString() }) : $"Refining of {text3} failed, downgraded to level {num3}", 0, (Sprite)null, true); ZLog.Log((object)$"Upgrader <color=orange>FAILED</color> {text3} level {quality}, level was reduced!"); break; } default: { ((Character)player).Message((MessageType)2, (Localization.instance != null) ? Localization.instance.Localize("$msg_upgrader_broke", new string[2] { text3, quality.ToString() }) : $"{text3} refinement failed and broke on level {quality}", 0, (Sprite)null, true); ZLog.Log((object)$"Upgrader <color=red>BROKE</color> {text3} level {quality} and was destroyed!"); float breakReturnIngreientsAmount = idolData.m_shared.m_breakReturnIngreientsAmount; if (!(breakReturnIngreientsAmount > 0f) || recipe.m_resources == null) { break; } for (int i = 0; i < recipe.m_resources.Length; i++) { Requirement val2 = recipe.m_resources[i]; if (val2 != null && val2.m_recover && (Object)(object)val2.m_resItem != (Object)null) { int num2 = Mathf.CeilToInt((float)(val2.GetAmount(1) + val2.GetAmount(quality)) * breakReturnIngreientsAmount); if (num2 > 0) { ((Humanoid)player).GetInventory().AddItem(((Object)val2.m_resItem).name, num2, 1, 0, player.GetPlayerID(), player.GetPlayerName(), new Vector2i(-1, -1), false, false, false); } } } break; } } } if (s_updateCraftingPanelMethod != null) { s_updateCraftingPanelMethod.Invoke(gui, new object[1] { false }); } } [HarmonyTranspiler] [HarmonyPatch("DoCrafting")] public static IEnumerable<CodeInstruction> DoCrafting_Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: 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 List<CodeInstruction> list = new List<CodeInstruction>(instructions); MethodInfo methodInfo = AccessTools.Method(typeof(InventoryGuiPatches), "SafeStationIsCheated", (Type[])null, (Type[])null); for (int i = 0; i < list.Count - 3; i++) { if (list[i].opcode == OpCodes.Callvirt && list[i].operand != null && list[i].operand.ToString().Contains("GetComponent") && list[i + 1].opcode == OpCodes.Callvirt && list[i + 1].operand != null && list[i + 1].operand.ToString().Contains("GetZDO")) { list[i] = new CodeInstruction(OpCodes.Call, (object)methodInfo); list[i + 1] = new CodeInstruction(OpCodes.Nop, (object)null); list[i + 2] = new CodeInstruction(OpCodes.Nop, (object)null); break; } } return list; } public static bool SafeStationIsCheated(CraftingStation station) { if ((Object)(object)station == (Object)null) { return false; } ZNetView component = ((Component)station).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null) { return false; } ZDO zDO = component.GetZDO(); if (zDO == null) { return false; } if (s_cheatUtilsMethod == null) { Type type = typeof(CraftingStation).Assembly.GetType("CheatUtils"); if (type != null) { s_cheatUtilsMethod = AccessTools.Method(type, "IsCheated", new Type[1] { typeof(ZDO) }, (Type[])null); } } if (s_cheatUtilsMethod != null) { try { return (bool)s_cheatUtilsMethod.Invoke(null, new object[1] { zDO }); } catch { } } return false; } [HarmonyPatch("DoCrafting")] [HarmonyPostfix] public static void DoCrafting_Postfix(InventoryGui __instance, Player player) { try { if ((Object)(object)__instance == (Object)null || (Object)(object)player == (Object)null) { return; } CraftingStation currentCraftingStation = player.GetCurrentCraftingStation(); GetSelectedRecipeAndItem(__instance, out var recipe, out var upgradeItem); if ((Object)(object)currentCraftingStation != (Object)null && currentCraftingStation.m_upgrader && upgradeItem != null && (Object)(object)recipe != (Object)null) { UpgradeSimulator.OutcomeMode effectiveOutcomeMode = ForesightForgePlugin.EffectiveOutcomeMode; UpgradeSimulator.Prediction prediction = UpgradeSimulator.Predict(player, recipe, upgradeItem, 25, effectiveOutcomeMode); if ((Object)(object)VolvaEyeBanner.Instance != (Object)null) { VolvaEyeBanner.Instance.UpdateDisplay(prediction, upgradeItem.m_shared.m_name); } } } catch (Exception arg) { ZLog.LogWarning((object)$"[ForesightForge] Error in DoCrafting_Postfix: {arg}"); } } } [HarmonyPatch(typeof(Terminal))] public static class TerminalPatches { private static bool s_commandsInitialized = false; private static FieldInfo s_commandsField = typeof(Terminal).GetField("commands", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); private static CraftingStation s_dummyUpgraderStation = null; public static void OpenForgeInterface() { //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Expected O, but got Unknown //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Expected O, but got Unknown //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Expected O, but got Unknown Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, "Must be in-game to open Forge of Potential.", 0, (Sprite)null, false, true); } return; } if ((Object)(object)s_dummyUpgraderStation == (Object)null) { GameObject val = new GameObject("_ForesightVirtualForge"); Object.DontDestroyOnLoad((Object)(object)val); val.transform.position = ((Component)localPlayer).transform.position; s_dummyUpgraderStation = val.AddComponent<CraftingStation>(); s_dummyUpgraderStation.m_name = "$piece_upgradestation"; s_dummyUpgraderStation.m_upgrader = true; s_dummyUpgraderStation.m_hasCraftTab = ForesightForgePlugin.EffectiveEnableIdolTransmutation; s_dummyUpgraderStation.m_showBasicRecipies = false; s_dummyUpgraderStation.m_canRepair = false; s_dummyUpgraderStation.m_useDistance = 999f; s_dummyUpgraderStation.m_rangeBuild = 0f; s_dummyUpgraderStation.m_discoverRange = 0f; s_dummyUpgraderStation.m_craftRequireRoof = false; s_dummyUpgraderStation.m_craftRequireFire = false; bool flag = false; if (ForesightForgePlugin.ConfigEnableAltarEffects != null && ForesightForgePlugin.ConfigEnableAltarEffects.Value && (Object)(object)ZNetScene.instance != (Object)null) { GameObject prefab = ZNetScene.instance.GetPrefab("piece_upgradestation"); if ((Object)(object)prefab != (Object)null) { CraftingStation component = prefab.GetComponent<CraftingStation>(); if ((Object)(object)component != (Object)null) { s_dummyUpgraderStation.m_craftItemEffects = component.m_craftItemEffects; s_dummyUpgraderStation.m_craftItemDoneEffects = component.m_craftItemDoneEffects; s_dummyUpgraderStation.m_craftItemDoneFailEffects = component.m_craftItemDoneFailEffects; flag = true; } } } if (!flag) { s_dummyUpgraderStation.m_craftItemEffects = new EffectList(); s_dummyUpgraderStation.m_craftItemDoneEffects = new EffectList(); s_dummyUpgraderStation.m_craftItemDoneFailEffects = new EffectList(); } } else { ((Component)s_dummyUpgraderStation).transform.position = ((Component)localPlayer).transform.position; } if ((Object)(object)ObjectDB.instance != (Object)null) { IdolRecipes.RegisterAllRecipes(ObjectDB.instance); } localPlayer.SetCraftingStation(s_dummyUpgraderStation); ForesightForgePlugin.SafeUpdateKnownRecipes(localPlayer); if ((Object)(object)InventoryGui.instance != (Object)null) { InventoryGui.instance.Show((Container)null, 3); } } public static int ExecuteSpawnIdols(Player player, int count) { //IL_0146: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return 0; } string[] array = new string[16] { "Upgrader0Weapon", "Upgrader1Weapon", "Upgrader2Weapon", "Upgrader3Weapon", "Upgrader4Weapon", "Upgrader5Weapon", "Upgrader6Weapon", "Upgrader7Weapon", "Upgrader0Armor", "Upgrader1Armor", "Upgrader2Armor", "Upgrader3Armor", "Upgrader4Armor", "Upgrader5Armor", "Upgrader6Armor", "Upgrader7Armor" }; int num = 0; for (int i = 0; i < array.Length; i++) { GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(array[i]) : null); if ((Object)(object)val != (Object)null) { ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null && component.m_itemData != null) { player.AddKnownItem(component.m_itemData); } ((Humanoid)player).GetInventory().AddItem(array[i], count, 1, 0, player.GetPlayerID(), player.GetPlayerName(), new Vector2i(-1, -1), false, false, false); num += count; } } if ((Object)(object)ObjectDB.instance != (Object)null) { IdolRecipes.RegisterAllRecipes(ObjectDB.instance); } ForesightForgePlugin.SafeUpdateKnownRecipes(player); return num; } public static void RegisterCommands() { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Expected O, but got Unknown //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Expected O, but got Unknown //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Expected O, but got Unknown //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Expected O, but got Unknown if (s_commandsInitialized) { return; } try { Dictionary<string, ConsoleCommand> dictionary = null; if (s_commandsField != null) { dictionary = s_commandsField.GetValue(null) as Dictionary<string, ConsoleCommand>; } if (dictionary != null && !dictionary.ContainsKey("openforge")) { new ConsoleCommand("openforge", "Opens the Forge of Potential upgrade interface directly (requires debugmode).", (ConsoleEvent)delegate(ConsoleEventArgs args) { if (!Player.m_debugMode) { args.Context.AddString("<color=red>The openforge command requires debugmode to be active.</color>"); } else { OpenForgeInterface(); args.Context.AddString("Opened Forge of Potential interface."); } }, true, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } if (dictionary != null && !dictionary.ContainsKey("openupgrader")) { new ConsoleCommand("openupgrader", "Opens the Forge of Potential upgrade interface directly (requires debugmode).", (ConsoleEvent)delegate(ConsoleEventArgs args) { if (!Player.m_debugMode) { args.Context.AddString("<color=red>The openupgrader command requires debugmode to be active.</color>"); } else { OpenForgeInterface(); args.Context.AddString("Opened Forge of Potential interface."); } }, true, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } if (dictionary != null && !dictionary.ContainsKey("resetseeds")) { new ConsoleCommand("resetseeds", "Clears all stored Forge of Potential upgrade seeds on the character (Dev Cheat, requires debugmode).", (ConsoleEvent)delegate(ConsoleEventArgs args) { if (!Player.m_debugMode) { args.Context.AddString("<color=red>The resetseeds command requires debugmode to be active.</color>"); } else { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { args.Context.AddString("No local player active."); } else { int num = UpgradeSimulator.ResetPlayerSeeds(localPlayer); args.Context.AddString($"ForesightForge: Cleared {num} stored upgrade seed(s)."); } } }, true, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } if (dictionary != null && !dictionary.ContainsKey("resetupgradeseeds")) { new ConsoleCommand("resetupgradeseeds", "Clears all stored Forge of Potential upgrade seeds on the character (Dev Cheat, requires debugmode).", (ConsoleEvent)delegate(ConsoleEventArgs args) { if (!Player.m_debugMode) { args.Context.AddString("<color=red>The resetupgradeseeds command requires debugmode to be active.</color>"); } else { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { args.Context.AddString("No local player active."); } else { int num = UpgradeSimulator.ResetPlayerSeeds(localPlayer); args.Context.AddString($"ForesightForge: Cleared {num} stored upgrade seed(s)."); } } }, true, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } if (dictionary != null && !dictionary.ContainsKey("listseeds")) { new ConsoleCommand("listseeds", "Lists stored Forge of Potential upgrade seeds on the character.", (ConsoleEvent)delegate(ConsoleEventArgs args) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { args.Context.AddString("No local player active."); } else { Dictionary<int, int> playerUpgradeSeeds = UpgradeSimulator.GetPlayerUpgradeSeeds(localPlayer); if (playerUpgradeSeeds != null && playerUpgradeSeeds.Count != 0) { args.Context.AddString($"Stored seeds count: {playerUpgradeSeeds.Count} (Mode: {ForesightForgePlugin.EffectiveOutcomeMode})"); { foreach (KeyValuePair<int, int> item in playerUpgradeSeeds) { UpgradeSimulator.SeedInfo info = UpgradeSimulator.AnalyzeSeed(item.Key, item.Value, ForesightForgePlugin.EffectiveOutcomeMode); args.Context.AddString(" " + UpgradeSimulator.FormatSeedInfo(info)); } return; } } args.Context.AddString("No stored upgrade seeds found on character."); } }, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } if (dictionary != null && !dictionary.ContainsKey("spawnidols")) { new ConsoleCommand("spawnidols", "Spawns 10 of each Battle and Protection Idol into player inventory (Dev Cheat, requires debugmode).", (ConsoleEvent)delegate(ConsoleEventArgs args) { if (!Player.m_debugMode) { args.Context.AddString("<color=red>The spawnidols command requires debugmode to be active.</color>"); } else { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { args.Context.AddString("No local player active."); } else { int result = 10; if (args.Length > 1) { int.TryParse(args[1], out result); if (result <= 0) { result = 10; } } int num = ExecuteSpawnIdols(localPlayer, result); args.Context.AddString($"<color=yellow>ForesightForge: Spawned {num} idols ({result} of each tier) into inventory.</color>"); } } }, true, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } s_commandsInitialized = true; } catch (Exception arg) { ZLog.LogWarning((object)$"[ForesightForge] Failed to register console commands: {arg}"); } } [HarmonyPatch("InitTerminal")] [HarmonyPostfix] public static void InitTerminal_Postfix() { RegisterCommands(); } } [HarmonyPatch(typeof(Chat))] public static class ChatCommandPatches { [HarmonyPatch("SendInput")] [HarmonyPrefix] public static bool SendInput_Prefix(Chat __instance) { if ((Object)(object)__instance == (Object)null || (Object)(object)((Terminal)__instance).m_input == (Object)null) { return true; } string text = ((TMP_InputField)((Terminal)__instance).m_input).text; if (string.IsNullOrEmpty(text)) { return true; } string text2 = text.Trim(); if (text2.Equals("/openforge", StringComparison.OrdinalIgnoreCase) || text2.Equals("/openupgrader", StringComparison.OrdinalIgnoreCase) || text2.Equals("/forge", StringComparison.OrdinalIgnoreCase)) { ((TMP_InputField)((Terminal)__instance).m_input).text = ""; if (!Terminal.m_cheat || !Player.m_debugMode) { if ((Object)(object)Chat.instance != (Object)null) { ((Terminal)Chat.instance).AddString("<color=red>The /openforge command requires devcommands and debugmode to be enabled.</color>"); } return false; } TerminalPatches.OpenForgeInterface(); return false; } if (text2.Equals("/resetseeds", StringComparison.OrdinalIgnoreCase) || text2.Equals("/resetupgradeseeds", StringComparison.OrdinalIgnoreCase)) { ((TMP_InputField)((Terminal)__instance).m_input).text = ""; if (!Terminal.m_cheat || !Player.m_debugMode) { if ((Object)(object)Chat.instance != (Object)null) { ((Terminal)Chat.instance).AddString("<color=red>The /resetseeds command requires devcommands and debugmode to be enabled.</color>"); } return false; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { int num = UpgradeSimulator.ResetPlayerSeeds(localPlayer); if ((Object)(object)Chat.instance != (Object)null) { ((Terminal)Chat.instance).AddString($"<color=yellow>ForesightForge: Cleared {num} stored upgrade seed(s).</color>"); } } return false; } if (text2.StartsWith("/spawnidols", StringComparison.OrdinalIgnoreCase)) { ((TMP_InputField)((Terminal)__instance).m_input).text = ""; if (!Terminal.m_cheat || !Player.m_debugMode) { if ((Object)(object)Chat.instance != (Object)null) { ((Terminal)Chat.instance).AddString("<color=red>The /spawnidols command requires devcommands and debugmode to be enabled.</color>"); } return false; } string[] array = text2.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); int result = 10; if (array.Length > 1) { int.TryParse(array[1], out result); if (result <= 0) { result = 10; } } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { int num2 = TerminalPatches.ExecuteSpawnIdols(localPlayer, result); if ((Object)(object)Chat.instance != (Object)null) { ((Terminal)Chat.instance).AddString($"<color=yellow>ForesightForge: Spawned {num2} idols ({result} of each tier) into inventory.</color>"); } } return false; } return true; } } [HarmonyPatch(typeof(CraftingStation))] public static class CraftingStationSafetyPatches { [HarmonyPatch("Start")] [HarmonyPostfix] public static void Start_Postfix(CraftingStation __instance) { if ((Object)(object)__instance != (Object)null && __instance.m_upgrader) { __instance.m_hasCraftTab = ForesightForgePlugin.EffectiveEnableIdolTransmutation; __instance.m_showBasicRecipies = false; __instance.m_canRepair = false; } } [HarmonyPatch("Interact")] [HarmonyPrefix] public static void Interact_Prefix(CraftingStation __instance, Humanoid user) { if ((Object)(object)__instance != (Object)null && __instance.m_upgrader) { __instance.m_hasCraftTab = ForesightForgePlugin.EffectiveEnableIdolTransmutation; __instance.m_showBasicRecipies = false; __instance.m_canRepair = false; if ((Object)(object)ObjectDB.instance != (Object)null) { IdolRecipes.RegisterAllRecipes(ObjectDB.instance); } Player val = (Player)(object)((user is Player) ? user : null); if ((Object)(object)val != (Object)null) { ForesightForgePlugin.SafeUpdateKnownRecipes(val); } } } [HarmonyPrefix] [HarmonyPatch("CheckUsable")] public static bool CheckUsable_Prefix(CraftingStation __instance, ref bool __result) { if ((Object)(object)__instance != (Object)null && __instance.m_upgrader) { __result = true; return false; } return true; } [HarmonyPrefix] [HarmonyPatch("GetExtentionCount")] public static bool GetExtentionCount_Prefix(CraftingStation __instance, ref int __result) { if ((Object)(object)__instance != (Object)null && __instance.m_upgrader) { __result = 0; return false; } return true; } [HarmonyPatch("InUseDistance")] [HarmonyPrefix] public static bool InUseDistance_Prefix(CraftingStation __instance, ref bool __result) { if ((Object)(object)__instance != (Object)null && __instance.m_upgrader) { __result = true; return false; } return true; } } [HarmonyPatch(typeof(Player))] public static class PlayerStationPatches { [HarmonyPrefix] [HarmonyPatch("KnowStationLevel")] public static bool KnowStationLevel_Prefix(string name, int level, ref bool __result) { if (name == "$piece_upgradestation" || name == "_ForesightVirtualForge" || name == "piece_upgradestation") { __result = true; return false; } return true; } [HarmonyPostfix] [HarmonyPatch("OnSpawned")] public static void OnSpawned_Postfix(Player __instance) { ForesightForgePlugin.SafeUpdateKnownRecipes(__instance); } [HarmonyPrefix] [HarmonyPatch("HaveRequirements", new Type[] { typeof(Recipe), typeof(bool), typeof(int), typeof(int) })] public static bool HaveRequirements_Prefix(Player __instance, Recipe recipe, bool discover, int qualityLevel, int amount, ref bool __result) { if ((Object)(object)recipe != (Object)null && ((Object)recipe).name != null && ((Object)recipe).name.StartsWith("Recipe_Transmute_Upgrader")) { if (recipe.m_resources != null && recipe.m_resources.Length > 0 && (Object)(object)recipe.m_resources[0].m_resItem != (Object)null && recipe.m_resources[0].m_resItem.m_itemData != null && recipe.m_resources[0].m_resItem.m_itemData.m_shared != null) { string name = recipe.m_resources[0].m_resItem.m_itemData.m_shared.m_name; if (discover) { __result = __instance.IsKnownMaterial(name); return false; } if (__instance.NoCostCheat() || ZoneSystem.instance.GetGlobalKey((GlobalKeys)25)) { __result = true; return false; } int num = recipe.m_resources[0].m_amount * amount; int num2 = ((Humanoid)__instance).GetInventory().CountItems(name, -1, false); string text = (((Object)(object)((Component)recipe.m_resources[0].m_resItem).gameObject != (Object)null) ? ((Object)((Component)recipe.m_resources[0].m_resItem).gameObject).name : ((Object)recipe.m_resources[0].m_resItem).name); if (num2 < num) { num2 = Math.Max(num2, ((Humanoid)__instance).GetInventory().CountItems(text, -1, false)); } __result = num2 >= num; return false; } __result = false; return false; } return true; } } public static class IdolRecipes { [HarmonyPatch(typeof(ObjectDB))] public static class ObjectDBPatches { [HarmonyPatch("Awake")] [HarmonyPostfix] public static void Awake_Postfix(ObjectDB __instance) { RegisterAllRecipes(__instance); } [HarmonyPatch("CopyOtherDB")] [HarmonyPostfix] public static void CopyOtherDB_Postfix(ObjectDB __instance) { RegisterAllRecipes(__instance); } } [HarmonyPatch(typeof(ZNetScene))] public static class ZNetScenePatches { [HarmonyPatch("Awake")] [HarmonyPostfix] public static void Awake_Postfix() { if ((Object)(object)ObjectDB.instance != (Object)null) { RegisterAllRecipes(ObjectDB.instance); } } } private static readonly List<Recipe> s_customRecipes = new List<Recipe>(); private static readonly string[][] WeaponProgression = new string[7][] { new string[2] { "Upgrader0Weapon", "Upgrader1Weapon" }, new string[2] { "Upgrader1Weapon", "Upgrader2Weapon" }, new string[2] { "Upgrader2Weapon", "Upgrader3Weapon" }, new string[2] { "Upgrader3Weapon", "Upgrader4Weapon" }, new string[2] { "Upgrader4Weapon", "Upgrader5Weapon" }, new string[2] { "Upgrader5Weapon", "Upgrader6Weapon" }, new string[2] { "Upgrader6Weapon", "Upgrader7Weapon" } }; private static readonly string[][] ArmorProgression = new string[7][] { new string[2] { "Upgrader0Armor", "Upgrader1Armor" }, new string[2] { "Upgrader1Armor", "Upgrader2Armor" }, new string[2] { "Upgrader2Armor", "Upgrader3Armor" }, new string[2] { "Upgrader3Armor", "Upgrader4Armor" }, new string[2] { "Upgrader4Armor", "Upgrader5Armor" }, new string[2] { "Upgrader5Armor", "Upgrader6Armor" }, new string[2] { "Upgrader6Armor", "Upgrader7Armor" } }; public static CraftingStation GetAltarStation() { if ((Object)(object)ZNetScene.instance != (Object)null) { GameObject prefab = ZNetScene.instance.GetPrefab("piece_upgradestation"); if ((Object)(object)prefab != (Object)null) { return prefab.GetComponent<CraftingStation>(); } } return null; } public static void RegisterAllRecipes(ObjectDB odb) { if ((Object)(object)odb == (Object)null || odb.m_items == null || odb.m_items.Count == 0) { return; } int num = ((ForesightForgePlugin.ConfigIdolUpgradeRatio != null) ? ForesightForgePlugin.ConfigIdolUpgradeRatio.Value : 3); num = Mathf.Clamp(num, 1, 10); CraftingStation altarStation = GetAltarStation(); if (s_customRecipes.Count == 0) { CreateAllCustomRecipes(odb, num, altarStation); } else { UpdateRecipeRatios(num); if ((Object)(object)altarStation != (Object)null) { for (int i = 0; i < s_customRecipes.Count; i++) { if ((Object)(object)s_customRecipes[i] != (Object)null && (Object)(object)s_customRecipes[i].m_craftingStation == (Object)null) { s_customRecipes[i].m_craftingStation = altarStation; } } } } int num2 = 0; for (int i = 0; i < s_customRecipes.Count; i++) { Recipe val = s_customRecipes[i]; if ((Object)(object)val != (Object)null && !odb.m_recipes.Contains(val)) { odb.m_recipes.Add(val); num2++; } } if (num2 > 0) { ZLog.Log((object)$"[ForesightForge] Injected {num2} Idol recipes into ObjectDB (Total in DB: {odb.m_recipes.Count})."); } } private static void CreateAllCustomRecipes(ObjectDB odb, int ratio, CraftingStation altarStation) { s_customRecipes.Clear(); for (int i = 0; i < WeaponProgression.Length; i++) { string sourcePrefabName = WeaponProgression[i][0]; string targetPrefabName = WeaponProgression[i][1]; Recipe val = CreateIdolRecipe(odb, sourcePrefabName, targetPrefabName, ratio, altarStation); if ((Object)(object)val != (Object)null) { s_customRecipes.Add(val); } } for (int i = 0; i < ArmorProgression.Length; i++) { string sourcePrefabName = ArmorProgression[i][0]; string targetPrefabName = ArmorProgression[i][1]; Recipe val = CreateIdolRecipe(odb, sourcePrefabName, targetPrefabName, ratio, altarStation); if ((Object)(object)val != (Object)null) { s_customRecipes.Add(val); } } ZLog.Log((object)$"[ForesightForge] Initialized {s_customRecipes.Count} Idol transmutation recipes (Ratio: {ratio}:1)."); } public static void SetRecipesEnabled(bool enabled) { for (int i = 0; i < s_customRecipes.Count; i++) { if ((Object)(object)s_customRecipes[i] != (Object)null) { s_customRecipes[i].m_enabled = enabled; } } } public static void UpdateRecipeRatios(int newRatio) { newRatio = Mathf.Clamp(newRatio, 1, 10); bool effectiveEnableIdolTransmutation = ForesightForgePlugin.EffectiveEnableIdolTransmutation; CraftingStation altarStation = GetAltarStation(); for (int i = 0; i < s_customRecipes.Count; i++) { Recipe val = s_customRecipes[i]; if ((Object)(object)val != (Object)null) { val.m_enabled = effectiveEnableIdolTransmutation; if ((Object)(object)altarStation != (Object)null && (Object)(object)val.m_craftingStation == (Object)null) { val.m_craftingStation = altarStation; } if (val.m_resources != null && val.m_resources.Length > 0) { val.m_resources[0].m_amount = newRatio; val.m_resources[0].m_upgraderResource = true; } } } } private static Recipe CreateIdolRecipe(ObjectDB odb, string sourcePrefabName, string targetPrefabName, int ratio, CraftingStation station) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown GameObject itemPrefab = odb.GetItemPrefab(sourcePrefabName); GameObject itemPrefab2 = odb.GetItemPrefab(targetPrefabName); ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); ItemDrop val2 = (((Object)(object)itemPrefab2 != (Object)null) ? itemPrefab2.GetComponent<ItemDrop>() : null); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return null; } Recipe val3 = ScriptableObject.CreateInstance<Recipe>(); ((Object)val3).name = $"Recipe_Transmute_{sourcePrefabName}_to_{targetPrefabName}"; val3.m_item = val2; val3.m_amount = 1; val3.m_enabled = ForesightForgePlugin.EffectiveEnableIdolTransmutation; val3.m_minStationLevel = 1; val3.m_craftingStation = station; Requirement val4 = new Requirement(); val4.m_resItem = val; val4.m_amount = ratio; val4.m_recover = false; val4.m_amountPerLevel = 0; val4.m_upgraderResource = true; val3.m_resources = (Requirement[])(object)new Requirement[1] { val4 }; return val3; } } public static class UpgradeSimulator { public enum OutcomeMode { Vanilla, TierScaled } public enum NextFailureType { None, NoChange, Downgrade, Break } public struct Prediction { public int SuccessCount; public NextFailureType NextFailure; public float NextRoll; public float UpgradeChance; public float BreakChance; public bool HasIdol; public int IdolTier; public OutcomeMode Mode; } public struct SeedInfo { public int Hash; public int Seed; public string ItemName; public string PrefabName; public int TargetQuality; public int GuaranteedUpgrades; public NextFailureType NextFailure; } private static FieldInfo s_itemUpgradeSeedsField = typeof(Player).GetField("m_itemUpgradeSeeds", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); public static Dictionary<int, int> GetPlayerUpgradeSeeds(Player player) { if ((Object)(object)player == (Object)null || s_itemUpgradeSeedsField == null) { return null; } return s_itemUpgradeSeedsField.GetValue(player) as Dictionary<int, int>; } public static int ResetPlayerSeeds(Player player) { if ((Object)(object)player == (Object)null) { return 0; } Dictionary<int, int> playerUpgradeSeeds = GetPlayerUpgradeSeeds(player); if (playerUpgradeSeeds == null) { return 0; } int count = playerUpgradeSeeds.Count; playerUpgradeSeeds.Clear(); string arg = $"ForesightForge: Cleared {count} stored upgrade seed(s) for character '{player.GetPlayerName()}'."; ZLog.Log((object)$"[ForesightForge] {arg}"); if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, $"ForesightForge: Reset {count} upgrade seed(s)!", 0, (Sprite)null, false, true); } if (InventoryGui.IsVisible() && (Object)(object)InventoryGui.instance != (Object)null) { try { MethodInfo method = typeof(InventoryGui).GetMethod("UpdateRecipe", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { method.Invoke(InventoryGui.instance, new object[2] { player, 0f }); } } catch { } } return count; } public static int GetIdolTier(ItemDrop idol) { if ((Object)(object)idol == (Object)null) { return 0; } string text = (((Object)(object)((Component)idol).gameObject != (Object)null) ? ((Object)((Component)idol).gameObject).name : ""); if (string.IsNullOrEmpty(text) && idol.m_itemData != null && (Object)(object)idol.m_itemData.m_dropPrefab != (Object)null) { text = ((Object)idol.m_itemData.m_dropPrefab).name; } if (text.IndexOf("Upgrader0", StringComparison.OrdinalIgnoreCase) >= 0) { return 0; } if (text.IndexOf("Upgrader1", StringComparison.OrdinalIgnoreCase) >= 0) { return 1; } if (text.IndexOf("Upgrader2", StringComparison.OrdinalIgnoreCase) >= 0) { return 2; } if (text.IndexOf("Upgrader3", StringComparison.OrdinalIgnoreCase) >= 0) { return 3; } if (text.IndexOf("Upgrader4", StringComparison.OrdinalIgnoreCase) >= 0) { return 4; } if (text.IndexOf("Upgrader5", StringComparison.OrdinalIgnoreCase) >= 0) { return 5; } if (text.IndexOf("Upgrader6", StringComparison.OrdinalIgnoreCase) >= 0) { return 6; } if (text.IndexOf("Upgrader7", StringComparison.OrdinalIgnoreCase) >= 0) { return 7; } if (idol.m_itemData != null && idol.m_itemData.m_shared != null) { string text2 = idol.m_itemData.m_shared.m_name ?? ""; if (text2.IndexOf("bronze", StringComparison.OrdinalIgnoreCase) >= 0) { return 1; } if (text2.IndexOf("iron", StringComparison.OrdinalIgnoreCase) >= 0) { return 2; } if (text2.IndexOf("silver", StringComparison.OrdinalIgnoreCase) >= 0) { return 3; } if (text2.IndexOf("blackmetal", StringComparison.OrdinalIgnoreCase) >= 0 || text2.IndexOf("black metal", StringComparison.OrdinalIgnoreCase) >= 0) { return 4; } if (text2.IndexOf("marble", StringComparison.OrdinalIgnoreCase) >= 0) { return 5; } if (text2.IndexOf("flametal", StringComparison.OrdinalIgnoreCase) >= 0) { return 6; } if (text2.IndexOf("bloodgold", StringComparison.OrdinalIgnoreCase) >= 0) { return 7; } } return 0; } public static NextFailureType EvaluateFailure(float roll, float upgradeChance, float vanillaBreakChance, int tier, OutcomeMode mode) { if (mode == OutcomeMode.Vanilla) { if (1f - roll < vanillaBreakChance) { return NextFailureType.Break; } return NextFailureType.Downgrade; } tier = Mathf.Clamp(tier, 0, 7); float num = 0.05f + 0.05f * (float)tier; float num2 = 0.05f + 0.05f * (float)tier; float num3 = 0.9f - 0.1f * (float)tier; float num4 = Mathf.Max(0.0001f, 1f - upgradeChance); float num5 = Mathf.Clamp01((roll - upgradeChance) / num4); if (num5 < num3) { return NextFailureType.NoChange; } if (num5 < num3 + num2) { return NextFailureType.Downgrade; } return NextFailureType.Break; } public static Prediction Predict(Player player, Recipe recipe, ItemData upgradeItem, int maxLookahead) { return Predict(player, recipe, upgradeItem, maxLookahead, ForesightForgePlugin.EffectiveOutcomeMode); } public static Prediction Predict(Player player, Recipe recipe, ItemData upgradeItem, int maxLookahead, OutcomeMode mode) { //IL_0299: 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_01ae: Unknown result type (might be due to invalid IL or missing references) Prediction result = new Prediction { SuccessCount = 0, NextFailure = NextFailureType.None, NextRoll = 0f, UpgradeChance = 0.65f, BreakChance = 1f, HasIdol = false, IdolTier = 0, Mode = mode }; if ((Object)(object)player == (Object)null || (Object)(object)recipe == (Object)null || upgradeItem == null) { return result; } ItemDrop val = null; if (recipe.m_resources != null) { for (int i = 0; i < recipe.m_resources.Length; i++) { Requirement val2 = recipe.m_resources[i]; if (val2 != null && val2.m_upgraderResource && (Object)(object)val2.m_resItem != (Object)null) { val = val2.m_resItem; break; } } } if ((Object)(object)val != (Object)null && val.m_itemData != null && val.m_itemData.m_shared != null) { result.HasIdol = true; result.UpgradeChance = val.m_itemData.m_shared.m_upgradeChance; result.BreakChance = val.m_itemData.m_shared.m_breakChance; result.IdolTier = GetIdolTier(val); } int num = upgradeItem.m_quality + 1; string text = (((Object)(object)recipe.m_item != (Object)null) ? ((Object)((Component)recipe.m_item).gameObject).name : ""); int stableHashCode = StringExtensionMethods.GetStableHashCode(text); Dictionary<int, int> playerUpgradeSeeds = GetPlayerUpgradeSeeds(player); string playerName = player.GetPlayerName(); int stableHashCode2 = StringExtensionMethods.GetStableHashCode(playerName); State state = Random.state; try { int num2 = 0; bool flag = true; for (int j = 0; j < maxLookahead; j++) { int num3 = num + j; int num4 = stableHashCode + num3; if (playerUpgradeSeeds == null || !playerUpgradeSeeds.TryGetValue(num4, out var value)) { value = stableHashCode2 + num4; } Random.InitState(value); float value2 = Random.value; if (flag) { result.NextRoll = value2; flag = false; } if (value2 <= result.UpgradeChance) { num2++; continue; } result.NextFailure = EvaluateFailure(value2, result.UpgradeChance, result.BreakChance, result.IdolTier, mode); break; } result.SuccessCount = num2; return result; } catch (Exception arg) { ZLog.LogWarning((object)$"[ForesightForge] Error during upgrade simulation: {arg}"); return result; } finally { Random.state = state; } } public static SeedInfo AnalyzeSeed(int itemHash, int seed) { return AnalyzeSeed(itemHash, seed, ForesightForgePlugin.EffectiveOutcomeMode); } public static SeedInfo AnalyzeSeed(int itemHash, int seed, OutcomeMode mode) { //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) SeedInfo result = new SeedInfo { Hash = itemHash, Seed = seed, ItemName = "Unknown Item", PrefabName = "", TargetQuality = 0, GuaranteedUpgrades = 0, NextFailure = NextFailureType.None }; int tier = 0; if ((Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items != null) { for (int i = 0; i < ObjectDB.instance.m_items.Count; i++) { GameObject val = ObjectDB.instance.m_items[i]; if ((Object)(object)val == (Object)null) { continue; } ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null) { continue; } int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)val).name); int num = component.m_itemData.m_shared.m_maxQuality; if (num < 2) { num = 4; } for (int j = 2; j <= num + 5; j++) { if (stableHashCode + j == itemHash) { result.PrefabName = ((Object)val).name; result.TargetQuality = j; string name = component.m_itemData.m_shared.m_name; result.ItemName = ((Localization.instance != null) ? Localization.instance.Localize(name) : name); break; } } if (!string.IsNullOrEmpty(result.PrefabName)) { break; } } } State state = Random.state; try { int num2 = 0; Player localPlayer = Player.m_localPlayer; string text = (((Object)(object)localPlayer != (Object)null) ? localPlayer.GetPlayerName() : ""); int stableHashCode2 = StringExtensionMethods.GetStableHashCode(text); Dictionary<int, int> dictionary = (((Object)(object)localPlayer != (Object)null) ? GetPlayerUpgradeSeeds(localPlayer) : null); int stableHashCode = ((!string.IsNullOrEmpty(result.PrefabName)) ? StringExtensionMethods.GetStableHashCode(result.PrefabName) : 0); for (int k = 0; k < 25; k++) { int value; if (k == 0) { value = seed; } else { if (string.IsNullOrEmpty(result.PrefabName)) { break; } int num3 = result.TargetQuality + k; int num4 = stableHashCode + num3; if (dictionary == null || !dictionary.TryGetValue(num4, out value)) { value = stableHashCode2 + num4; } } Random.InitState(value); float value2 = Random.value; if (value2 <= 0.65f) { num2++; continue; } result.NextFailure = EvaluateFailure(value2, 0.65f, 1f, tier, mode); break; } result.GuaranteedUpgrades = num2; } finally { Random.state = state; } return result; } public static string FormatSeedInfo(SeedInfo info) { string arg; if (info.TargetQuality <= 1) { arg = ((info.TargetQuality != 1) ? info.ItemName : $"{info.ItemName} (Lvl 1)"); } else { int num = info.TargetQuality - 1; arg = $"{info.ItemName} (Lvl {num} -> {info.TargetQuality})"; } string arg2; if (info.GuaranteedUpgrades <= 0) { arg2 = ((info.NextFailure == NextFailureType.NoChange) ? "0 Upgrades (Will Resist/No Change)" : ((info.NextFailure != NextFailureType.Downgrade) ? "0 Upgrades (Will Break)" : "0 Upgrades (Will Downgrade)")); } else { string arg3 = ((info.GuaranteedUpgrades > 1) ? "s" : ""); arg2 = $"{info.GuaranteedUpgrades} Upgrade{arg3}"; } return $"{info.Seed} [{arg}, {arg2}]"; } } public class VolvaEyeBanner : MonoBehaviour { private ValheimUiBanner m_banner; public static VolvaEyeBanner Instance { get; private set; } public static void Initialize(InventoryGui gui) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown if (!((Object)(object)Instance != (Object)null) && !((Object)(object)gui == (Object)null)) { Transform val = (((Object)(object)gui.m_inventoryRoot != (Object)null) ? ((Component)gui.m_inventoryRoot).transform : ((Component)gui).transform); if (!((Object)(object)val == (Object)null)) { GameObject val2 = new GameObject("VolvaEyeBanner_Holder"); val2.transform.SetParent(val, false); Instance = val2.AddComponent<VolvaEyeBanner>(); Instance.BuildUI(val); } } } private void BuildUI(Transform parent) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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) //IL_0094: Unknown result type (might be due to invalid IL or missing references) m_banner = ValheimUiBuilder.CreateBanner("ForesightForge_ProphecyBanner", "-- VOLVA'S PROPHECY --", "Peering into the weave of fate...", new Vector2(520f, 88f), parent); RectTransform component = ((Component)m_banner).GetComponent<RectTransform>(); if ((Object)(object)component != (Object)null) { component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = new Vector2(0f, 210f); } m_banner.Hide(); } public void UpdateDisplay(UpgradeSimulator.Prediction prediction, string itemName) { if ((Object)(object)m_banner == (Object)null) { return; } if (prediction.SuccessCount > 0) { string arg = ((prediction.SuccessCount > 1) ? "s" : ""); m_banner.SetTitle("<color=#FFBA40>-- VOLVA'S PROPHECY --</color>"); if (prediction.Mode == UpgradeSimulator.OutcomeMode.TierScaled) { if (prediction.NextFailure == UpgradeSimulator.NextFailureType.NoChange) { m_banner.SetStatus($"<color=#FFF5EA>Sees </color><color=#55FF55><b>{prediction.SuccessCount}</b></color><color=#FFF5EA> upgrade{arg}! <color=#70C0FF>(Next failure will RESIST safely)</color></color>"); } else if (prediction.NextFailure == UpgradeSimulator.NextFailureType.Downgrade) { m_banner.SetStatus($"<color=#FFF5EA>Sees </color><color=#55FF55><b>{prediction.SuccessCount}</b></color><color=#FFF5EA> upgrade{arg}! <color=#FFAA00>(Caution: Will DOWNGRADE on failure)</color></color>"); } else { m_banner.SetStatus($"<color=#FFF5EA>Sees </color><color=#55FF55><b>{prediction.SuccessCount}</b></color><color=#FFF5EA> upgrade{arg}! <color=#FF4444>(Warning: Will SHATTER on failure)</color></color>"); } } else { m_banner.SetStatus($"<color=#FFF5EA>Sees </color><color=#55FF55><b>{prediction.SuccessCount}</b></color><color=#FFF5EA> successful upgrade{arg} in this item's future!</color>"); } } else if (prediction.NextFailure == UpgradeSimulator.NextFailureType.NoChange) { m_banner.SetTitle("<color=#FFBA40>-- VOLVA'S EYE : </color><color=#70C0FF>RESISTANCE</color><color=#FFBA40> --</color>"); m_banner.SetStatus("<color=#FFF5EA>The thread holds firm! 0 upgrades (Will </color><color=#70C0FF><b>RESIST / NO CHANGE</b></color><color=#FFF5EA>)</color>"); } else if (prediction.NextFailure == UpgradeSimulator.NextFailureType.Downgrade) { m_banner.SetTitle("<color=#FFBA40>-- VOLVA'S EYE : </color><color=#FFAA00>WARNING</color><color=#FFBA40> --</color>"); m_banner.SetStatus("<color=#FFF5EA>The thread frays! 0 upgrades remaining (Will </color><color=#FFAA00><b>DOWNGRADE</b></color><color=#FFF5EA>)</color>"); } else if (prediction.NextFailure == UpgradeSimulator.NextFailureType.Break) { m_banner.SetTitle("<color=#FFBA40>-- VOLVA'S EYE : </color><color=#FF4444>DOOM</color><color=#FFBA40> --</color>"); m_banner.SetStatus("<color=#FFF5EA>The item will </color><color=#FF4444><b>SHATTER</b></color><color=#FFF5EA> and be </color><color=#FF4444><b>DESTROYED</b></color><color=#FFF5EA> on the next strike!</color>"); } else { m_banner.SetTitle("<color=#FFBA40>-- VOLVA'S EYE --</color>"); m_banner.SetStatus("<color=#FFF5EA>The weave is clouded for this offering.</color>"); } m_banner.Show(); } public void SetVisible(bool visible) { if ((Object)(object)m_banner != (Object)null) { m_banner.SetVisible(visible); } } } } namespace ValheimShared.UI { public static class ValheimUiBuilder { public static readonly Color ColorNorseGold = new Color(1f, 0.73f, 0.25f, 1f); public static readonly Color ColorParchment = new Color(0.88f, 0.82f, 0.72f, 1f); public static readonly Color ColorMutedText = new Color(0.7f, 0.65f, 0.55f, 1f); public static readonly Color ColorSunkenDark = new Color(0.08f, 0.07f, 0.06f, 0.9f); public static readonly Color ColorSunkenBg = new Color(0.06f, 0.05f, 0.04f, 0.65f); public static readonly Color ColorDividerGold = new Color(0.75f, 0.58f, 0.22f, 0.4f); private static TMP_FontAsset s_valheimFont; private static Material s_valheimFontMaterial; private static Dictionary<string, Sprite> s_spriteCache = new Dictionary<string, Sprite>(StringComparer.OrdinalIgnoreCase); private static GameObject s_woodPanelTemplate; private static TMP_Text s_cleanTextTemplate; private static Button s_buttonTemplate; public static TMP_Text GetOrCreateTextTemplate() { //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_cleanTextTemplate != (Object)null) { return s_cleanTextTemplate; } TMP_Text val = null; if ((Object)(object)PlayerCustomizaton.m_barberInstance != (Object)null && (Object)(object)PlayerCustomizaton.m_barberInstance.m_selectedHair != (Object)null) { val = PlayerCustomizaton.m_barberInstance.m_selectedHair; } else if ((Object)(object)PlayerCustomizaton.m_barberInstance != (Object)null && (Object)(object)PlayerCustomizaton.m_barberInstance.m_rootPanel != (Object)null) { TMP_Text[] componentsInChildren = PlayerCustomizaton.m_barberInstance.m_rootPanel.GetComponentsInChildren<TMP_Text>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null && (Object)(object)componentsInChildren[i].font != (Object)null) { val = componentsInChildren[i]; break; } } } if ((Object)(object)val == (Object)null) { TMP_Text[] array = Resources.FindObjectsOfTypeAll<TMP_Text>(); if (array != null) { for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null && (Object)(object)array[i].font != (Object)null) { val = array[i]; break; } } } } if ((Object)(object)val != (Object)null) { s_valheimFont = val.font; s_valheimFontMaterial = val.fontSharedMaterial; try { GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject); ((Object)val2).name = "ValheimUi_CleanTextTemplate"; val2.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val2); StripLocalize(val2); for (int i = val2.transform.childCount - 1; i >= 0; i--) { Object.DestroyImmediate((Object)(object)((Component)val2.transform.GetChild(i)).gameObject); } Component[] components = val2.GetComponents<Component>(); foreach (Component val3 in components) { if (!((Object)(object)val3 == (Object)null) && !(val3 is Transform) && !(val3 is RectTransform) && !(val3 is TMP_Text) && !(val3 is CanvasRenderer)) { Object.DestroyImmediate((Object)(object)val3); } } s_cleanTextTemplate = val2.GetComponent<TMP_Text>(); if ((Object)(object)s_cleanTextTemplate != (Object)null) { s_cleanTextTemplate.enableAutoSizing = false; s_cleanTextTemplate.margin = Vector4.zero; s_cleanTextTemplate.textWrappingMode = (TextWrappingModes)0; s_cleanTextTemplate.overflowMode = (TextOverflowModes)1; s_cleanTextTemplate.rectTransform.anchoredPosition = Vector2.zero; s_cleanTextTemplate.rectTransform.offsetMin = Vector2.zero; s_cleanTextTemplate.rectTransform.offsetMax = Vector2.zero; } return s_cleanTextTemplate; } catch { return val; } } return null; } public static TMP_FontAsset GetValheimFont() { if ((Object)(object)s_valheimFont != (Object)null) { return s_valheimFont; } GetOrCreateTextTemplate(); return s_valheimFont; } public static Material GetValheimFontMaterial() { if ((Object)(object)s_valheimFontMaterial != (Object)null) { return s_valheimFontMaterial; } GetOrCreateTextTemplate(); return s_valheimFontMaterial; } public static Sprite GetValheimSprite(string spriteName) { if (string.IsNullOrEmpty(spriteName)) { return null; } if (s_spriteCache.TryGetValue(spriteName, out var value) && (Object)(object)value != (Object)null) { return value; } Sprite[] array = Resources.FindObjectsOfTypeAll<Sprite>(); if (array != null) { for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null && string.Equals(((Object)array[i]).name, spriteName, StringComparison.OrdinalIgnoreCase)) { s_spriteCache[spriteName] = array[i]; return array[i]; } } } return null; } public static GameObject GetOrCreateWoodPanelTemplate() { //IL_00a7: 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)s_woodPanelTemplate != (Object)null) { return s_woodPanelTemplate; } if ((Object)(object)PlayerCustomizaton.m_barberInstance != (Object)null && (Object)(object)PlayerCustomizaton.m_barberInstance.m_rootPanel != (Object)null) { s_woodPanelTemplate = PlayerCustomizaton.m_barberInstance.m_rootPanel; return s_woodPanelTemplate; } if ((Object)(object)InventoryGui.instance != (Object)null && (Object)(object)InventoryGui.instance.m_trophiesPanel != (Object)null) { s_woodPanelTemplate = InventoryGui.instance.m_trophiesPanel; return s_woodPanelTemplate; } Scene activeScene = SceneManager.GetActiveScene(); GameObject[] rootGameObjects = ((Scene)(ref activeScene)).GetRootGameObjects(); if (rootGameObjects != null) { for (int i = 0; i < rootGameObjects.Length; i++) { PlayerCustomizaton componentInChildren = rootGameObjects[i].GetComponentInChildren<PlayerCustomizaton>(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.m_rootPanel != (Object)null) { s_woodPanelTemplate = componentInChildren.m_rootPanel; return s_woodPanelTemplate; } } } return null; } public static void PlayButtonClickAudio() { try { } catch { } } public static bool IsAnyInputFocused() { if ((Object)(object)EventSystem.current != (Object)null) { GameObject currentSelectedGameObject = EventSystem.current.currentSelectedGameObject; if ((Object)(object)currentSelectedGameObject != (Object)null && ((Object)(object)currentSelectedGameObject.GetComponentInParent<TMP_InputField>() != (Object)null || (Object)(object)currentSelectedGameObject.GetComponentInParent<InputField>() != (Object)null)) { return true; } } return false; } public static ValheimUiPanel CreatePanel(string name, string title, Vector2 size, Transform parent = null, Action onClose = null, bool draggable = true) { //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Expected O, but got Unknown //IL_042f: Unknown result type (might be due to invalid IL or missing references) //IL_044f: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Unknown result type (might be due to invalid IL or missing references) //IL_047d: Unknown result type (might be due to invalid IL or missing references) //IL_048a: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_04a0: Unknown result type (might be due to invalid IL or missing references) //IL_04b1: Unknown result type (might be due to invalid IL or missing references) //IL_04c8: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)parent == (Object)null) { if ((Object)(object)Hud.instance != (Object)null && (Object)(object)Hud.instance.m_rootObject != (Object)null) { parent = Hud.instance.m_rootObject.transform; } else { Canvas val = Object.FindAnyObjectByType<Canvas>(); if ((Object)(object)val != (Object)null) { parent = ((Component)val).transform; } } } GameObject orCreateWoodPanelTemplate = GetOrCreateWoodPanelTemplate(); GameObject val2; if ((Object)(object)orCreateWoodPanelTemplate != (Object)null) { val2 = Object.Instantiate<GameObject>(orCreateWoodPanelTemplate, parent, false); ((Object)val2).name = name; MonoBehaviour[] components = val2.GetComponents<MonoBehaviour>(); for (int i = 0; i < components.Length; i++) { if ((Object)(object)components[i] != (Object)null && ((object)components[i]).GetType().Name != "RectTransform" && ((object)components[i]).GetType().Name != "Image" && ((object)components[i]).GetType().Name != "CanvasRenderer") { Object.DestroyImmediate((Object)(object)components[i]); } } VerticalLayoutGroup component = val2.GetComponent<VerticalLayoutGroup>(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } HorizontalLayoutGroup component2 = val2.GetComponent<HorizontalLayoutGroup>(); if ((Object)(object)component2 != (Object)null) { Object.DestroyImmediate((Object)(object)component2); } ContentSizeFitter component3 = val2.GetComponent<ContentSizeFitter>(); if ((Object)(object)component3 != (Object)null) { Object.DestroyImmediate((Object)(object)component3); } CanvasGroup component4 = val2.GetComponent<CanvasGroup>(); if ((Object)(object)component4 != (Object)null) { Object.DestroyImmediate((Object)(object)component4); } Component component5 = val2.GetComponent("Animator"); if ((Object)(object)component5 != (Object)null) { Object.DestroyImmediate((Object)(object)component5); } Image val3 = val2.GetComponent<Image>(); if ((Object)(object)val3 == (Object)null) { val3 = val2.GetComponentInChildren<Image>(true); } for (int i = val2.transform.childCount - 1; i >= 0; i--) { Transform child = val2.transform.GetChild(i); if (!((Object)(object)val3 != (Object)null) || !((Object)(object)((Component)child).gameObject == (Object)(object)((Component)val3).gameObject)) { Object.DestroyImmediate((Object)(object)((Component)child).gameObject); } } if ((Object)(object)val3 != (Object)null) { if (((Graphic)val3).color == Color.white) { ((Graphic)val3).color = new Color(0.24f, 0.17f, 0.12f, 0.98f); } if ((Object)(object)((Component)val3).gameObject != (Object)(object)val2) { RectTransform rectTransform = ((Graphic)val3).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = Vector2.zero; rectTransform.offsetMax = Vector2.zero; ((Transform)rectTransform).localScale = Vector3.one; } } else { val3 = val2.AddComponent<Image>(); Sprite val4 = GetValheimSprite("woodpanel_settings") ?? GetValheimSprite("box_sunken"); if ((Object)(object)val4 != (Object)null) { val3.sprite = val4; val3.type = (Type)1; } ((Graphic)val3).color = new Color(0.24f, 0.17f, 0.12f, 0.98f); } } else { val2 = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(Image) }); val2.transform.SetParent(parent, false); Image component6 = val2.GetComponent<Image>(); Sprite val4 = GetValheimSprite("woodpanel_settings") ?? GetValheimSprite("box_sunken"); if ((Object)(object)val4 != (Object)null) { component6.sprite = val4; component6.type = (Type)1; } ((Graphic)component6).color = new Color(0.24f, 0.17f, 0.12f, 0.98f); } RectTransform component7 = val2.GetComponent<RectTransform>(); component7.anchorMin = new Vector2(0.5f, 0.5f); component7.anchorMax = new Vector2(0.5f, 0.5f); component7.pivot = new Vector2(0.5f, 0.5f); component7.anchoredPosition = Vector2.zero; component7.sizeDelta = size; ((Transform)component7).localScale = Vector3.one; val2.transform.localScale = Vector3.one; ValheimUiPanel valheimUiPanel = val2.AddComponent<ValheimUiPanel>(); valheimUiPanel.Initialize(name, title, size, onClose, draggable); return valheimUiPanel; } public static ValheimUiBanner CreateBanner(string name, string title, string status, Vector2 size, Transform parent = null, bool draggable = true) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Expected O, but got Unknown //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)parent == (Object)null) { if ((Object)(object)Hud.instance != (Object)null && (Object)(object)Hud.instance.m_rootObject != (Object)null) { parent = Hud.instance.m_rootObject.transform; } else { Canvas val = Object.FindAnyObjectByType<Canvas>(); if ((Object)(object)val != (Object)null) { parent = ((Component)val).transform; } } } GameObject val2 = new GameObject(name, new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(parent, false); RectTransform component = val2.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = Vector2.zero; component.sizeDelta = size; ((Transform)component).localScale = Vector3.one; GameObject val3 = new GameObject("BannerBackground", new Type[2] { typeof(RectTransform), typeof(Image) }); val3.transform.SetParent(val2.transform, false); RectTransform component2 = val3.GetComponent<RectTransform>(); component2.anchorMin = Vector2.zero; component2.anchorMax = Vector2.one; component2.offsetMin = Vector2.zero; component2.offsetMax = Vector2.zero; Image component3 = val3.GetComponent<Image>(); ((Graphic)component3).color = new Color(0.18f, 0.13f, 0.09f, 0.98f); ((Graphic)component3).raycastTarget = true; GameObject val4 = new GameObject("BannerFrame", new Type[2] { typeof(RectTransform), typeof(Image) }); val4.transform.SetParent(val2.transform, false); RectTransform component4 = val4.GetComponent<RectTransform>(); component4.anchorMin = Vector2.zero; component4.anchorMax = Vector2.one; component4.offsetMin = Vector2.zero; component4.offsetMax = Vector2.zero; Image component5 = val4.GetComponent<Image>(); ((Graphic)component5).raycastTarget = false; Sprite valheimSprite = GetValheimSprite("woodpanel_settings"); if ((Object)(object)valheimSprite == (Object)null) { valheimSprite = GetValheimSprite("woodpanel_popup"); } if ((Object)(object)valheimSprite == (Object)null) { valheimSprite = GetValheimSprite("woodpanel_modal"); } if ((Object)(object)valheimSprite == (Object)null) { valheimSprite = GetValheimSprite("crafting_panel"); } if ((Object)(object)valheimSprite == (Object)null) { valheimSprite = GetValheimSprite("box_sunken"); } if ((Object)(object)valheimSprite != (Object)null) { component5.sprite = valheimSprite; component5.type = (Type)1; ((Graphic)component5).color = new Color(0.9f, 0.75f, 0.6f, 0.95f); } else { ((Graphic)component5).color = Color.clear; } ValheimUiBanner valheimUiBanner = val2.AddComponent<ValheimUiBanner>(); valheimUiBanner.Initialize(name, title, status, size, draggable); return valheimUiBanner; } public static TMP_Text CreateLabel(Transform parent, string text, float fontSize = 14f, Color? color = null, TextAlignmentOptions align = (TextAlignmentOptions)513, float width = 0f, float height = 0f, FontStyles fontStyle = (FontStyles)0) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0130: 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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) TMP_Text orCreateTextTemplate = GetOrCreateTextTemplate(); GameObject val; TMP_Text component; if ((Object)(object)orCreateTextTemplate != (Object)null) { val = Object.Instantiate<GameObject>(((Component)orCreateTextTemplate).gameObject, parent, false); ((Object)val).name = "Label_" + text; val.transform.localScale = Vector3.one; val.SetActive(true); component = val.GetComponent<TMP_Text>(); } else { val = new GameObject("Label_" + text, new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); if ((Object)(object)parent != (Object)null) { val.transform.SetParent(parent, false); } val.transform.localScale = Vector3.one; component = (TMP_Text)(object)val.GetComponent<TextMeshProUGUI>(); TMP_FontAsset valheimFont = GetValheimFont(); if ((Object)(object)valheimFont != (Object)null) { component.font = valheimFont; Material valheimFontMaterial = GetValheimFontMaterial(); if ((Object)(object)valheimFontMaterial != (Object)null) { component.fontSharedMaterial = valheimFontMaterial; } } } component.text = text; component.enableAutoSizing = false; component.fontSize = fontSize; component.fontStyle = fontStyle; component.margin = Vector4.zero; ((Graphic)component).color = (color.HasValue ? color.Value : ColorParchment); component.alignment = align; component.textWrappingMode = (TextWrappingModes)0; ((Graphic)component).raycastTarget = false; RectTransform rectTransform = component.rectTransform; float num = ((width > 0f) ? width : ((rectTransform.sizeDelta.x > 0f) ? rectTransform.sizeDelta.x : 160f)); float num2 = ((height > 0f) ? height : ((rectTransform.sizeDelta.y > 0f) ? rectTransform.sizeDelta.y : 24f)); rectTransform.sizeDelta = new Vector2(num, num2); rectTransform.anchoredPosition = Vector2.zero; if (width > 0f || height > 0f) { LayoutElement val2 = val.GetComponent<LayoutElement>(); if ((Object)(object)val2 == (Object)null) { val2 = val.AddComponent<LayoutElement>(); } if (width > 0f) { val2.minWidth = width; val2.preferredWidth = width; } if (height > 0f) { val2.minHeight = height; val2.preferredHeight = height; } } return component; } public static Button GetOrCreateButtonTemplate() { if ((Object)(object)s_buttonTemplate != (Object)null) { return s_buttonTemplate; } if ((Object)(object)PlayerCustomizaton.m_barberInstance != (Object)null && (Object)(object)PlayerCustomizaton.m_barberInstance.m_apply != (Object)null) { s_buttonTemplate = PlayerCustomizaton.m_barberInstance.m_apply; return s_buttonTemplate; } Button[] array = Resources.FindObjectsOfTypeAll<Button>(); if (array != null) { for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null && (Object)(object)((Component)array[i]).GetComponentInChildren<TMP_Text>() != (Object)null) { s_buttonTemplate = array[i]; return s_buttonTemplate; } } } return null; } public static void StripLocalize(GameObject go) { if ((Object)(object)go == (Object)null) { return; } Component[] componentsInChildren = go.GetComponentsInChildren(typeof(Component), true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null && ((object)componentsInChildren[i]).GetType().Name == "Localize") { Component obj = componentsInChildren[i]; Behaviour val = (Behaviour)(object)((obj is Behaviour) ? obj : null); if ((Object)(object)val != (Object)null) { val.enabled = false; } Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } } } public static void SetButtonTextColor(Button btn, Color col) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)btn == (Object)null)) { TMP_Text componentInChildren = ((Component)btn).GetComponentInChildren<TMP_Text>(); if ((Object)(object)componentInChildren != (Object)null) { ((Graphic)componentInChildren).color = col; } } } public static void SetButtonFontSize(Button btn, float fontSize) { if (!((Object)(object)btn == (Object)null)) { TMP_Text componentInChildren = ((Component)btn).GetComponentInChildren<TMP_Text>(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.fontSize = fontSize; } } } public static Button CreateButton(Transform parent, string label, Action onClick, Vector2? size = null, float fontSize = 14.5f) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expecte