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 Lethal Company Unrandomizer v1.0.2
Lethal_Company_Unrandomizer/LethalUnrandomizer.dll
Decompiled a month agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("LethalUnrandomizer")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("LethalUnrandomizer")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("6c25caf0-1388-40bc-bddb-6fdbfa57c098")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace LethalUnrandomizer { internal class ConfigHandler { private string keyframeSetRegex = "[0-9.]+:[0-9.]+$"; private ConfigEntry<bool> ForceWeatherCfg; private ConfigEntry<int> ForcedWeatherTypeCfg; private ConfigEntry<bool> ForceMeteorsCfg; private ConfigEntry<bool> ForceInfestationsCfg; private ConfigEntry<int> ForcedInfestationTypeCfg; private ConfigEntry<bool> ForceLowestScrapValueCfg; private ConfigEntry<bool> ForceLowestScrapAmountCfg; private ConfigEntry<string> ChangeLandmineAmtKeyframesCfg; private ConfigEntry<string> ChangeTurretAmtKeyframesCfg; private ConfigEntry<string> ChangeSpikeTrapAmtKeyframesCfg; private ConfigEntry<bool> ChangeLandmineSpawnrateCfg; private ConfigEntry<bool> ChangeTurretSpawnrateCfg; private ConfigEntry<bool> ChangeSpikeTrapSpawnrateCfg; private ConfigEntry<bool> WorstLuckRandomLightningCfg; internal bool ForceWeather { get { return ForceWeatherCfg.Value; } set { ForceWeatherCfg.Value = value; } } internal int ForcedWeatherType { get { if (ForcedWeatherTypeCfg.Value < -1 || ForcedWeatherTypeCfg.Value > 5) { return (int)((ConfigEntryBase)ForcedWeatherTypeCfg).DefaultValue; } return ForcedWeatherTypeCfg.Value; } set { ForcedWeatherTypeCfg.Value = value; } } internal bool ForceMeteors { get { return ForceMeteorsCfg.Value; } set { ForceMeteorsCfg.Value = value; } } internal bool ForceInfestations { get { return ForceInfestationsCfg.Value; } set { ForceInfestationsCfg.Value = value; } } internal int ForcedInfestationType { get { if (ForcedInfestationTypeCfg.Value < 0 || ForcedInfestationTypeCfg.Value > 2) { return (int)((ConfigEntryBase)ForcedInfestationTypeCfg).DefaultValue; } return ForcedInfestationTypeCfg.Value; } set { ForcedInfestationTypeCfg.Value = value; } } internal bool ForceLowestScrapValue { get { return ForceLowestScrapValueCfg.Value; } set { ForceLowestScrapValueCfg.Value = value; } } internal bool ForceLowestScrapAmount { get { return ForceLowestScrapAmountCfg.Value; } set { ForceLowestScrapAmountCfg.Value = value; } } internal string ChangeLandmineAmtKeyframes { get { if (!Regex.IsMatch(ChangeLandmineAmtKeyframesCfg.Value, keyframeSetRegex)) { return (string)((ConfigEntryBase)ChangeLandmineAmtKeyframesCfg).DefaultValue; } return ChangeLandmineAmtKeyframesCfg.Value; } set { ChangeLandmineAmtKeyframesCfg.Value = value; } } internal string ChangeTurretAmtKeyframes { get { if (!Regex.IsMatch(ChangeTurretAmtKeyframesCfg.Value, keyframeSetRegex)) { return (string)((ConfigEntryBase)ChangeTurretAmtKeyframesCfg).DefaultValue; } return ChangeTurretAmtKeyframesCfg.Value; } set { ChangeTurretAmtKeyframesCfg.Value = value; } } internal string ChangeSpikeTrapAmtKeyframes { get { if (!Regex.IsMatch(ChangeSpikeTrapAmtKeyframesCfg.Value, keyframeSetRegex)) { return (string)((ConfigEntryBase)ChangeSpikeTrapAmtKeyframesCfg).DefaultValue; } return ChangeSpikeTrapAmtKeyframesCfg.Value; } set { ChangeSpikeTrapAmtKeyframesCfg.Value = value; } } internal bool ChangeLandmineSpawnrate { get { return ChangeLandmineSpawnrateCfg.Value; } set { ChangeLandmineSpawnrateCfg.Value = value; } } internal bool ChangeTurretSpawnrate { get { return ChangeTurretSpawnrateCfg.Value; } set { ChangeTurretSpawnrateCfg.Value = value; } } internal bool ChangeSpikeTrapSpawnrate { get { return ChangeSpikeTrapSpawnrateCfg.Value; } set { ChangeSpikeTrapSpawnrateCfg.Value = value; } } internal bool WorstLuckRandomLightning { get { return WorstLuckRandomLightningCfg.Value; } set { WorstLuckRandomLightningCfg.Value = value; } } public ConfigHandler(ConfigFile Config) { ForceWeatherCfg = Config.Bind<bool>("Weather Modifiers", "Force Weather", false, "Forces every moon to have weather type specified by 'forced weather type' (does NOT include FIRST DAY)."); ForcedWeatherTypeCfg = Config.Bind<int>("Weather Modifiers", "Forced Weather Type", 5, "Weather IDs: -1 = clear, 0 = dust clouds (unused), 1 = rainy, 2 = stormy, 3 = foggy, 4 = flooded, 5 = eclipse."); ForceMeteorsCfg = Config.Bind<bool>("Special Event Modifiers", "Force Meteors", false, "Forces every day to have a meteor shower."); ForceInfestationsCfg = Config.Bind<bool>("Special Event Modifiers", "Force Infestations", false, "Attempts to force every day to have a hording bug or nutcracker infestation specified by 'forced infestation type'. If the selected moon cannot spawn infested enemy type, the infestation will be canceled."); ForcedInfestationTypeCfg = Config.Bind<int>("Special Event Modifiers", "Forced Infestation Type", 0, "Infestation Settings: 0 = random (25% nutcracker, 75% hording bug), 1 = nutcracker, 2 = hording bug."); ForceLowestScrapValueCfg = Config.Bind<bool>("Inside Generation Modifiers", "Force Lowest Scrap Value", false, "Force all inside scrap to roll their minimum value."); ForceLowestScrapAmountCfg = Config.Bind<bool>("Inside Generation Modifiers", "Force Lowest Scrap Amount", false, "Force all moons to roll their minimum scrap amount."); ChangeLandmineAmtKeyframesCfg = Config.Bind<string>("Trap Spawning Modifiers", "Set Keyframes for Landmine Spawning", "0:5,1:20", "Set keyframes for landmine spawing. Make \"orderd pairs\" using the syntax '<time>:<value>' where '<time>' is a x-value (input) between 0-1 on the graph and '<value>' is a y-value (output) on the graph that represents the amount of landmines to spawn when randomly rolling the coressponding x-value. Use commas \",\" to seperate keyframes. EXAMPLE: \"0:10,1:20\" (when rolling a 0, 10 landmines spawn, when rolling a 0.5, 15 landmines spawn assuming linear interpolation and when rolling a 1, 20 landmines spawn)"); ChangeTurretAmtKeyframesCfg = Config.Bind<string>("Trap Spawning Modifiers", "Set Keyframes for Turret Spawning", "0:5,1:20", "Set keyframes for turret spawing. Make \"orderd pairs\" using the syntax '<time>:<value>' where '<time>' is a x-value (input) between 0-1 on the graph and '<value>' is a y-value (output) on the graph that represents the amount of turrets to spawn when randomly rolling the coressponding x-value. Use commas \",\" to seperate keyframes. EXAMPLE: \"0:10,1:20\" (when rolling a 0, 10 turrets spawn, when rolling a 0.5, 15 turrets spawn assuming linear interpolation and when rolling a 1, 20 turrets spawn)"); ChangeSpikeTrapAmtKeyframesCfg = Config.Bind<string>("Trap Spawning Modifiers", "Set Keyframes for Spike Trap Spawning", "0:5,1:20", "Set keyframes for spike trap spawing. Make \"orderd pairs\" using the syntax '<time>:<value>' where '<time>' is a x-value (input) between 0-1 on the graph and '<value>' is a y-value (output) on the graph that represents the amount of spike traps to spawn when randomly rolling the coressponding x-value. Use commas \",\" to seperate keyframes. EXAMPLE: \"0:10,1:20\" (when rolling a 0, 10 spike traps spawn, when rolling a 0.5, 15 spike traps spawn assuming linear interpolation and when rolling a 1, 20 spike traps spawn)"); ChangeLandmineSpawnrateCfg = Config.Bind<bool>("Trap Spawning Modifiers", "Enable Custom Landmine Spawnrate", false, "Enables / disables \"Set Keyframes for Landmine Spawning\""); ChangeTurretSpawnrateCfg = Config.Bind<bool>("Trap Spawning Modifiers", "Enable Custom Turret Spawnrate", false, "Enables / disables \"Set Keyframes for Turret Spawning\""); ChangeSpikeTrapSpawnrateCfg = Config.Bind<bool>("Trap Spawning Modifiers", "Enable Custom Spike Trap Spawnrate", false, "Enables / disables \"Set Keyframes for Spike Trap Spawning\""); WorstLuckRandomLightningCfg = Config.Bind<bool>("Weather Modifiers", "Force Worst Luck Random Lightning", false, "Forces random lightning to always strike a player if it can (glitchy) and makes random lightning have as low of a cooldown as possible"); } } [BepInPlugin("Aliki.LethalUnrandomizer", "Lethal Unrandomizer", "0.1.0.0")] public class UnrandomizerModBase : BaseUnityPlugin { private const string modGUID = "Aliki.LethalUnrandomizer"; private const string modName = "Lethal Unrandomizer"; private const string modVersion = "0.1.0.0"; private readonly Harmony harmonyOBJ = new Harmony("Aliki.LethalUnrandomizer"); internal static UnrandomizerModBase Instance; internal ManualLogSource mlsOBJ; internal ConfigHandler configHandlerOBJ; internal RoundManager currentRound; private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } mlsOBJ = Logger.CreateLogSource("Aliki.LethalUnrandomizer"); mlsOBJ.LogInfo((object)"Unrandomizer is awake and unrandomizing the randoms (._. )"); harmonyOBJ.PatchAll(); configHandlerOBJ = new ConfigHandler(((BaseUnityPlugin)this).Config); } } } namespace LethalUnrandomizer.Patches { [HarmonyPatch(typeof(RoundManager))] internal class RoundManagerPatch { private static ManualLogSource mls = UnrandomizerModBase.Instance.mlsOBJ; [HarmonyPatch("Start")] [HarmonyPrefix] private static void roundManagerReferenceFetchPatch(ref RoundManager __instance) { UnrandomizerModBase.Instance.currentRound = __instance; } [HarmonyPatch("RefreshEnemiesList")] [HarmonyPostfix] private static void indoorFogPatch(ref MonoBehaviour ___indoorFog) { ((Component)___indoorFog).gameObject.SetActive(true); } [HarmonyPatch("RefreshEnemiesList")] [HarmonyPostfix] private static void infestationAndSetCurrentLevelPatch(ref SelectableLevel ___currentLevel, ref int ___enemyRushIndex, ref float ___currentMaxInsidePower) { if (!UnrandomizerModBase.Instance.configHandlerOBJ.ForceInfestations) { return; } Random random = new Random(); switch (UnrandomizerModBase.Instance.configHandlerOBJ.ForcedInfestationType) { case 0: if (random.Next(0, 100) < 25) { ___enemyRushIndex = infestIndex(___currentLevel, "Nutcracker"); if (___enemyRushIndex != -1) { ___currentMaxInsidePower = 20f; break; } ___enemyRushIndex = infestIndex(___currentLevel, "Hoarding bug"); if (___enemyRushIndex != -1) { ___currentMaxInsidePower = 30f; } } else { ___enemyRushIndex = infestIndex(___currentLevel, "Hoarding bug"); if (___enemyRushIndex != -1) { ___currentMaxInsidePower = 30f; } } break; case 1: ___enemyRushIndex = infestIndex(___currentLevel, "Nutcracker"); if (___enemyRushIndex != -1) { ___currentMaxInsidePower = 20f; break; } ___enemyRushIndex = infestIndex(___currentLevel, "Hoarding bug"); if (___enemyRushIndex != -1) { ___currentMaxInsidePower = 30f; } break; default: ___enemyRushIndex = infestIndex(___currentLevel, "Hoarding bug"); if (___enemyRushIndex != -1) { ___currentMaxInsidePower = 30f; } break; } static int infestIndex(SelectableLevel currentLevel, string name) { int result = -1; for (int i = 0; i < currentLevel.Enemies.Count; i++) { if (currentLevel.Enemies[i].enemyType.enemyName.Equals(name)) { result = i; break; } } return result; } } [HarmonyPatch("SpawnScrapInLevel")] [HarmonyPrefix] private static void setAllItemsMinValue(ref SelectableLevel ___currentLevel) { if (!UnrandomizerModBase.Instance.configHandlerOBJ.ForceLowestScrapValue) { return; } foreach (SpawnableItemWithRarity item in ___currentLevel.spawnableScrap) { item.spawnableItem.maxValue = item.spawnableItem.minValue; } } [HarmonyPatch("SpawnScrapInLevel")] [HarmonyPrefix] private static void rollMinScrapAmount(ref SelectableLevel ___currentLevel) { if (UnrandomizerModBase.Instance.configHandlerOBJ.ForceLowestScrapAmount) { ___currentLevel.maxScrap = ___currentLevel.minScrap; } } [HarmonyPatch("SpawnMapObjects")] [HarmonyPrefix] private static void changeTrapCount(ref SelectableLevel ___currentLevel) { if (UnrandomizerModBase.Instance.configHandlerOBJ.ChangeLandmineSpawnrate) { mapObjAdjustKeyframes("landmines", UnrandomizerModBase.Instance.configHandlerOBJ.ChangeLandmineAmtKeyframes, ___currentLevel); } if (UnrandomizerModBase.Instance.configHandlerOBJ.ChangeTurretSpawnrate) { mapObjAdjustKeyframes("turrets", UnrandomizerModBase.Instance.configHandlerOBJ.ChangeTurretAmtKeyframes, ___currentLevel); } if (UnrandomizerModBase.Instance.configHandlerOBJ.ChangeSpikeTrapSpawnrate) { mapObjAdjustKeyframes("spiketraps", UnrandomizerModBase.Instance.configHandlerOBJ.ChangeSpikeTrapAmtKeyframes, ___currentLevel); } } public static void mapObjAdjustKeyframes(string objName, string keyframes, SelectableLevel currentLevel) { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) int num = -1; for (int i = 0; i < currentLevel.indoorMapHazards.Length; i++) { if (((Object)currentLevel.indoorMapHazards[i].hazardType).name.ToLower().Replace(" ", "").Equals(objName)) { num = i; } } if (num != -1) { string[] array = keyframes.Split(",".ToCharArray()); Keyframe[] array2 = (Keyframe[])(object)new Keyframe[array.Length]; for (int j = 0; j < array2.Length; j++) { array2[j] = new Keyframe(float.Parse(array[j].Split(":".ToCharArray())[0]), float.Parse(array[j].Split(":".ToCharArray())[1])); } currentLevel.indoorMapHazards[num].numberToSpawn.keys = array2; } else { mls.LogMessage((object)("Hazard type \"" + objName + "\" not found in list")); } } } [HarmonyPatch(typeof(StormyWeather))] internal class StormyWeatherPatch { public static Random rand = new Random(39802); [HarmonyPatch("DetermineNextStrikeInterval")] [HarmonyPostfix] private static void strikeIntervalPatch(ref float ___randomThunderTime, ref float ___timeAtLastStrike) { if (UnrandomizerModBase.Instance.configHandlerOBJ.WorstLuckRandomLightning) { ___randomThunderTime = ___timeAtLastStrike; ___randomThunderTime += Mathf.Clamp(-1.25f, 0.6f, 110f) / Mathf.Clamp(TimeOfDay.Instance.currentWeatherVariable, 1f, 100f); } } [HarmonyPatch("LightningStrikeRandom")] [HarmonyPrefix] private static bool randomStrikeSkipMethodPatch() { if (UnrandomizerModBase.Instance.configHandlerOBJ.WorstLuckRandomLightning) { return false; } return true; } [HarmonyPatch("LightningStrikeRandom")] [HarmonyPostfix] private static void randomStrikeTargetsPlayerPatch(ref StormyWeather __instance) { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0257: 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_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016b: 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_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018e: 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_01b6: 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_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0235: 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_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) if (!UnrandomizerModBase.Instance.configHandlerOBJ.WorstLuckRandomLightning) { return; } GameObject[] allPlayerObjects = StartOfRound.Instance.allPlayerObjects; PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; int[] array = new int[3]; for (int i = 0; i < array.Length; i++) { if (!allPlayerScripts[i].isInsideFactory && !allPlayerScripts[i].isPlayerDead && allPlayerScripts[i].AllowPlayerDeath()) { array[i] = i; } else { array[i] = -1; } } int num = rand.Next(0, array.Length); int num2 = 0; while (array[num] == -1) { num = rand.Next(0, array.Length); num2++; if (num2 > 10) { array[0] = 0; num = 0; break; } } Vector3 val = allPlayerObjects[array[num]].transform.position; Vector3 position = UnrandomizerModBase.Instance.currentRound.GetClosestNode(val, true).position; if (Math.Sqrt(Math.Pow(val.x - position.x, 2.0) + Math.Pow(val.z - position.z, 2.0)) > 15.0) { Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(val.x - position.x, val.z - position.z); Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor((float)Math.Sign(val2.x), (float)Math.Sign(val2.y)); double num3 = (Math.Pow(val2.x, 2.0) + Math.Pow(val2.y, 2.0)) / Math.Pow(15.0, 2.0); Vector2 val4 = new Vector2((float)Math.Sqrt(Math.Pow(val2.x, 2.0) / num3), (float)Math.Sqrt(Math.Pow(val2.y, 2.0) / num3)) * val3; val = position + new Vector3(val4.x, 0f, val4.y); } __instance.LightningStrike(val, false); } } [HarmonyPatch(typeof(TimeOfDay))] internal class TimeOfDayPatch { [HarmonyPatch("DecideRandomDayEvents")] [HarmonyPrefix] private static void meteorPatch(ref int ___overrideMeteorChance) { if (UnrandomizerModBase.Instance.configHandlerOBJ.ForceMeteors) { ___overrideMeteorChance = 1000; } } } [HarmonyPatch(typeof(StartOfRound))] internal class StartOfRoundPatch { [HarmonyPatch("SetPlanetsWeather")] [HarmonyPostfix] private static void weatherPatch(ref SelectableLevel[] ___levels) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) if (UnrandomizerModBase.Instance.configHandlerOBJ.ForceWeather) { SelectableLevel[] array = ___levels; foreach (SelectableLevel val in array) { val.currentWeather = (LevelWeatherType)UnrandomizerModBase.Instance.configHandlerOBJ.ForcedWeatherType; } } } } }