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 MoonsEqualised v1.0.2
BepInEx\plugins\MoonsEqualised\MoonsEqualised.dll
Decompiled 4 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MoonsEqualised")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("MoonsEqualised")] [assembly: AssemblyTitle("MoonsEqualised")] [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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 MoonsEqualised { [BepInPlugin("jakov.moonsequalised", "Moons Equalised", "1.0.0")] public class Plugin : BaseUnityPlugin { private sealed class MoonConfig { public float FactorySizeMultiplier { get; } public int MinScrap { get; } public int MaxScrap { get; } public int MaxIndoorPower { get; } public int MaxOutdoorPower { get; } public int FacilityChance { get; } public int MineshaftChance { get; } public int MansionChance { get; } public MoonConfig(float factorySizeMultiplier, int minScrap, int maxScrap, int maxIndoorPower, int maxOutdoorPower, int facilityChance, int mineshaftChance, int mansionChance) { FactorySizeMultiplier = factorySizeMultiplier; MinScrap = minScrap; MaxScrap = maxScrap; MaxIndoorPower = maxIndoorPower; MaxOutdoorPower = maxOutdoorPower; FacilityChance = facilityChance; MineshaftChance = mineshaftChance; MansionChance = mansionChance; } } private static Harmony _harmony; private static ManualLogSource _log; private void Awake() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown if (_log == null) { _log = Logger.CreateLogSource("Moons Equalised"); } _log.LogInfo((object)"Moons Equalised awake."); if (_harmony == null) { _harmony = new Harmony("jakov.moonsequalised"); } try { PatchMethod(typeof(RoundManager), "LoadNewLevel", "RoundManager_LoadNewLevel_Prefix"); PatchMethod(typeof(Terminal), "LoadNewNode", "Terminal_LoadNewNode_Prefix", "Terminal_LoadNewNode_Postfix"); PatchMethod(typeof(Terminal), "LoadNewNodeIfAffordable", "Terminal_LoadNewNodeIfAffordable_Prefix", "Terminal_LoadNewNodeIfAffordable_Postfix"); _log.LogInfo((object)"Harmony patches applied successfully."); } catch (Exception arg) { _log.LogError((object)$"Failed to apply Harmony patches: {arg}"); } } private static void PatchMethod(Type targetType, string methodName, string patchName, string? postfixName = null) { //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown MethodInfo method = targetType.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method == null) { _log.LogError((object)("Patch target not found: " + targetType.Name + "." + methodName)); return; } MethodInfo method2 = typeof(Plugin).GetMethod(patchName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method2 == null) { _log.LogError((object)("Patch method not found: " + patchName)); return; } HarmonyMethod val = null; if (!string.IsNullOrEmpty(postfixName)) { MethodInfo method3 = typeof(Plugin).GetMethod(postfixName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method3 == null) { _log.LogError((object)("Patch postfix method not found: " + postfixName)); return; } val = new HarmonyMethod(method3); } _harmony.Patch((MethodBase)method, new HarmonyMethod(method2), val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); _log.LogInfo((object)("Patched " + targetType.Name + "." + methodName + " with " + patchName + ((val != null) ? " + postfix" : string.Empty) + ".")); } private static void RoundManager_LoadNewLevel_Prefix(RoundManager __instance, int randomSeed, SelectableLevel newLevel) { try { if ((Object)(object)newLevel == (Object)null) { ManualLogSource log = _log; if (log != null) { log.LogWarning((object)"LoadNewLevel called with a null SelectableLevel."); } return; } ManualLogSource log2 = _log; if (log2 != null) { log2.LogInfo((object)("LoadNewLevel called for " + newLevel.PlanetName)); } ApplyLevelPatch(newLevel); ApplyDoorPricePatch(); } catch (Exception arg) { ManualLogSource log3 = _log; if (log3 != null) { log3.LogError((object)$"RoundManager_LoadNewLevel_Prefix error: {arg}"); } } } [HarmonyPatch(typeof(Terminal), "LoadNewNode")] [HarmonyPrefix] private static void Terminal_LoadNewNode_Prefix(Terminal __instance, TerminalNode node) { try { ApplyTerminalRoutePrice(node); } catch (Exception arg) { ManualLogSource log = _log; if (log != null) { log.LogError((object)$"Terminal_LoadNewNode_Prefix error: {arg}"); } } } private static void Terminal_LoadNewNode_Postfix(Terminal __instance) { try { if ((Object)(object)__instance != (Object)null && (Object)(object)__instance.currentNode != (Object)null) { ApplyTerminalRoutePrice(__instance.currentNode); } } catch (Exception arg) { ManualLogSource log = _log; if (log != null) { log.LogError((object)$"Terminal_LoadNewNode_Postfix error: {arg}"); } } } [HarmonyPatch(typeof(Terminal), "LoadNewNodeIfAffordable")] [HarmonyPrefix] private static void Terminal_LoadNewNodeIfAffordable_Prefix(Terminal __instance, TerminalNode node) { try { ApplyTerminalRoutePrice(node); } catch (Exception arg) { ManualLogSource log = _log; if (log != null) { log.LogError((object)$"Terminal_LoadNewNodeIfAffordable_Prefix error: {arg}"); } } } private static void Terminal_LoadNewNodeIfAffordable_Postfix(Terminal __instance) { try { if ((Object)(object)__instance != (Object)null && (Object)(object)__instance.currentNode != (Object)null) { ApplyTerminalRoutePrice(__instance.currentNode); } } catch (Exception arg) { ManualLogSource log = _log; if (log != null) { log.LogError((object)$"Terminal_LoadNewNodeIfAffordable_Postfix error: {arg}"); } } } private static void ApplyLevelPatch(SelectableLevel level) { if ((Object)(object)level == (Object)null) { return; } Dictionary<string, MoonConfig> dictionary = new Dictionary<string, MoonConfig> { ["Experimentation"] = new MoonConfig(1.1f, 12, 15, 6, 9, 75, 25, 0), ["Assurance"] = new MoonConfig(1.2f, 13, 15, 6, 8, 65, 35, 0), ["Vow"] = new MoonConfig(1.1f, 12, 14, 7, 6, 50, 50, 0), ["Offense"] = new MoonConfig(1.5f, 17, 19, 10, 8, 0, 100, 0), ["March"] = new MoonConfig(1.3f, 16, 16, 14, 12, 85, 0, 15), ["Adamance"] = new MoonConfig(1.2f, 16, 18, 13, 11, 50, 50, 0), ["Rend"] = new MoonConfig(1.8f, 25, 29, 12, 6, 0, 0, 100), ["Dine"] = new MoonConfig(1.8f, 30, 30, 10, 9, 0, 20, 80), ["Titan"] = new MoonConfig(2.2f, 31, 33, 16, 7, 34, 33, 33), ["Artifice"] = new MoonConfig(1.8f, 27, 30, 12, 13, 60, 40, 0) }; string text = NormalizeMoonName(level.PlanetName); if (string.IsNullOrEmpty(text)) { return; } if (dictionary.TryGetValue(text, out var value)) { ApplyMoonConfig(level, value); ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("Patched " + text + " level values.")); } } if (text == "Dine") { ApplyDineLootPool(level); } } private static void ApplyDoorPricePatch() { Terminal val = Object.FindObjectOfType<Terminal>(); if ((Object)(object)val == (Object)null || (Object)(object)val.terminalNodes == (Object)null) { return; } List<TerminalNode> terminalNodes = val.terminalNodes.terminalNodes; if (terminalNodes == null) { return; } foreach (TerminalNode item in terminalNodes) { ApplyTerminalRoutePrice(item); } } private static void ApplyTerminalRoutePrice(TerminalNode node) { if ((Object)(object)node == (Object)null || (Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.levels == null) { return; } SelectableLevel[] levels = StartOfRound.Instance.levels; foreach (SelectableLevel val in levels) { if ((Object)(object)val == (Object)null || node.buyRerouteToMoon != val.levelID) { continue; } string text = NormalizeMoonName(val.PlanetName); switch (text) { default: if (!(text == "Artifice")) { continue; } break; case "Rend": case "Dine": case "Titan": break; } node.itemCost = 1000; UpdateTerminalRouteUi(node, 1000); ManualLogSource log = _log; if (log != null) { log.LogInfo((object)("Reroute cost set to 1000 for " + text + ".")); } } } private static void UpdateTerminalRouteUi(TerminalNode node, int newCost) { if ((Object)(object)node == (Object)null) { return; } if (!string.IsNullOrEmpty(node.displayText)) { node.displayText = ReplaceRouteCost(node.displayText, newCost); } Terminal val = Object.FindObjectOfType<Terminal>(); if ((Object)(object)val == (Object)null) { return; } if (!string.IsNullOrEmpty(val.currentText)) { val.currentText = ReplaceRouteCost(val.currentText, newCost); } List<Object> list = new List<Object>(); if ((Object)(object)val.screenText != (Object)null) { list.Add((Object)(object)val.screenText); } if ((Object)(object)val.inputFieldText != (Object)null) { list.Add((Object)(object)val.inputFieldText); } if ((Object)(object)val.topRightText != (Object)null) { list.Add((Object)(object)val.topRightText); } TextMeshProUGUI[] array = Object.FindObjectsOfType<TextMeshProUGUI>(); foreach (TextMeshProUGUI val2 in array) { if ((Object)(object)val2 != (Object)null) { list.Add((Object)(object)val2); } } foreach (Object item in list) { if (item == (Object)null) { continue; } PropertyInfo property = ((object)item).GetType().GetProperty("text"); if (property == null || property.PropertyType != typeof(string)) { continue; } string text = property.GetValue(item) as string; if (!string.IsNullOrEmpty(text)) { string text2 = ReplaceRouteCost(text, newCost); if (!string.Equals(text, text2, StringComparison.Ordinal)) { property.SetValue(item, text2); } } } } private static string ReplaceRouteCost(string input, int newCost) { if (string.IsNullOrEmpty(input)) { return input; } return Regex.Replace(input, "(?i)(costs?\\s+)(\\d+)(\\s+credits?)", (Match match) => $"{match.Groups[1].Value}{newCost}{match.Groups[3].Value}"); } private static string NormalizeMoonName(string? moonName) { if (string.IsNullOrWhiteSpace(moonName)) { return string.Empty; } string text = moonName.Trim(); string[] array = text.Split(new char[2] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); if (array.Length > 1 && int.TryParse(array[0], out var _)) { return string.Join(" ", array, 1, array.Length - 1); } return text; } private static void ApplyMoonConfig(SelectableLevel level, MoonConfig config) { if (!((Object)(object)level == (Object)null)) { int minScrap = level.minScrap; int maxScrap = level.maxScrap; int minTotalScrapValue = level.minTotalScrapValue; int maxTotalScrapValue = level.maxTotalScrapValue; level.factorySizeMultiplier = config.FactorySizeMultiplier; level.minScrap = config.MinScrap; level.maxScrap = config.MaxScrap; if (minScrap > 0) { level.minTotalScrapValue = Mathf.RoundToInt((float)config.MinScrap * ((float)minTotalScrapValue / (float)minScrap)); } else { level.minTotalScrapValue = config.MinScrap * 45; } if (maxScrap > 0) { level.maxTotalScrapValue = Mathf.RoundToInt((float)config.MaxScrap * ((float)maxTotalScrapValue / (float)maxScrap)); } else { level.maxTotalScrapValue = config.MaxScrap * 75; } level.maxEnemyPowerCount = config.MaxIndoorPower; level.maxInsideDiversityPowerCount = config.MaxIndoorPower; level.maxDaytimeEnemyPowerCount = config.MaxIndoorPower; level.maxOutsideEnemyPowerCount = config.MaxOutdoorPower; level.maxOutsideDiversityPowerCount = config.MaxOutdoorPower; ApplyDungeonWeights(level, config.FacilityChance, config.MineshaftChance, config.MansionChance); } } private static void ApplyDungeonWeights(SelectableLevel level, int facilityChance, int mineshaftChance, int mansionChance) { if (!((Object)(object)level == (Object)null) && level.dungeonFlowTypes != null) { SetRarityAtIndex(level.dungeonFlowTypes, 0, facilityChance); SetRarityAtIndex(level.dungeonFlowTypes, 1, mineshaftChance); SetRarityAtIndex(level.dungeonFlowTypes, 2, mansionChance); } } private static void SetRarityAtIndex(Array dungeonFlowTypes, int index, int value) { if (dungeonFlowTypes == null || index < 0 || index >= dungeonFlowTypes.Length) { return; } object value2 = dungeonFlowTypes.GetValue(index); if (value2 != null) { FieldInfo field = value2.GetType().GetField("rarity", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { field.SetValue(value2, value); } } } private static void ApplyDineLootPool(SelectableLevel dineLevel) { if ((Object)(object)dineLevel == (Object)null || (Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.levels == null) { return; } SelectableLevel[] levels = StartOfRound.Instance.levels; foreach (SelectableLevel val in levels) { if (!((Object)(object)val != (Object)null) || !(NormalizeMoonName(val.PlanetName) == "Rend")) { continue; } FieldInfo field = typeof(SelectableLevel).GetField("spawnableScrap", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo field2 = typeof(SelectableLevel).GetField("spawnableScrap", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null && field2 != null) { object value = field.GetValue(val); field2.SetValue(dineLevel, value); ManualLogSource log = _log; if (log != null) { log.LogInfo((object)"Dine loot pool reset to a Rend-like scrap pool."); } } break; } } } }