using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using BinaryMoonsOverhaul.Components; using BinaryMoonsOverhaul.Models; using BinaryMoonsOverhaul.Patches; using GameNetcodeStuff; using HarmonyLib; using LethalNetworkAPI; using Unity.Netcode; using UnityEngine; [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyCompany("Skit")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("BinaryMoonsOverhaul")] [assembly: AssemblyFileVersion("5.1.0.0")] [assembly: AssemblyInformationalVersion("5.1.0")] [assembly: AssemblyProduct("BinaryMoonsOverhaul")] [assembly: AssemblyTitle("BinaryMoonsOverhaul")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("5.1.0.0")] [module: UnverifiableCode] [module: UnverifiableCode] namespace BinaryMoonsOverhaul { public static class FlavorText { public const string TerminalMoonsCatalogueHeader = "\n\nWelcome to the exomoons catalogue.\nTo route the autopilot to a moon, use the word ROUTE.\nTo learn about any moon, use the word INFO.\n\n* The Company building // Buying at [companyBuyingRate].\n\nAvailable moons:\n"; public const string TerminalRerollRerouteText = "\nRerolling Moons...\n\n"; public const string TerminalNoRerollsText = "\nNo rerolls remaining! You earn 1 reroll at the start of each quota.\n\n"; public const string TerminalAccessDeniedHeader = "\n[ ACCESS DENIED ]\n\nThis celestial body is currently outside the authorized routing protocols for this quota.\n\nAvailable Destinations:\n"; public const string TerminalRerollRemainingText = "\n\nYou have {0} moon REROLL remaining.\nUse RE-ROLL to refresh the choices!\nType FIXMOON if your moon list does not match the host's.\n\n"; public const string HUDQuotaRewardHeader = "QUOTA REWARD"; public const string HUDQuotaRewardBody = "You've earned 1 extra moon REROLL!"; public const string HUDModifierActiveHeader = "MODIFIER ACTIVE"; public const string HUDModifierActiveBodySuffix = " is currently affecting the moon."; public const string HUDExpressEntryChat = "EXPRESS ENTRY: Crew deployed directly to facility entrance."; public const string ModExpressEntryHeader = "Rapid Deployment Initiated"; public const string ModExpressEntryBody = "Crew deployed directly to facility."; public const string HUDExpressEntryTipHeader = "EXPRESS ENTRY"; public const string HUDExpressEntryTipBody = "Crew relocated to the main entrance."; public const string HUDHighUVExposureHeader = "High UV Exposure"; public const string HUDHighUVExposureBody = "Higher than recommended levels of UV detected!"; public const string HUDInteriorLoadedHeader = "INTERIOR LOADED"; public const string HUDOrientationDayHeader = "ORIENTATION DAY"; public const string HUDOrientationDayBody = "New recruit has arrived for orientation and requires supervision"; public const string HUDStatusErrorHeader = "S\u0337T\u0334A\u0334T\u0338U\u0335S\u0335 E\u0337R\u0338R\u0335O\u0335R\u0335"; public const string HUDTipID = "LC_Tip1"; public const string ModWatchDogHeader = "ACTIVE GUARD DOGS"; public const string ModWatchDogBody = "Guard dogs detected in area. Please avoid and do not interere with their patrol."; public const string ModToxicAtmosphereHeader = "TOXIC ATMOSPHERE"; public const string ModToxicAtmosphereBody = "Toxic gases detected. Involuntary motor disruption and hallucinations possible. Inhalors recommended."; public const string ModLowGravityHeader = "LOW GRAVITY"; public const string ModLowGravityBody = "Gravitational limitations mitigated; quota adjusted accordingly."; public const string ModRadioactiveSunlightHeader = "UV RADIATION WARNING"; public const string ModRadioactiveSunlightBody = "UV exposure may result in dermal compromise. Seek shelter and avoid prolonged exposure during daylight hours."; public const string ModHauntedHeader = "PARANORMAL ACTIVITY DETECTED"; public const string ModHauntedBody = "Error: Unidentified UNKNOWABLE U\u0335\u035d\u0346\u0344\u031b\u031f\u0359\u0355N\u0335\u035d\u034b\u0312\u0320K\u0338\u0313\u0341\u0357\u0360\u032d\u033aI\u0337\u033e\u035d\u0300\u0320\u032e\u0319\u0333L\u0334\u033e\u0360\u0312\u0330L\u0334\u0341\u033f\u031a\u0343\u0316A\u0334\u035d\u0309\u035c\u0323B\u0336\u030b\u0309\u030a\u0352\u0326L\u0337\u0306\u035d\u0310\u035d\u0324E\u0338\u034b\u034b\u0342\u0315\u035c."; public const string ModOxygenRichHeader = "OXYGEN RICH"; public const string ModOxygenRichBody = "Recovery thresholds recalibrated for increased productivity."; public const string ModEquipmentCacheHeader = "EQUIPMENT CACHE"; public const string ModEquipmentCacheBody = "Locate dropship for additional tools and ship upgrades."; public const string ModNewHireHeader = "EMPLOYEE ORIENTATION"; public const string ModNewHireBody = "New employee en route. Please rendezvous and assist in on site orientation."; public const string ModWeaponDeliveryHeader = "WEAPON DROP"; public const string ModWeaponDeliveryBody = "Look down. Pick it up."; public const string ModGroovyHeader = "GROOVY MOON"; public const string ModGroovyBody = "Rare cosmic frequencies detected! Scrap may contain enhanced value."; public const string ModNameLowGravity = "Low Gravity"; public const string ModNameOxygenRich = "Oxygen Rich"; public const string ModNameEquipmentCache = "Equipment Cache"; public const string ModNameExpressEntry = "Express Entry"; public const string ModNameGroovy = "Groovy"; public const string ModNameWatchDog = "Guard Dog"; public const string ModNameRadioactiveSunlight = "High UV"; public const string ModNameHaunted = "Paranormal Activity"; public const string ModNameToxicAtmosphere = "Toxic Atmosphere"; public const string ModNameNewHire = "New Hire"; public const string ModNameWeaponDelivery = "Weapon Delivery"; public const string ModNameStandard = "Standard"; public const string ModNameUnknown = "Unknown"; public const string CompanySearchGordion = "gordion"; public const string CompanySearchCompany = "company"; public const string RainbowGroovy = "Groovy"; public const string ColorRed = "#FF0000"; public const string ColorGreen = "#00FF00"; public const string ColorWhite = "#FFFFFF"; public const string NetTagAskSync = ""; public const string NetTagRerollReq = ""; public const string NetTagRerollSyncPrefix = ":"; public const string NetTagSyncCfg = ":"; public const string NetTagSyncMoon = ":"; public const string NetTagSyncDone = ""; public const string NetTagRerollDeny = ""; public const string ItemNameTZP = "tzp"; public const string TerminalSellSuccess = "SHIP SCRAP LIQUIDATED. \n\nTotal: {0} credits for {1} items. \n\nThe Company appreciates your productivity."; public const string TerminalSellNoScrap = "NO SCRAP DETECTED ON SHIP."; public const string TerminalSellNotAtCompany = "RE ROUTE TO COMPANY BUILDING TO LIQUIDATE ASSETS."; public const string ManifestDescription = "2 random FREE moons per day. Custom Moon compatible (LLL). Includes terminal sell command and reroll mechanics."; public const string ReadmeTitle = "Binary Moons Overhaul (Restored)"; public const string ReadmeBody = "A roguelike experience for Lethal Company that restricts the autopilot to a choice of 2 random moons per day, each potentially having unique global modifiers."; public const string ReadmeFeatures = "### Features\n* **Daily Random Selection**: Only 2 moons are available for routing each day.\n* **100% Free Travel**: All selected moons are **FREE** to visit, regardless of their standard cost.\n* **Custom Moon Compatible**: Fully compatible with all custom moons via **Lethal Level Loader**.\n* **Unique Modifiers**: Paranormal Activity, Weapon Delivery, Equipment Cache, Guard Dog and more coming soon. These modifiers are in addition to weather.\n* **Economy Modifiers**: Positive modifiers increase the quota; negative modifiers provide bonus credits.\n* **Moon Rerolls**: Spend your earned rerolls to refresh the daily choices!\n\n(not currently v.80 compatible, and prefered LethalLevelLoader v1.6.8 prefered. Sorry.)"; public const string ReadmeCommands = "### Commands\n* `moons` - Open the custom catalogue.\n* `reroll` / `re-roll` / `rr` - Refresh the daily moon options (uses 1 Reroll).\n* `sell` / `sell all` - **[WIP]** Sells all scrap on ship at Company Desk (Note: Currently only adds to credits, not quota requirement).\n* `fixmoon` - Force-sync your moon list with the Host."; public static readonly string[] HauntedMessages = new string[9] { "I\u0337\u0352\u034a \u0336\u0352\u033eC\u0336\u0352\u034aA\u0336\u0352\u034aN\u0336\u0352\u034a \u0336\u0352\u033eF\u0336\u0352\u034aE\u0336\u0352\u034aE\u0336\u0352\u034aL\u0336\u0352\u034a \u0336\u0352\u033eY\u0336\u0352\u034aO\u0336\u0352\u034aU\u0336\u0352\u034a \u0336\u0352\u033eS\u0336\u0352\u034aH\u0336\u0352\u034aI\u0336\u0352\u034aV\u0336\u0352\u034aE\u0336\u0352\u034aR\u0336\u0352\u034a \u0336\u0352\u033eI\u0336\u0352\u034aN\u0336\u0352\u034a \u0336\u0352\u033eT\u0336\u0352\u034aH\u0336\u0352\u034aE\u0336\u0352\u034aR\u0336\u0352\u034aE\u0336\u0352\u034a .", "Y\u0334O\u0334U\u0337R\u0335 \u0335L\u0338U\u0338N\u0337G\u0337S\u0335 \u0337F\u0335E\u0334E\u0338L\u0334 \u0337S\u0338O\u0335 \u0338F\u0336U\u0338L\u0336L\u0337 \u0338O\u0337F\u0336 \u0337M\u0336Y\u0338 \u0335B\u0338R\u0336E\u0335A\u0335T\u0337H\u0335 .", "W\u0338H\u0336Y\u0336 \u0335A\u0334R\u0338E\u0335 \u0335Y\u0334O\u0334U\u0337 \u0334S\u0334T\u0337I\u0336L\u0336L\u0338 \u0335L\u0336O\u0335O\u0336K\u0338I\u0335N\u0337G\u0338?\u0334", "T\u0337H\u0335E\u0337Y\u0335 \u0335C\u0338A\u0338N\u0335'\u0337T\u0338 \u0335H\u0336E\u0337L\u0337P\u0336 \u0335Y\u0334O\u0334U\u0334 .", "S\u0338O\u0334O\u0336N\u0337 \u0338W\u0335E\u0336 \u0338W\u0338I\u0335L\u0336L\u0335 \u0337B\u0336E\u0335 \u0335O\u0337O\u0337N\u0337E\u0337 .", "D\u0338O\u0338N\u0336'\u0336T\u0336 \u0334T\u0337U\u0337R\u0338N\u0336 \u0337A\u0338R\u0338O\u0334U\u0335N\u0335D\u0334 .", "T\u0338H\u0338E\u0336 \u0334D\u0336A\u0336R\u0336K\u0337N\u0334E\u0337S\u0336S\u0334 \u0336H\u0334A\u0335S\u0336 \u0336T\u0335E\u0337E\u0337T\u0338H\u0338 .", "I\u0335S\u0336 \u0338T\u0335H\u0338A\u0336T\u0337 \u0334Y\u0337O\u0338U\u0336R\u0335 \u0335H\u0336E\u0338A\u0338R\u0338T\u0335B\u0335E\u0337A\u0336T\u0336?\u0336 \u0338I\u0335T\u0338'\u0338S\u0337 \u0334S\u0337O\u0337 \u0336F\u0334A\u0337S\u0336T\u0334 .", "Y\u0334O\u0334U\u0335 \u0335L\u0335O\u0336O\u0338K\u0335 \u0338L\u0338O\u0335V\u0337E\u0334L\u0338Y\u0335 \u0334I\u0337N\u0338 \u0335T\u0334H\u0338E\u0337 \u0335V\u0334O\u0334I\u0336D\u0338 ." }; } [BepInPlugin("BinaryMoonsOverhaul", "BinaryMoonsOverhaul", "7.0.55")] public class BinaryMoons : BaseUnityPlugin { [HarmonyPatch(typeof(GameNetworkManager), "Start")] public class NetworkingPatch { [HarmonyPostfix] public static void StartPostfix() { BMO_Networking.Initialize(); } } public static ConfigEntry BlacklistedMoons; public static ConfigEntry BonusPayMin; public static ConfigEntry BonusPayMax; public static ConfigEntry QuotaPenaltyMin; public static ConfigEntry QuotaPenaltyMax; public static ConfigEntry EnableOxygenRich; public static ConfigEntry EnableLowGravity; public static ConfigEntry EnableEquipmentCache; public static ConfigEntry EnableWatchDog; public static ConfigEntry EnableRadioactiveSunlight; public static ConfigEntry EnableHaunted; public static ConfigEntry EnableToxicAtmosphere; public static ConfigEntry EnableExpressEntry; public static ConfigEntry EnableGroovy; public static ConfigEntry EnableStandardMoons; public static ConfigEntry EnableNewHire; public static ConfigEntry EnableWeaponDelivery; public static ConfigEntry NewHireSpawnTime; public static ConfigEntry GroovyLootMultiplier; public static ConfigEntry GroovySpeedMultiplier; public static ConfigEntry StartingRerolls; public static ConfigEntry LowGravityStrength; public static ConfigEntry OxygenStaminaMultiplier; public static ConfigEntry HauntedGhostSpawnTime; public static ConfigEntry WatchDogWakeTime; public static ConfigEntry RadioactiveSunlightEndTime; public static ConfigEntry EnableLogSpam; public static ConfigEntry EquipmentCacheWhitelist; public static ConfigEntry EquipmentCacheBlacklist; public static HashSet MasterEquipmentPool; public static BinaryMoons Instance { get; private set; } internal static ManualLogSource Logger { get; private set; } internal static Harmony Harmony { get; set; } private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Instance = this; ReflectionCache.Initialize(); BlacklistedMoons = ((BaseUnityPlugin)this).Config.Bind("General", "BlacklistedMoons", "Gordion, end, liquidation", "Comma-separated list of moons to NEVER include in the rotation."); StartingRerolls = ((BaseUnityPlugin)this).Config.Bind("General", "StartingRerolls", 1, "Number of rerolls granted at the start of a new save."); EnableLogSpam = ((BaseUnityPlugin)this).Config.Bind("General", "EnableLogSpam", false, "Enable detailed diagnostic logging in the console."); BonusPayMin = ((BaseUnityPlugin)this).Config.Bind("Settings", "BonusPayMin", 50, "Minimum base reward for negative modifiers"); BonusPayMax = ((BaseUnityPlugin)this).Config.Bind("Settings", "BonusPayMax", 100, "Maximum base reward for negative modifiers"); QuotaPenaltyMin = ((BaseUnityPlugin)this).Config.Bind("Settings", "QuotaPenaltyMin", 25, "Minimum base penalty for positive modifiers"); QuotaPenaltyMax = ((BaseUnityPlugin)this).Config.Bind("Settings", "QuotaPenaltyMax", 50, "Maximum base penalty for positive modifiers"); GroovyLootMultiplier = ((BaseUnityPlugin)this).Config.Bind("Settings", "GroovyLootMultiplier", 1.15f, "Value multiplier for scrap on Groovy moons."); GroovySpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind("Settings", "GroovySpeedMultiplier", 1.15f, "Movement speed multiplier on Groovy moons."); NewHireSpawnTime = ((BaseUnityPlugin)this).Config.Bind("Settings", "NewHireSpawnTime", 12f, "Time when the New Hire dropship arrives (12.0 = Noon)."); LowGravityStrength = ((BaseUnityPlugin)this).Config.Bind("Settings", "LowGravityStrength", 18f, "Gravity force for Low Gravity (13 is normal)."); OxygenStaminaMultiplier = ((BaseUnityPlugin)this).Config.Bind("Settings", "OxygenStaminaMultiplier", 1.5f, "Stamina efficiency for Oxygen Rich."); HauntedGhostSpawnTime = ((BaseUnityPlugin)this).Config.Bind("Settings", "HauntedGhostSpawnTime", 17f, "Time when Ghost Girl spawns (17.0 = 5 PM)."); WatchDogWakeTime = ((BaseUnityPlugin)this).Config.Bind("Settings", "WatchDogWakeTime", 12f, "Time when Watch Dog wakes up."); RadioactiveSunlightEndTime = ((BaseUnityPlugin)this).Config.Bind("Settings", "RadioactiveSunlightEndTime", 18f, "Time when Radiation stops."); EquipmentCacheWhitelist = ((BaseUnityPlugin)this).Config.Bind("Settings", "EquipmentCacheWhitelist", "", "Comma-separated list of additional unlockable names to ADD to the Equipment Cache pool (e.g., 'Model Ship, Fancy Table')."); EquipmentCacheBlacklist = ((BaseUnityPlugin)this).Config.Bind("Settings", "EquipmentCacheBlacklist", "", "Comma-separated list of unlockable names to REMOVE from the pool."); EnableOxygenRich = ((BaseUnityPlugin)this).Config.Bind("Modifiers", "EnableOxygenRich", false, "[WIP] Enable Oxygen Rich."); EnableLowGravity = ((BaseUnityPlugin)this).Config.Bind("Modifiers", "EnableLowGravity", false, "[WIP] Enable Low Gravity."); EnableEquipmentCache = ((BaseUnityPlugin)this).Config.Bind("Modifiers", "EnableEquipmentCache", true, "Enable Equipment Cache."); EnableWatchDog = ((BaseUnityPlugin)this).Config.Bind("Modifiers", "EnableWatchDog", true, "Enable Guard Dog."); EnableRadioactiveSunlight = ((BaseUnityPlugin)this).Config.Bind("Modifiers", "EnableRadioactiveSunlight", false, "[WIP] Enable High UV."); EnableHaunted = ((BaseUnityPlugin)this).Config.Bind("Modifiers", "EnableHaunted", true, "Enable Paranormal Activity."); EnableToxicAtmosphere = ((BaseUnityPlugin)this).Config.Bind("Modifiers", "EnableToxicAtmosphere", false, "[WIP] Enable Toxic Atmosphere."); EnableExpressEntry = ((BaseUnityPlugin)this).Config.Bind("Modifiers", "EnableExpressEntry", false, "[WIP] Enable Express Entry."); EnableGroovy = ((BaseUnityPlugin)this).Config.Bind("Modifiers", "EnableGroovy", false, "[WIP] Enable Groovy."); EnableNewHire = ((BaseUnityPlugin)this).Config.Bind("Modifiers", "EnableNewHire", false, "[WIP] Enable New Hire."); EnableWeaponDelivery = ((BaseUnityPlugin)this).Config.Bind("Modifiers", "EnableWeaponDelivery", true, "Enable Weapon Delivery."); EnableStandardMoons = ((BaseUnityPlugin)this).Config.Bind("Modifiers", "EnableStandardMoons", true, "Enable Standard moons in the rotation."); InitializeMasterEquipmentPool(); Patch(); RegisterHotReloading(); Logger.LogInfo((object)"BinaryMoonsOverhaul v7.0.55 has loaded!"); } private void RegisterHotReloading() { Action onCfgChanged = delegate { if ((Object)(object)StartOfRound.Instance != (Object)null && ((NetworkBehaviour)StartOfRound.Instance).IsServer) { Logger.LogInfo((object)"[BMO] Config Hot-Reload detected. Broadcasting update..."); BMO_Networking.BroadcastSync(); } }; BonusPayMin.SettingChanged += delegate { onCfgChanged(); }; BonusPayMax.SettingChanged += delegate { onCfgChanged(); }; QuotaPenaltyMin.SettingChanged += delegate { onCfgChanged(); }; QuotaPenaltyMax.SettingChanged += delegate { onCfgChanged(); }; GroovyLootMultiplier.SettingChanged += delegate { onCfgChanged(); }; GroovySpeedMultiplier.SettingChanged += delegate { onCfgChanged(); }; NewHireSpawnTime.SettingChanged += delegate { onCfgChanged(); }; LowGravityStrength.SettingChanged += delegate { onCfgChanged(); }; OxygenStaminaMultiplier.SettingChanged += delegate { onCfgChanged(); }; HauntedGhostSpawnTime.SettingChanged += delegate { onCfgChanged(); }; WatchDogWakeTime.SettingChanged += delegate { onCfgChanged(); }; RadioactiveSunlightEndTime.SettingChanged += delegate { onCfgChanged(); }; StartingRerolls.SettingChanged += delegate { onCfgChanged(); }; } internal static void Patch() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown if (Harmony == null) { Harmony = new Harmony("BinaryMoonsOverhaul"); } Logger.LogDebug((object)"Patching core components..."); try { Harmony.PatchAll(); ReflectionCache.Initialize(); if (ReflectionCache.HUDManager_UpdateProfitQuota != null) { Logger.LogInfo((object)("[BMO] Manual Patching: " + ReflectionCache.HUDManager_UpdateProfitQuota.DeclaringType.Name + "." + ReflectionCache.HUDManager_UpdateProfitQuota.Name + "...")); Harmony.Patch((MethodBase)ReflectionCache.HUDManager_UpdateProfitQuota, (HarmonyMethod)null, new HarmonyMethod(typeof(ModifierLogicPatch), "QuotaVisualPatch", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { Logger.LogWarning((object)"[BMO] Could not find a stable Profit Quota Sync method. Quota fallback active."); } } catch (Exception ex) { Logger.LogError((object)("[BMO] Harmony Patching Failed: " + ex.Message)); } TerminalPatch.ApplyLLLHijack(Harmony); BMO_Networking.Initialize(); Logger.LogInfo((object)"Binary Moons Overhaul Restored (v7.0.55) Loaded!"); } internal static void Unpatch() { Logger.LogDebug((object)"Unpatching..."); Harmony harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } Logger.LogDebug((object)"Finished unpatching!"); } private void InitializeMasterEquipmentPool() { string[] collection = new string[15] { "Teleporter", "Inverse Teleporter", "Loud horn", "Signal translator", "Television", "Toilet", "Shower", "Record player", "Romantic table", "Table", "Company Cruiser", "Plushie mummy", "Pajama plushie", "Jack-o-lantern", "Cupboard" }; MasterEquipmentPool = new HashSet(collection, StringComparer.OrdinalIgnoreCase); IEnumerable enumerable = from s in EquipmentCacheWhitelist.Value.Split(',') select s.Trim() into s where !string.IsNullOrEmpty(s) select s; IEnumerable enumerable2 = from s in EquipmentCacheBlacklist.Value.Split(',') select s.Trim() into s where !string.IsNullOrEmpty(s) select s; foreach (string item in enumerable) { MasterEquipmentPool.Add(item); } foreach (string item2 in enumerable2) { MasterEquipmentPool.Remove(item2); } Logger.LogInfo((object)$"[LM] Equipment Cache Pool initialized with {MasterEquipmentPool.Count} valid items."); } } public static class ReflectionCache { public static FieldInfo Terminal_buyItemSFX; public static FieldInfo Terminal_shipIsComing; public static FieldInfo TerminalNode_isLocked; public static FieldInfo SelectableLevel_itemCost; public static MethodInfo TimeOfDay_SyncStats_ClientRpc; public static MethodInfo HUDManager_UpdateProfitQuota; public static MethodInfo Terminal_TriggerDropshipServerRpc; public static bool IsLethalLevelLoaderLoaded; public static Terminal CachedTerminal; public static EnemyType[] CachedEnemies; public static TerminalNode[] CachedTerminalNodes; public static Item CachedKnife; public static Item CachedShotgun; public static void Initialize() { try { IsLethalLevelLoaderLoaded = Chainloader.PluginInfos.ContainsKey("com.iamabatman.lethallevelloader"); Terminal_buyItemSFX = typeof(Terminal).GetField("buyItemSFX", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? typeof(Terminal).GetField("itemBoughtSound", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? typeof(Terminal).GetField("buyItemAudio", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); Terminal_shipIsComing = typeof(Terminal).GetField("shipIsComing", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); Terminal_TriggerDropshipServerRpc = typeof(Terminal).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name.Contains("Trigger") && m.Name.Contains("Dropship") && m.Name.Contains("ServerRpc")); TerminalNode_isLocked = typeof(TerminalNode).GetField("isLocked", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); SelectableLevel_itemCost = typeof(SelectableLevel).GetField("itemCost", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); TimeOfDay_SyncStats_ClientRpc = typeof(TimeOfDay).GetMethod("SyncStats_ClientRpc", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); HUDManager_UpdateProfitQuota = typeof(HUDManager).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name.Contains("UpdateProfitQuota") || m.Name.Contains("SetProfitQuota") || m.Name.Contains("SyncQuotaHUD")); BinaryMoons.Logger.LogInfo((object)"Reflection Cache Initialized Successfully."); } catch (Exception ex) { BinaryMoons.Logger.LogError((object)("Failed to initialize Reflection Cache: " + ex.Message)); } } public static void InitializeAssets(Terminal terminal) { if ((Object)(object)CachedTerminal != (Object)null) { return; } CachedTerminal = terminal; try { CachedEnemies = Resources.FindObjectsOfTypeAll(); CachedTerminalNodes = Resources.FindObjectsOfTypeAll(); if ((Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.allItemsList != (Object)null) { CachedKnife = ((IEnumerable)StartOfRound.Instance.allItemsList.itemsList).FirstOrDefault((Func)((Item i) => i.itemName.ToLower().Contains("kitchen knife") || i.itemName.ToLower().Contains("knife"))); CachedShotgun = ((IEnumerable)StartOfRound.Instance.allItemsList.itemsList).FirstOrDefault((Func)((Item i) => i.itemName.ToLower().Contains("shotgun"))); } BinaryMoons.Logger.LogInfo((object)"[LM] Asset Cache Initialized Successfully (Terminal, Enemies, Nodes, Items)."); } catch (Exception ex) { BinaryMoons.Logger.LogError((object)("[LM] Failed to initialize Asset Cache: " + ex.Message)); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "BinaryMoonsOverhaul"; public const string PLUGIN_NAME = "BinaryMoonsOverhaul"; public const string PLUGIN_VERSION = "7.0.55"; } } namespace BinaryMoonsOverhaul.Patches { [HarmonyPatch(typeof(ItemDropship), "Update")] public class DropShipNewHirePatch { private static bool landingMessagePlayed; [HarmonyPostfix] private static void Postfix(ItemDropship __instance) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)StartOfRound.Instance).IsServer) { return; } if (__instance.shipLanded) { if (!landingMessagePlayed) { landingMessagePlayed = true; if (TerminalPatch.IsModifierActive("New Hire")) { BMO_Networking.SendTip("ORIENTATION DAY", "New recruit has arrived for orientation and requires supervision", isPositive: true); if (ModifierLogicPatch.isNewHireDropshipActive) { ModifierLogicPatch.isNewHireDropshipActive = false; Terminal cachedTerminal = ReflectionCache.CachedTerminal; if ((Object)(object)cachedTerminal != (Object)null && cachedTerminal.numberOfItemsInDropship > 0) { cachedTerminal.numberOfItemsInDropship--; BinaryMoons.Logger.LogInfo((object)"New Hire: Cleaned up phantom dropship item count."); } } SpawnMaskedAtDropship(((Component)__instance).transform.position); } } if (!TerminalPatch.IsModifierActive("Equipment Cache") || !ModifierLogicPatch.waitingForDropshipArrival || ModifierLogicPatch.pendingVoucherUpgradeIndex == -1) { return; } bool flag = false; PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if ((Object)(object)val != (Object)null && val.isPlayerControlled && !val.isPlayerDead && Vector3.Distance(((Component)val).transform.position, ((Component)__instance).transform.position) < 4.5f) { flag = true; break; } } if (flag) { ModifierLogicPatch.waitingForDropshipArrival = false; int pendingVoucherUpgradeIndex = ModifierLogicPatch.pendingVoucherUpgradeIndex; string pendingVoucherUpgradeName = ModifierLogicPatch.pendingVoucherUpgradeName; ModifierLogicPatch.pendingVoucherUpgradeIndex = -1; ModifierLogicPatch.pendingVoucherUpgradeName = ""; Terminal cachedTerminal2 = ReflectionCache.CachedTerminal; int num = (((Object)(object)cachedTerminal2 != (Object)null) ? cachedTerminal2.groupCredits : 0); StartOfRound.Instance.BuyShipUnlockableServerRpc(pendingVoucherUpgradeIndex, num); HUDManager instance = HUDManager.Instance; if (instance != null) { instance.AddTextToChatOnServer("EQUIPMENT CACHE: " + pendingVoucherUpgradeName + " voucher secured.", -1); } BMO_Networking.SendTip("EQUIPMENT CACHE", "Recovered: " + pendingVoucherUpgradeName + " voucher.", isPositive: false); BinaryMoons.Logger.LogInfo((object)("[LM] Equipment Cache reward COLLECTED via proximity interaction: " + pendingVoucherUpgradeName)); } } else { landingMessagePlayed = false; } } private static void SpawnMaskedAtDropship(Vector3 position) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)RoundManager.Instance == (Object)null || (Object)(object)RoundManager.Instance.currentLevel == (Object)null || RoundManager.Instance.currentLevel.Enemies == null) { return; } EnemyType val = ModifierLogicPatch.CachedMasked; if ((Object)(object)val == (Object)null) { val = ((IEnumerable)RoundManager.Instance.currentLevel.Enemies).FirstOrDefault((Func)((SpawnableEnemyWithRarity e) => (Object)(object)e.enemyType != (Object)null && e.enemyType.enemyName.ToLower().Contains("masked")))?.enemyType; } if ((Object)(object)val != (Object)null) { RoundManager.Instance.SpawnEnemyGameObject(position, 0f, -1, val); BinaryMoons.Logger.LogInfo((object)"New Hire: Masked spawned at dropship!"); } } } [HarmonyPatch] public class ModifierLogicPatch { [CompilerGenerated] private sealed class d__19 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__19(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: { <>1__state = -1; float num = 25f; <>2__current = (object)new WaitForSeconds(num); <>1__state = 1; return true; } case 1: <>1__state = -1; if (SyncManager.ActiveModifiersBitmask == 0) { BinaryMoons.Logger.LogInfo((object)"[BMO] Event-Driven Audit: State missing. Requesting Sync..."); BMO_Networking.RequestSync(); } 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(); } } private static string[] hauntedMessages = FlavorText.HauntedMessages; private static bool spawnedGhostGirl5PM = false; private static bool spawnedWatchDogNoon = false; private static bool spawnedNewHireEvent = false; private static bool sentExpressEntryMessage = false; private static bool spawnedWeaponDelivery = false; private static bool shownRadioactiveWarningToday = false; public static bool isNewHireDropshipActive = false; private static bool triggeredShipLandedModifiers = false; public static bool waitingForDropshipArrival = false; public static int pendingVoucherUpgradeIndex = -1; public static string pendingVoucherUpgradeName = ""; private static bool statesNeedReset = true; public static EnemyType CachedGhostGirl; public static EnemyType CachedWatchDog; public static EnemyType CachedMasked; [HarmonyPatch(typeof(RoundManager), "FinishGeneratingLevel")] [HarmonyPostfix] private static void LevelGenerationFinished() { if ((Object)(object)StartOfRound.Instance != (Object)null && ((NetworkBehaviour)StartOfRound.Instance).IsServer) { BMO_Networking.BroadcastSync(); } } public static void ResetAllStates() { spawnedGhostGirl5PM = false; spawnedWatchDogNoon = false; spawnedNewHireEvent = false; sentExpressEntryMessage = false; BMO_Networking.ResetFlags(); shownRadioactiveWarningToday = false; triggeredShipLandedModifiers = false; isNewHireDropshipActive = false; waitingForDropshipArrival = false; pendingVoucherUpgradeIndex = -1; pendingVoucherUpgradeName = ""; BMO_PlayerModifierManager[] array = Object.FindObjectsOfType(); BMO_PlayerModifierManager[] array2 = array; foreach (BMO_PlayerModifierManager bMO_PlayerModifierManager in array2) { bMO_PlayerModifierManager.ResetLocalTimers(); } BMO_Networking.RefreshActiveModifierFlags(); } [HarmonyPatch(typeof(PlayerControllerB), "Awake")] [HarmonyPostfix] private static void PlayerAwakePostfix(PlayerControllerB __instance) { if ((Object)(object)((Component)__instance).GetComponent() == (Object)null) { ((Component)__instance).gameObject.AddComponent(); } if (!((NetworkBehaviour)StartOfRound.Instance).IsServer) { ((MonoBehaviour)StartOfRound.Instance).StartCoroutine(RunAuditAtTime()); } } [IteratorStateMachine(typeof(d__19))] private static IEnumerator RunAuditAtTime() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__19(0); } [HarmonyPatch(typeof(PlayerControllerB), "Update")] [HarmonyPostfix] private static void PlayerUpdatePostfix(PlayerControllerB __instance) { if (((NetworkBehaviour)__instance).IsOwner && __instance.isPlayerControlled && !((Object)(object)StartOfRound.Instance == (Object)null)) { _ = StartOfRound.Instance.inShipPhase; } } private static void CleanupUV(PlayerControllerB player) { RadioactiveSunlightComponent component = ((Component)player).gameObject.GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } } [HarmonyPatch(typeof(PlayerControllerB), "KillPlayer")] [HarmonyPostfix] private static void KillPlayerPostfix(PlayerControllerB __instance) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)StartOfRound.Instance != (Object)null && ((NetworkBehaviour)StartOfRound.Instance).IsServer && TerminalPatch.IsModifierActive("Paranormal Activity")) { SpawnGhostGirl(((Component)__instance).transform.position); } } [HarmonyPatch(typeof(TimeOfDay), "Update")] [HarmonyPostfix] private static void TimeOfDayModUpdate(TimeOfDay __instance) { if ((Object)(object)StartOfRound.Instance == (Object)null) { return; } bool isServer = ((NetworkBehaviour)StartOfRound.Instance).IsServer; float num = __instance.normalizedTimeOfDay * (60f * (float)__instance.numberOfHours) + 360f; int num2 = (int)(num / 60f); if (!StartOfRound.Instance.inShipPhase) { statesNeedReset = true; } else if (statesNeedReset) { ResetAllStates(); statesNeedReset = false; return; } if (StartOfRound.Instance.inShipPhase) { return; } if (isServer && num >= 485f && num < 490f && !sentExpressEntryMessage) { sentExpressEntryMessage = true; BMO_Networking.RefreshActiveModifierFlags(); if (SyncManager.IsExpressEntryActive) { BMO_Networking.ForceExpressEntry.SendClients(true); } } if (TerminalPatch.IsModifierActive("New Hire") && !spawnedNewHireEvent && num >= SyncManager.GetNewHireSpawnTime() * 60f) { spawnedNewHireEvent = true; TriggerNewHireDropship(); BMO_Networking.SendTip("EMPLOYEE ORIENTATION", "New employee en route. Please rendezvous and assist in on site orientation.", isPositive: false); } if (TerminalPatch.IsModifierActive("Weapon Delivery") && !spawnedWeaponDelivery && num2 >= 8) { spawnedWeaponDelivery = true; TriggerWeaponDelivery(); BMO_Networking.SendTip("WEAPON DROP", "Look down. Pick it up.", isPositive: true); } if (TerminalPatch.IsModifierActive("Guard Dog") && !spawnedWatchDogNoon && num2 >= 12 && isServer && num >= SyncManager.GetWatchDogWakeTime() * 60f) { spawnedWatchDogNoon = true; SpawnWatchDogDynamic(); BMO_Networking.SendTip("ACTIVE GUARD DOGS", "Guard dogs detected in area. Please avoid and do not interere with their patrol.", isPositive: false); } } private static void TriggerNewHireDropship() { Terminal val = Object.FindObjectOfType(); if (!((Object)(object)val == (Object)null)) { val.orderedItemsFromTerminal.Add(0); val.numberOfItemsInDropship++; isNewHireDropshipActive = true; if (ReflectionCache.Terminal_TriggerDropshipServerRpc != null) { ReflectionCache.Terminal_TriggerDropshipServerRpc.Invoke(val, null); } else { ReflectionCache.Terminal_shipIsComing?.SetValue(val, true); } } } private static void SpawnWatchDogDynamic() { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)RoundManager.Instance == (Object)null || (Object)(object)RoundManager.Instance.currentLevel == (Object)null) { return; } EnemyType val = CachedWatchDog; if ((Object)(object)val == (Object)null) { val = ((IEnumerable)RoundManager.Instance.currentLevel.OutsideEnemies).FirstOrDefault((Func)((SpawnableEnemyWithRarity e) => e.enemyType.enemyName.ToLower().Contains("mouthdog")))?.enemyType; } if (!((Object)(object)val != (Object)null)) { return; } GameObject[] outsideAINodes = RoundManager.Instance.outsideAINodes; if (outsideAINodes != null && outsideAINodes.Length != 0) { for (int i = 0; i < 2; i++) { GameObject val2 = outsideAINodes[Random.Range(0, outsideAINodes.Length)]; RoundManager.Instance.SpawnEnemyGameObject(val2.transform.position, 0f, -1, val); } } } private static void SpawnGhostGirl(Vector3 position) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)RoundManager.Instance == (Object)null || (Object)(object)RoundManager.Instance.currentLevel == (Object)null) { return; } EnemyType val = CachedGhostGirl; if ((Object)(object)val == (Object)null) { val = ((IEnumerable)RoundManager.Instance.currentLevel.Enemies).FirstOrDefault((Func)((SpawnableEnemyWithRarity e) => (Object)(object)e.enemyType != (Object)null && e.enemyType.enemyName.ToLower().Contains("girl")))?.enemyType; } if ((Object)(object)val != (Object)null) { RoundManager.Instance.SpawnEnemyGameObject(position, 0f, -1, val); } } [HarmonyPatch(typeof(StartOfRound), "Update")] [HarmonyPostfix] private static void UpdateModifierHooks(StartOfRound __instance) { if (__instance.shipHasLanded && !triggeredShipLandedModifiers) { triggeredShipLandedModifiers = true; if (!((NetworkBehaviour)__instance).IsServer) { return; } BMO_Networking.RefreshActiveModifierFlags(); if (!SyncManager.IsEquipmentCacheActive) { return; } Terminal cachedTerminal = ReflectionCache.CachedTerminal; if ((Object)(object)cachedTerminal != (Object)null && cachedTerminal.buyableItemsList != null && cachedTerminal.buyableItemsList.Length != 0) { int num = Random.Range(5, 11); var list = (from x in __instance.unlockablesList.unlockables.Select((UnlockableItem u, int i) => new { upgrade = u, index = i }) where x.upgrade != null && !x.upgrade.hasBeenUnlockedByPlayer && !x.upgrade.alreadyUnlocked && (Object)(object)x.upgrade.shopSelectionNode != (Object)null where BinaryMoons.MasterEquipmentPool.Contains(x.upgrade.unlockableName) select x).ToList(); if (list.Count > 0) { var anon = list[Random.Range(0, list.Count)]; pendingVoucherUpgradeIndex = anon.index; pendingVoucherUpgradeName = anon.upgrade.unlockableName; num--; } for (int j = 0; j < num; j++) { cachedTerminal.orderedItemsFromTerminal.Add(Random.Range(0, cachedTerminal.buyableItemsList.Length)); } ReflectionCache.Terminal_shipIsComing?.SetValue(cachedTerminal, true); waitingForDropshipArrival = true; BMO_Networking.SendTip("EQUIPMENT CACHE", "Locate dropship for additional tools and ship upgrades.", isPositive: true); } } else if (!__instance.shipHasLanded && triggeredShipLandedModifiers) { triggeredShipLandedModifiers = false; pendingVoucherUpgradeIndex = -1; pendingVoucherUpgradeName = ""; waitingForDropshipArrival = false; spawnedNewHireEvent = false; } } private static void TriggerWeaponDelivery() { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)StartOfRound.Instance == (Object)null || !((NetworkBehaviour)StartOfRound.Instance).IsServer) { return; } Item cachedKnife = ReflectionCache.CachedKnife; Item cachedShotgun = ReflectionCache.CachedShotgun; if ((Object)(object)cachedKnife == (Object)null || (Object)(object)cachedShotgun == (Object)null) { return; } PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (!((Object)(object)val == (Object)null) && val.isPlayerControlled && !val.isPlayerDead) { Item val2 = ((Random.Range(0, 2) == 0) ? cachedKnife : cachedShotgun); GameObject val3 = Object.Instantiate(val2.spawnPrefab, ((Component)val).transform.position + Vector3.up * 0.5f, Quaternion.identity); GrabbableObject component = val3.GetComponent(); if ((Object)(object)component != (Object)null) { ((NetworkBehaviour)component).NetworkObject.Spawn(false); } } } Terminal cachedTerminal = ReflectionCache.CachedTerminal; if ((Object)(object)cachedTerminal != (Object)null) { TerminalPatch.PlayBuySound(cachedTerminal); } } [HarmonyPatch(typeof(PlayerControllerB), "DamagePlayer")] [HarmonyPrefix] private static bool DamagePlayerPrefix(PlayerControllerB __instance, CauseOfDeath causeOfDeath) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)causeOfDeath == 2 && SyncManager.IsLowGravityActive) { return false; } return true; } [HarmonyPatch(typeof(StartOfRound), "ShipLeave")] [HarmonyPostfix] private static void ShipLeaveSync(StartOfRound __instance) { if (((NetworkBehaviour)__instance).IsServer) { BinaryMoons.Logger.LogInfo((object)"[BMO] Ship Leaving. Broadcasting End-of-Day Sync..."); BMO_Networking.BroadcastSync(); } } public static void QuotaVisualPatch() { if (BMO_Networking.IsInitialized) { BMO_Networking.ApplyRemoteState(force: true); } } } [HarmonyPatch] public class TerminalPatch { [CompilerGenerated] private sealed class d__48 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public int levelID; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__48(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(4.5f); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)StartOfRound.Instance != (Object)null && ((NetworkBehaviour)StartOfRound.Instance).IsServer) { Terminal cachedTerminal = ReflectionCache.CachedTerminal; int num = (((Object)(object)cachedTerminal != (Object)null) ? cachedTerminal.groupCredits : 0); StartOfRound.Instance.ChangeLevelServerRpc(levelID, num); } <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 2; return true; case 2: { <>1__state = -1; StartOfRound instance = StartOfRound.Instance; if (instance != null) { instance.SetMapScreenInfoToCurrentLevel(); } 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__29 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__29(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(2f); <>1__state = 1; return true; case 1: <>1__state = -1; UnlockAllMoons(); initializedNouns = 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(); } } private static bool initializedNouns = false; private static List selectedMoons = new List(); private static List moonsPickedThisQuota = new List(); public static Dictionary DailyModifiers = new Dictionary(); private static int lastDaysUntilDeadline = -1; private static int lastProfitQuota = -1; private static int lastTimesFulfilledQuota = -1; public static int AvailableRerolls = 1; public static int TotalRerollsUsed = 0; public static int DailyRandomOffset = 0; private static bool modifierAppliedToday = false; private static bool expressEntryAppliedToday = false; private static bool routedCompany0Day = false; public static bool HasSyncedWithHost = false; private static HashSet unlockedPlanetLogs = new HashSet(); public static string CurrentNormalizedMoonName = ""; [HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")] [HarmonyPostfix] private static void OnPlayerConnect() { if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsServer) { BinaryMoons.Logger.LogInfo((object)"[BMO] Initial Join Detected (ConnectClientToPlayerObject). Triggering Sync..."); BMO_Networking.ApplyRemoteState(); } } [HarmonyPatch(typeof(StartOfRound), "StartGame")] [HarmonyPostfix] private static void StartGamePostfix() { BMO_Networking.RefreshActiveModifierFlags(); } public static List GetSelectedMoons() { return selectedMoons; } [HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")] [HarmonyPostfix] private static void ParsePlayerSentencePostfix(Terminal __instance, ref TerminalNode __result) { string text = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded); if (text.ToLower().Contains("fixm") || text.ToLower().Contains("fixmoon") || text.ToLower().Contains("fixmoons")) { if (NetworkManager.Singleton.IsServer) { BMO_Networking.BroadcastSync(); __result = CreateTerminalNode("\n[ SYSTEM RECALIBRATION ]\n\nMoon data broadcasted to all units.\n\n"); } else { BMO_Networking.ApplyRemoteState(force: true); BMO_Networking.RequestSync(); __result = CreateTerminalNode("\n[ SYSTEM SYNCHRONIZATION ]\n\nRequesting latest orbital data from Host...\nWait 2 seconds and type 'moons' to refresh the catalogue.\n\n"); } } } [HarmonyPatch(typeof(Terminal), "BeginUsingTerminal")] [HarmonyPostfix] private static void BeginUsingTerminalPostfix() { if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsClient && !NetworkManager.Singleton.IsServer) { BMO_Networking.RequestSync(); } } private static TerminalNode CreateTerminalNode(string text) { TerminalNode val = ScriptableObject.CreateInstance(); val.displayText = text; val.clearPreviousText = true; return val; } public static bool IsModifierActive(string modName, bool allowOrbit = true) { if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)StartOfRound.Instance.currentLevel == (Object)null) { return false; } if (!StartOfRound.Instance.shipHasLanded && !allowOrbit) { return false; } CurrentNormalizedMoonName = NormalizeName(StartOfRound.Instance.currentLevel.PlanetName); if (DailyModifiers.TryGetValue(CurrentNormalizedMoonName, out var value) && value.Name.ToLower() == modName.ToLower()) { return true; } return false; } public static string NormalizeName(string name) { if (string.IsNullOrEmpty(name)) { return ""; } string input = name.ToLower(); input = Regex.Replace(input, "^\\d+\\s*", ""); int num = input.IndexOf('('); if (num != -1) { input = input.Substring(0, num).Trim(); } return input.Replace(" ", "").Trim(); } private static void InitializeEnemyCache() { if (ReflectionCache.CachedEnemies != null) { EnemyType[] cachedEnemies = ReflectionCache.CachedEnemies; ModifierLogicPatch.CachedGhostGirl = ((IEnumerable)cachedEnemies).FirstOrDefault((Func)((EnemyType e) => (Object)(object)e != (Object)null && e.enemyName.ToLower().Contains("girl"))); ModifierLogicPatch.CachedWatchDog = ((IEnumerable)cachedEnemies).FirstOrDefault((Func)((EnemyType e) => (Object)(object)e != (Object)null && e.enemyName.ToLower().Contains("mouthdog"))); ModifierLogicPatch.CachedMasked = ((IEnumerable)cachedEnemies).FirstOrDefault((Func)((EnemyType e) => (Object)(object)e != (Object)null && e.enemyName.ToLower().Contains("masked"))); } } public static List GetAvailableModifiers() { List list = new List(); if (BinaryMoons.EnableLowGravity.Value) { list.Add(new MoonModifier { Name = "Low Gravity", IsPositive = true }); } if (BinaryMoons.EnableOxygenRich.Value) { list.Add(new MoonModifier { Name = "Oxygen Rich", IsPositive = true }); } if (BinaryMoons.EnableEquipmentCache.Value) { list.Add(new MoonModifier { Name = "Equipment Cache", IsPositive = true }); } if (BinaryMoons.EnableExpressEntry.Value) { list.Add(new MoonModifier { Name = "Express Entry", IsPositive = true }); } if (BinaryMoons.EnableGroovy.Value) { list.Add(new MoonModifier { Name = "Groovy", IsPositive = true }); } if (BinaryMoons.EnableWatchDog.Value) { list.Add(new MoonModifier { Name = "Guard Dog", IsPositive = false }); } if (BinaryMoons.EnableRadioactiveSunlight.Value) { list.Add(new MoonModifier { Name = "High UV", IsPositive = false }); } if (BinaryMoons.EnableHaunted.Value) { list.Add(new MoonModifier { Name = "Paranormal Activity", IsPositive = false }); } if (BinaryMoons.EnableToxicAtmosphere.Value) { list.Add(new MoonModifier { Name = "Toxic Atmosphere", IsPositive = false }); } if (BinaryMoons.EnableNewHire.Value) { list.Add(new MoonModifier { Name = "New Hire", IsPositive = false }); } if (BinaryMoons.EnableWeaponDelivery.Value) { list.Add(new MoonModifier { Name = "Weapon Delivery", IsPositive = true }); } if (list.Count == 0) { list.Add(new MoonModifier { Name = "Unknown", IsPositive = true, ValueAmount = 0 }); } return list; } [HarmonyPatch(typeof(GameNetworkManager), "SaveGameValues")] [HarmonyPostfix] private static void SaveGameValues(GameNetworkManager __instance) { if (__instance.isHostingGame) { PlayerPrefs.SetInt(__instance.currentSaveFileName + "_LMRerolls", AvailableRerolls); PlayerPrefs.SetInt(__instance.currentSaveFileName + "_LMTotalRerolls", TotalRerollsUsed); PlayerPrefs.Save(); } } [HarmonyPatch(typeof(StartOfRound), "Start")] [HarmonyPostfix] private static void StartOfRoundStart(StartOfRound __instance) { lastDaysUntilDeadline = -1; lastProfitQuota = -1; lastTimesFulfilledQuota = -1; moonsPickedThisQuota.Clear(); selectedMoons.Clear(); DailyModifiers.Clear(); ModifierLogicPatch.ResetAllStates(); if (!NetworkManager.Singleton.IsServer) { Terminal val = Object.FindObjectOfType(); if ((Object)(object)val != (Object)null && val.moonsCatalogueList != null) { SelectableLevel val2 = ((IEnumerable)val.moonsCatalogueList).FirstOrDefault((Func)((SelectableLevel m) => NormalizeName(m.PlanetName).Contains("experimentation"))); SelectableLevel val3 = ((IEnumerable)val.moonsCatalogueList).FirstOrDefault((Func)((SelectableLevel m) => NormalizeName(m.PlanetName).Contains("assurance"))); if ((Object)(object)val2 != (Object)null) { selectedMoons.Add(val2); } if ((Object)(object)val3 != (Object)null) { selectedMoons.Add(val3); } BinaryMoons.Logger.LogInfo((object)"[BMO] Client: Initialized with Vanilla Fallback (Experimentation/Assurance)."); } return; } DailyRandomOffset = Random.Range(100, 999999); if ((Object)(object)GameNetworkManager.Instance != (Object)null && !string.IsNullOrEmpty(GameNetworkManager.Instance.currentSaveFileName)) { string currentSaveFileName = GameNetworkManager.Instance.currentSaveFileName; if (__instance.gameStats.daysSpent == 0) { AvailableRerolls = BinaryMoons.StartingRerolls.Value; TotalRerollsUsed = 0; PlayerPrefs.SetInt(currentSaveFileName + "_LMRerolls", AvailableRerolls); PlayerPrefs.SetInt(currentSaveFileName + "_LMTotalRerolls", TotalRerollsUsed); PlayerPrefs.Save(); } else { AvailableRerolls = PlayerPrefs.GetInt(currentSaveFileName + "_LMRerolls", BinaryMoons.StartingRerolls.Value); TotalRerollsUsed = PlayerPrefs.GetInt(currentSaveFileName + "_LMTotalRerolls", 0); } } BroadcastAbsoluteStateNative(); } [HarmonyPatch(typeof(Terminal), "Start")] [HarmonyPostfix] private static void TerminalStartPostfix(Terminal __instance) { ReflectionCache.InitializeAssets(__instance); InitializeEnemyCache(); if (!initializedNouns) { ((MonoBehaviour)__instance).StartCoroutine(DelayedInitialUnlock()); } if ((Object)(object)StartOfRound.Instance != (Object)null) { _ = NetworkManager.Singleton.IsServer; } RandomizeMoons(__instance); } [IteratorStateMachine(typeof(d__29))] private static IEnumerator DelayedInitialUnlock() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__29(0); } [HarmonyPatch(typeof(Terminal), "BeginUsingTerminal")] [HarmonyPostfix] private static void BeginUsingTerminalPostfix(Terminal __instance) { UnlockAllMoons(); if ((Object)(object)NetworkManager.Singleton != (Object)null && !NetworkManager.Singleton.IsServer) { if (selectedMoons == null || selectedMoons.Count == 0) { BinaryMoons.Logger.LogInfo((object)"[BMO] Terminal moon list empty on client. Requesting state from Host..."); BMO_Networking.RequestSync(); } else { BMO_Networking.ApplyRemoteState(); } } } public static void UnlockAllMoons() { Terminal val = Object.FindObjectOfType(); if ((Object)(object)val == (Object)null || val.moonsCatalogueList == null) { return; } SelectableLevel[] moonsCatalogueList = val.moonsCatalogueList; foreach (SelectableLevel val2 in moonsCatalogueList) { if (!((Object)(object)val2 == (Object)null)) { try { typeof(SelectableLevel).GetField("itemCost", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(val2, 0); } catch { } } } TerminalNode[] array = Resources.FindObjectsOfTypeAll(); TerminalNode[] array2 = array; foreach (TerminalNode val3 in array2) { if ((Object)(object)val3 == (Object)null || (val3.buyRerouteToMoon == -1 && (((Object)val3).name == null || !((Object)val3).name.ToLower().Contains("route")))) { continue; } UnlockNode(val3); if (val3.terminalOptions == null) { continue; } CompatibleNoun[] terminalOptions = val3.terminalOptions; foreach (CompatibleNoun val4 in terminalOptions) { if ((Object)(object)val4.result != (Object)null) { UnlockNode(val4.result); } } } } private static void UnlockNode(TerminalNode node) { if (!((Object)(object)node == (Object)null)) { if (node.buyRerouteToMoon != -1 || (((Object)node).name != null && ((Object)node).name.ToLower().Contains("route"))) { node.itemCost = 0; } typeof(TerminalNode).GetField("isLocked", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(node, false); } } [HarmonyPatch(typeof(TimeOfDay), "Update")] [HarmonyPostfix] private static void TimeOfDayUpdate(TimeOfDay __instance) { bool flag = false; if (__instance.profitQuota != lastProfitQuota || __instance.timesFulfilledQuota != lastTimesFulfilledQuota) { bool flag2 = lastTimesFulfilledQuota != -1 && __instance.timesFulfilledQuota > lastTimesFulfilledQuota; lastProfitQuota = __instance.profitQuota; lastTimesFulfilledQuota = __instance.timesFulfilledQuota; moonsPickedThisQuota.Clear(); flag = true; if (flag2 && (Object)(object)StartOfRound.Instance != (Object)null && ((NetworkBehaviour)StartOfRound.Instance).IsServer) { AvailableRerolls++; HUDManager instance = HUDManager.Instance; if (instance != null) { instance.DisplayTip("QUOTA REWARD", "You've earned 1 extra moon REROLL!", false, false, "LC_Tip1"); } } } if (__instance.daysUntilDeadline != lastDaysUntilDeadline) { lastDaysUntilDeadline = __instance.daysUntilDeadline; flag = true; modifierAppliedToday = false; if ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.gameStats.daysSpent == 0 && ((NetworkBehaviour)StartOfRound.Instance).IsServer && AvailableRerolls != BinaryMoons.StartingRerolls.Value) { AvailableRerolls = BinaryMoons.StartingRerolls.Value; TotalRerollsUsed = 0; } } if (flag) { Terminal cachedTerminal = ReflectionCache.CachedTerminal; if ((Object)(object)cachedTerminal != (Object)null) { RandomizeMoons(cachedTerminal); } } if ((Object)(object)StartOfRound.Instance != (Object)null && !StartOfRound.Instance.shipHasLanded) { modifierAppliedToday = false; expressEntryAppliedToday = false; } if ((Object)(object)StartOfRound.Instance == (Object)null || !StartOfRound.Instance.shipHasLanded) { return; } float num = __instance.normalizedTimeOfDay * (60f * (float)__instance.numberOfHours) + 360f; int num2 = (int)(num / 60f); int num3 = (int)(num % 60f); if (!expressEntryAppliedToday && num2 >= 8 && SyncManager.IsExpressEntryActive && ((NetworkBehaviour)StartOfRound.Instance).IsServer) { expressEntryAppliedToday = true; BMO_Networking.ForceExpressEntry.SendClients(true); HUDManager instance2 = HUDManager.Instance; if (instance2 != null) { instance2.AddTextToChatOnServer("EXPRESS ENTRY: Crew deployed directly to facility entrance.", -1); } BMO_Networking.SendTip("EXPRESS ENTRY", "Crew relocated to the main entrance.", isPositive: true); } if (modifierAppliedToday || (num2 <= 8 && (num2 != 8 || num3 < 5))) { return; } SelectableLevel currentLevel = StartOfRound.Instance.currentLevel; if (!((Object)(object)currentLevel != (Object)null) || !DailyModifiers.TryGetValue(NormalizeName(currentLevel.PlanetName), out var value)) { return; } modifierAppliedToday = true; if (value.Name != "Standard" && value.Name != "Unknown" && !string.IsNullOrEmpty(value.Name)) { GetImmersiveMessage(value.Name, out var header, out var body); string text = (value.IsPositive ? $"\n(Quota +${value.ValueAmount}Q)" : $"\n(Credits +${value.ValueAmount})"); if (value.Name == "Groovy") { text = $"\n(Quota +${value.ValueAmount}Q / Credits +${value.ValueAmount})"; } HUDManager instance3 = HUDManager.Instance; if (instance3 != null) { instance3.DisplayTip(header, body + text, value.IsPositive, false, "LC_Tip1"); } } if (((NetworkBehaviour)StartOfRound.Instance).IsServer) { Terminal cachedTerminal2 = ReflectionCache.CachedTerminal; PlayBuySound(cachedTerminal2); if (value.Name == "Groovy") { ApplyQuotaPenalty(__instance, value, showTip: false); ApplyCreditBonus(value, showTip: false); ApplyGroovyLootBuff(); } else { ApplyQuotaModifier(__instance, value); } } } [HarmonyPatch(typeof(RoundManager), "FinishGeneratingLevel")] [HarmonyPostfix] private static void OnLevelGeneratedPostfix() { if (SyncManager.IsGroovyActive) { BinaryMoons.Logger.LogInfo((object)"[LM] Level Generated! This is a Groovy moon! Initiating global party scan."); ApplyGroovyScrapEffects(); } } public static void ApplyGroovyScrapEffects() { List list = (from g in Object.FindObjectsOfType() where (Object)(object)g.itemProperties != (Object)null && g.itemProperties.isScrap select g).ToList(); BinaryMoons.Logger.LogInfo((object)$"[LM] Groovy Scan: Found {list.Count} pieces of scrap."); int num = 0; foreach (GrabbableObject item in list) { if ((Object)(object)((Component)item).gameObject.GetComponent() == (Object)null) { ((Component)item).gameObject.AddComponent(); num++; } } BinaryMoons.Logger.LogInfo((object)$"[LM] Groovy Scan Complete: {num} new disco souls joined the party."); } private static void ApplyGroovyLootBuff() { float groovyLootMultiplier = SyncManager.GetGroovyLootMultiplier(); List list = (from g in Object.FindObjectsOfType() where (Object)(object)g.itemProperties != (Object)null && g.itemProperties.isScrap select g).ToList(); foreach (GrabbableObject item in list) { item.SetScrapValue((int)((float)item.scrapValue * groovyLootMultiplier)); } BinaryMoons.Logger.LogInfo((object)$"[LM] Groovy Moon (Server): Multiplied {list.Count} items by {groovyLootMultiplier}."); ApplyGroovyScrapEffects(); } private static void ApplyQuotaModifier(TimeOfDay tod, MoonModifier mod) { if (mod.IsPositive) { ApplyQuotaPenalty(tod, mod, showTip: false); } else { ApplyCreditBonus(mod, showTip: false); } } [HarmonyPatch(typeof(GrabbableObject), "Start")] [HarmonyPostfix] private static void GrabbableStartPostfix(GrabbableObject __instance) { if (SyncManager.IsGroovyActive && (Object)(object)__instance.itemProperties != (Object)null && __instance.itemProperties.isScrap && (Object)(object)((Component)__instance).gameObject.GetComponent() == (Object)null) { ((Component)__instance).gameObject.AddComponent(); } } private static void ApplyQuotaPenalty(TimeOfDay tod, MoonModifier mod, bool showTip) { tod.profitQuota += mod.ValueAmount; lastProfitQuota = tod.profitQuota; if (ReflectionCache.TimeOfDay_SyncStats_ClientRpc != null) { ReflectionCache.TimeOfDay_SyncStats_ClientRpc.Invoke(tod, new object[4] { tod.profitQuota, tod.quotaFulfilled, tod.timesFulfilledQuota, tod.daysUntilDeadline }); } BMO_Networking.SyncQuotaHUD(); if (((NetworkBehaviour)StartOfRound.Instance).IsServer) { BMO_Networking.BroadcastSync(); } if (showTip && mod.Name != "Standard" && mod.Name != "Unknown" && !string.IsNullOrEmpty(mod.Name)) { GetImmersiveMessage(mod.Name, out var header, out var body); HUDManager instance = HUDManager.Instance; if (instance != null) { instance.DisplayTip(header, $"{body}\n(Quota +${mod.ValueAmount})", true, false, "LC_Tip1"); } } } private static void ApplyCreditBonus(MoonModifier mod, bool showTip) { Terminal cachedTerminal = ReflectionCache.CachedTerminal; if ((Object)(object)cachedTerminal == (Object)null) { return; } cachedTerminal.groupCredits += mod.ValueAmount; cachedTerminal.SyncGroupCreditsServerRpc(cachedTerminal.groupCredits, cachedTerminal.numberOfItemsInDropship); if (showTip && mod.Name != "Standard" && mod.Name != "Unknown" && !string.IsNullOrEmpty(mod.Name)) { GetImmersiveMessage(mod.Name, out var header, out var body); HUDManager instance = HUDManager.Instance; if (instance != null) { instance.DisplayTip(header, $"{body}\n(Credits +${mod.ValueAmount})", false, false, "LC_Tip1"); } } } private static void GetImmersiveMessage(string modName, out string header, out string body) { header = "MODIFIER ACTIVE"; body = modName + " is currently affecting the moon."; if (modName == null) { return; } switch (modName.Length) { case 11: switch (modName[0]) { case 'L': if (modName == "Low Gravity") { header = "LOW GRAVITY"; body = "Gravitational limitations mitigated; quota adjusted accordingly."; } break; case 'O': if (modName == "Oxygen Rich") { header = "OXYGEN RICH"; body = "Recovery thresholds recalibrated for increased productivity."; } break; } break; case 15: switch (modName[0]) { case 'E': if (modName == "Equipment Cache") { header = "EQUIPMENT CACHE"; body = "Locate dropship for additional tools and ship upgrades."; } break; case 'W': if (modName == "Weapon Delivery") { header = "WEAPON DROP"; body = "Look down. Pick it up."; } break; } break; case 9: if (modName == "Guard Dog") { header = "ACTIVE GUARD DOGS"; body = "Guard dogs detected in area. Please avoid and do not interere with their patrol."; } break; case 16: if (modName == "Toxic Atmosphere") { header = "TOXIC ATMOSPHERE"; body = "Toxic gases detected. Involuntary motor disruption and hallucinations possible. Inhalors recommended."; } break; case 7: if (modName == "High UV") { header = "UV RADIATION WARNING"; body = "UV exposure may result in dermal compromise. Seek shelter and avoid prolonged exposure during daylight hours."; } break; case 19: if (modName == "Paranormal Activity") { header = "PARANORMAL ACTIVITY DETECTED"; body = "Error: Unidentified UNKNOWABLE U\u0335\u035d\u0346\u0344\u031b\u031f\u0359\u0355N\u0335\u035d\u034b\u0312\u0320K\u0338\u0313\u0341\u0357\u0360\u032d\u033aI\u0337\u033e\u035d\u0300\u0320\u032e\u0319\u0333L\u0334\u033e\u0360\u0312\u0330L\u0334\u0341\u033f\u031a\u0343\u0316A\u0334\u035d\u0309\u035c\u0323B\u0336\u030b\u0309\u030a\u0352\u0326L\u0337\u0306\u035d\u0310\u035d\u0324E\u0338\u034b\u034b\u0342\u0315\u035c."; } break; case 13: if (modName == "Express Entry") { header = "Rapid Deployment Initiated"; body = "Crew deployed directly to facility."; } break; case 8: if (modName == "New Hire") { header = "EMPLOYEE ORIENTATION"; body = "New employee en route. Please rendezvous and assist in on site orientation."; } break; case 6: if (modName == "Groovy") { header = "GROOVY MOON"; body = "Rare cosmic frequencies detected! Scrap may contain enhanced value."; } break; case 10: case 12: case 14: case 17: case 18: break; } } public static void PlayBuySound(Terminal terminal) { if (!((Object)(object)terminal == (Object)null) && ReflectionCache.Terminal_buyItemSFX != null) { object? value = ReflectionCache.Terminal_buyItemSFX.GetValue(terminal); AudioClip val = (AudioClip)((value is AudioClip) ? value : null); if ((Object)(object)val != (Object)null && (Object)(object)terminal.terminalAudio != (Object)null) { terminal.terminalAudio.PlayOneShot(val); } } } [HarmonyPatch(typeof(StartOfRound), "Update")] [HarmonyPostfix] private static void SorUpdateOrbitCompany(StartOfRound __instance) { if (!((NetworkBehaviour)__instance).IsServer || (Object)(object)TimeOfDay.Instance == (Object)null) { return; } if (TimeOfDay.Instance.daysUntilDeadline <= 0) { if (__instance.inShipPhase && !__instance.travellingToNewLevel && !routedCompany0Day && (Object)(object)__instance.currentLevel != (Object)null && !__instance.currentLevel.PlanetName.ToLower().Contains("gordion") && !__instance.currentLevel.PlanetName.ToLower().Contains("company")) { Terminal cachedTerminal = ReflectionCache.CachedTerminal; SelectableLevel val = ((IEnumerable)cachedTerminal?.moonsCatalogueList).FirstOrDefault((Func)((SelectableLevel m) => m.PlanetName.ToLower().Contains("company") || m.PlanetName.ToLower().Contains("gordion"))); if ((Object)(object)val != (Object)null && (Object)(object)cachedTerminal != (Object)null) { routedCompany0Day = true; __instance.ChangeLevelServerRpc(val.levelID, cachedTerminal.groupCredits); __instance.SetMapScreenInfoToCurrentLevel(); } } } else { routedCompany0Day = false; } } public static void RandomizeMoons(Terminal terminal) { if (!((NetworkBehaviour)StartOfRound.Instance).IsServer) { return; } UnlockAllMoons(); int num = DailyRandomOffset + (StartOfRound.Instance?.randomMapSeed ?? 0); TimeOfDay instance = TimeOfDay.Instance; int seed = num + ((instance != null) ? (instance.daysUntilDeadline * 100) : 0) + TotalRerollsUsed; Random random = new Random(seed); List list = new List(); if (BinaryMoons.EnableOxygenRich.Value) { list.Add(new MoonModifier { Name = "Oxygen Rich", IsPositive = true, ValueAmount = random.Next(SyncManager.GetQuotaPenaltyMin(), SyncManager.GetQuotaPenaltyMax() + 1) }); } if (BinaryMoons.EnableLowGravity.Value) { list.Add(new MoonModifier { Name = "Low Gravity", IsPositive = true, ValueAmount = random.Next(SyncManager.GetQuotaPenaltyMin(), SyncManager.GetQuotaPenaltyMax() + 1) }); } if (BinaryMoons.EnableEquipmentCache.Value) { list.Add(new MoonModifier { Name = "Equipment Cache", IsPositive = true, ValueAmount = random.Next(SyncManager.GetQuotaPenaltyMin(), SyncManager.GetQuotaPenaltyMax() + 1) }); } if (BinaryMoons.EnableExpressEntry.Value) { list.Add(new MoonModifier { Name = "Express Entry", IsPositive = true, ValueAmount = random.Next(SyncManager.GetQuotaPenaltyMin(), SyncManager.GetQuotaPenaltyMax() + 1) }); } if (BinaryMoons.EnableWatchDog.Value) { list.Add(new MoonModifier { Name = "Guard Dog", IsPositive = false, ValueAmount = random.Next(SyncManager.GetBonusPayMin(), SyncManager.GetBonusPayMax() + 1) }); } if (BinaryMoons.EnableRadioactiveSunlight.Value) { list.Add(new MoonModifier { Name = "High UV", IsPositive = false, ValueAmount = random.Next(SyncManager.GetBonusPayMin(), SyncManager.GetBonusPayMax() + 1) }); } if (BinaryMoons.EnableHaunted.Value) { list.Add(new MoonModifier { Name = "Paranormal Activity", IsPositive = false, ValueAmount = random.Next(SyncManager.GetBonusPayMin(), SyncManager.GetBonusPayMax() + 1) }); } if (BinaryMoons.EnableToxicAtmosphere.Value) { list.Add(new MoonModifier { Name = "Toxic Atmosphere", IsPositive = false, ValueAmount = random.Next(SyncManager.GetBonusPayMin(), SyncManager.GetBonusPayMax() + 1) }); } if (BinaryMoons.EnableNewHire.Value) { list.Add(new MoonModifier { Name = "New Hire", IsPositive = false, ValueAmount = random.Next(SyncManager.GetBonusPayMin(), SyncManager.GetBonusPayMax() + 1) }); } if (BinaryMoons.EnableWeaponDelivery.Value) { list.Add(new MoonModifier { Name = "Weapon Delivery", IsPositive = true, ValueAmount = random.Next(SyncManager.GetQuotaPenaltyMin(), SyncManager.GetQuotaPenaltyMax() + 1) }); } if (BinaryMoons.EnableGroovy.Value) { list.Add(new MoonModifier { Name = "Groovy", IsPositive = true, ValueAmount = random.Next(SyncManager.GetQuotaPenaltyMin(), SyncManager.GetQuotaPenaltyMax() + 1) }); } if (BinaryMoons.EnableStandardMoons.Value) { list.Add(new MoonModifier { Name = "Standard", IsPositive = true, ValueAmount = 0 }); } List list2 = terminal.moonsCatalogueList.Where((SelectableLevel m) => !(from s in BinaryMoons.BlacklistedMoons.Value.ToLower().Split(',') select s.Trim()).Contains(NormalizeName(m.PlanetName).ToLower())).ToList(); List list3 = list2.Where((SelectableLevel m) => !moonsPickedThisQuota.Contains(NormalizeName(m.PlanetName))).ToList(); if (list3.Count < 2) { moonsPickedThisQuota.Clear(); list3 = list2; } selectedMoons.Clear(); DailyModifiers.Clear(); for (int j = 0; j < 100; j++) { if (selectedMoons.Count >= 2) { break; } SelectableLevel item = list3[random.Next(list3.Count)]; if (!selectedMoons.Contains(item)) { selectedMoons.Add(item); } } foreach (SelectableLevel i in selectedMoons) { moonsPickedThisQuota.Add(NormalizeName(i.PlanetName)); DailyModifiers[NormalizeName(i.PlanetName)] = list[random.Next(list.Count)]; TerminalNode val = ((IEnumerable)terminal.terminalNodes.allKeywords).FirstOrDefault((Func)((TerminalKeyword k) => k.word == NormalizeName(i.PlanetName).ToLower()))?.specialKeywordResult; if (!((Object)(object)val != (Object)null)) { continue; } UnlockNode(val); if (val.terminalOptions == null) { continue; } CompatibleNoun[] terminalOptions = val.terminalOptions; foreach (CompatibleNoun val2 in terminalOptions) { if ((Object)(object)val2.result != (Object)null) { UnlockNode(val2.result); } } } UnlockAllMoons(); if ((Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.currentLevel != (Object)null && selectedMoons.Count > 0) { TimeOfDay instance2 = TimeOfDay.Instance; if (((instance2 != null && instance2.daysUntilDeadline > 0) || (Object)(object)TimeOfDay.Instance == (Object)null) && !selectedMoons.Contains(StartOfRound.Instance.currentLevel) && !StartOfRound.Instance.currentLevel.PlanetName.ToLower().Contains("company") && ((NetworkBehaviour)StartOfRound.Instance).IsServer) { ((MonoBehaviour)terminal).StartCoroutine(DelayedChangeLevel(selectedMoons[0].levelID)); } } if ((Object)(object)StartOfRound.Instance != (Object)null && ((NetworkBehaviour)StartOfRound.Instance).IsServer) { BroadcastAbsoluteStateNative(); } } [HarmonyPatch(typeof(HUDManager), "AddChatMessage")] [HarmonyPrefix] private static bool AddChatMessagePrefix(string chatMessage, string nameOfUserWhoTyped) { return true; } public static void BroadcastAbsoluteStateNative() { BMO_Networking.BroadcastSync(); } private static void InstantChangeLevel(int levelID) { if ((Object)(object)StartOfRound.Instance != (Object)null && ((NetworkBehaviour)StartOfRound.Instance).IsServer) { Terminal cachedTerminal = ReflectionCache.CachedTerminal; int num = (((Object)(object)cachedTerminal != (Object)null) ? cachedTerminal.groupCredits : 0); StartOfRound.Instance.ChangeLevelServerRpc(levelID, num); StartOfRound.Instance.SetMapScreenInfoToCurrentLevel(); } } [IteratorStateMachine(typeof(d__48))] private static IEnumerator DelayedChangeLevel(int levelID) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__48(0) { levelID = levelID }; } [HarmonyPriority(800)] [HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")] [HarmonyPrefix] private static bool ParsePlayerSentencePrefix(Terminal __instance, ref TerminalNode __result) { UnlockAllMoons(); if ((Object)(object)__instance.screenText == (Object)null) { return true; } string text = __instance.screenText.text.Substring(Math.Max(0, __instance.screenText.text.Length - __instance.textAdded)).ToLower().Trim(); if (string.IsNullOrEmpty(text)) { return true; } switch (text) { case "re-roll": case "reroll": case "rr": { TerminalNode val2 = ScriptableObject.CreateInstance(); val2.displayText = "\nRerolling Moons...\n\n"; val2.clearPreviousText = true; __result = val2; if (((NetworkBehaviour)StartOfRound.Instance).IsServer) { if (AvailableRerolls > 0) { AvailableRerolls--; TotalRerollsUsed++; RandomizeMoons(__instance); BroadcastAbsoluteStateNative(); } else { val2.displayText = "\nNo rerolls remaining! You earn 1 reroll at the start of each quota.\n\n"; } } else { BMO_Networking.RequestReroll(); } return false; } case "sellall": case "sell": case "sell all": if ((Object)(object)StartOfRound.Instance != (Object)null) { string text2 = StartOfRound.Instance.currentLevel.PlanetName.ToLower(); if (text2.Contains("gordion") || text2.Contains("company")) { if (NetworkManager.Singleton.IsServer) { int num = ExecuteSellAll(isServer: true); if (num > 0) { __result = CreateTerminalNode(string.Format("SHIP SCRAP LIQUIDATED. \n\nTotal: {0} credits for {1} items. \n\nThe Company appreciates your productivity.", num, "multiple")); } else { __result = CreateTerminalNode("NO SCRAP DETECTED ON SHIP."); } } else { BMO_Networking.SellRequest.SendServer(true); __result = CreateTerminalNode("\n[ TRANSACTION REQUESTED ]\n\nContacting the Company to authorize scrap transfer...\nChecking ship storage now.\n\n"); } } else { __result = CreateTerminalNode("RE ROUTE TO COMPANY BUILDING TO LIQUIDATE ASSETS."); } } return false; case "moon": case "m": case "moons": { TerminalKeyword val = ((IEnumerable)__instance.terminalNodes.allKeywords).FirstOrDefault((Func)((TerminalKeyword k) => k.word == "moons")); if ((Object)(object)val != (Object)null && (Object)(object)val.specialKeywordResult != (Object)null) { __result = val.specialKeywordResult; return false; } break; } } return true; } [HarmonyPriority(800)] [HarmonyPatch(typeof(Terminal), "LoadNewNode")] [HarmonyPrefix] private static void LoadNewNodePrefix(Terminal __instance, ref TerminalNode node) { UnlockAllMoons(); if ((Object)(object)node == (Object)null) { return; } UnlockNode(node); if (node.terminalOptions != null) { CompatibleNoun[] terminalOptions = node.terminalOptions; foreach (CompatibleNoun val in terminalOptions) { if ((Object)(object)val.result != (Object)null) { UnlockNode(val.result); } } } if (node.buyRerouteToMoon == -1 && node.displayPlanetInfo == -1) { return; } int rID = node.buyRerouteToMoon; int iID = node.displayPlanetInfo; SelectableLevel targetLevel = ((IEnumerable)__instance.moonsCatalogueList).FirstOrDefault((Func)((SelectableLevel m) => m.levelID == rID || m.levelID == iID)); if (!((Object)(object)targetLevel != (Object)null)) { return; } bool flag = selectedMoons.Any((SelectableLevel m) => m.levelID == targetLevel.levelID) || selectedMoons.Any((SelectableLevel m) => NormalizeName(m.PlanetName) == NormalizeName(targetLevel.PlanetName)); string text = NormalizeName(targetLevel.PlanetName).ToLower(); bool flag2 = text.Contains("gordion") || text.Contains("company"); if (flag || flag2) { return; } if (BinaryMoons.EnableLogSpam.Value) { BinaryMoons.Logger.LogInfo((object)("[LM] Gatekeeper: Blocking " + targetLevel.PlanetName + " (Not in daily selection)")); } TerminalNode val2 = ScriptableObject.CreateInstance(); val2.displayText = "\n[ ACCESS DENIED ]\n\nThis celestial body is currently outside the authorized routing protocols for this quota.\n\nAvailable Destinations:\n"; foreach (SelectableLevel selectedMoon in selectedMoons) { val2.displayText = val2.displayText + "* " + NormalizeName(selectedMoon.PlanetName) + "\n"; } val2.displayText += "\n\n"; val2.clearPreviousText = true; node = val2; } [HarmonyPatch(typeof(Terminal), "TextPostProcess")] [HarmonyPostfix] private static void TextPostProcessPostfix(ref string __result, TerminalNode node) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Invalid comparison between Unknown and I4 //IL_008b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)node == (Object)null || ((Object)node).name != "MoonsCatalogue") { return; } string text = "\n\nWelcome to the exomoons catalogue.\nTo route the autopilot to a moon, use the word ROUTE.\nTo learn about any moon, use the word INFO.\n\n* The Company building // Buying at [companyBuyingRate].\n\nAvailable moons:\n"; if (selectedMoons.Count == 0 && !((NetworkBehaviour)StartOfRound.Instance).IsServer && !HasSyncedWithHost) { text += "\n\nSYNCING DATA FROM HOST...\n(Please wait a moment and type 'moons' again)\n\n"; __result = text; return; } foreach (SelectableLevel selectedMoon in selectedMoons) { string key = NormalizeName(selectedMoon.PlanetName); string text2 = (((int)selectedMoon.currentWeather != -1) ? $" ({selectedMoon.currentWeather})" : ""); string text3 = ""; if (DailyModifiers.TryGetValue(key, out var value)) { if (value.Name == "Groovy") { string text4 = "Groovy"; text3 = string.Format(" ({0}: +${2}Q / +${4})", text4, "#FF0000", value.ValueAmount, "#00FF00", value.ValueAmount); } else { text3 = ((!(value.Name != "Standard")) ? "" : (value.IsPositive ? string.Format(" ({0}: +${2}Q)", value.Name, "#FF0000", value.ValueAmount) : string.Format(" ({1}: +${3})", "#FF0000", value.Name, "#00FF00", value.ValueAmount))); } } text = text + "* " + selectedMoon.PlanetName + "" + text2 + text3 + "\n"; } text += $"\n\nYou have {AvailableRerolls} moon REROLL remaining.\nUse RE-ROLL to refresh the choices!\nType FIXMOON if your moon list does not match the host's.\n\n"; if ((Object)(object)StartOfRound.Instance != (Object)null) { text = text.Replace("[companyBuyingRate]", Mathf.RoundToInt(StartOfRound.Instance.companyBuyingRate * 100f) + "%"); } __result = text; } [HarmonyPatch(typeof(PlayerControllerB), "Update")] [HarmonyPrefix] private static void PlayerUpdateSpeedPrefix(PlayerControllerB __instance) { if ((Object)(object)((Component)__instance).GetComponent() != (Object)null) { __instance.movementSpeed /= SyncManager.GetGroovySpeedMultiplier(); } } [HarmonyPatch(typeof(PlayerControllerB), "Update")] [HarmonyPostfix] private static void PlayerUpdateSpeedPostfix(PlayerControllerB __instance) { bool flag = IsModifierActive("Groovy"); GroovySpeedTracker component = ((Component)__instance).GetComponent(); if (flag && __instance.isPlayerControlled && !__instance.inTerminalMenu && !__instance.isTypingChat && !__instance.quickMenuManager.isMenuOpen) { if ((Object)(object)component == (Object)null) { ((Component)__instance).gameObject.AddComponent(); } __instance.movementSpeed *= SyncManager.GetGroovySpeedMultiplier(); } else if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } } public static int ExecuteSellAll(bool isServer) { if (!isServer || (Object)(object)StartOfRound.Instance == (Object)null) { return 0; } GrabbableObject[] array = Object.FindObjectsOfType(); int num = 0; int num2 = 0; GrabbableObject[] array2 = array; foreach (GrabbableObject val in array2) { if ((Object)(object)val.itemProperties != (Object)null && val.itemProperties.isScrap && !val.isHeld && val.isInShipRoom && !val.isPocketed && val.scrapValue > 1) { num += val.scrapValue; num2++; NetworkObject component = ((Component)val).gameObject.GetComponent(); if (component != null) { component.Despawn(true); } } } if (num2 > 0) { Terminal cachedTerminal = ReflectionCache.CachedTerminal; if ((Object)(object)cachedTerminal != (Object)null) { cachedTerminal.groupCredits += num; cachedTerminal.SyncGroupCreditsServerRpc(cachedTerminal.groupCredits, cachedTerminal.numberOfItemsInDropship); } if ((Object)(object)TimeOfDay.Instance != (Object)null) { TimeOfDay instance = TimeOfDay.Instance; instance.quotaFulfilled += num; if (ReflectionCache.TimeOfDay_SyncStats_ClientRpc != null) { ReflectionCache.TimeOfDay_SyncStats_ClientRpc.Invoke(TimeOfDay.Instance, new object[4] { TimeOfDay.Instance.profitQuota, TimeOfDay.Instance.quotaFulfilled, TimeOfDay.Instance.timesFulfilledQuota, TimeOfDay.Instance.daysUntilDeadline }); } } BMO_Networking.BroadcastSync(); BinaryMoons.Logger.LogInfo((object)$"[BMO] Server: Sold {num2} items for ${num}. Quota updated."); } return num; } public static void ApplyLLLHijack(Harmony harmony) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown try { if (!AppDomain.CurrentDomain.GetAssemblies().Any((Assembly a) => a.GetName().Name == "LethalLevelLoader")) { return; } Type type = AccessTools.TypeByName("LethalLevelLoader.ExtendedLevel"); if (!(type != null)) { return; } string[] array = new string[3] { "IsLocked", "IsRouteLocked", "IsRouteHidden" }; string[] array2 = array; foreach (string text in array2) { MethodInfo methodInfo = AccessTools.PropertyGetter(type, text); if (methodInfo != null) { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(TerminalPatch), "LLLBoolGetterPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } MethodInfo methodInfo2 = AccessTools.PropertyGetter(type, "RoutePrice"); if (methodInfo2 != null) { harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(TerminalPatch), "LLLIntGetterPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } BinaryMoons.Logger.LogInfo((object)"[LM] Successfully hijacked LethalLevelLoader.ExtendedLevel property getters (Absolute Global Unlock)"); } catch (Exception ex) { BinaryMoons.Logger.LogWarning((object)("Failed to ApplyLLLHijack: " + ex.Message)); } } private static void LLLBoolGetterPostfix(ref bool __result) { __result = false; } private static void LLLIntGetterPostfix(ref int __result) { __result = 0; } } } namespace BinaryMoonsOverhaul.Models { public class MoonModifier { public string Name; public bool IsPositive; public int ValueAmount; } } namespace BinaryMoonsOverhaul.Components { public class BMO_PlayerModifierManager : MonoBehaviour { [CompilerGenerated] private sealed class d__18 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public BMO_PlayerModifierManager <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__18(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; BMO_PlayerModifierManager bMO_PlayerModifierManager = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(2f); <>1__state = 1; return true; case 1: { <>1__state = -1; EntranceTeleport[] array = Object.FindObjectsOfType(); EntranceTeleport val = array?.FirstOrDefault((Func)((EntranceTeleport e) => (Object)(object)e != (Object)null && e.entranceId == 0 && e.isEntranceToBuilding)); if ((Object)(object)val == (Object)null) { val = array?.FirstOrDefault((Func)((EntranceTeleport e) => (Object)(object)e != (Object)null && e.isEntranceToBuilding)); } if ((Object)(object)val == (Object)null) { val = array?.FirstOrDefault(); } if ((Object)(object)val != (Object)null) { bMO_PlayerModifierManager.player.TeleportPlayer(val.entrancePoint.position + Vector3.up * 0.2f, false, 0f, false, true); BinaryMoons.Logger.LogInfo((object)("[BMO] Express Entry: Local player " + bMO_PlayerModifierManager.player.playerUsername + " moved to entrance point " + ((Object)val).name + ".")); HUDManager instance = HUDManager.Instance; if (instance != null) { instance.DisplayTip("EXPRESS ENTRY", "Crew relocated to the main entrance.", false, false, "LC_Tip1"); } if (((NetworkBehaviour)StartOfRound.Instance).IsServer) { HUDManager instance2 = HUDManager.Instance; if (instance2 != null) { instance2.AddTextToChatOnServer("EXPRESS ENTRY: Crew deployed directly to facility entrance.", -1); } } } else { BinaryMoons.Logger.LogWarning((object)"[BMO] Express Entry: FAILED - No entrance triggers found in scene!"); } 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(); } } private PlayerControllerB player; private float hauntedFearTimer; private float hauntedFearInterval = 15f; private float hauntedMessageTimer; private float hauntedMessageInterval = 45f; private float tzpImmunityTimer; private float tzpHoldTimer; private float lastDrunkness; private bool wasJumping; private bool expressEntryAppliedToday; private void Awake() { player = ((Component)this).GetComponent(); hauntedFearInterval = Random.Range(10f, 25f); hauntedMessageInterval = Random.Range(30f, 60f); } private void OnEnable() { BMO_Networking.OnExpressEntryTriggered = (Action)Delegate.Combine(BMO_Networking.OnExpressEntryTriggered, new Action(TriggerExpressEntry)); BMO_Networking.OnStateChanged = (Action)Delegate.Combine(BMO_Networking.OnStateChanged, new Action(ApplySettingsReactive)); } private void OnDisable() { BMO_Networking.OnExpressEntryTriggered = (Action)Delegate.Remove(BMO_Networking.OnExpressEntryTriggered, new Action(TriggerExpressEntry)); BMO_Networking.OnStateChanged = (Action)Delegate.Remove(BMO_Networking.OnStateChanged, new Action(ApplySettingsReactive)); } private void ApplySettingsReactive(int mask) { if (!((Object)(object)player == (Object)null)) { if (SyncManager.IsActive(mask, 0)) { player.jumpForce = SyncManager.GetLowGravityStrength(); } else { player.jumpForce = 13f; } } } private void TriggerExpressEntry() { if (!((Object)(object)player == (Object)null) && ((NetworkBehaviour)player).IsOwner && player.isPlayerControlled && !expressEntryAppliedToday) { expressEntryAppliedToday = true; ((MonoBehaviour)this).StartCoroutine(DelayedExpressEntry()); } } public void ResetLocalTimers() { hauntedFearTimer = 0f; hauntedMessageTimer = 0f; tzpImmunityTimer = 0f; tzpHoldTimer = 0f; expressEntryAppliedToday = false; } private void Update() { if ((Object)(object)player == (Object)null || !((NetworkBehaviour)player).IsOwner || !player.isPlayerControlled || (Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.inShipPhase) { return; } if (SyncManager.IsHauntedActive) { hauntedFearTimer += Time.deltaTime; if (hauntedFearTimer >= hauntedFearInterval) { hauntedFearTimer = 0f; hauntedFearInterval = Random.Range(20f, 45f); player.JumpToFearLevel(1f, true); player.insanityLevel = Mathf.Max(player.insanityLevel, 50f); } hauntedMessageTimer += Time.deltaTime; if (hauntedMessageTimer >= hauntedMessageInterval) { hauntedMessageTimer = 0f; hauntedMessageInterval = Random.Range(45f, 90f); if ((Object)(object)HUDManager.Instance != (Object)null) { string text = FlavorText.HauntedMessages[Random.Range(0, FlavorText.HauntedMessages.Length)]; HUDManager.Instance.DisplayTip("S\u0337T\u0334A\u0334T\u0338U\u0335S\u0335 E\u0337R\u0338R\u0335O\u0335R\u0335", text, true, false, "LC_Tip1"); } } } if (SyncManager.IsToxicAtmosphereActive) { bool flag = (Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.hangarDoorsClosed; if (!player.isInsideFactory && !(player.isInHangarShipRoom && flag) && tzpImmunityTimer <= 0f) { player.increasingDrunknessThisFrame = true; if (player.drunkness < 0.4f) { player.drunkness = Mathf.MoveTowards(player.drunkness, 0.41f, Time.deltaTime * 0.1f); } if (player.drunknessInertia < 1.5f) { PlayerControllerB obj = player; obj.drunknessInertia += Time.deltaTime * 0.2f; } } else if (tzpImmunityTimer > 0f) { player.increasingDrunknessThisFrame = false; player.drunkness = 0f; player.drunknessInertia = 0f; } } if (SyncManager.IsLowGravityActive && (Object)(object)player.thisController != (Object)null && !player.thisController.isGrounded && player.fallValue > 8f) { player.fallValue = 8f; } if (SyncManager.IsOxygenRichActive) { float num = SyncManager.GetOxygenStaminaMultiplier(); if (num < 1.1f) { num = 1.1f; } if (player.isSprinting) { PlayerControllerB obj2 = player; obj2.sprintMeter += Time.deltaTime / 11f * (1f - 1f / num); } else { PlayerControllerB obj3 = player; obj3.sprintMeter += Time.deltaTime / 9f * (num - 1f); } } if (player.isHoldingObject && (Object)(object)player.currentlyHeldObjectServer != (Object)null && player.currentlyHeldObjectServer.itemProperties.itemName.ToLower().Contains("tzp") && player.activatingItem) { tzpHoldTimer += Time.deltaTime; if (tzpHoldTimer >= 0.5f) { tzpImmunityTimer = 3f; player.drunkness = 0f; player.drunknessInertia = 0f; tzpHoldTimer = -1f; } } else if (!player.activatingItem) { tzpHoldTimer = 0f; } lastDrunkness = player.drunkness; if (tzpImmunityTimer > 0f) { tzpImmunityTimer -= Time.deltaTime; } if (SyncManager.IsRadioactiveSunlightActive) { if ((Object)(object)((Component)player).gameObject.GetComponent() == (Object)null) { ((Component)player).gameObject.AddComponent(); } return; } RadioactiveSunlightComponent component = ((Component)this).GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } } private void CleanupUV() { RadioactiveSunlightComponent component = ((Component)this).GetComponent(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } } [IteratorStateMachine(typeof(d__18))] private IEnumerator DelayedExpressEntry() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__18(0) { <>4__this = this }; } } public class GroovyComponent : MonoBehaviour { private float noiseTimer; private Light discoLight; private AudioSource discoAudio; private float rotationOffset; private GrabbableObject scrap; private static Light lightTemplate; private static AudioClip audioTemplate; private static bool searchedForAssets; private void Start() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Expected O, but got Unknown //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) scrap = ((Component)this).GetComponent(); if (!searchedForAssets) { FindDiscoAssets(); } if ((Object)(object)lightTemplate != (Object)null) { GameObject val = new GameObject("GroovyLight"); val.transform.SetParent(((Component)this).transform); val.transform.localPosition = Vector3.up * 0.5f; discoLight = val.AddComponent(); discoLight.type = lightTemplate.type; discoLight.range = 8f; discoLight.intensity = lightTemplate.intensity * 1.3f; discoLight.cookie = lightTemplate.cookie; discoLight.color = lightTemplate.color; discoLight.shadows = (LightShadows)0; } if ((Object)(object)audioTemplate != (Object)null) { GameObject val2 = new GameObject("GroovyAudio"); val2.transform.SetParent(((Component)this).transform); val2.transform.localPosition = Vector3.up * 0.5f; discoAudio = val2.AddComponent(); discoAudio.clip = audioTemplate; discoAudio.loop = true; discoAudio.playOnAwake = true; discoAudio.volume = 0.5f; discoAudio.spatialBlend = 1f; discoAudio.maxDistance = 20f; discoAudio.rolloffMode = (AudioRolloffMode)1; discoAudio.Play(); } } private void FindDiscoAssets() { searchedForAssets = true; if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)StartOfRound.Instance.unlockablesList == (Object)null) { return; } UnlockableItem val = ((IEnumerable)StartOfRound.Instance.unlockablesList.unlockables).FirstOrDefault((Func)((UnlockableItem u) => u?.unlockableName.ToLower().Contains("disco") ?? false)); if (val != null && (Object)(object)val.prefabObject != (Object)null) { lightTemplate = val.prefabObject.GetComponentInChildren(); AudioSource componentInChildren = val.prefabObject.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { audioTemplate = componentInChildren.clip; } } } private void Update() { //IL_0077: 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) if ((Object)(object)StartOfRound.Instance == (Object)null) { return; } if (!SyncManager.IsGroovyActive) { Object.Destroy((Object)(object)this); return; } if ((Object)(object)discoLight != (Object)null && (Object)(object)discoLight.cookie != (Object)null) { rotationOffset += Time.deltaTime * 60f; ((Component)discoLight).transform.localRotation = Quaternion.Euler(rotationOffset, rotationOffset * 0.5f, 0f); } noiseTimer += Time.deltaTime; if (noiseTimer >= 0.8f) { noiseTimer = 0f; if ((Object)(object)RoundManager.Instance != (Object)null) { RoundManager.Instance.PlayAudibleNoise(((Component)this).transform.position, 15f, 0.7f, 0, false, 0); } } } private void OnDestroy() { if ((Object)(object)discoLight != (Object)null) { Object.Destroy((Object)(object)((Component)discoLight).gameObject); } if ((Object)(object)discoAudio != (Object)null) { Object.Destroy((Object)(object)((Component)discoAudio).gameObject); } } } public class GroovySpeedTracker : MonoBehaviour { } public class RadioactiveSunlightComponent : MonoBehaviour { private PlayerControllerB player; private float timer; private float currentInterval = 10f; private bool isPeak; private void Start() { player = ((Component)this).GetComponent(); ResetInterval(); } public void ResetInterval() { float num = (((Object)(object)TimeOfDay.Instance != (Object)null) ? (TimeOfDay.Instance.normalizedTimeOfDay * (60f * (float)TimeOfDay.Instance.numberOfHours) + 360f) : 360f); isPeak = num >= 720f && num <= 900f; currentInterval = (isPeak ? 5f : 10f); timer = 0f; } private void Update() { //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || !((NetworkBehaviour)player).IsOwner || !player.isPlayerControlled || (Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.inShipPhase) { return; } if (player.isInsideFactory || player.isInHangarShipRoom) { if (currentInterval < (isPeak ? 5f : 10f)) { ResetInterval(); } } else { if ((Object)(object)TimeOfDay.Instance != (Object)null && TimeOfDay.Instance.normalizedTimeOfDay >= SyncManager.GetSunlightEndTime() / 24f) { return; } timer += Time.deltaTime; if (timer >= currentInterval) { timer = 0f; player.DamagePlayer(2, true, true, (CauseOfDeath)0, 0, false, default(Vector3)); float num = Mathf.Max(2f, currentInterval - 0.5f); if (num != currentInterval) { currentInterval = num; } } } } } public static class SyncManager { public static float SunlightEndTime = 18f; public static float GroovySpeedMultiplier = 1.15f; public static float OxygenStaminaMultiplier = 1.5f; public static float LowGravityStrength = 18f; public static float NewHireSpawnTime = 12f; public static float HauntedGhostSpawnTime = 17f; public static float WatchDogWakeTime = 12f; public static int BonusPayMin = 10; public static int BonusPayMax = 100; public static int QuotaPenaltyMin = 50; public static int QuotaPenaltyMax = 150; public static float GroovyLootMultiplier = 1.25f; public static int ActiveModifiersBitmask = 0; public static bool IsLowGravityActive => (ActiveModifiersBitmask & 1) != 0; public static bool IsOxygenRichActive => (ActiveModifiersBitmask & 2) != 0; public static bool IsGroovyActive => (ActiveModifiersBitmask & 4) != 0; public static bool IsRadioactiveSunlightActive => (ActiveModifiersBitmask & 8) != 0; public static bool IsHauntedActive => (ActiveModifiersBitmask & 0x10) != 0; public static bool IsToxicAtmosphereActive => (ActiveModifiersBitmask & 0x20) != 0; public static bool IsWatchDogActive => (ActiveModifiersBitmask & 0x40) != 0; public static bool IsNewHireActive => (ActiveModifiersBitmask & 0x80) != 0; public static bool IsWeaponDeliveryActive => (ActiveModifiersBitmask & 0x100) != 0; public static bool IsEquipmentCacheActive => (ActiveModifiersBitmask & 0x200) != 0; public static bool IsExpressEntryActive => (ActiveModifiersBitmask & 0x400) != 0; public static bool IsHost { get { if ((Object)(object)StartOfRound.Instance != (Object)null) { return ((NetworkBehaviour)StartOfRound.Instance).IsServer; } return false; } } public static bool IsActive(int mask, int bitIndex) { return (mask & (1 << bitIndex)) != 0; } public static float GetSunlightEndTime() { if (!IsHost) { return SunlightEndTime; } return BinaryMoons.RadioactiveSunlightEndTime.Value; } public static float GetGroovySpeedMultiplier() { if (!IsHost) { return GroovySpeedMultiplier; } return BinaryMoons.GroovySpeedMultiplier.Value; } public static float GetOxygenStaminaMultiplier() { if (!IsHost) { return OxygenStaminaMultiplier; } return BinaryMoons.OxygenStaminaMultiplier.Value; } public static float GetLowGravityStrength() { if (!IsHost) { return LowGravityStrength; } return BinaryMoons.LowGravityStrength.Value; } public static float GetNewHireSpawnTime() { if (!IsHost) { return NewHireSpawnTime; } return BinaryMoons.NewHireSpawnTime.Value; } public static float GetHauntedGhostSpawnTime() { if (!IsHost) { return HauntedGhostSpawnTime; } return BinaryMoons.HauntedGhostSpawnTime.Value; } public static float GetWatchDogWakeTime() { if (!IsHost) { return WatchDogWakeTime; } return BinaryMoons.WatchDogWakeTime.Value; } public static int GetBonusPayMin() { if (!IsHost) { return BonusPayMin; } return BinaryMoons.BonusPayMin.Value; } public static int GetBonusPayMax() { if (!IsHost) { return BonusPayMax; } return BinaryMoons.BonusPayMax.Value; } public static int GetQuotaPenaltyMin() { if (!IsHost) { return QuotaPenaltyMin; } return BinaryMoons.QuotaPenaltyMin.Value; } public static int GetQuotaPenaltyMax() { if (!IsHost) { return QuotaPenaltyMax; } return BinaryMoons.QuotaPenaltyMax.Value; } public static float GetGroovyLootMultiplier() { if (!IsHost) { return GroovyLootMultiplier; } return BinaryMoons.GroovyLootMultiplier.Value; } public static void UpdateFromSync(string[] parts) { if (parts.Length >= 12) { if (float.TryParse(parts[0], out var result)) { SunlightEndTime = result; } if (float.TryParse(parts[1], out var result2)) { GroovySpeedMultiplier = result2; } if (float.TryParse(parts[2], out var result3)) { OxygenStaminaMultiplier = result3; } if (float.TryParse(parts[3], out var result4)) { LowGravityStrength = result4; } if (float.TryParse(parts[4], out var result5)) { NewHireSpawnTime = result5; } if (float.TryParse(parts[5], out var result6)) { HauntedGhostSpawnTime = result6; } if (float.TryParse(parts[6], out var result7)) { WatchDogWakeTime = result7; } if (int.TryParse(parts[7], out var result8)) { BonusPayMin = result8; } if (int.TryParse(parts[8], out var result9)) { BonusPayMax = result9; } if (int.TryParse(parts[9], out var result10)) { QuotaPenaltyMin = result10; } if (int.TryParse(parts[10], out var result11)) { QuotaPenaltyMax = result11; } if (float.TryParse(parts[11], out var result12)) { GroovyLootMultiplier = result12; } } } } [Serializable] public struct BMO_SyncPacket : INetworkSerializable { public int AvailableRerolls; public int TotalRerollsUsed; public int DailyRandomOffset; public int SyncID; public int ProfitQuota; public int GroupCredits; public int DaysUntilDeadline; public string ConfigData; public string MoonData; public unsafe void NetworkSerialize(BufferSerializer serializer) where T : IReaderWriter { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) ((BufferSerializer*)(&serializer))->SerializeValue(ref AvailableRerolls, default(ForPrimitives)); ((BufferSerializer*)(&serializer))->SerializeValue(ref TotalRerollsUsed, default(ForPrimitives)); ((BufferSerializer*)(&serializer))->SerializeValue(ref DailyRandomOffset, default(ForPrimitives)); ((BufferSerializer*)(&serializer))->SerializeValue(ref SyncID, default(ForPrimitives)); ((BufferSerializer*)(&serializer))->SerializeValue(ref ProfitQuota, default(ForPrimitives)); ((BufferSerializer*)(&serializer))->SerializeValue(ref GroupCredits, default(ForPrimitives)); ((BufferSerializer*)(&serializer))->SerializeValue(ref DaysUntilDeadline, default(ForPrimitives)); serializer.SerializeValue(ref ConfigData, false); serializer.SerializeValue(ref MoonData, false); } } [Serializable] public struct BMOTipPacket : INetworkSerializable { public string Header; public string Body; public bool IsPositive; public unsafe void NetworkSerialize(BufferSerializer serializer) where T : IReaderWriter { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) serializer.SerializeValue(ref Header, false); serializer.SerializeValue(ref Body, false); ((BufferSerializer*)(&serializer))->SerializeValue(ref IsPositive, default(ForPrimitives)); } } public static class BMO_Networking { [CompilerGenerated] private sealed class d__25 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__25(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; if (ApplyRemoteState(force: true)) { retryTask = null; return false; } } else { <>1__state = -1; } <>2__current = (object)new WaitForSeconds(4f); <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static MethodInfo _cachedUpdateHUD; private static bool _initializedHUDCache = false; public static LNetworkVariable ActiveModifiersBitmask; public static LNetworkVariable GlobalState; public static LNetworkMessage RerollRequest; public static LNetworkMessage AskSyncRequest; public static LNetworkMessage SellRequest; public static LNetworkMessage ForceExpressEntry; public static LNetworkMessage NetworkedTip; public static Action OnExpressEntryTriggered; public static Action OnStateChanged; private static Coroutine retryTask; private static BMO_SyncPacket? bufferedPacket; private static int localSyncID = -1; public static bool IsInitialized { get; private set; } private static void InitializeHUDCache() { if (_initializedHUDCache) { return; } _initializedHUDCache = true; if (!((Object)(object)HUDManager.Instance == (Object)null)) { _cachedUpdateHUD = ((object)HUDManager.Instance).GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name.Contains("UpdateProfitQuota") || m.Name.Contains("SetProfitQuota") || m.Name.Contains("SyncQuotaHUD")); } } public static void Initialize() { if (IsInitialized) { return; } IsInitialized = true; ActiveModifiersBitmask = LNetworkVariable.Connect("BMO_Bitmask", 0, (LNetworkVariableWritePerms)0, (Action)null); GlobalState = LNetworkVariable.Connect("BMO_GlobalState_v2", default(BMO_SyncPacket), (LNetworkVariableWritePerms)0, (Action)null); RerollRequest = LNetworkMessage.Connect("BMO_RerollReq", (Action)OnRerollReceived, (Action)null, (Action)null); AskSyncRequest = LNetworkMessage.Connect("BMO_AskSync", (Action)OnAskSyncReceived, (Action)null, (Action)null); SellRequest = LNetworkMessage.Connect("BMO_SellReq", (Action)OnSellReceived, (Action)null, (Action)null); ForceExpressEntry = LNetworkMessage.Connect("BMO_ForceExpress", (Action)delegate { OnExpressEntryTriggered?.Invoke(); }, (Action)null, (Action)null); NetworkedTip = LNetworkMessage.Connect("BMO_Tip", (Action)delegate(BMOTipPacket pkt, ulong id) { if ((Object)(object)HUDManager.Instance != (Object)null) { HUDManager.Instance.DisplayTip(pkt.Header, pkt.Body, pkt.IsPositive, false, "LC_Tip1"); } }, (Action)null, (Action)null); GlobalState.OnValueChanged += OnGlobalStateChanged; ActiveModifiersBitmask.OnValueChanged += OnBitmaskChanged; } private static void OnGlobalStateChanged(BMO_SyncPacket oldVal, BMO_SyncPacket newVal) { bufferedPacket = newVal; ApplyRemoteState(); } private static void OnBitmaskChanged(int oldVal, int newVal) { SyncManager.ActiveModifiersBitmask = newVal; BinaryMoons.Logger.LogDebug((object)$"[BMO] Modifier Bitmask Updated: {newVal}"); if (SyncManager.IsGroovyActive) { TerminalPatch.ApplyGroovyScrapEffects(); } if (newVal != 0 && (Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)StartOfRound.Instance.currentLevel != (Object)null) { SelectableLevel currentLevel = StartOfRound.Instance.currentLevel; if (SyncManager.IsWatchDogActive) { InjectEnemyToLevel(currentLevel, ModifierLogicPatch.CachedWatchDog, outside: true); } if (SyncManager.IsHauntedActive) { InjectEnemyToLevel(currentLevel, ModifierLogicPatch.CachedGhostGirl, outside: false); } if (SyncManager.IsNewHireActive) { InjectEnemyToLevel(currentLevel, ModifierLogicPatch.CachedMasked, outside: false); } } OnStateChanged?.Invoke(newVal); } public static bool ApplyRemoteState(bool force = false) { if (!bufferedPacket.HasValue && !force) { return false; } BMO_SyncPacket bMO_SyncPacket = ((force && GlobalState != null) ? GlobalState.Value : bufferedPacket.Value); if (string.IsNullOrEmpty(bMO_SyncPacket.MoonData) && !force) { return false; } Terminal val = Object.FindObjectOfType(); if ((Object)(object)val == (Object)null || val.moonsCatalogueList == null || val.moonsCatalogueList.Length == 0) { if (retryTask == null && (Object)(object)StartOfRound.Instance != (Object)null && !force) { retryTask = ((MonoBehaviour)StartOfRound.Instance).StartCoroutine(SyncRetryLoop()); } return false; } TerminalPatch.AvailableRerolls = bMO_SyncPacket.AvailableRerolls; TerminalPatch.TotalRerollsUsed = bMO_SyncPacket.TotalRerollsUsed; TerminalPatch.DailyRandomOffset = bMO_SyncPacket.DailyRandomOffset; if ((Object)(object)TimeOfDay.Instance != (Object)null) { TimeOfDay.Instance.profitQuota = bMO_SyncPacket.ProfitQuota; TimeOfDay.Instance.daysUntilDeadline = bMO_SyncPacket.DaysUntilDeadline; SyncQuotaHUD(); } if ((Object)(object)ReflectionCache.CachedTerminal != (Object)null) { ReflectionCache.CachedTerminal.groupCredits = bMO_SyncPacket.GroupCredits; } bool flag = ApplyStateHardened(bMO_SyncPacket.MoonData, bMO_SyncPacket.ConfigData, val); if (flag) { TerminalPatch.HasSyncedWithHost = true; if (retryTask != null && (Object)(object)StartOfRound.Instance != (Object)null) { ((MonoBehaviour)StartOfRound.Instance).StopCoroutine(retryTask); retryTask = null; } bufferedPacket = null; if (SyncManager.IsGroovyActive) { TerminalPatch.ApplyGroovyScrapEffects(); } } else if (retryTask == null && (Object)(object)StartOfRound.Instance != (Object)null && !force) { retryTask = ((MonoBehaviour)StartOfRound.Instance).StartCoroutine(SyncRetryLoop()); } return flag; } public static void SyncQuotaHUD() { if ((Object)(object)HUDManager.Instance == (Object)null) { return; } if (!_initializedHUDCache) { InitializeHUDCache(); } if (!(_cachedUpdateHUD != null)) { return; } try { if (_cachedUpdateHUD.GetParameters().Length == 2) { _cachedUpdateHUD.Invoke(HUDManager.Instance, new object[2] { TimeOfDay.Instance.profitQuota, TimeOfDay.Instance.quotaFulfilled }); } else if (_cachedUpdateHUD.GetParameters().Length == 0) { _cachedUpdateHUD.Invoke(HUDManager.Instance, null); } } catch { } } public static void SendTip(string header, string body, bool isPositive) { if (NetworkManager.Singleton.IsServer) { NetworkedTip.SendClients(new BMOTipPacket { Header = header, Body = body, IsPositive = isPositive }); } } [IteratorStateMachine(typeof(d__25))] private static IEnumerator SyncRetryLoop() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__25(0); } public static void BroadcastSync() { if (GlobalState != null && NetworkManager.Singleton.IsServer) { localSyncID++; string configData = $"{BinaryMoons.RadioactiveSunlightEndTime.Value}:{BinaryMoons.GroovySpeedMultiplier.Value}:" + $"{BinaryMoons.OxygenStaminaMultiplier.Value}:{BinaryMoons.LowGravityStrength.Value}:" + $"{BinaryMoons.NewHireSpawnTime.Value}:{BinaryMoons.HauntedGhostSpawnTime.Value}:{BinaryMoons.WatchDogWakeTime.Value}:" + $"{BinaryMoons.BonusPayMin.Value}:{BinaryMoons.BonusPayMax.Value}:{BinaryMoons.QuotaPenaltyMin.Value}:{BinaryMoons.QuotaPenaltyMax.Value}:" + $"{BinaryMoons.GroovyLootMultiplier.Value}"; string moonData = string.Join("|", from s in TerminalPatch.GetSelectedMoons().Select(delegate(SelectableLevel m) { string text = TerminalPatch.NormalizeName(m.PlanetName); MoonModifier value2; return TerminalPatch.DailyModifiers.TryGetValue(text, out value2) ? $"{text};{value2.Name};{value2.IsPositive};{value2.ValueAmount}" : ""; }) where !string.IsNullOrEmpty(s) select s); BMO_SyncPacket bMO_SyncPacket = default(BMO_SyncPacket); bMO_SyncPacket.AvailableRerolls = TerminalPatch.AvailableRerolls; bMO_SyncPacket.TotalRerollsUsed = TerminalPatch.TotalRerollsUsed; bMO_SyncPacket.DailyRandomOffset = TerminalPatch.DailyRandomOffset; bMO_SyncPacket.SyncID = localSyncID; bMO_SyncPacket.ProfitQuota = (((Object)(object)TimeOfDay.Instance != (Object)null) ? TimeOfDay.Instance.profitQuota : 0); bMO_SyncPacket.GroupCredits = (((Object)(object)ReflectionCache.CachedTerminal != (Object)null) ? ReflectionCache.CachedTerminal.groupCredits : 0); bMO_SyncPacket.DaysUntilDeadline = (((Object)(object)TimeOfDay.Instance != (Object)null) ? TimeOfDay.Instance.daysUntilDeadline : 0); bMO_SyncPacket.ConfigData = configData; bMO_SyncPacket.MoonData = moonData; BMO_SyncPacket value = bMO_SyncPacket; GlobalState.Value = value; RefreshActiveModifierFlags(); } } private static bool ApplyStateHardened(string moonData, string configData, Terminal terminal) { string[] parts = configData.Split(':'); SyncManager.UpdateFromSync(parts); TerminalPatch.DailyModifiers.Clear(); TerminalPatch.GetSelectedMoons().Clear(); ResetFlags(); string[] array = moonData.Split('|'); int num = 0; string[] array2 = array; foreach (string text in array2) { if (string.IsNullOrEmpty(text)) { continue; } string[] array3 = text.Split(';'); if (array3.Length < 4) { continue; } string hostMoonNormalized = array3[0].ToLower(); string name = array3[1]; bool isPositive = bool.Parse(array3[2]); int valueAmount = int.Parse(array3[3]); SelectableLevel val = ((IEnumerable)terminal.moonsCatalogueList).FirstOrDefault((Func)delegate(SelectableLevel m) { string text2 = TerminalPatch.NormalizeName(m.PlanetName); return text2.Contains(hostMoonNormalized) || hostMoonNormalized.Contains(text2); }); if ((Object)(object)val != (Object)null) { num++; string key = TerminalPatch.NormalizeName(val.PlanetName); if (!TerminalPatch.GetSelectedMoons().Contains(val)) { TerminalPatch.GetSelectedMoons().Add(val); } TerminalPatch.DailyModifiers[key] = new MoonModifier { Name = name, IsPositive = isPositive, ValueAmount = valueAmount }; } } TerminalPatch.UnlockAllMoons(); RefreshActiveModifierFlags(); return num >= 1; } public static void ResetFlags() { if (ActiveModifiersBitmask != null && NetworkManager.Singleton.IsServer) { ActiveModifiersBitmask.Value = 0; } SyncManager.ActiveModifiersBitmask = 0; } public static void RefreshActiveModifierFlags() { if ((Object)(object)StartOfRound.Instance == (Object)null || (Object)(object)StartOfRound.Instance.currentLevel == (Object)null || ActiveModifiersBitmask == null || !NetworkManager.Singleton.IsServer) { return; } int num = 0; string key = TerminalPatch.NormalizeName(StartOfRound.Instance.currentLevel.PlanetName); if (TerminalPatch.DailyModifiers.TryGetValue(key, out var value)) { string name = value.Name; if (name == "Low Gravity") { num |= 1; } if (name == "Oxygen Rich") { num |= 2; } if (name == "Groovy") { num |= 4; } if (name == "High UV") { num |= 8; } if (name == "Paranormal Activity") { num |= 0x10; } if (name == "Toxic Atmosphere") { num |= 0x20; } if (name == "Guard Dog") { num |= 0x40; } if (name == "New Hire") { num |= 0x80; } if (name == "Weapon Delivery") { num |= 0x100; } if (name == "Equipment Cache") { num |= 0x200; } if (name == "Express Entry") { num |= 0x400; } } ActiveModifiersBitmask.Value = num; SyncManager.ActiveModifiersBitmask = num; } private static void InjectEnemyToLevel(SelectableLevel level, EnemyType enemy, bool outside) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown if (!((Object)(object)level == (Object)null) && !((Object)(object)enemy == (Object)null)) { List list = (outside ? level.OutsideEnemies : level.Enemies); if (list != null && !list.Any((SpawnableEnemyWithRarity e) => e != null && (Object)(object)e.enemyType == (Object)(object)enemy)) { SpawnableEnemyWithRarity item = new SpawnableEnemyWithRarity(enemy, 0); list.Add(item); BinaryMoons.Logger.LogInfo((object)("[BMO] Pool Injection: Added " + enemy.enemyName + " to " + (outside ? "Outside" : "Inside") + " list for " + level.PlanetName + ". Prefabs will now replicate to clients.")); } } } private static void OnRerollReceived(bool val, ulong clientId) { if (NetworkManager.Singleton.IsServer && TerminalPatch.AvailableRerolls > 0) { TerminalPatch.AvailableRerolls--; TerminalPatch.TotalRerollsUsed++; TerminalPatch.RandomizeMoons(Object.FindObjectOfType()); BroadcastSync(); } } private static void OnAskSyncReceived(bool val, ulong clientId) { if (NetworkManager.Singleton.IsServer) { BroadcastSync(); } } private static void OnSellReceived(bool val, ulong clientId) { if (NetworkManager.Singleton.IsServer) { TerminalPatch.ExecuteSellAll(isServer: true); } } public static void RequestReroll() { if (NetworkManager.Singleton.IsServer) { OnRerollReceived(val: true, 0uL); } else { RerollRequest.SendServer(true); } } public static void RequestSync() { if (NetworkManager.Singleton.IsServer) { BroadcastSync(); } else { AskSyncRequest.SendServer(true); } } } [HarmonyPatch(typeof(StartOfRound), "Start")] public class BMO_JoinSyncPatch { [HarmonyPostfix] private static void Postfix() { if ((Object)(object)NetworkManager.Singleton != (Object)null && !NetworkManager.Singleton.IsServer && BMO_Networking.IsInitialized) { SyncManager.ActiveModifiersBitmask = BMO_Networking.ActiveModifiersBitmask.Value; BMO_Networking.ApplyRemoteState(force: true); if (SyncManager.IsGroovyActive) { TerminalPatch.ApplyGroovyScrapEffects(); } } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }