Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of EnemyCompatibilityFixes v1.2.0
EnemyCompatibilityFixes.dll
Decompiled 3 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("EnemyCompatibilityFixes")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.2.0.0")] [assembly: AssemblyInformationalVersion("1.2.0")] [assembly: AssemblyProduct("EnemyCompatibilityFixes")] [assembly: AssemblyTitle("EnemyCompatibilityFixes")] [assembly: AssemblyVersion("1.2.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EnemyCompatibilityFixes { [BepInPlugin("enemycompatibilityfixes.plugin", "Enemy Compatibility Fixes", "1.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "enemycompatibilityfixes.plugin"; public const string PluginName = "Enemy Compatibility Fixes"; public const string PluginVersion = "1.2.0"; private Harmony _harmony; private ConfigEntry<bool> _fixMinecraftSpider; private ConfigEntry<bool> _guardScp999Targeting; private ConfigEntry<bool> _fixModelReplacementSlots; private ConfigEntry<bool> _fixModDataRegistration; private ConfigEntry<bool> _fixLethalCasinoMenu; private ConfigEntry<bool> _fixUtilitySlotDestruction; private ConfigEntry<bool> _fixOccludedAudio; private ConfigEntry<bool> _fixPermanentMoonsDisconnect; private ConfigEntry<bool> _enableDaySpeed; private ConfigEntry<float> _daySpeedMultiplier; private ConfigEntry<bool> _enableDifficultyScrap; private ConfigEntry<int> _scrapD; private ConfigEntry<int> _scrapC; private ConfigEntry<int> _scrapB; private ConfigEntry<int> _scrapA; private ConfigEntry<int> _scrapS; private ConfigEntry<int> _scrapSS; private ConfigEntry<int> _scrapUnknown; private ConfigEntry<bool> _showMoonPrices; private ConfigEntry<bool> _compensateEnemySchedule; private ConfigEntry<float> _enemyScheduleMultiplier; private ConfigEntry<int> _minimumInsideEnemies; private ConfigEntry<int> _minimumOutsideEnemies; private ConfigEntry<bool> _showShipScanNode; private ConfigEntry<bool> _showMainEntranceScanNode; private ConfigEntry<int> _navigationScanRange; private ConfigEntry<bool> _compressInteriorWeights; private ConfigEntry<int> _interiorWeightExponent; private void Awake() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown BindFixSettings(); BindGameplaySettings(); _harmony = new Harmony("enemycompatibilityfixes.plugin"); if (_fixMinecraftSpider.Value) { PatchMinecraftSpider(); } if (_guardScp999Targeting.Value) { PatchScp999Targeting(); } if (_fixModelReplacementSlots.Value) { PatchModelReplacementSlots(); } if (_fixModDataRegistration.Value) { PatchModDataRegistration(); } if (_fixLethalCasinoMenu.Value) { PatchLethalCasinoMenu(); } if (_fixUtilitySlotDestruction.Value) { PatchUtilitySlotDestruction(); } if (_fixOccludedAudio.Value) { PatchOccludedAudio(); } if (_fixPermanentMoonsDisconnect.Value) { PatchPermanentMoonsDisconnect(); } PatchGameplaySettings(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Enemy Compatibility Fixes 1.2.0 loaded."); } private void BindFixSettings() { _fixMinecraftSpider = ((BaseUnityPlugin)this).Config.Bind<bool>("Fixes", "Fix Minecraft Spider state", true, "Prevents MinecraftSpiderMod from accessing invalid state after level transitions, unusual spawning, or enemy cleanup."); _guardScp999Targeting = ((BaseUnityPlugin)this).Config.Bind<bool>("Fixes", "Guard SCP-999 enemy targeting", true, "Stops SCP-999 enemy targeting from flooding the log when another enemy has incomplete targeting data."); _fixModelReplacementSlots = ((BaseUnityPlugin)this).Config.Bind<bool>("Fixes", "Fix ModelReplacement item slots", true, "Prevents ModelReplacementAPI from reading outside the inventory array when a tool or reserved slot is selected."); _fixModDataRegistration = ((BaseUnityPlugin)this).Config.Bind<bool>("Fixes", "Fix LethalModDataLib registration", true, "Skips unloaded plugin instances while LethalModDataLib scans mod data attributes."); _fixLethalCasinoMenu = ((BaseUnityPlugin)this).Config.Bind<bool>("Fixes", "Fix LethalCasino menu check", true, "Skips an obsolete LC_API warning check that calls a menu method removed from the current game."); _fixUtilitySlotDestruction = ((BaseUnityPlugin)this).Config.Bind<bool>("Fixes", "Fix utility slot item destruction", true, "Uses the correct HUD icon when an item in the game's utility-only slot is destroyed."); _fixOccludedAudio = ((BaseUnityPlugin)this).Config.Bind<bool>("Fixes", "Guard broken occluded audio", true, "Stops invalid OccludeAudio components from flooding the log every frame on broken custom scenes."); _fixPermanentMoonsDisconnect = ((BaseUnityPlugin)this).Config.Bind<bool>("Fixes", "Fix Permanent Moons disconnect", true, "Prevents Permanent Moons from accessing the messaging manager after networking has already shut down."); } private void BindGameplaySettings() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Expected O, but got Unknown //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Expected O, but got Unknown //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Expected O, but got Unknown //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Expected O, but got Unknown //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Expected O, but got Unknown _enableDaySpeed = ((BaseUnityPlugin)this).Config.Bind<bool>("Time", "Enable day speed multiplier", true, "Enables the global day speed setting below. This stacks with each moon's DaySpeedMultiplier."); _daySpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Time", "Day speed multiplier", 1f, new ConfigDescription("How quickly time passes. 0 pauses the day, 0.5 makes it twice as long, 1 is normal, and 2 makes it twice as fast.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); _enableDifficultyScrap = ((BaseUnityPlugin)this).Config.Bind<bool>("Scrap by moon difficulty", "Enable scrap count multipliers", true, "Changes the number of spawned scrap items according to the moon's displayed risk level. The host controls the result."); _scrapD = BindPercent("D or easier percent", 150, "Scrap count on D, safe, and similarly easy moons."); _scrapC = BindPercent("C percent", 135, "Scrap count on C and C+ moons."); _scrapB = BindPercent("B percent", 120, "Scrap count on B and B+ moons."); _scrapA = BindPercent("A percent", 110, "Scrap count on A and A+ moons."); _scrapS = BindPercent("S percent", 100, "Scrap count on S and S+ moons."); _scrapSS = BindPercent("SS or harder percent", 100, "Scrap count on SS, SSS, and harder moons."); _scrapUnknown = BindPercent("Unknown difficulty percent", 100, "Scrap count when a custom moon uses an unrecognized risk label."); _showMoonPrices = ((BaseUnityPlugin)this).Config.Bind<bool>("Terminal", "Show current moon prices", true, "Adds each moon's current route price after its weather in the moons catalogue."); _compensateEnemySchedule = ((BaseUnityPlugin)this).Config.Bind<bool>("Enemy spawning", "Compensate for slower days", true, "Moves scheduled indoor enemy spawns earlier when the day speed multiplier is below 1. The host controls spawning."); _enemyScheduleMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Enemy spawning", "Enemy schedule multiplier", 0f, new ConfigDescription("0 automatically follows the day speed multiplier. Values below 1 make scheduled enemies appear earlier; 1 leaves timing unchanged.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>())); _minimumInsideEnemies = ((BaseUnityPlugin)this).Config.Bind<int>("Enemy spawning", "Minimum inside enemies per batch", 1, new ConfigDescription("Minimum number considered for each indoor spawn batch. 0 keeps the game's normal minimum.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 20), Array.Empty<object>())); _minimumOutsideEnemies = ((BaseUnityPlugin)this).Config.Bind<int>("Enemy spawning", "Minimum outside enemies per batch", 1, new ConfigDescription("Minimum number considered for each outside spawn batch. 0 keeps the game's normal minimum.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 20), Array.Empty<object>())); _showShipScanNode = ((BaseUnityPlugin)this).Config.Bind<bool>("Outside scanner", "Always show ship", true, "Shows the ship as a navigation marker whenever the scanner is used outside."); _showMainEntranceScanNode = ((BaseUnityPlugin)this).Config.Bind<bool>("Outside scanner", "Always show main entrance", true, "Shows the main entrance as a navigation marker whenever the scanner is used outside."); _navigationScanRange = ((BaseUnityPlugin)this).Config.Bind<int>("Outside scanner", "Navigation marker range", 10000, new ConfigDescription("Maximum range of the ship and main entrance scan markers.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(50, 50000), Array.Empty<object>())); _compressInteriorWeights = ((BaseUnityPlugin)this).Config.Bind<bool>("Interior variety", "Compress interior weight differences", true, "Reduces extreme rarity differences among interiors that are actually valid for the selected moon."); _interiorWeightExponent = ((BaseUnityPlugin)this).Config.Bind<int>("Interior variety", "Weight exponent percent", 50, new ConfigDescription("100 keeps original weights, 50 uses their square root, and 0 makes all valid interiors equally likely.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>())); } private ConfigEntry<int> BindPercent(string key, int defaultValue, string description) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown return ((BaseUnityPlugin)this).Config.Bind<int>("Scrap by moon difficulty", key, defaultValue, new ConfigDescription(description + " 100 means unchanged.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 500), Array.Empty<object>())); } private void PatchMinecraftSpider() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown Type type = FindType("MinecraftSpiderMod.Patches.SandSpiderAIPatch"); if (type == null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"MinecraftSpiderMod was not found; its compatibility fix was skipped."); return; } SpiderStateGuard.Initialize(type, ((BaseUnityPlugin)this).Logger); HarmonyMethod val = new HarmonyMethod(typeof(SpiderStateGuard), "EnsureStatePrefix", (Type[])null); val.priority = 800; val.before = new string[1] { "SkunkWerx.MinecraftSpiderMod" }; HarmonyMethod val2 = val; string[] array = new string[2] { "Update", "MoveLegsProcedurally" }; foreach (string text in array) { MethodInfo methodInfo = AccessTools.Method(typeof(SandSpiderAI), text, (Type[])null, (Type[])null); if (methodInfo != null) { _harmony.Patch((MethodBase)methodInfo, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } MethodInfo methodInfo2 = AccessTools.Method(typeof(SandSpiderAI), "KillEnemy", (Type[])null, (Type[])null); if (methodInfo2 != null) { HarmonyMethod val3 = new HarmonyMethod(typeof(SpiderStateGuard), "KillEnemyFinalizer", (Type[])null); _harmony.Patch((MethodBase)methodInfo2, val2, (HarmonyMethod)null, (HarmonyMethod)null, val3, (HarmonyMethod)null); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"MinecraftSpiderMod state guard enabled."); } private void PatchScp999Targeting() { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown Type type = FindType("SnowyLib.EnemyAIExtensions"); if (type == null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"SnowyLib was not found; the SCP-999 targeting guard was skipped."); return; } MethodInfo methodInfo = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo method) => method.Name == "TargetClosestEnemy" && method.ReturnType == typeof(bool)); if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"SnowyLib.TargetClosestEnemy was not found; the SCP-999 targeting guard could not be applied."); return; } Scp999TargetingGuard.SetLogger(((BaseUnityPlugin)this).Logger); _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(Scp999TargetingGuard), "Finalizer", (Type[])null), (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"SCP-999 targeting exception guard enabled."); } private void PatchModelReplacementSlots() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown Type type = FindType("ModelReplacement.BodyReplacementBase"); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "UpdateItemTransform", (Type[])null, (Type[])null)); if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"ModelReplacementAPI was not found; its item-slot guard was skipped."); return; } ModelReplacementSlotGuard.Initialize(type, ((BaseUnityPlugin)this).Logger); _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(ModelReplacementSlotGuard), "Prefix", (Type[])null) { priority = 800 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"ModelReplacementAPI item-slot guard enabled."); } private void PatchModDataRegistration() { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown Type type = FindType("LethalModDataLib.Features.ModDataAttributeCollector"); MethodInfo methodInfo = type?.GetMethod("RegisterModDataAttributes", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); MethodInfo methodInfo2 = type?.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo method) => method.Name == "RegisterModDataAttributes" && method.GetParameters().Length == 4); if (methodInfo == null || methodInfo2 == null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalModDataLib was not found; its registration guard was skipped."); return; } ModDataRegistrationGuard.Initialize(methodInfo2, ((BaseUnityPlugin)this).Logger); _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(ModDataRegistrationGuard), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalModDataLib registration guard enabled."); } private void PatchLethalCasinoMenu() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown Type type = FindType("LethalCasino.Patches.MenuManagerPatch"); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "StartPatch", (Type[])null, (Type[])null)); if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalCasino was not found; its obsolete menu check guard was skipped."); return; } _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(LethalCasinoMenuGuard), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalCasino obsolete menu check disabled."); } private void PatchUtilitySlotDestruction() { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(PlayerControllerB), "DestroyItemInSlot", (Type[])null, (Type[])null); if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"PlayerControllerB.DestroyItemInSlot was not found; its utility-slot fix was skipped."); return; } UtilitySlotDestructionPatch.SetLogger(((BaseUnityPlugin)this).Logger); _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(UtilitySlotDestructionPatch), "Transpiler", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Utility-only slot destruction fix enabled."); } private void PatchGameplaySettings() { //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown //IL_0127: Expected O, but got Unknown //IL_0127: Expected O, but got Unknown //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Expected O, but got Unknown //IL_019c: Expected O, but got Unknown //IL_019c: Expected O, but got Unknown //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Expected O, but got Unknown //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Expected O, but got Unknown //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Expected O, but got Unknown //IL_0297: Expected O, but got Unknown //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02e0: Expected O, but got Unknown TimeSpeedPatch.Initialize(_enableDaySpeed, _daySpeedMultiplier); ScrapAmountPatch.Initialize(_enableDifficultyScrap, _scrapD, _scrapC, _scrapB, _scrapA, _scrapS, _scrapSS, _scrapUnknown, ((BaseUnityPlugin)this).Logger); EnemySpawnTimingPatch.Initialize(_compensateEnemySchedule, _enemyScheduleMultiplier, _enableDaySpeed, _daySpeedMultiplier, _minimumInsideEnemies, _minimumOutsideEnemies, ((BaseUnityPlugin)this).Logger); TerminalMoonPricePatch.Initialize(_showMoonPrices, ((BaseUnityPlugin)this).Logger); NavigationScanPatch.Initialize(_showShipScanNode, _showMainEntranceScanNode, _navigationScanRange); InteriorWeightPatch.Initialize(_compressInteriorWeights, _interiorWeightExponent, ((BaseUnityPlugin)this).Logger); MethodInfo methodInfo = AccessTools.Method(typeof(TimeOfDay), "MoveGlobalTime", (Type[])null, (Type[])null); if (methodInfo != null) { _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(TimeSpeedPatch), "Prefix", (Type[])null), new HarmonyMethod(typeof(TimeSpeedPatch), "Restore", (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(TimeSpeedPatch), "Finalizer", (Type[])null), (HarmonyMethod)null); } MethodInfo methodInfo2 = AccessTools.Method(typeof(RoundManager), "SpawnScrapInLevel", (Type[])null, (Type[])null); if (methodInfo2 != null) { _harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(ScrapAmountPatch), "Prefix", (Type[])null) { priority = 0 }, new HarmonyMethod(typeof(ScrapAmountPatch), "Restore", (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(ScrapAmountPatch), "Finalizer", (Type[])null), (HarmonyMethod)null); } MethodInfo methodInfo3 = AccessTools.Method(typeof(RoundManager), "PlotOutEnemiesForNextHour", (Type[])null, (Type[])null); if (methodInfo3 != null) { _harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(typeof(EnemySpawnTimingPatch), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo4 = AccessTools.Method(typeof(RoundManager), "BeginEnemySpawning", (Type[])null, (Type[])null); if (methodInfo4 != null) { _harmony.Patch((MethodBase)methodInfo4, new HarmonyMethod(typeof(EnemySpawnTimingPatch), "BeginPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo5 = AccessTools.Method(typeof(Terminal), "TextPostProcess", (Type[])null, (Type[])null); if (methodInfo5 != null) { _harmony.Patch((MethodBase)methodInfo5, new HarmonyMethod(typeof(TerminalMoonPricePatch), "Prefix", (Type[])null) { priority = 800 }, new HarmonyMethod(typeof(TerminalMoonPricePatch), "Postfix", (Type[])null) { priority = 0 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo6 = AccessTools.Method(typeof(HUDManager), "AssignNewNodes", (Type[])null, (Type[])null); if (methodInfo6 != null) { _harmony.Patch((MethodBase)methodInfo6, (HarmonyMethod)null, new HarmonyMethod(typeof(NavigationScanPatch), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } PatchInteriorWeights(); } private void PatchOccludedAudio() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(OccludeAudio), "Update", (Type[])null, (Type[])null); if (!(methodInfo == null)) { OccludedAudioGuard.SetLogger(((BaseUnityPlugin)this).Logger); _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(OccludedAudioGuard), "Finalizer", (Type[])null), (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"OccludeAudio exception guard enabled."); } } private void PatchPermanentMoonsDisconnect() { //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Expected O, but got Unknown Type type = FindType("Plugin"); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "UnregisterMessages", (Type[])null, (Type[])null)); if (methodInfo == null || type.Assembly.GetName().Name != "PermanentMoons") { methodInfo = (from assembly in AppDomain.CurrentDomain.GetAssemblies() where assembly.GetName().Name == "PermanentMoons" select assembly.GetType("Plugin", throwOnError: false) into type2 where type2 != null select AccessTools.Method(type2, "UnregisterMessages", (Type[])null, (Type[])null)).FirstOrDefault((MethodInfo method) => method != null); } if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Permanent Moons was not found; its disconnect guard was skipped."); return; } _harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(PermanentMoonsDisconnectGuard), "Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Permanent Moons disconnect guard enabled."); } private void PatchInteriorWeights() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown Type type = FindType("LethalLevelLoader.DungeonManager"); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "GetValidExtendedDungeonFlows", (Type[])null, (Type[])null)); if (methodInfo == null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalLevelLoader was not found; interior weight compression was skipped."); return; } InteriorWeightPatch.InitializeResultType(methodInfo.ReturnType); _harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(InteriorWeightPatch), "Postfix", (Type[])null) { priority = 0 }, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Interior weight compression support enabled."); } private static Type FindType(string fullName) { return (from assembly in AppDomain.CurrentDomain.GetAssemblies() select assembly.GetType(fullName, throwOnError: false)).FirstOrDefault((Type type) => type != null); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal static class SpiderStateGuard { private static FieldInfo _timerDictionaryField; private static ManualLogSource _logger; private static int _repairNoticeWritten; private static int _killNoticeWritten; internal static void Initialize(Type spiderPatchType, ManualLogSource logger) { _timerDictionaryField = AccessTools.Field(spiderPatchType, "_timeSinceMovingLegs"); _logger = logger; } public static void EnsureStatePrefix(SandSpiderAI __instance) { if ((Object)(object)__instance == (Object)null || _timerDictionaryField == null) { return; } try { IDictionary dictionary = _timerDictionaryField.GetValue(null) as IDictionary; if (dictionary == null) { dictionary = Activator.CreateInstance(_timerDictionaryField.FieldType) as IDictionary; _timerDictionaryField.SetValue(null, dictionary); } if (dictionary == null || dictionary.Contains(__instance)) { return; } dictionary.Add(__instance, Random.Range(0.1f, 0.9f)); if (Interlocked.Exchange(ref _repairNoticeWritten, 1) == 0) { ManualLogSource logger = _logger; if (logger != null) { logger.LogInfo((object)"Repaired missing MinecraftSpiderMod leg state."); } } } catch (Exception ex) { ManualLogSource logger2 = _logger; if (logger2 != null) { logger2.LogWarning((object)("Could not initialize MinecraftSpiderMod state: " + ex.Message)); } } } public static Exception KillEnemyFinalizer(Exception __exception) { if (__exception is NullReferenceException) { if (Interlocked.Exchange(ref _killNoticeWritten, 1) == 0) { ManualLogSource logger = _logger; if (logger != null) { logger.LogWarning((object)"Ignored invalid MinecraftSpiderMod cleanup data while a spider was being removed."); } } return null; } return __exception; } } internal static class Scp999TargetingGuard { private static ManualLogSource _logger; private static int _noticeWritten; internal static void SetLogger(ManualLogSource logger) { _logger = logger; } public static Exception Finalizer(Exception __exception, ref bool __result) { if (__exception is NullReferenceException) { __result = false; if (Interlocked.Exchange(ref _noticeWritten, 1) == 0) { ManualLogSource logger = _logger; if (logger != null) { logger.LogWarning((object)"Ignored invalid enemy data while SCP-999 was selecting a target."); } } return null; } return __exception; } } internal static class ModelReplacementSlotGuard { private static FieldInfo _heldItemField; private static MethodInfo _controllerGetter; private static ManualLogSource _logger; private static int _noticeWritten; internal static void Initialize(Type bodyType, ManualLogSource logger) { _heldItemField = AccessTools.Field(bodyType, "heldItem"); _controllerGetter = AccessTools.PropertyGetter(bodyType, "controller"); _logger = logger; } public static bool Prefix(object __instance) { if (__instance == null || _heldItemField == null || _controllerGetter == null) { return true; } try { object? value = _heldItemField.GetValue(__instance); GrabbableObject val = (GrabbableObject)((value is GrabbableObject) ? value : null); if ((Object)(object)val == (Object)null || val is BeltBagItem) { return true; } object? obj = _controllerGetter.Invoke(__instance, null); object? obj2 = ((obj is PlayerControllerB) ? obj : null); int num = ((PlayerControllerB)(obj2?)).currentItemSlot ?? (-1); int valueOrDefault = (((PlayerControllerB)(obj2?)).ItemSlots?.Length).GetValueOrDefault(); if (num >= 0 && num < valueOrDefault) { return true; } _heldItemField.SetValue(__instance, null); if (Interlocked.Exchange(ref _noticeWritten, 1) == 0) { ManualLogSource logger = _logger; if (logger != null) { logger.LogWarning((object)$"Prevented ModelReplacementAPI item-slot overflow (slot {num}, inventory size {valueOrDefault})."); } } return false; } catch (Exception ex) { if (Interlocked.Exchange(ref _noticeWritten, 1) == 0) { ManualLogSource logger2 = _logger; if (logger2 != null) { logger2.LogWarning((object)("Could not validate a ModelReplacementAPI item slot: " + ex.Message)); } } return true; } } } internal static class ModDataRegistrationGuard { private static MethodInfo _registerOne; private static ManualLogSource _logger; internal static void Initialize(MethodInfo registerOne, ManualLogSource logger) { _registerOne = registerOne; _logger = logger; } public static bool Prefix() { if (_registerOne == null) { return true; } int num = 0; foreach (PluginInfo value in Chainloader.PluginInfos.Values) { BaseUnityPlugin val = ((value != null) ? value.Instance : null); if ((Object)(object)val == (Object)null) { num++; continue; } IEnumerable<Type> loadableTypes; try { loadableTypes = GetLoadableTypes(((object)val).GetType().Assembly); } catch (Exception ex) { ManualLogSource logger = _logger; if (logger != null) { BepInPlugin metadata = value.Metadata; logger.LogWarning((object)("Could not inspect " + (((metadata != null) ? metadata.GUID : null) ?? "an unknown plugin") + " for mod data: " + ex.Message)); } continue; } foreach (Type item in loadableTypes) { try { _registerOne.Invoke(null, new object[4] { value.Metadata.GUID, item, null, null }); } catch (TargetInvocationException ex2) { ManualLogSource logger2 = _logger; if (logger2 != null) { logger2.LogWarning((object)("Could not register mod data from " + item.FullName + ": " + (ex2.InnerException ?? ex2).Message)); } } catch (Exception ex3) { ManualLogSource logger3 = _logger; if (logger3 != null) { logger3.LogWarning((object)("Could not register mod data from " + item.FullName + ": " + ex3.Message)); } } } } if (num > 0) { ManualLogSource logger4 = _logger; if (logger4 != null) { logger4.LogInfo((object)$"Skipped {num} unloaded plugin instance(s) during LethalModDataLib registration."); } } return false; } private static IEnumerable<Type> GetLoadableTypes(Assembly assembly) { try { return assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { return ex.Types.Where((Type type) => type != null); } } } internal static class LethalCasinoMenuGuard { public static bool Prefix() { return false; } } internal static class UtilitySlotDestructionPatch { private static ManualLogSource _logger; internal static void SetLogger(ManualLogSource logger) { _logger = logger; } public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Expected O, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown List<CodeInstruction> list = instructions.ToList(); MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(HUDManager), "Instance"); FieldInfo fieldInfo = AccessTools.Field(typeof(HUDManager), "itemSlotIcons"); MethodInfo methodInfo2 = AccessTools.PropertySetter(typeof(Behaviour), "enabled"); MethodInfo methodInfo3 = AccessTools.Method(typeof(UtilitySlotDestructionPatch), "DisableCorrectSlotIcon", (Type[])null, (Type[])null); for (int i = 0; i <= list.Count - 6; i++) { if (CodeInstructionExtensions.Calls(list[i], methodInfo) && CodeInstructionExtensions.LoadsField(list[i + 1], fieldInfo, false) && !(list[i + 2].opcode != OpCodes.Ldarg_1) && !(list[i + 3].opcode != OpCodes.Ldelem_Ref) && !(list[i + 4].opcode != OpCodes.Ldc_I4_0) && CodeInstructionExtensions.Calls(list[i + 5], methodInfo2)) { CodeInstruction item = new CodeInstruction(OpCodes.Call, (object)methodInfo3); list.RemoveRange(i, 6); list.Insert(i, new CodeInstruction(OpCodes.Ldarg_1, (object)null)); list.Insert(i + 1, item); ManualLogSource logger = _logger; if (logger != null) { logger.LogInfo((object)"Patched DestroyItemInSlot for the utility-only HUD slot."); } return list; } } ManualLogSource logger2 = _logger; if (logger2 != null) { logger2.LogWarning((object)"Could not locate the utility-slot HUD sequence in DestroyItemInSlot; original code was left unchanged."); } return list; } public static void DisableCorrectSlotIcon(int itemSlot) { HUDManager instance = HUDManager.Instance; if ((Object)(object)instance == (Object)null) { return; } if (itemSlot == 50) { if ((Object)(object)instance.itemOnlySlotIcon != (Object)null) { ((Behaviour)instance.itemOnlySlotIcon).enabled = false; } } else if (instance.itemSlotIcons != null && itemSlot >= 0 && itemSlot < instance.itemSlotIcons.Length && (Object)(object)instance.itemSlotIcons[itemSlot] != (Object)null) { ((Behaviour)instance.itemSlotIcons[itemSlot]).enabled = false; } } } internal static class TimeSpeedPatch { private static ConfigEntry<bool> _enabled; private static ConfigEntry<float> _multiplier; internal static void Initialize(ConfigEntry<bool> enabled, ConfigEntry<float> multiplier) { _enabled = enabled; _multiplier = multiplier; } public static void Prefix(TimeOfDay __instance, out float __state) { __state = __instance.globalTimeSpeedMultiplier; if (_enabled.Value) { __instance.globalTimeSpeedMultiplier = __state * _multiplier.Value; } } public static void Restore(TimeOfDay __instance, float __state) { __instance.globalTimeSpeedMultiplier = __state; } public static Exception Finalizer(TimeOfDay __instance, float __state, Exception __exception) { __instance.globalTimeSpeedMultiplier = __state; return __exception; } } internal static class ScrapAmountPatch { private static ConfigEntry<bool> _enabled; private static ConfigEntry<int> _d; private static ConfigEntry<int> _c; private static ConfigEntry<int> _b; private static ConfigEntry<int> _a; private static ConfigEntry<int> _s; private static ConfigEntry<int> _ss; private static ConfigEntry<int> _unknown; private static ManualLogSource _logger; internal static void Initialize(ConfigEntry<bool> enabled, ConfigEntry<int> d, ConfigEntry<int> c, ConfigEntry<int> b, ConfigEntry<int> a, ConfigEntry<int> s, ConfigEntry<int> ss, ConfigEntry<int> unknown, ManualLogSource logger) { _enabled = enabled; _d = d; _c = c; _b = b; _a = a; _s = s; _ss = ss; _unknown = unknown; _logger = logger; } public static void Prefix(RoundManager __instance, out float __state) { __state = __instance.scrapAmountMultiplier; if (_enabled.Value && !((Object)(object)__instance.currentLevel == (Object)null)) { string text = (__instance.currentLevel.riskLevel ?? string.Empty).Trim().ToUpperInvariant(); int percent = GetPercent(text); __instance.scrapAmountMultiplier = __state * (float)percent / 100f; ManualLogSource logger = _logger; if (logger != null) { logger.LogInfo((object)$"Scrap count multiplier for {__instance.currentLevel.PlanetName} (risk {text}): {percent}%."); } } } public static void Restore(RoundManager __instance, float __state) { __instance.scrapAmountMultiplier = __state; } public static Exception Finalizer(RoundManager __instance, float __state, Exception __exception) { __instance.scrapAmountMultiplier = __state; return __exception; } private static int GetPercent(string risk) { if (risk.StartsWith("SS", StringComparison.Ordinal)) { return _ss.Value; } if (risk.StartsWith("S", StringComparison.Ordinal)) { return _s.Value; } if (risk.StartsWith("A", StringComparison.Ordinal)) { return _a.Value; } if (risk.StartsWith("B", StringComparison.Ordinal)) { return _b.Value; } if (risk.StartsWith("C", StringComparison.Ordinal)) { return _c.Value; } if (risk.StartsWith("D", StringComparison.Ordinal) || risk.Contains("SAFE") || risk.Contains("EASY")) { return _d.Value; } return _unknown.Value; } } internal static class OccludedAudioGuard { private static ManualLogSource _logger; private static int _noticeWritten; internal static void SetLogger(ManualLogSource logger) { _logger = logger; } public static Exception Finalizer(OccludeAudio __instance, Exception __exception) { if (!(__exception is NullReferenceException)) { return __exception; } if ((Object)(object)__instance != (Object)null) { ((Behaviour)__instance).enabled = false; } if (Interlocked.Exchange(ref _noticeWritten, 1) == 0) { ManualLogSource logger = _logger; if (logger != null) { logger.LogWarning((object)"Disabled a broken OccludeAudio component that was throwing every frame."); } } return null; } } internal static class PermanentMoonsDisconnectGuard { public static bool Prefix() { NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton != (Object)null) { return singleton.CustomMessagingManager != null; } return false; } } internal static class EnemySpawnTimingPatch { private static ConfigEntry<bool> _enabled; private static ConfigEntry<float> _scheduleMultiplier; private static ConfigEntry<bool> _daySpeedEnabled; private static ConfigEntry<float> _daySpeedMultiplier; private static ConfigEntry<int> _minimumInside; private static ConfigEntry<int> _minimumOutside; private static ManualLogSource _logger; private static int _lastLoggedDay = int.MinValue; internal static void Initialize(ConfigEntry<bool> enabled, ConfigEntry<float> scheduleMultiplier, ConfigEntry<bool> daySpeedEnabled, ConfigEntry<float> daySpeedMultiplier, ConfigEntry<int> minimumInside, ConfigEntry<int> minimumOutside, ManualLogSource logger) { _enabled = enabled; _scheduleMultiplier = scheduleMultiplier; _daySpeedEnabled = daySpeedEnabled; _daySpeedMultiplier = daySpeedMultiplier; _minimumInside = minimumInside; _minimumOutside = minimumOutside; _logger = logger; } public static void BeginPrefix(RoundManager __instance) { if (_enabled.Value && !((Object)(object)__instance == (Object)null)) { __instance.minEnemiesToSpawn = Math.Max(__instance.minEnemiesToSpawn, _minimumInside.Value); __instance.minOutsideEnemiesToSpawn = Math.Max(__instance.minOutsideEnemiesToSpawn, _minimumOutside.Value); } } public static void Postfix(RoundManager __instance) { if (!_enabled.Value || (Object)(object)__instance == (Object)null || !((NetworkBehaviour)__instance).IsServer || (Object)(object)__instance.timeScript == (Object)null) { return; } float num = _scheduleMultiplier.Value; if (num <= 0f) { num = (_daySpeedEnabled.Value ? _daySpeedMultiplier.Value : 1f); } num = Mathf.Clamp(num, 0.05f, 5f); if (num >= 0.999f) { return; } float currentDayTime = __instance.timeScript.currentDayTime; for (int i = 0; i < __instance.enemySpawnTimes.Count; i++) { int num2 = __instance.enemySpawnTimes[i]; int value = Mathf.CeilToInt(currentDayTime + Math.Max(1f, (float)num2 - currentDayTime) * num); __instance.enemySpawnTimes[i] = value; } __instance.enemySpawnTimes.Sort(); if (__instance.allEnemyVents != null) { EnemyVent[] allEnemyVents = __instance.allEnemyVents; foreach (EnemyVent val in allEnemyVents) { if (!((Object)(object)val == (Object)null) && val.occupied && !(val.spawnTime <= currentDayTime)) { val.spawnTime = currentDayTime + Math.Max(1f, val.spawnTime - currentDayTime) * num; } } } int num3 = StartOfRound.Instance?.gameStats?.daysSpent ?? (-1); if (_lastLoggedDay != num3) { _lastLoggedDay = num3; ManualLogSource logger = _logger; if (logger != null) { logger.LogInfo((object)$"Enemy schedule compensation active at {num:0.##}x with minimum batches inside/outside {_minimumInside.Value}/{_minimumOutside.Value}."); } } } } internal static class TerminalMoonPricePatch { private const string MarkerPrefix = "[ecfMoonPrice:"; private static ConfigEntry<bool> _enabled; private static ManualLogSource _logger; private static readonly Regex MarkerRegex = new Regex("\\[ecfMoonPrice:(\\d+)\\]", RegexOptions.Compiled); internal static void Initialize(ConfigEntry<bool> enabled, ManualLogSource logger) { _enabled = enabled; _logger = logger; } public static void Prefix(ref string modifiedDisplayText) { if (_enabled.Value && !string.IsNullOrEmpty(modifiedDisplayText) && modifiedDisplayText.Contains("[planetTime]")) { int index = 0; modifiedDisplayText = Regex.Replace(modifiedDisplayText, Regex.Escape("[planetTime]"), (Match _) => "[planetTime][ecfMoonPrice:" + index++ + "]"); } } public static void Postfix(Terminal __instance, ref string __result) { if (!_enabled.Value || string.IsNullOrEmpty(__result) || !__result.Contains("[ecfMoonPrice:")) { return; } try { __result = MarkerRegex.Replace(__result, delegate(Match match) { if (!int.TryParse(match.Groups[1].Value, out var result) || __instance?.moonsCatalogueList == null || result < 0 || result >= __instance.moonsCatalogueList.Length) { return string.Empty; } int currentRoutePrice = GetCurrentRoutePrice(__instance.moonsCatalogueList[result]); return $" // Price: ${Math.Max(0, currentRoutePrice)}"; }); } catch (Exception ex) { ManualLogSource logger = _logger; if (logger != null) { logger.LogWarning((object)("Could not add moon prices to the terminal: " + ex.Message)); } __result = MarkerRegex.Replace(__result, string.Empty); } } private static int GetCurrentRoutePrice(SelectableLevel level) { if ((Object)(object)level == (Object)null) { return 0; } try { Type type = (from assembly in AppDomain.CurrentDomain.GetAssemblies() select assembly.GetType("LethalLevelLoader.PatchedContent", throwOnError: false)).FirstOrDefault((Type type3) => type3 != null); if (((type == null) ? null : AccessTools.Property(type, "ExtendedLevels"))?.GetValue(null, null) is IEnumerable enumerable) { foreach (object item in enumerable) { Type type2 = item.GetType(); object? obj = AccessTools.Property(type2, "SelectableLevel")?.GetValue(item, null); if (!((Object)((obj is SelectableLevel) ? obj : null) != (Object)(object)level)) { object obj2 = AccessTools.Property(type2, "RoutePrice")?.GetValue(item, null) ?? AccessTools.Field(type2, "routePrice")?.GetValue(item); if (obj2 is int) { return (int)obj2; } } } } } catch { } Terminal val = Object.FindObjectOfType<Terminal>(); if (val?.terminalNodes?.allKeywords != null) { TerminalKeyword[] allKeywords = val.terminalNodes.allKeywords; foreach (TerminalKeyword val2 in allKeywords) { if (val2?.compatibleNouns == null) { continue; } CompatibleNoun[] compatibleNouns = val2.compatibleNouns; for (int num2 = 0; num2 < compatibleNouns.Length; num2++) { TerminalNode val3 = compatibleNouns[num2]?.result; if ((Object)(object)val3 != (Object)null && val3.displayPlanetInfo == level.levelID && val3.itemCost >= 0) { return val3.itemCost; } } } } return 0; } } internal static class NavigationScanPatch { private static ConfigEntry<bool> _shipEnabled; private static ConfigEntry<bool> _entranceEnabled; private static ConfigEntry<int> _range; private static ScanNodeProperties _shipNode; private static ScanNodeProperties _entranceNode; private static MethodInfo _attemptScanNode; internal static void Initialize(ConfigEntry<bool> shipEnabled, ConfigEntry<bool> entranceEnabled, ConfigEntry<int> range) { _shipEnabled = shipEnabled; _entranceEnabled = entranceEnabled; _range = range; _attemptScanNode = AccessTools.Method(typeof(HUDManager), "AttemptScanNode", (Type[])null, (Type[])null); } public static void Postfix(HUDManager __instance, PlayerControllerB playerScript) { if ((Object)(object)__instance == (Object)null || (Object)(object)playerScript == (Object)null || playerScript.isInsideFactory || (Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.inShipPhase) { return; } if (_shipEnabled.Value) { Transform anchor = (((Object)(object)StartOfRound.Instance.shipBounds != (Object)null) ? ((Component)StartOfRound.Instance.shipBounds).transform : StartOfRound.Instance.elevatorTransform); _shipNode = GetOrCreateNode(_shipNode, anchor, "ECF Ship Scan Node", "SHIP", "Navigation"); if ((Object)(object)_shipNode != (Object)null) { _attemptScanNode?.Invoke(__instance, new object[3] { _shipNode, -1, playerScript }); } } if (_entranceEnabled.Value) { EntranceTeleport val = ((IEnumerable<EntranceTeleport>)Object.FindObjectsOfType<EntranceTeleport>()).FirstOrDefault((Func<EntranceTeleport, bool>)((EntranceTeleport item) => (Object)(object)item != (Object)null && item.entranceId == 0 && item.isEntranceToBuilding)); Transform anchor2 = (((Object)(object)val?.entrancePoint != (Object)null) ? val.entrancePoint : ((val != null) ? ((Component)val).transform : null)); _entranceNode = GetOrCreateNode(_entranceNode, anchor2, "ECF Main Entrance Scan Node", "MAIN ENTRANCE", "Navigation"); if ((Object)(object)_entranceNode != (Object)null) { _attemptScanNode?.Invoke(__instance, new object[3] { _entranceNode, -1, playerScript }); } } } private static ScanNodeProperties GetOrCreateNode(ScanNodeProperties existing, Transform anchor, string objectName, string header, string subText) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)anchor == (Object)null) { return null; } if ((Object)(object)existing == (Object)null) { GameObject val = new GameObject(objectName); val.transform.SetParent(anchor, false); existing = val.AddComponent<ScanNodeProperties>(); } else if ((Object)(object)((Component)existing).transform.parent != (Object)(object)anchor) { ((Component)existing).transform.SetParent(anchor, false); } ((Component)existing).transform.localPosition = Vector3.zero; existing.maxRange = _range.Value; existing.minRange = -1; existing.requiresLineOfSight = false; existing.headerText = header; existing.subText = subText; existing.nodeType = 1; return existing; } } internal static class InteriorWeightPatch { private static ConfigEntry<bool> _enabled; private static ConfigEntry<int> _exponentPercent; private static FieldInfo _rarityField; private static ManualLogSource _logger; private static int _noticeWritten; internal static void Initialize(ConfigEntry<bool> enabled, ConfigEntry<int> exponentPercent, ManualLogSource logger) { _enabled = enabled; _exponentPercent = exponentPercent; _logger = logger; } internal static void InitializeResultType(Type resultType) { Type type = (resultType.IsGenericType ? resultType.GetGenericArguments().FirstOrDefault() : null); _rarityField = ((type == null) ? null : AccessTools.Field(type, "rarity")); } public static void Postfix(object __result) { if (!_enabled.Value || _rarityField == null || !(__result is IEnumerable enumerable)) { return; } float num = (float)_exponentPercent.Value / 100f; int num2 = 0; foreach (object item in enumerable) { if (item == null) { continue; } int num3 = (int)_rarityField.GetValue(item); if (num3 > 0) { int num4 = ((num <= 0f) ? 1 : Math.Max(1, Mathf.RoundToInt(Mathf.Pow((float)num3, num)))); if (num4 != num3) { _rarityField.SetValue(item, num4); num2++; } } } if (num2 > 0 && Interlocked.Exchange(ref _noticeWritten, 1) == 0) { ManualLogSource logger = _logger; if (logger != null) { logger.LogInfo((object)$"Compressed {num2} valid interior selection weights using exponent {_exponentPercent.Value}%."); } } } } }