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 WiresForgeOfPotentialRework v1.1.1
WiresForgeOfPotentialRework.dll
Decompiled 3 weeks agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("WiresForgeOfPotentialRework")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("WiresForgeOfPotentialRework")] [assembly: AssemblyTitle("WiresForgeOfPotentialRework")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace WiresForgeOfPotentialRework { [BepInPlugin("wire.valheim.forgeofpotentialrework", "Wire's Forge of Potential Rework", "1.1.1")] [BepInProcess("valheim.exe")] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "wire.valheim.forgeofpotentialrework"; public const string Name = "Wire's Forge of Potential Rework"; public const string Version = "1.1.1"; private Harmony _harmony; private void Awake() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown _harmony = new Harmony("wire.valheim.forgeofpotentialrework"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Wire's Forge of Potential Rework 1.1.1 loaded."); } private void OnDestroy() { ForgeContext.Clear(); if (_harmony != null) { _harmony.UnpatchSelf(); } } } internal enum ForgeOutcome { None, Success, Jackpot, Ignore, Loss, Break } internal static class ForgeRules { internal static float GetWinChance(int potential) { return Mathf.Max(0.65f, 0.9f - 0.05f * (float)Mathf.Max(0, potential)); } internal static bool LossRiskActive(int potential) { return potential >= 2; } internal static bool MultiLossRiskActive(int potential) { return potential >= 4; } internal static bool BreakRiskActive(int potential) { return potential >= 5; } internal static int RollLossLevels(int potential) { int num = Mathf.Max(1, potential); int i = 1; if (!MultiLossRiskActive(potential)) { return i; } float num2 = 1f - GetWinChance(potential); for (; i < num; i++) { if (!(Random.value < num2)) { break; } } return i; } internal static float GetConditionalBreakChance(int potential) { if (!BreakRiskActive(potential)) { return 0f; } float num = 1f - GetWinChance(potential); if (!(num > 0f)) { return 0f; } return Mathf.Clamp01(0.1f / num); } } internal static class ForgeContext { internal static bool Active; internal static Player Player; internal static ItemData OriginalItem; internal static ItemData UpgraderResource; internal static Recipe Recipe; internal static Vector2i OriginalPosition; internal static string CraftedPrefabName; internal static string SharedItemName; internal static int OriginalQuality; internal static int AttemptedQuality; internal static int TargetQuality; internal static int Delta; internal static ForgeOutcome Outcome; internal static float OldUpgradeChance; internal static float OldBreakChance; internal static CraftingStation Station; internal static EffectList OldFailEffects; internal static void Clear() { Active = false; Player = null; OriginalItem = null; UpgraderResource = null; Recipe = null; CraftedPrefabName = null; SharedItemName = null; OriginalQuality = 0; AttemptedQuality = 0; TargetQuality = 0; Delta = 0; Outcome = ForgeOutcome.None; Station = null; OldFailEffects = null; } internal static void RestoreChanceFields() { if (UpgraderResource != null && UpgraderResource.m_shared != null) { UpgraderResource.m_shared.m_upgradeChance = OldUpgradeChance; UpgraderResource.m_shared.m_breakChance = OldBreakChance; if ((Object)(object)Station != (Object)null && OldFailEffects != null) { Station.m_craftItemDoneFailEffects = OldFailEffects; } } } } [HarmonyPatch(typeof(InventoryGui), "DoCrafting")] internal static class ForgeCraftPatch { [HarmonyPrefix] private static void Prefix(Recipe ___m_craftRecipe, ItemData ___m_craftUpgradeItem) { //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Expected O, but got Unknown ForgeContext.Clear(); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)___m_craftRecipe == (Object)null || ___m_craftUpgradeItem == null) { return; } CraftingStation currentCraftingStation = localPlayer.GetCurrentCraftingStation(); if ((Object)(object)currentCraftingStation == (Object)null || !currentCraftingStation.m_upgrader) { return; } ItemData val = null; Requirement[] resources = ___m_craftRecipe.m_resources; foreach (Requirement val2 in resources) { if (val2 != null && val2.m_upgraderResource && (Object)(object)val2.m_resItem != (Object)null) { val = val2.m_resItem.m_itemData; break; } } if (val == null || val.m_shared == null) { return; } int num = Mathf.Max(1, ___m_craftRecipe.m_item.m_itemData.m_shared.m_maxQuality); int quality = ___m_craftUpgradeItem.m_quality; int potential = Mathf.Max(0, quality - num); float winChance = ForgeRules.GetWinChance(potential); int num2; int delta; ForgeOutcome forgeOutcome; if (Random.value < winChance) { int j = 1; if (Random.value < 0.2f) { for (j = 2; j < 5; j++) { if (!(Random.value < 0.2f)) { break; } } } num2 = quality + j; delta = j; forgeOutcome = ((j == 1) ? ForgeOutcome.Success : ForgeOutcome.Jackpot); } else if (!ForgeRules.LossRiskActive(potential)) { num2 = quality; delta = 0; forgeOutcome = ForgeOutcome.Ignore; } else if (ForgeRules.BreakRiskActive(potential) && Random.value < ForgeRules.GetConditionalBreakChance(potential)) { num2 = 0; delta = 0; forgeOutcome = ForgeOutcome.Break; } else { int num3 = ForgeRules.RollLossLevels(potential); num2 = Mathf.Max(num, quality - num3); delta = num2 - quality; forgeOutcome = ForgeOutcome.Loss; } ForgeContext.Active = true; ForgeContext.Player = localPlayer; ForgeContext.OriginalItem = ___m_craftUpgradeItem; ForgeContext.UpgraderResource = val; ForgeContext.Recipe = ___m_craftRecipe; ForgeContext.OriginalPosition = ___m_craftUpgradeItem.m_gridPos; ForgeContext.CraftedPrefabName = ((Object)((Component)___m_craftRecipe.m_item).gameObject).name; ForgeContext.SharedItemName = ___m_craftUpgradeItem.m_shared.m_name; ForgeContext.OriginalQuality = quality; ForgeContext.AttemptedQuality = quality + 1; ForgeContext.TargetQuality = num2; ForgeContext.Delta = delta; ForgeContext.Outcome = forgeOutcome; ForgeContext.OldUpgradeChance = val.m_shared.m_upgradeChance; ForgeContext.OldBreakChance = val.m_shared.m_breakChance; ForgeContext.Station = currentCraftingStation; if (forgeOutcome == ForgeOutcome.Success || forgeOutcome == ForgeOutcome.Jackpot) { val.m_shared.m_upgradeChance = 2f; val.m_shared.m_breakChance = -1f; return; } ForgeContext.OldFailEffects = currentCraftingStation.m_craftItemDoneFailEffects; currentCraftingStation.m_craftItemDoneFailEffects = new EffectList(); val.m_shared.m_upgradeChance = -1f; val.m_shared.m_breakChance = ((forgeOutcome == ForgeOutcome.Break) ? 2f : (-1f)); } [HarmonyPostfix] private static void Postfix(EffectList ___m_craftBonusEffect) { //IL_0063: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) if (!ForgeContext.Active) { return; } try { Player player = ForgeContext.Player; if (!((Object)(object)player == (Object)null) && ForgeContext.OriginalItem != null && !((Humanoid)player).GetInventory().ContainsItem(ForgeContext.OriginalItem)) { if (ForgeContext.Outcome == ForgeOutcome.Ignore || ForgeContext.Outcome == ForgeOutcome.Loss || ForgeContext.Outcome == ForgeOutcome.Break) { PlaySafeFailureEffect(player); } if (ForgeContext.Outcome == ForgeOutcome.Jackpot && ___m_craftBonusEffect != null) { ___m_craftBonusEffect.Create(((Component)player).transform.position + Vector3.up, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } ShowResult(player); } } finally { ForgeContext.RestoreChanceFields(); ForgeContext.Clear(); } } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception) { if (__exception != null && ForgeContext.Active) { ForgeContext.RestoreChanceFields(); ForgeContext.Clear(); } return __exception; } private static void PlaySafeFailureEffect(Player player) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || ForgeContext.OldFailEffects == null) { return; } GameObject[] array = ForgeContext.OldFailEffects.Create(((Component)player).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); foreach (GameObject val in array) { if ((Object)(object)val == (Object)null) { continue; } MonoBehaviour[] componentsInChildren = val.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val2 in componentsInChildren) { if (val2 is IProjectile) { ((Behaviour)val2).enabled = false; Object.Destroy((Object)(object)val2); } } } } private static void ShowResult(Player player) { string text = ((Localization.instance != null) ? Localization.instance.Localize(ForgeContext.SharedItemName) : ForgeContext.SharedItemName); switch (ForgeContext.Outcome) { case ForgeOutcome.Jackpot: ((Character)player).Message((MessageType)2, "JACKPOT! " + text + " gained +" + ForgeContext.Delta + " quality (Q" + ForgeContext.TargetQuality + ").", 0, (Sprite)null, true); break; case ForgeOutcome.Ignore: ((Character)player).Message((MessageType)2, "Refinement had no effect on " + text + " (Q" + ForgeContext.OriginalQuality + ").", 0, (Sprite)null, true); break; case ForgeOutcome.Loss: { int num = -ForgeContext.Delta; ((Character)player).Message((MessageType)2, text + " lost " + num + " Potential level" + ((num == 1) ? "" : "s") + " (Q" + ForgeContext.TargetQuality + ").", 0, (Sprite)null, true); break; } } } } [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(string), typeof(int), typeof(int), typeof(int), typeof(long), typeof(string), typeof(Vector2i), typeof(bool), typeof(bool), typeof(bool) })] internal static class ForgeReturnedItemQualityPatch { [HarmonyPrefix] private static void Prefix(string name, ref int quality, Vector2i position) { //IL_0014: 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) if (ForgeContext.Active && !(name != ForgeContext.CraftedPrefabName) && position.x == ForgeContext.OriginalPosition.x && position.y == ForgeContext.OriginalPosition.y) { quality = ForgeContext.TargetQuality; } } } [HarmonyPatch(typeof(InventoryGui), "UpdateRecipe")] internal static class ForgeStatusTextPatch { private static readonly FieldInfo SelectedRecipeField = AccessTools.Field(typeof(InventoryGui), "m_selectedRecipe"); private static readonly PropertyInfo SelectedItemProperty = ((SelectedRecipeField != null) ? SelectedRecipeField.FieldType.GetProperty("ItemData", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) : null); [HarmonyPostfix] private static void Postfix(InventoryGui __instance) { Player localPlayer = Player.m_localPlayer; if ((Object)(object)__instance == (Object)null || (Object)(object)localPlayer == (Object)null || (Object)(object)__instance.m_itemCraftType == (Object)null) { return; } CraftingStation currentCraftingStation = localPlayer.GetCurrentCraftingStation(); if (!((Object)(object)currentCraftingStation == (Object)null) && currentCraftingStation.m_upgrader && !(SelectedRecipeField == null) && !(SelectedItemProperty == null)) { object value = SelectedRecipeField.GetValue(__instance); object? value2 = SelectedItemProperty.GetValue(value, null); ItemData val = (ItemData)((value2 is ItemData) ? value2 : null); if (val != null && val.m_shared != null) { int num = Mathf.Max(1, val.m_shared.m_maxQuality); int potential = Mathf.Max(0, val.m_quality - num); string text = ((!ForgeRules.LossRiskActive(potential)) ? "The item can withstand further forging." : ((!ForgeRules.MultiLossRiskActive(potential)) ? "Further forging may weaken the item." : (ForgeRules.BreakRiskActive(potential) ? "Further forging may destroy the item." : "Further forging may greatly weaken the item."))); ((Component)__instance.m_itemCraftType).gameObject.SetActive(true); __instance.m_itemCraftType.text = text; } } } } [HarmonyPatch(typeof(Player), "Message")] internal static class ForgeVanillaMessagePatch { [HarmonyPrefix] private static bool Prefix(MessageType type, string msg) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 if (!ForgeContext.Active || (int)type != 2 || Localization.instance == null) { return true; } string text = Localization.instance.Localize("$msg_upgrader_success", new string[2] { ForgeContext.SharedItemName, ForgeContext.AttemptedQuality.ToString() }); string text2 = Localization.instance.Localize("$msg_upgrader_failed", new string[2] { ForgeContext.SharedItemName, (ForgeContext.AttemptedQuality - 2).ToString() }); string text3 = Localization.instance.Localize("$msg_upgrader_broke", new string[2] { ForgeContext.SharedItemName, (ForgeContext.AttemptedQuality - 1).ToString() }); if (msg == text) { return ForgeContext.Outcome == ForgeOutcome.Success; } if (msg == text3) { return ForgeContext.Outcome == ForgeOutcome.Break; } if (msg == text2) { return false; } return true; } } }