using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("ScrapVisbility")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ScrapVisbility")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("8a6853bd-bdc9-4741-95c7-5aa2c8c6a6f9")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace LC_MissionRandomizer; [BepInPlugin("yellowcube.lc.mission_randomizer", "Mission Randomizer", "0.1.25")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "yellowcube.lc.mission_randomizer"; public const string PluginName = "Mission Randomizer"; public const string PluginVersion = "0.1.25"; internal static ManualLogSource Log; internal static Plugin Instance; private Harmony harmony; internal ConfigEntry ModEnabled; internal ConfigEntry BlockMoonTerminalCommands; internal ConfigEntry ForceStarterMoon; internal ConfigEntry RestrictTerminalMoonCatalogue; internal ConfigEntry DisableOutsideAndDaytimePower; internal ConfigEntry ShowMonitorStats; internal ConfigEntry DebugLogging; internal ConfigEntry AutoFileDebugLogging; internal ConfigEntry HostDebugTeleportScrapWithP; internal ConfigEntry NormalizeGeneratedScrapValue; internal ConfigEntry EnforceGeneratedScrapCount; internal ConfigEntry PreClampScrapValuesBeforeGeneration; internal ConfigEntry CleaningCompanySupport; internal ConfigEntry MinimumTotalScrapValue; internal ConfigEntry MaximumTotalScrapValueCap; internal ConfigEntry QuotaCoverageMultiplier; internal ConfigEntry MinimumScrapCount; internal ConfigEntry MaximumScrapCountCap; internal ConfigEntry MaximumMissionScrapCount; internal ConfigEntry MaximumInsideEnemyPowerCap; internal ConfigEntry MaximumMinEnemiesToSpawn; internal ConfigEntry MaximumFactorySizeMultiplier; internal ConfigEntry MaximumScrapAmountMultiplier; internal ConfigEntry MaximumScrapValueMultiplier; internal ConfigEntry CleaningCompanyConversionSearchRadius; internal ConfigEntry CleaningCompanyConversionWindowSeconds; internal ConfigEntry SeedOffset; private void Awake() { //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_0434: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; try { ((BaseUnityPlugin)this).Config.SaveOnConfigSet = true; } catch { } ModEnabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Enable or disable the mission randomizer."); BlockMoonTerminalCommands = ((BaseUnityPlugin)this).Config.Bind("General", "BlockMoonTerminalCommands", true, "If true, the moons and route terminal commands are replaced with mission information / blocked."); ForceStarterMoon = ((BaseUnityPlugin)this).Config.Bind("General", "ForceStarterMoon", true, "If true, the current level is forced back to the starter moon while in orbit and before loading a level."); RestrictTerminalMoonCatalogue = ((BaseUnityPlugin)this).Config.Bind("General", "RestrictTerminalMoonCatalogue", false, "If true, the terminal moon catalogue is trimmed to only the starter moon and the Company. Leave false if another mod expects the normal catalogue."); DisableOutsideAndDaytimePower = ((BaseUnityPlugin)this).Config.Bind("General", "DisableOutsideAndDaytimePower", true, "If true, outside and daytime enemy power caps are forced to zero."); ShowMonitorStats = ((BaseUnityPlugin)this).Config.Bind("General", "ShowMonitorStats", true, "If true, ship monitor text is replaced with the current randomized mission stats."); DebugLogging = ((BaseUnityPlugin)this).Config.Bind("Debug", "DebugEnabled", false, "If true, enable diagnostic console logging and allow debug files to be written."); AutoFileDebugLogging = ((BaseUnityPlugin)this).Config.Bind("Debug", "WriteDebugFiles", true, "If true and DebugEnabled is true, write orbit / landed / manual diagnostic snapshots to BepInEx/MissionRandomizerDebugLogs."); HostDebugTeleportScrapWithP = ((BaseUnityPlugin)this).Config.Bind("Debug", "HostCanPressPToTeleportScrap", false, "If true, the host can press P to teleport scrap to themselves for testing. This only works on the host/server and does not sync scrap positions to clients."); NormalizeGeneratedScrapValue = ((BaseUnityPlugin)this).Config.Bind("Gameplay", "NormalizeGeneratedScrapValue", true, "If true, the host keeps generated mission scrap inside the displayed total value range. It no longer forces the total to always equal the max value."); EnforceGeneratedScrapCount = ((BaseUnityPlugin)this).Config.Bind("Gameplay", "EnforceGeneratedScrapCount", true, "If true, the host removes excess generated mission scrap above the mission profile max count before vanilla scrap values sync."); PreClampScrapValuesBeforeGeneration = ((BaseUnityPlugin)this).Config.Bind("Gameplay", "PreScaleScrapValuesBeforeGeneration", false, "Legacy option. Keep this off. The mod now edits the real vanilla scrap values before the vanilla scrap sync instead of using temporary fake item ranges."); CleaningCompanySupport = ((BaseUnityPlugin)this).Config.Bind("Compatibility", "CleaningCompanySupport", true, "If true, preserve scrap value for direct Cleaning Company conversions: Scav Goop / Thumper Drool to Dirty Water, and Bone Pile / Nail Pile Item / BrackenDustItem / Ethereal Essence / Hoarding Bug Eggs / Spore Pile to Full Garbage Bag."); MinimumTotalScrapValue = ((BaseUnityPlugin)this).Config.Bind("Scaling", "MinimumTotalScrapValue", 220, "Lowest maxTotalScrapValue the mod will generate."); MaximumTotalScrapValueCap = ((BaseUnityPlugin)this).Config.Bind("Scaling", "MaximumTotalScrapValueCap", 1250, "Hard cap for generated maxTotalScrapValue."); QuotaCoverageMultiplier = ((BaseUnityPlugin)this).Config.Bind("Scaling", "QuotaCoverageMultiplier", 1.2f, "Each remaining day tries to offer at least quotaRemaining / daysLeft multiplied by this value."); MinimumScrapCount = ((BaseUnityPlugin)this).Config.Bind("Scaling", "MinimumScrapCount", 12, "Lowest generated minScrap count."); MaximumScrapCountCap = ((BaseUnityPlugin)this).Config.Bind("Scaling", "MaximumScrapCountCap", 48, "Legacy cap for generated maxScrap count. MaximumMissionScrapCount is the main physical scrap cap."); MaximumMissionScrapCount = ((BaseUnityPlugin)this).Config.Bind("Scaling", "MaximumMissionScrapCount", 48, "Hard cap for how many physical mission scrap items can spawn. This does not cap total scrap value."); MaximumInsideEnemyPowerCap = ((BaseUnityPlugin)this).Config.Bind("Scaling", "MaximumInsideEnemyPowerCap", 14, "Hard cap for generated maxEnemyPowerCount."); MaximumMinEnemiesToSpawn = ((BaseUnityPlugin)this).Config.Bind("Scaling", "MaximumMinEnemiesToSpawn", 3, "Hard cap for RoundManager.minEnemiesToSpawn."); MaximumFactorySizeMultiplier = ((BaseUnityPlugin)this).Config.Bind("Scaling", "MaximumFactorySizeMultiplier", 2.05f, "Hard cap for generated factorySizeMultiplier / RoundManager.mapSizeMultiplier."); MaximumScrapAmountMultiplier = ((BaseUnityPlugin)this).Config.Bind("Scaling", "MaximumScrapAmountMultiplier", 2.25f, "Hard cap for RoundManager.scrapAmountMultiplier."); MaximumScrapValueMultiplier = ((BaseUnityPlugin)this).Config.Bind("Scaling", "MaximumScrapValueMultiplier", 2.25f, "Hard cap for RoundManager.scrapValueMultiplier."); CleaningCompanyConversionSearchRadius = ((BaseUnityPlugin)this).Config.Bind("Compatibility", "CleaningCompanyConversionSearchRadius", 6f, "How close a newly appeared scrap item must be to a disappeared Cleaning Company mess or converted scrap item to inherit its value."); CleaningCompanyConversionWindowSeconds = ((BaseUnityPlugin)this).Config.Bind("Compatibility", "CleaningCompanyConversionWindowSeconds", 4f, "How long a disappeared scrap value stays pending while waiting for a nearby newly appeared scrap item."); SeedOffset = ((BaseUnityPlugin)this).Config.Bind("Scaling", "SeedOffset", 7319, "Change this to produce a different deterministic mission sequence."); try { ((BaseUnityPlugin)this).Config.Save(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Mission Randomizer config saved to: " + ((BaseUnityPlugin)this).Config.ConfigFilePath)); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Mission Randomizer config save failed: " + ex.Message)); } MissionController.Initialize(this); harmony = new Harmony("yellowcube.lc.mission_randomizer"); harmony.PatchAll(typeof(Plugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Mission Randomizer 0.1.25 loaded."); } private void OnDestroy() { try { MissionController.Shutdown(); Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } catch { } } private void OnGUI() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 Event current = Event.current; if (current != null && (int)current.type == 4 && (int)current.keyCode == 112 && HostDebugTeleportScrapWithP != null && HostDebugTeleportScrapWithP.Value) { MissionController.DebugTeleportScrapToPlayer(); } } } internal static class MissionController { [CompilerGenerated] private sealed class d__65 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string reason; public float delaySeconds; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__65(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (delaySeconds > 0f) { <>2__current = (object)new WaitForSeconds(delaySeconds); <>1__state = 1; return true; } break; case 1: <>1__state = -1; break; } NormalizeSpawnedScrapForCurrentRoll(reason, writeLog: true); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__67 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public string reason; public float delaySeconds; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__67(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (delaySeconds > 0f) { <>2__current = (object)new WaitForSeconds(delaySeconds); <>1__state = 1; return true; } break; case 1: <>1__state = -1; break; } RestoreTemporaryScrapValueRanges(reason, writeLog: true); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__174 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ulong clientId; public float delaySeconds; private StartOfRound 5__1; private RoundManager 5__2; private TimeOfDay