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 MySix ForgeOfPotential v1.0.3
MySix.ForgeOfPotential.dll
Decompiled an hour agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using HarmonyLib; using MySix.Core; 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: AssemblyVersion("0.0.0.0")] namespace MySix { internal static class SuiteVersion { public const string Value = "1.0.3"; } } namespace MySix.ForgeOfPotential { public enum ForgeMode { Vanilla, NeverBreak, Gamble } public static class ForgeHooks { public static Setting<ForgeMode> Mode; public static Setting<float> FailChance; public static Setting<bool> FailureEffect; public static Setting<bool> LogOutcomes; private static readonly EffectList NoEffects = new EffectList(); private static float _vanillaUpgradeChance; private static float _breakChance; private static readonly FieldRef<InventoryGui, Recipe> CraftRecipe = AccessTools.FieldRefAccess<InventoryGui, Recipe>("m_craftRecipe"); public static float UpgradeChance(float vanilla) { _vanillaUpgradeChance = vanilla; if (Mode.Value == ForgeMode.Vanilla) { return vanilla; } float num = ((FailChance != null) ? Mathf.Clamp01(FailChance.Value) : 0.35f); return 1f - num; } public static float BreakChance(float vanilla) { _breakChance = vanilla; if (Mode.Value != ForgeMode.Vanilla) { return 0f; } return vanilla; } public static EffectList FailEffects(EffectList vanilla) { if (Mode.Value == ForgeMode.Vanilla) { return vanilla; } if (FailureEffect != null && FailureEffect.Value) { return vanilla; } return NoEffects; } public static string FailedMessage() { return Mode.Value switch { ForgeMode.NeverBreak => "The idol crumbles and nothing comes of it. {0} is unharmed.", ForgeMode.Gamble => "The idol crumbles and {0} is weakened, down to level {1}.", _ => "$msg_upgrader_failed", }; } public static int FailedLevel(int targetLevel) { int num = targetLevel + ((Mode.Value == ForgeMode.NeverBreak) ? (-1) : (-2)); num = Mathf.Max(1, num); if (LogOutcomes != null && LogOutcomes.Value) { CorePlugin.Log.LogInfo((object)($"ForgeOfPotential [{Mode.Value}]: target level {targetLevel}, the game " + $"would have rolled upgrade {_vanillaUpgradeChance:0.###} / break " + $"{_breakChance:0.###}, handing back level {num}")); } return num; } private static int MaxQuality() { try { if ((Object)(object)InventoryGui.instance == (Object)null) { return 0; } ItemDrop val = CraftRecipe.Invoke(InventoryGui.instance)?.m_item; return ((Object)(object)val != (Object)null) ? val.m_itemData.m_shared.m_maxQuality : 0; } catch { return 0; } } } [HarmonyPatch(typeof(InventoryGui), "DoCrafting")] public static class DoCraftingPatch { private static readonly FieldInfo UpgradeChanceField = AccessTools.Field(typeof(SharedData), "m_upgradeChance"); private static readonly FieldInfo BreakChanceField = AccessTools.Field(typeof(SharedData), "m_breakChance"); private static readonly FieldInfo FailEffectsField = AccessTools.Field(typeof(CraftingStation), "m_craftItemDoneFailEffects"); private static readonly MethodInfo AddItem = AccessTools.Method(typeof(Inventory), "AddItem", new Type[10] { typeof(string), typeof(int), typeof(int), typeof(int), typeof(long), typeof(string), typeof(Vector2i), typeof(bool), typeof(bool), typeof(bool) }, (Type[])null); public static bool Applied { get; private set; } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Expected O, but got Unknown //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Expected O, but got Unknown //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Expected O, but got Unknown List<CodeInstruction> list = new List<CodeInstruction>(instructions); int num = 0; int num2 = 0; int num3 = 0; for (int i = 0; i < list.Count; i++) { if (!(list[i].opcode != OpCodes.Ldfld)) { if (list[i].operand == UpgradeChanceField || object.Equals(list[i].operand, UpgradeChanceField)) { list.Insert(++i, new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(ForgeHooks), "UpgradeChance", (Type[])null, (Type[])null))); num++; } else if (list[i].operand == BreakChanceField || object.Equals(list[i].operand, BreakChanceField)) { list.Insert(++i, new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(ForgeHooks), "BreakChance", (Type[])null, (Type[])null))); num++; } } } for (int j = 0; j < list.Count; j++) { if (list[j].opcode == OpCodes.Ldstr && (string)list[j].operand == "$msg_upgrader_failed") { list[j] = new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(ForgeHooks), "FailedMessage", (Type[])null, (Type[])null)) { labels = list[j].labels, blocks = list[j].blocks }; num2++; break; } } for (int k = 0; k < list.Count; k++) { if (!(list[k].opcode == OpCodes.Callvirt) || !object.Equals(list[k].operand, AddItem)) { continue; } int num4 = k - 1; while (num4 > k - 20 && num4 > 1) { if (list[num4].opcode == OpCodes.Sub && CodeInstructionExtensions.LoadsConstant(list[num4 - 1], 2L) && CodeInstructionExtensions.IsLdloc(list[num4 - 2], (LocalBuilder)null)) { list[num4 - 1] = new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(ForgeHooks), "FailedLevel", (Type[])null, (Type[])null)); list.RemoveAt(num4); num3++; break; } num4--; } if (num3 > 0) { break; } } int num5 = 0; for (int l = 0; l < list.Count; l++) { if (list[l].opcode == OpCodes.Ldfld && object.Equals(list[l].operand, FailEffectsField)) { list.Insert(++l, new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(ForgeHooks), "FailEffects", (Type[])null, (Type[])null))); num5++; } } if (num5 != 1) { CorePlugin.Log.LogWarning((object)($"ForgeOfPotential hooked {num5} failure effect sites, expected 1; " + "a failed refinement may still set off the forge blast.")); } if (num == 2 && num2 == 1 && num3 == 1) { Applied = true; return list; } CorePlugin.Log.LogError((object)($"ForgeOfPotential could not patch DoCrafting (chance hooks {num}/2, " + $"message {num2}/1, level {num3}/1). The game may have changed; " + "the Forge of Potential will behave normally.")); return instructions; } } [BepInPlugin("com.mysix.forgeofpotential", "MySix Forge of Potential", "1.0.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class ForgeOfPotentialPlugin : BaseUnityPlugin { public const string PluginGuid = "com.mysix.forgeofpotential"; public const string PluginName = "MySix Forge of Potential"; public const string PluginVersion = "1.0.3"; private const int RequiredCoreApi = 1; private Harmony _harmony; private void Awake() { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown if (CorePlugin.RequireApi("MySix Forge of Potential", 1)) { ForgeHooks.Mode = Settings.Register<ForgeMode>("MySix Forge of Potential", ((BaseUnityPlugin)this).Config.Bind<ForgeMode>("ForgeOfPotential", "Mode", ForgeMode.NeverBreak, "Vanilla: unchanged, so a failed refinement destroys the item. NeverBreak: the idol is used up, but a failure costs nothing else. Gamble: as NeverBreak, except a failure also takes the item down one level. Neither modified mode ever destroys the item."), (Scope)0, (string)null); ForgeHooks.FailChance = Settings.Register<float>("MySix Forge of Potential", ((BaseUnityPlugin)this).Config.Bind<float>("ForgeOfPotential", "FailChance", 0.35f, "Chance a refinement does not take, in NeverBreak and Gamble. 0.35 matches the odds the game itself uses, so a success is still the usual one level of upgrade 65% of the time."), (Scope)0, (string)null); ForgeHooks.FailureEffect = Settings.Register<bool>("MySix Forge of Potential", ((BaseUnityPlugin)this).Config.Bind<bool>("ForgeOfPotential", "FailureEffect", false, "Play the station's own failure effect when a refinement does not take. It is only for show and harms nothing, but it looks like a disaster, so it is off by default in modes where the gear survives."), (Scope)0, (string)null); ForgeHooks.LogOutcomes = Settings.Register<bool>("MySix Forge of Potential", ((BaseUnityPlugin)this).Config.Bind<bool>("ForgeOfPotential", "LogOutcomes", false, "Log every upgrade outcome, for checking the odds behave as expected."), (Scope)1, (string)null); _harmony = new Harmony("com.mysix.forgeofpotential"); _harmony.PatchAll(typeof(ForgeOfPotentialPlugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)(string.Format("{0} {1} loaded; mode {2}, ", "MySix Forge of Potential", "1.0.3", ForgeHooks.Mode.Value) + "patch " + (DoCraftingPatch.Applied ? "applied" : "NOT applied"))); } } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } }