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 Apollo11 v1.0.4
BepInEx/plugins/RFGames-Apollo11/RFGames.Apollo11Mod.dll
Decompiled 19 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using Apollo11Mod.Enemies; using Apollo11Mod.Items; using Apollo11Mod.Moon; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Dissonance; using Dissonance.Audio.Capture; using GameNetcodeStuff; using HarmonyLib; using LethalLevelLoader; using LethalLib.Modules; using Microsoft.CodeAnalysis; using NAudio.Wave; using RFGames.Apollo11Mod.NetcodePatcher; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; using UnityEngine.Audio; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.Rendering.HighDefinition; using UnityEngine.SceneManagement; [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("RFGames.Apollo11Mod")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.4.0")] [assembly: AssemblyInformationalVersion("1.0.4")] [assembly: AssemblyProduct("Apollo11Mod")] [assembly: AssemblyTitle("RFGames.Apollo11Mod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.4.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] 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 Apollo11Mod { internal static class DeanieRegistration { internal static EnemyType DeanieType; internal static int Rarity = 30; internal static int TestRarity = 1000; internal static string TestMoons = ""; internal static void Register(AssetBundle bundle, ConfigFile cfg) { //IL_03a7: Unknown result type (might be due to invalid IL or missing references) EnemyType val = bundle.LoadAsset<EnemyType>("DeanieEnemy"); TerminalNode val2 = bundle.LoadAsset<TerminalNode>("DeanieTN"); TerminalKeyword val3 = bundle.LoadAsset<TerminalKeyword>("DeanieTK"); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"DeanieEnemy not in bundle (build it with Apollo11BuildDeanie) - Deanie disabled."); return; } NetworkPrefabs.RegisterNetworkPrefab(val.enemyPrefab); Rarity = cfg.Bind<int>("Deanie", "Rarity", 30, "Spawn weight inside the Lunar Base on 11 Apollo.").Value; val.MaxCount = cfg.Bind<int>("Deanie", "MaxCount", 1, "Max Deanies alive at once.").Value; bool value = cfg.Bind<bool>("Deanie", "TestForceSpawn", false, "TESTING: huge spawn weight + spawn from the start of the day on TestMoons.").Value; TestRarity = cfg.Bind<int>("Deanie", "TestRarity", 1000, "Weight used when TestForceSpawn is true.").Value; TestMoons = (value ? cfg.Bind<string>("Deanie", "TestMoons", "Apollo", "Planet-name fragments (comma separated) or All.").Value : ""); if (value) { val.probabilityCurve = AnimationCurve.Constant(0f, 1f, 1f); } DeanieSettings.FollowDistance = cfg.Bind<float>("Deanie", "FollowDistance", DeanieSettings.FollowDistance, "Cute form keeps about this far (m) from its player.").Value; DeanieSettings.AffectionPerPet = cfg.Bind<float>("Deanie", "AffectionPerPet", DeanieSettings.AffectionPerPet, "Affection added per completed pet (hold E ~1 s).").Value; DeanieSettings.AffectionThresholdMin = cfg.Bind<float>("Deanie", "ThresholdMin", DeanieSettings.AffectionThresholdMin, "Transform threshold is rolled per Deanie between ThresholdMin and ThresholdMax.").Value; DeanieSettings.AffectionThresholdMax = cfg.Bind<float>("Deanie", "ThresholdMax", DeanieSettings.AffectionThresholdMax, "See ThresholdMin.").Value; DeanieSettings.AffectionDecayPerSecond = cfg.Bind<float>("Deanie", "AffectionDecayPerSecond", DeanieSettings.AffectionDecayPerSecond, "How fast affection drains.").Value; DeanieSettings.AffectionOnHit = cfg.Bind<float>("Deanie", "AffectionOnHit", DeanieSettings.AffectionOnHit, "Affection added when the cute form is hit.").Value; DeanieSettings.HuntSpeed = cfg.Bind<float>("Deanie", "HuntSpeed", DeanieSettings.HuntSpeed, "Monster chase speed.").Value; DeanieSettings.CarrySpeed = cfg.Bind<float>("Deanie", "CarrySpeed", DeanieSettings.CarrySpeed, "Monster speed while carrying a player.").Value; DeanieSettings.MonsterHP = cfg.Bind<int>("Deanie", "MonsterHP", DeanieSettings.MonsterHP, "Monster health (shovel hit = 1).").Value; DeanieSettings.MonsterKillable = cfg.Bind<bool>("Deanie", "MonsterKillable", DeanieSettings.MonsterKillable, "Whether the monster form can be killed.").Value; DeanieSettings.HitsToDrop = cfg.Bind<int>("Deanie", "HitsToDrop", DeanieSettings.HitsToDrop, "Damage it takes while holding someone before it drops them and is stunned.").Value; DeanieSettings.StunAfterDrop = cfg.Bind<float>("Deanie", "StunAfterDrop", DeanieSettings.StunAfterDrop, "Stun seconds after dropping a victim.").Value; DeanieSettings.PetDamage = cfg.Bind<int>("Deanie", "PetDamage", DeanieSettings.PetDamage, "Damage per tick while being petted to death at the nest.").Value; DeanieSettings.PetTickInterval = cfg.Bind<float>("Deanie", "PetTickInterval", DeanieSettings.PetTickInterval, "Seconds between petting damage ticks.").Value; DeanieSettings.RevertAfterKill = cfg.Bind<bool>("Deanie", "RevertAfterKill", DeanieSettings.RevertAfterKill, "Turn cute again after killing someone, then wander off.").Value; DeanieSettings.CalmDownTime = cfg.Bind<float>("Deanie", "CalmDownTime", DeanieSettings.CalmDownTime, "Monster turns cute again after this many seconds with no target inside.").Value; DeanieSettings.RedEyeTimer = cfg.Bind<float>("Deanie", "RedEyeTimer", DeanieSettings.RedEyeTimer, "Once eyes go red, transform after this many seconds even if petting stops (0 = off). Visual twitch/red eyes stay; purr sound does not change.").Value; ((EnemyAI)val.enemyPrefab.GetComponent<DeanieAI>()).enemyHP = DeanieSettings.MonsterHP; Enemies.RegisterEnemy(val, Rarity, (LevelTypes)1, val2, val3); DeanieType = val; new Harmony("rfgames.apollo11mod.deanie").PatchAll(typeof(DeanieRegistration)); Plugin.Log.LogInfo((object)string.Format("Deanie registered (rarity {0}{1}).", Rarity, value ? $", TEST weight {TestRarity} on '{TestMoons}'" : "")); } [HarmonyPatch(typeof(RoundManager), "LoadNewLevel")] [HarmonyPrefix] private static void Inject(SelectableLevel newLevel) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown try { if ((Object)(object)DeanieType == (Object)null || (Object)(object)newLevel == (Object)null) { return; } int num = (MoonFeatures.MoonMatches(newLevel, TestMoons) ? TestRarity : (MoonFeatures.IsApollo(newLevel) ? Rarity : 0)); SpawnableEnemyWithRarity val = ((IEnumerable<SpawnableEnemyWithRarity>)newLevel.Enemies).FirstOrDefault((Func<SpawnableEnemyWithRarity, bool>)((SpawnableEnemyWithRarity e) => e != null && (Object)(object)e.enemyType == (Object)(object)DeanieType)); if (num <= 0) { if (val != null) { newLevel.Enemies.Remove(val); } return; } if (val == null) { val = new SpawnableEnemyWithRarity(DeanieType, num); newLevel.Enemies.Add(val); } val.rarity = num; Plugin.Log.LogInfo((object)$"Deanie weight {num} on '{newLevel.PlanetName}'."); } catch (Exception ex) { Plugin.Log.LogError((object)("Deanie Inject: " + ex)); } } } internal static class DoppelRegistration { internal static EnemyType DoppelType; internal static int Rarity = 25; internal static int TestRarity = 1000; internal static string TestMoons = ""; internal static void Register(AssetBundle bundle, ConfigFile cfg) { //IL_0424: Unknown result type (might be due to invalid IL or missing references) EnemyType val = bundle.LoadAsset<EnemyType>("DoppelEnemy"); TerminalNode val2 = bundle.LoadAsset<TerminalNode>("DoppelTN"); TerminalKeyword val3 = bundle.LoadAsset<TerminalKeyword>("DoppelTK"); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"DoppelEnemy not in bundle (build with Apollo11BuildDoppel) - Doppel disabled."); return; } NetworkPrefabs.RegisterNetworkPrefab(val.enemyPrefab); Rarity = cfg.Bind<int>("Doppel", "Rarity", 25, "Spawn weight inside the Lunar Base on 11 Apollo.").Value; val.MaxCount = cfg.Bind<int>("Doppel", "MaxCount", 1, "Max Doppels alive at once.").Value; bool value = cfg.Bind<bool>("Doppel", "TestForceSpawn", false, "TESTING: huge spawn weight + spawn from day start on TestMoons.").Value; TestRarity = cfg.Bind<int>("Doppel", "TestRarity", 1000, "Weight when TestForceSpawn is true.").Value; TestMoons = (value ? cfg.Bind<string>("Doppel", "TestMoons", "Apollo", "Planet-name fragments or All.").Value : ""); if (value) { val.probabilityCurve = AnimationCurve.Constant(0f, 1f, 1f); } DoppelSettings.FollowDistance = cfg.Bind<float>("Doppel", "FollowDistance", DoppelSettings.FollowDistance, "How far from the group centre it idles.").Value; DoppelSettings.WalkSpeed = cfg.Bind<float>("Doppel", "WalkSpeed", DoppelSettings.WalkSpeed, "Speed while holding the flashlight.").Value; DoppelSettings.ApproachSpeed = cfg.Bind<float>("Doppel", "ApproachSpeed", DoppelSettings.ApproachSpeed, "Speed while sneaking with the shovel.").Value; DoppelSettings.CrouchSpeed = cfg.Bind<float>("Doppel", "CrouchSpeed", DoppelSettings.CrouchSpeed, "Speed of the final crouched sneak.").Value; DoppelSettings.CrouchSneakDistance = cfg.Bind<float>("Doppel", "CrouchSneakDistance", DoppelSettings.CrouchSneakDistance, "Crouches when this close to its victim.").Value; DoppelSettings.ShovelDamage = cfg.Bind<int>("Doppel", "ShovelDamage", DoppelSettings.ShovelDamage, "Damage of one sneak shovel hit.").Value; DoppelSettings.HitCooldown = cfg.Bind<float>("Doppel", "HitCooldown", DoppelSettings.HitCooldown, "Seconds between sneak attacks.").Value; DoppelSettings.LookFovDegrees = cfg.Bind<float>("Doppel", "LookFovDegrees", DoppelSettings.LookFovDegrees, "Camera cone (degrees) that counts as looking at the Doppel.").Value; DoppelSettings.EnableVoiceMimic = cfg.Bind<bool>("DoppelVoice", "EnableVoiceMimic", true, "Doppel repeats real players' recorded voice clips (memory only, never saved). Off = garbled radio clips only.").Value; DoppelSettings.VoiceUseOwnOnly = cfg.Bind<bool>("DoppelVoice", "VoiceUseOwnOnly", false, "Solo/testing: every client hears the Doppel replay ITS OWN player's voice instead of the copied player's.").Value; DoppelSettings.ShareVoiceClips = cfg.Bind<bool>("DoppelVoice", "ShareVoiceClips", true, "Send your own recorded clips to the other players (host relays). Off = your voice is only mimicked on your own machine.").Value; DoppelSettings.RecordOnlyWhileTransmitting = cfg.Bind<bool>("DoppelVoice", "RecordOnlyWhileTransmitting", true, "Only record while your voice chat is actually transmitting (respects push-to-talk / mute).").Value; DoppelSettings.MaxClipsPerPlayer = cfg.Bind<int>("DoppelVoice", "MaxClipsPerPlayer", 20, "Recent clips kept per player.").Value; DoppelSettings.MinClipLength = cfg.Bind<float>("DoppelVoice", "MinClipLength", 1f, "Shortest clip kept (s).").Value; DoppelSettings.MaxClipLength = cfg.Bind<float>("DoppelVoice", "MaxClipLength", 4f, "Longest clip (s); longer speech is split.").Value; DoppelSettings.VoiceVadThreshold = cfg.Bind<float>("DoppelVoice", "VoiceActivityThreshold", 0.012f, "RMS level counted as speech (lower = more sensitive).").Value; DoppelSettings.VoiceSendMinInterval = cfg.Bind<float>("DoppelVoice", "SendMinInterval", 2f, "Min seconds between uploading clips (rate limit, newest clip wins).").Value; DoppelSettings.VoiceIntervalMin = cfg.Bind<float>("DoppelVoice", "PlayIntervalMin", DoppelSettings.VoiceIntervalMin, "Min seconds between Doppel lines.").Value; DoppelSettings.VoiceIntervalMax = cfg.Bind<float>("DoppelVoice", "PlayIntervalMax", DoppelSettings.VoiceIntervalMax, "Max seconds between Doppel lines.").Value; DoppelSettings.NearPlayerIntervalMultiplier = cfg.Bind<float>("DoppelVoice", "NearPlayerIntervalMultiplier", 0.5f, "Interval multiplier when a player is within 12 m (talks more).").Value; DoppelSettings.MimicVoiceVolume = cfg.Bind<float>("DoppelVoice", "MimicVoiceVolume", 1f, "Volume of replayed voice clips.").Value; ((EnemyAI)val.enemyPrefab.GetComponent<DoppelAI>()).enemyHP = DoppelSettings.MaxHP; Enemies.RegisterEnemy(val, Rarity, (LevelTypes)1, val2, val3); DoppelType = val; new Harmony("rfgames.apollo11mod.doppel").PatchAll(typeof(DoppelRegistration)); Plugin.Log.LogInfo((object)string.Format("Doppel registered (rarity {0}{1}).", Rarity, value ? $", TEST weight {TestRarity} on '{TestMoons}'" : "")); } [HarmonyPatch(typeof(RoundManager), "LoadNewLevel")] [HarmonyPrefix] private static void Inject(SelectableLevel newLevel) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown try { if ((Object)(object)DoppelType == (Object)null || (Object)(object)newLevel == (Object)null) { return; } int num = (MoonFeatures.MoonMatches(newLevel, TestMoons) ? TestRarity : (MoonFeatures.IsApollo(newLevel) ? Rarity : 0)); SpawnableEnemyWithRarity val = ((IEnumerable<SpawnableEnemyWithRarity>)newLevel.Enemies).FirstOrDefault((Func<SpawnableEnemyWithRarity, bool>)((SpawnableEnemyWithRarity e) => e != null && (Object)(object)e.enemyType == (Object)(object)DoppelType)); if (num <= 0) { if (val != null) { newLevel.Enemies.Remove(val); } return; } if (val == null) { val = new SpawnableEnemyWithRarity(DoppelType, num); newLevel.Enemies.Add(val); } val.rarity = num; Plugin.Log.LogInfo((object)$"Doppel weight {num} on '{newLevel.PlanetName}'."); } catch (Exception ex) { Plugin.Log.LogError((object)("Doppel Inject: " + ex)); } } } [HarmonyPatch(typeof(StartOfRound), "Start")] internal static class DoppelVoiceHooks { [HarmonyPostfix] private static void Postfix(StartOfRound __instance) { try { if (DoppelSettings.EnableVoiceMimic) { if ((Object)(object)((Component)__instance).GetComponent<DoppelVoiceRunner>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<DoppelVoiceRunner>(); } DoppelVoice.Init(); } } catch (Exception ex) { Plugin.Log.LogError((object)("DoppelVoice hook: " + ex)); } } } internal static class GoldScrapRegistration { internal static readonly List<Item> Items = new List<Item>(); internal static int ApolloRarity = 3; internal static int VanillaRarity = 1; internal static int MaxPerRound = 3; internal static string VanillaMoons = ""; internal static bool TestForceSpawn; internal static int TestCount = 4; internal static string TestMoons = "Apollo"; private static string lastKey; internal static void Register(AssetBundle bundle, ConfigFile cfg) { //IL_03c2: Unknown result type (might be due to invalid IL or missing references) if (!cfg.Bind<bool>("GoldScrap", "Enabled", true, "Add cursed gold scrap (golden vanilla scrap that whispers and explodes if held too long).").Value) { return; } GoldScrapSettings.FixedValue = Math.Max(1, cfg.Bind<int>("GoldScrap", "Value", 500, "Fixed sell value (credits) of every gold item, independent of the moon's scrap multiplier.").Value); ApolloRarity = cfg.Bind<int>("GoldScrap", "ApolloRarity", 3, "Spawn weight of EACH gold item on 11 Apollo (13 items; the moon's normal scrap pool weighs ~570, so 3 = about 1 gold item per round).").Value; VanillaRarity = cfg.Bind<int>("GoldScrap", "VanillaRarity", 1, "Spawn weight of EACH gold item on the moons listed in VanillaMoons (1 = roughly one gold item every 4-5 days).").Value; MaxPerRound = cfg.Bind<int>("GoldScrap", "MaxPerRound", 3, "Host: at most this many gold items are spawned inside the facility per round; extras are removed right after scrap spawning. 0 = no cap.").Value; VanillaMoons = cfg.Bind<string>("GoldScrap", "VanillaMoons", "Experimentation,Assurance,Vow,Offense,March,Adamance,Rend,Dine,Titan,Artifice,Embrion", "Comma-separated planet-name fragments (or All, or empty for none) where gold scrap also spawns with VanillaRarity. Remove a moon to turn it off.").Value; GoldScrapSettings.FuseMin = cfg.Bind<float>("GoldScrap", "FuseMin", 20f, "Shortest hidden fuse (s of continuous holding). Rerolled on every pickup.").Value; GoldScrapSettings.FuseMax = cfg.Bind<float>("GoldScrap", "FuseMax", 60f, "Longest hidden fuse (s).").Value; GoldScrapSettings.WarningSeconds = cfg.Bind<float>("GoldScrap", "WarningSeconds", 5f, "Accelerating beeps for this many seconds before it explodes.").Value; GoldScrapSettings.HeldMeansInInventory = cfg.Bind<bool>("GoldScrap", "HeldMeansInInventory", false, "false = the fuse only runs while it is the item in your hands (pocketing it resets the fuse like dropping). true = runs while it is anywhere in your inventory.").Value; GoldScrapSettings.WhisperIntervalMin = cfg.Bind<float>("GoldScrap", "WhisperIntervalMin", 7f, "Min seconds between whispers while held.").Value; GoldScrapSettings.WhisperIntervalMax = cfg.Bind<float>("GoldScrap", "WhisperIntervalMax", 18f, "Max seconds between whispers while held.").Value; GoldScrapSettings.WhisperVolume = cfg.Bind<float>("GoldScrap", "WhisperVolume", 0.75f, "Whisper volume in the holder's ear.").Value; GoldScrapSettings.OthersHearWhispers = cfg.Bind<bool>("GoldScrap", "OthersHearWhispers", true, "Nearby players faintly hear the whispers (3D, short range).").Value; GoldScrapSettings.KillRange = cfg.Bind<float>("GoldScrap", "KillRange", 5.7f, "Explosion kill radius (landmine = 5.7).").Value; GoldScrapSettings.DamageRange = cfg.Bind<float>("GoldScrap", "DamageRange", 6.4f, "Explosion damage radius (landmine = 6.4).").Value; GoldScrapSettings.NonLethalDamage = cfg.Bind<int>("GoldScrap", "NonLethalDamage", 50, "Damage between kill and damage radius.").Value; TestForceSpawn = cfg.Bind<bool>("GoldScrap", "TestForceSpawn", false, "TESTING: host spawns TestCount gold items just inside the main entrance on TestMoons.").Value; TestCount = cfg.Bind<int>("GoldScrap", "TestCount", 4, "TESTING: how many gold items to spawn.").Value; TestMoons = cfg.Bind<string>("GoldScrap", "TestMoons", "Apollo", "TESTING: planet-name fragments (or All) for TestForceSpawn.").Value; int maxValue = Mathf.RoundToInt((float)GoldScrapSettings.FixedValue / 0.4f); Item[] array = bundle.LoadAllAssets<Item>(); foreach (Item val in array) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.spawnPrefab == (Object)null) && !((Object)(object)val.spawnPrefab.GetComponent<CursedGoldItem>() == (Object)null)) { val.minValue = (val.maxValue = maxValue); Utilities.FixMixerGroups(val.spawnPrefab); NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab); Items.RegisterScrap(val, 0, (LevelTypes)1); Items.Add(val); } } if (Items.Count == 0) { Plugin.Log.LogError((object)"No gold scrap items in the bundle."); return; } Plugin.Log.LogInfo((object)string.Format("Gold scrap: {0} items ({1}), value {2}.", Items.Count, string.Join(", ", Items.Select((Item val2) => val2.itemName)), GoldScrapSettings.FixedValue)); new Harmony("rfgames.apollo11mod.goldscrap").PatchAll(typeof(GoldScrapRegistration)); } [HarmonyPatch(typeof(RoundManager), "LoadNewLevel")] [HarmonyPrefix] private static void Inject(SelectableLevel newLevel) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown try { if ((Object)(object)newLevel == (Object)null || newLevel.spawnableScrap == null) { return; } int num = (MoonFeatures.IsApollo(newLevel) ? ApolloRarity : (MoonFeatures.MoonMatches(newLevel, VanillaMoons) ? VanillaRarity : 0)); newLevel.spawnableScrap.RemoveAll((SpawnableItemWithRarity s) => s != null && Items.Contains(s.spawnableItem)); if (num <= 0) { return; } foreach (Item item in Items) { newLevel.spawnableScrap.Add(new SpawnableItemWithRarity(item, num)); } Plugin.Log.LogInfo((object)$"Gold scrap weight {num} x{Items.Count} on '{newLevel.PlanetName}'."); } catch (Exception ex) { Plugin.Log.LogError((object)("GoldScrap inject: " + ex)); } } [HarmonyPatch(typeof(GrabbableObject), "SetScrapValue")] [HarmonyPostfix] private static void FixValue(GrabbableObject __instance) { if (__instance is CursedGoldItem && __instance.scrapValue != GoldScrapSettings.FixedValue) { __instance.scrapValue = GoldScrapSettings.FixedValue; ScanNodeProperties componentInChildren = ((Component)__instance).GetComponentInChildren<ScanNodeProperties>(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.subText = $"Value: ${GoldScrapSettings.FixedValue}"; componentInChildren.scrapValue = GoldScrapSettings.FixedValue; } } } [HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")] [HarmonyPostfix] [HarmonyPriority(800)] private static void CapPerRound(RoundManager __instance) { try { if (MaxPerRound <= 0 || TestForceSpawn || !((NetworkBehaviour)__instance).IsServer) { return; } List<CursedGoldItem> list = (from g in Object.FindObjectsOfType<CursedGoldItem>() where (Object)(object)g != (Object)null && ((GrabbableObject)g).isInFactory && !((GrabbableObject)g).isInShipRoom && !((GrabbableObject)g).isHeld && (Object)(object)((GrabbableObject)g).playerHeldBy == (Object)null select g).ToList(); if (list.Count <= MaxPerRound) { if (list.Count > 0) { Plugin.Log.LogInfo((object)$"Gold scrap this round: {list.Count} (cap {MaxPerRound})."); } return; } List<CursedGoldItem> list2 = list.OrderBy((CursedGoldItem _) => Random.value).Skip(MaxPerRound).ToList(); foreach (CursedGoldItem item in list2) { NetworkObject component = ((Component)item).GetComponent<NetworkObject>(); if ((Object)(object)component != (Object)null && component.IsSpawned) { component.Despawn(true); } else { Object.Destroy((Object)(object)((Component)item).gameObject); } } Plugin.Log.LogInfo((object)$"Gold scrap this round: {list.Count} rolled, {list2.Count} removed (cap {MaxPerRound})."); } catch (Exception ex) { Plugin.Log.LogError((object)("GoldScrap cap: " + ex)); } } [HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")] [HarmonyPostfix] private static void TestSpawn(RoundManager __instance) { //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) try { if (!TestForceSpawn || Items.Count == 0 || !((NetworkBehaviour)__instance).IsServer) { return; } SelectableLevel currentLevel = __instance.currentLevel; if ((Object)(object)currentLevel == (Object)null || !MoonFeatures.MoonMatches(currentLevel, TestMoons)) { return; } string text = currentLevel.levelID + ":" + StartOfRound.Instance.randomMapSeed; if (text == lastKey) { return; } lastKey = text; EntranceTeleport val = ((IEnumerable<EntranceTeleport>)Object.FindObjectsOfType<EntranceTeleport>()).FirstOrDefault((Func<EntranceTeleport, bool>)((EntranceTeleport e) => e.entranceId == 0 && !e.isEntranceToBuilding)); if ((Object)(object)val == (Object)null || (Object)(object)val.entrancePoint == (Object)null) { Plugin.Log.LogWarning((object)"[GoldTest] no main entrance."); return; } Vector3 position = val.entrancePoint.position; for (int num = 0; num < TestCount; num++) { Item val2 = Items[(num + Random.Range(0, Items.Count)) % Items.Count]; Vector3 val3 = __instance.GetRandomNavMeshPositionInRadius(position + val.entrancePoint.forward * 2.5f, 2.5f, default(NavMeshHit)) + Vector3.up * 0.5f; GameObject obj = Object.Instantiate<GameObject>(val2.spawnPrefab, val3, Quaternion.identity, __instance.spawnedScrapContainer); GrabbableObject component = obj.GetComponent<GrabbableObject>(); component.fallTime = 0f; component.isInFactory = true; component.SetScrapValue(GoldScrapSettings.FixedValue); obj.GetComponent<NetworkObject>().Spawn(false); Plugin.Log.LogInfo((object)$"[GoldTest] spawned {val2.itemName} at {val3} ({Vector3.Distance(val3, position):F1} m from main entrance inside)."); } } catch (Exception ex) { Plugin.Log.LogError((object)("[GoldTest] failed: " + ex)); } } } internal static class LllPreRegisterFix { private static bool hookedRecovery; private static RuntimeAnimatorController cachedStub; internal static void ApplyPatches(Harmony harmony) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Expected O, but got Unknown int num = 0; BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; MethodInfo[] methods = typeof(ExtendedMod).GetMethods(bindingFlags); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name != "RegisterExtendedContent" || methodInfo.IsGenericMethodDefinition) { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 1) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(LllPreRegisterFix), "PrefixObject", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[Apollo11] LllPreRegisterFix patched ExtendedMod." + methodInfo.Name + "(" + parameters[0].ParameterType.Name + ")")); } num++; } } Type type = AccessTools.TypeByName("LethalLevelLoader.LethalBundleManager"); if (type != null) { methods = type.GetMethods(bindingFlags | BindingFlags.Static); foreach (MethodInfo methodInfo2 in methods) { if (methodInfo2.Name != "RegisterExtendedMod") { continue; } ParameterInfo[] parameters2 = methodInfo2.GetParameters(); if (parameters2.Length >= 1 && typeof(ExtendedMod).IsAssignableFrom(parameters2[0].ParameterType)) { harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(LllPreRegisterFix), "PrefixObject", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)"[Apollo11] LllPreRegisterFix patched LethalBundleManager.RegisterExtendedMod"); } num++; } } } if (num == 0) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogError((object)"[Apollo11] LllPreRegisterFix: no LLL register methods found to patch."); } } HookRecovery(); } private static void HookRecovery() { if (hookedRecovery) { return; } hookedRecovery = true; try { Plugin.onSetupComplete += TryRecoverApollo; if (Plugin.IsSetupComplete) { TryRecoverApollo(); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Apollo11] LllPreRegisterFix recovery hook failed: " + ex.Message)); } } } private static void TryRecoverApollo() { try { foreach (ExtendedLevel extendedLevel in PatchedContent.ExtendedLevels) { if ((Object)(object)((extendedLevel != null) ? extendedLevel.SelectableLevel : null) != (Object)null && MoonFeatures.IsApollo(extendedLevel.SelectableLevel)) { return; } } ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[Apollo11] 11 Apollo not in LLL ExtendedLevels after setup — attempting recovery re-register."); } ExtendedMod val = null; ExtendedMod[] array = Resources.FindObjectsOfTypeAll<ExtendedMod>(); foreach (ExtendedMod val2 in array) { if (!((Object)(object)val2 == (Object)null) && val2.ModName != null && val2.ModName.IndexOf("Apollo", StringComparison.OrdinalIgnoreCase) >= 0) { val = val2; break; } } if ((Object)(object)val == (Object)null) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogError((object)"[Apollo11] Recovery: Apollo ExtendedMod not found in memory."); } return; } List<ExtendedLevel> list = new List<ExtendedLevel>(); if (val.ExtendedLevels != null) { foreach (ExtendedLevel extendedLevel2 in val.ExtendedLevels) { if ((Object)(object)((extendedLevel2 != null) ? extendedLevel2.SelectableLevel : null) != (Object)null && MoonFeatures.IsApollo(extendedLevel2.SelectableLevel)) { list.Add(extendedLevel2); } } } if (list.Count == 0) { ExtendedLevel[] array2 = Resources.FindObjectsOfTypeAll<ExtendedLevel>(); foreach (ExtendedLevel val3 in array2) { if (!((Object)(object)((val3 != null) ? val3.SelectableLevel : null) == (Object)null) && MoonFeatures.IsApollo(val3.SelectableLevel)) { list.Add(val3); } } } if (list.Count == 0) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogError((object)"[Apollo11] Recovery: no Apollo ExtendedLevel in memory."); } return; } MethodInfo method = typeof(ExtendedMod).GetMethod("RegisterExtendedContent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(ExtendedLevel) }, null); if (method == null) { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogError((object)"[Apollo11] Recovery: RegisterExtendedContent(ExtendedLevel) not found."); } return; } foreach (ExtendedLevel item in list) { FixPlanet(item.SelectableLevel); try { method.Invoke(val, new object[1] { item }); ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogInfo((object)("[Apollo11] Recovery: re-registered " + ((Object)item).name)); } } catch (Exception ex) { ManualLogSource log6 = Plugin.Log; if (log6 != null) { log6.LogError((object)("[Apollo11] Recovery re-register failed: " + (ex.InnerException ?? ex))); } } } } catch (Exception ex2) { ManualLogSource log7 = Plugin.Log; if (log7 != null) { log7.LogError((object)("[Apollo11] TryRecoverApollo: " + ex2)); } } } private static void PrefixObject(object __0) { try { ExtendedLevel val = (ExtendedLevel)((__0 is ExtendedLevel) ? __0 : null); if (val != null) { FixPlanet(val.SelectableLevel); return; } ExtendedMod val2 = (ExtendedMod)((__0 is ExtendedMod) ? __0 : null); if (val2 == null) { return; } List<ExtendedLevel> extendedLevels = val2.ExtendedLevels; if (extendedLevels == null) { return; } foreach (ExtendedLevel item in extendedLevels) { if ((Object)(object)item != (Object)null) { FixPlanet(item.SelectableLevel); } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)("[Apollo11] LllPreRegisterFix: " + ex)); } } } internal static void FixPlanet(SelectableLevel sl) { GameObject val = sl?.planetPrefab; if ((Object)(object)val == (Object)null) { return; } VanillaRefs component = val.GetComponent<VanillaRefs>(); if ((Object)(object)component != (Object)null) { component.resolved = false; component.Resolve(); } Animator val2 = val.GetComponent<Animator>() ?? val.GetComponentInChildren<Animator>(true); if ((Object)(object)val2 == (Object)null) { return; } if ((Object)(object)val2.runtimeAnimatorController != (Object)null) { RuntimeAnimatorController runtimeAnimatorController = val2.runtimeAnimatorController; AnimatorOverrideController val3 = (AnimatorOverrideController)(object)((runtimeAnimatorController is AnimatorOverrideController) ? runtimeAnimatorController : null); if (val3 == null || !((Object)(object)val3.runtimeAnimatorController == (Object)null)) { return; } } RuntimeAnimatorController val4 = FindUsableController(); if ((Object)(object)val4 == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogError((object)"[Apollo11] Planet animator: no RuntimeAnimatorController available for LLL registration (GasGiant/Deanie/Airlock none loaded)."); } return; } val2.runtimeAnimatorController = val4; ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)("[Apollo11] Planet animator: assigned '" + ((Object)val4).name + "' before LLL registration.")); } } private static RuntimeAnimatorController FindUsableController() { if ((Object)(object)cachedStub != (Object)null) { return cachedStub; } RuntimeAnimatorController[] array = Resources.FindObjectsOfTypeAll<RuntimeAnimatorController>().Where(delegate(RuntimeAnimatorController c) { if ((Object)(object)c != (Object)null) { AnimatorOverrideController val4 = (AnimatorOverrideController)(object)((c is AnimatorOverrideController) ? c : null); if (val4 != null) { return !((Object)(object)val4.runtimeAnimatorController == (Object)null); } return true; } return false; }).ToArray(); RuntimeAnimatorController val = Pick(array, (RuntimeAnimatorController c) => ((Object)c).name == "GasGiant") ?? Pick(array, (RuntimeAnimatorController c) => ((Object)c).name != null && ((Object)c).name.StartsWith("Apollo11Planet", StringComparison.Ordinal)) ?? Pick(array, (RuntimeAnimatorController c) => ((Object)c).name != null && (((Object)c).name.StartsWith("Deanie", StringComparison.Ordinal) || ((Object)c).name.StartsWith("LB_", StringComparison.Ordinal) || ((Object)c).name.StartsWith("Apollo11", StringComparison.Ordinal))) ?? array.FirstOrDefault(); if ((Object)(object)val == (Object)null && (Object)(object)Plugin.Bundle != (Object)null) { string[] allAssetNames = Plugin.Bundle.GetAllAssetNames(); foreach (string text in allAssetNames) { if (text != null && (text.EndsWith(".controller", StringComparison.OrdinalIgnoreCase) || text.Contains("deanie") || text.Contains("anim"))) { RuntimeAnimatorController val2 = Plugin.Bundle.LoadAsset<RuntimeAnimatorController>(text); if ((Object)(object)val2 != (Object)null) { val = val2; break; } } } if ((Object)(object)val == (Object)null) { RuntimeAnimatorController[] array2 = Plugin.Bundle.LoadAllAssets<RuntimeAnimatorController>(); foreach (RuntimeAnimatorController val3 in array2) { if ((Object)(object)val3 != (Object)null) { val = val3; break; } } } } if ((Object)(object)val != (Object)null) { cachedStub = val; } return val; static RuntimeAnimatorController Pick(IEnumerable<RuntimeAnimatorController> all, Func<RuntimeAnimatorController, bool> pred) { return all.FirstOrDefault((Func<RuntimeAnimatorController, bool>)((RuntimeAnimatorController c) => Object.op_Implicit((Object)(object)c) && pred(c))); } } } internal static class MoonFeatures { internal static EnemyType CrackType; internal static int ApolloRarity = 40; internal static int TestRarity = 1000; internal static string TestMoons = ""; internal static bool LowGravity = true; internal static float GravityScale = 0.65f; internal static bool IsApollo(SelectableLevel l) { if ((Object)(object)l != (Object)null && l.PlanetName != null) { return l.PlanetName.IndexOf("Apollo", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } internal static bool MoonMatches(SelectableLevel l, string list) { if ((Object)(object)l == (Object)null || string.IsNullOrWhiteSpace(list)) { return false; } if (list.Trim().Equals("All", StringComparison.OrdinalIgnoreCase)) { return true; } return (from s in list.Split(',') select s.Trim() into s where s.Length > 0 select s).Any((string s) => l.PlanetName.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0); } [HarmonyPatch(typeof(RoundManager), "LoadNewLevel")] [HarmonyPrefix] private static void InjectCrack(SelectableLevel newLevel) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Expected O, but got Unknown try { if ((Object)(object)CrackType == (Object)null || (Object)(object)newLevel == (Object)null) { return; } int num = (MoonMatches(newLevel, TestMoons) ? TestRarity : (IsApollo(newLevel) ? ApolloRarity : 0)); SpawnableEnemyWithRarity val = ((IEnumerable<SpawnableEnemyWithRarity>)newLevel.Enemies).FirstOrDefault((Func<SpawnableEnemyWithRarity, bool>)((SpawnableEnemyWithRarity e) => e != null && (Object)(object)e.enemyType == (Object)(object)CrackType)); if (num <= 0) { if (val != null) { newLevel.Enemies.Remove(val); } return; } if (val == null) { val = new SpawnableEnemyWithRarity(CrackType, num); newLevel.Enemies.Add(val); } val.rarity = num; Plugin.Log.LogInfo((object)$"Wall Crack weight {num} on '{newLevel.PlanetName}'."); } catch (Exception ex) { Plugin.Log.LogError((object)("InjectCrack: " + ex)); } } [HarmonyPatch(typeof(PlayerControllerB), "Update")] [HarmonyPostfix] private static void LunarGravity(PlayerControllerB __instance) { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || !IsApollo(instance.currentLevel) || instance.inShipPhase) { return; } GameNetworkManager instance2 = GameNetworkManager.Instance; if (!((Object)(object)instance2 == (Object)null) && !((Object)(object)__instance != (Object)(object)instance2.localPlayerController)) { MoonFog.Tick(__instance.isInsideFactory); if (!__instance.isInsideFactory && !__instance.isPlayerDead && !__instance.isClimbingLadder && !__instance.isUnderwater && __instance.isPlayerControlled && LowGravity && !(GravityScale >= 0.999f) && !((Object)(object)__instance.thisController == (Object)null) && !__instance.thisController.isGrounded && !__instance.isInHangarShipRoom) { float num = 1f - GravityScale; float deltaTime = Time.deltaTime; __instance.fallValue = Mathf.Min(__instance.fallValue + 38f * num * deltaTime, __instance.jumpForce); __instance.fallValueUncapped += 38f * num * deltaTime; } } } } internal static class MoonFog { internal static bool Enabled = true; private static Volume vol; internal static void Init() { SceneManager.sceneLoaded += OnSceneLoaded; } private static void OnSceneLoaded(Scene scene, LoadSceneMode mode) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown if (!Enabled || ((Scene)(ref scene)).name != "Apollo11Level") { return; } int num = 0; GameObject[] rootGameObjects = ((Scene)(ref scene)).GetRootGameObjects(); for (int i = 0; i < rootGameObjects.Length; i++) { LocalVolumetricFog[] componentsInChildren = rootGameObjects[i].GetComponentsInChildren<LocalVolumetricFog>(true); for (int j = 0; j < componentsInChildren.Length; j++) { ((Behaviour)componentsInChildren[j]).enabled = false; num++; } } GameObject val = new GameObject("Apollo11_NoFogVolume"); SceneManager.MoveGameObjectToScene(val, scene); vol = val.AddComponent<Volume>(); vol.isGlobal = true; vol.priority = 1000f; vol.weight = 1f; VolumeProfile val2 = ScriptableObject.CreateInstance<VolumeProfile>(); Fog obj = val2.Add<Fog>(true); ((VolumeParameter<bool>)(object)obj.enabled).Override(false); ((VolumeParameter<bool>)(object)obj.enableVolumetricFog).Override(false); ((VolumeParameter<bool>)(object)val2.Add<VolumetricClouds>(true).enable).Override(false); vol.sharedProfile = val2; Plugin.Log.LogInfo((object)$"MoonFog: no-fog volume added on {((Scene)(ref scene)).name}, disabled {num} LocalVolumetricFog."); } internal static void Tick(bool inside) { if ((Object)(object)vol != (Object)null) { vol.weight = (inside ? 0f : 1f); } } } [BepInPlugin("rfgames.apollo11mod", "Apollo 11", "1.0.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static AssetBundle Bundle; private const string BundleName = "apollo11assets"; private void Awake() { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; InitNetcodePatcher(); string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "apollo11assets"); if (!File.Exists(text)) { Log.LogError((object)("Asset bundle not found at " + text + ". Build it in Unity first (see README).")); return; } Bundle = AssetBundle.LoadFromFile(text); RegisterWallCrack(); DeanieRegistration.Register(Bundle, ((BaseUnityPlugin)this).Config); DoppelRegistration.Register(Bundle, ((BaseUnityPlugin)this).Config); GoldScrapRegistration.Register(Bundle, ((BaseUnityPlugin)this).Config); SuitsRegistration.Register(Bundle, ((BaseUnityPlugin)this).Config); ZombieRegistration.Register(Bundle, ((BaseUnityPlugin)this).Config); new Harmony("rfgames.apollo11mod").PatchAll(typeof(TestSpawner)); new Harmony("rfgames.apollo11mod.deanietest").PatchAll(typeof(TestSpawnerDeanie)); new Harmony("rfgames.apollo11mod.doppeltest").PatchAll(typeof(TestSpawnerDoppel)); new Harmony("rfgames.apollo11mod.doppelvoice").PatchAll(typeof(DoppelVoiceHooks)); new Harmony("rfgames.apollo11mod.vanillarefs").PatchAll(typeof(VanillaAssetHooks)); LllPreRegisterFix.ApplyPatches(new Harmony("rfgames.apollo11mod.lllprereg")); Log.LogInfo((object)"Apollo 11 1.0.4 loaded."); } private void RegisterWallCrack() { //IL_029c: Unknown result type (might be due to invalid IL or missing references) EnemyType val = Bundle.LoadAsset<EnemyType>("WallCrackEnemy"); TerminalNode val2 = Bundle.LoadAsset<TerminalNode>("WallCrackTN"); TerminalKeyword val3 = Bundle.LoadAsset<TerminalKeyword>("WallCrackTK"); if ((Object)(object)val == (Object)null) { Log.LogError((object)"WallCrackEnemy not in bundle."); return; } NetworkPrefabs.RegisterNetworkPrefab(val.enemyPrefab); int value = ((BaseUnityPlugin)this).Config.Bind<int>("WallCrack", "Rarity", 40, "Spawn weight of the Wall Crack inside the Lunar Base on 11 Apollo (the only moon it spawns on in normal play).").Value; bool value2 = ((BaseUnityPlugin)this).Config.Bind<bool>("Testing", "ForceSpawn", false, "TESTING: give the Wall Crack a huge spawn weight on the ForceSpawnMoons. Set false for normal play.").Value; int value3 = ((BaseUnityPlugin)this).Config.Bind<int>("Testing", "ForceSpawnRarity", 1000, "Spawn weight used when ForceSpawn is true.").Value; string value4 = ((BaseUnityPlugin)this).Config.Bind<string>("Testing", "ForceSpawnMoons", "Experimentation,Apollo", "Comma-separated planet-name fragments that get the forced weight / test spawns (e.g. Experimentation,Apollo), or All.").Value; int value5 = ((BaseUnityPlugin)this).Config.Bind<int>("Testing", "MaxCount", 2, "Max Wall Cracks alive at once.").Value; val.MaxCount = value5; TestSpawner.CrackType = val; TestSpawner.Moons = value4; TestSpawner.Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Testing", "SpawnOnLevelLoad", false, "TESTING: host spawns Count Wall Cracks near the main entrance (inside) as soon as the interior has generated (ForceSpawnMoons only).").Value; TestSpawner.Count = ((BaseUnityPlugin)this).Config.Bind<int>("Testing", "Count", 3, "How many Wall Cracks SpawnOnLevelLoad spawns.").Value; WallCrackAI.ShowDebugMarker = ((BaseUnityPlugin)this).Config.Bind<bool>("Testing", "DebugMarker", false, "TESTING: show a bright green sphere + light at each Wall Crack's final position.").Value; Log.LogInfo((object)$"Testing: DebugMarker={WallCrackAI.ShowDebugMarker}, SpawnOnLevelLoad={TestSpawner.Enabled}, Count={TestSpawner.Count}, moons={value4}"); if (value2) { val.probabilityCurve = AnimationCurve.Constant(0f, 1f, 1f); Log.LogWarning((object)$"TESTING: Wall Crack forced spawn weight {value3} on '{value4}'."); } Enemies.RegisterEnemy(val, value, (LevelTypes)1, val2, val3); MoonFeatures.CrackType = val; MoonFeatures.ApolloRarity = value; MoonFeatures.TestMoons = (value2 ? value4 : ""); MoonFeatures.TestRarity = value3; MoonFeatures.LowGravity = ((BaseUnityPlugin)this).Config.Bind<bool>("Moon", "LowGravity", true, "Lower gravity while outdoors on 11 Apollo.").Value; MoonFeatures.GravityScale = Mathf.Clamp(((BaseUnityPlugin)this).Config.Bind<float>("Moon", "GravityScale", 0.65f, "Fraction of normal gravity outdoors on 11 Apollo (1 = vanilla). 0.65 = ~1.5x jump height, slower falls.").Value, 0.3f, 1f); new Harmony("rfgames.apollo11mod.moon").PatchAll(typeof(MoonFeatures)); bool value6 = ((BaseUnityPlugin)this).Config.Bind<bool>("Testing", "FreeRoute", false, "TESTING: make the route to 11 Apollo free (overrides [Moon] RoutePrice).").Value; int value7 = ((BaseUnityPlugin)this).Config.Bind<int>("Moon", "RoutePrice", 250, "Route price to 11 Apollo in normal play.").Value; LaserBridge.CycleEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Bridge", "BridgeEnabled", true, "Timed hard-light bridge over the hatch chasm on 11 Apollo. false = the bridge stays on (solid) all day. The host's settings are used.").Value; LaserBridge.OnTime = Mathf.Clamp(((BaseUnityPlugin)this).Config.Bind<float>("Bridge", "BridgeOnTime", 5.5f, "Seconds the bridge is steady and solid. Default = 1.8 x the ~3.05 s standing-start sprint across the 26 m deck. The bridge stays solid through the warning too.").Value, 1f, 120f); LaserBridge.WarningTime = Mathf.Clamp(((BaseUnityPlugin)this).Config.Bind<float>("Bridge", "BridgeWarningTime", 3f, "Seconds of warning (still solid: flicker, rising beeps, amber then red pylon lights) before it switches off.").Value, 0.5f, 30f); LaserBridge.OffTime = Mathf.Clamp(((BaseUnityPlugin)this).Config.Bind<float>("Bridge", "BridgeOffTime", 8f, "Seconds the bridge is OFF (no deck: anyone on it falls). Includes the 1.5 s power-up flicker at the end.").Value, 2f, 120f); MoonFog.Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Moon", "NoFog", true, "Remove all fog/haze outdoors on 11 Apollo.").Value; MoonFog.Init(); RoutePriceOverride.Price = ((!value6) ? Math.Max(0, value7) : 0); if (Chainloader.PluginInfos.ContainsKey("imabatby.lethallevelloader")) { HookRoutePrice(); } else { Log.LogWarning((object)"LethalLevelLoader not found - route price override disabled."); } } [MethodImpl(MethodImplOptions.NoInlining)] private static void HookRoutePrice() { RoutePriceOverride.Hook(); } private static void InitNetcodePatcher() { Type[] types = Assembly.GetExecutingAssembly().GetTypes(); for (int i = 0; i < types.Length; i++) { MethodInfo[] methods = types[i].GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0) { methodInfo.Invoke(null, null); } } } } } internal static class RoutePriceOverride { internal static int Price = 250; internal static void Hook() { Plugin.onSetupComplete += Apply; Plugin.onLobbyInitialized += Apply; if (Plugin.IsSetupComplete) { Apply(); } } private static void Apply() { try { bool flag = false; foreach (ExtendedLevel extendedLevel in PatchedContent.ExtendedLevels) { SelectableLevel val = ((extendedLevel != null) ? extendedLevel.SelectableLevel : null); if (!((Object)(object)val == (Object)null) && MoonFeatures.IsApollo(val)) { extendedLevel.RoutePrice = Price; flag = true; Plugin.Log.LogInfo((object)$"Route price for '{val.PlanetName}' set to {Price} (now {extendedLevel.RoutePrice})."); } } if (!flag) { Plugin.Log.LogWarning((object)"RoutePriceOverride: 11 Apollo ExtendedLevel not found."); } } catch (Exception ex) { Plugin.Log.LogError((object)("RoutePriceOverride: " + ex)); } } } internal static class SuitsRegistration { private static readonly (string key, string name)[] Suits = new(string, string)[4] { ("Moonwalker", "Moonwalker suit"), ("Pumpkin", "Pumpkin suit"), ("Sokol", "Sokol suit"), ("ApolloA7L", "Apollo A7L suit") }; internal static void Register(AssetBundle bundle, ConfigFile cfg) { //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Expected O, but got Unknown if (!cfg.Bind<bool>("Suits", "Enabled", true, "Add the space suits to the ship's suit rack.").Value) { return; } bool value = cfg.Bind<bool>("Suits", "SuitsAlwaysUnlocked", true, "true = suits hang on the rack from the start (free). false = buy them in the terminal store.").Value; int value2 = cfg.Bind<int>("Suits", "Price", 60, "Store price per suit when SuitsAlwaysUnlocked = false.").Value; List<string> source = (from s in cfg.Bind<string>("Suits", "EnabledSuits", "Moonwalker,Pumpkin,Sokol,ApolloA7L", "Comma-separated suits to add (Moonwalker, Pumpkin, Sokol, ApolloA7L).").Value.Split(',') select s.Trim() into s where s.Length > 0 select s).ToList(); int num = 0; (string, string)[] suits = Suits; for (int num2 = 0; num2 < suits.Length; num2++) { var (key, unlockableName) = suits[num2]; if (!source.Any((string s) => s.Equals(key, StringComparison.OrdinalIgnoreCase))) { continue; } Material val = bundle.LoadAsset<Material>("Apollo11Suit_" + key); if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)("Suit material missing: Apollo11Suit_" + key)); continue; } UnlockableItem val2 = new UnlockableItem { unlockableName = unlockableName, unlockableType = 0, suitMaterial = val, alreadyUnlocked = value, alwaysInStock = true, IsPlaceable = false, spawnPrefab = false, canBeStored = false, maxNumber = 1 }; if (value) { Unlockables.RegisterUnlockable(val2, (StoreType)0, (TerminalNode)null, (TerminalNode)null, (TerminalNode)null, -1); } else { Unlockables.RegisterUnlockable(val2, (StoreType)1, (TerminalNode)null, (TerminalNode)null, (TerminalNode)null, Math.Max(0, value2)); } num++; } Plugin.Log.LogInfo((object)string.Format("Suits: {0} space suits registered ({1}).", num, value ? "always unlocked" : ("store, " + value2 + " credits"))); } } [HarmonyPatch(typeof(RoundManager), "RefreshEnemyVents")] internal static class TestSpawner { internal static bool Enabled; internal static int Count = 3; internal static string Moons = "Experimentation"; internal static EnemyType CrackType; private static string lastKey; [HarmonyPostfix] private static void Postfix(RoundManager __instance) { //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) try { if (!Enabled || (Object)(object)CrackType == (Object)null || !((NetworkBehaviour)__instance).IsServer || !__instance.dungeonFinishedGeneratingForAllPlayers) { return; } SelectableLevel currentLevel = __instance.currentLevel; if ((Object)(object)currentLevel == (Object)null || !currentLevel.spawnEnemiesAndScrap) { return; } string text = currentLevel.levelID + ":" + StartOfRound.Instance.randomMapSeed; if (text == lastKey) { return; } lastKey = text; if (!MoonFeatures.MoonMatches(currentLevel, Moons)) { Plugin.Log.LogInfo((object)("[TestSpawn] skipping, level '" + currentLevel.PlanetName + "' not in ForceSpawnMoons='" + Moons + "'.")); return; } EntranceTeleport val = ((IEnumerable<EntranceTeleport>)Object.FindObjectsOfType<EntranceTeleport>()).FirstOrDefault((Func<EntranceTeleport, bool>)((EntranceTeleport e) => e.entranceId == 0 && !e.isEntranceToBuilding)); Vector3 origin = (((Object)(object)val != (Object)null) ? val.entrancePoint.position : ((__instance.insideAINodes.Length != 0) ? __instance.insideAINodes[0].transform.position : Vector3.zero)); Plugin.Log.LogInfo((object)($"[TestSpawn] level '{currentLevel.PlanetName}', main entrance (inside) at {origin} (found={(Object)(object)val != (Object)null}), " + $"insideAINodes={__instance.insideAINodes.Length}, spawning {Count} Wall Crack(s).")); List<GameObject> list = (from n in __instance.insideAINodes where (Object)(object)n != (Object)null orderby Vector3.Distance(n.transform.position, origin) select n).Take(Math.Max(Count * 3, 6)).ToList(); if (list.Count == 0) { Plugin.Log.LogError((object)"[TestSpawn] no insideAINodes, cannot spawn."); return; } Random random = new Random(StartOfRound.Instance.randomMapSeed + 4711); for (int num = 0; num < Count; num++) { GameObject val2 = list[Math.Min(list.Count - 1, num * 3 + random.Next(0, 2))]; Vector3 randomNavMeshPositionInRadius = __instance.GetRandomNavMeshPositionInRadius(val2.transform.position, 1.5f, default(NavMeshHit)); try { __instance.SpawnEnemyGameObject(randomNavMeshPositionInRadius, (float)random.NextDouble() * 360f, -1, CrackType); Plugin.Log.LogInfo((object)$"[TestSpawn] #{num + 1} spawned at {randomNavMeshPositionInRadius} (node '{((Object)val2).name}', {Vector3.Distance(randomNavMeshPositionInRadius, origin):F1} m from main entrance)."); } catch (Exception arg) { Plugin.Log.LogError((object)$"[TestSpawn] #{num + 1} spawn at {randomNavMeshPositionInRadius} failed: {arg}"); } } } catch (Exception ex) { Plugin.Log.LogError((object)("[TestSpawn] failed: " + ex)); } } } [HarmonyPatch(typeof(RoundManager), "RefreshEnemyVents")] internal static class TestSpawnerDeanie { private static string lastKey; [HarmonyPostfix] private static void Postfix(RoundManager __instance) { //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) try { EnemyType type = DeanieRegistration.DeanieType; string testMoons = DeanieRegistration.TestMoons; if ((Object)(object)type == (Object)null || string.IsNullOrEmpty(testMoons) || !((NetworkBehaviour)__instance).IsServer || !__instance.dungeonFinishedGeneratingForAllPlayers) { return; } SelectableLevel currentLevel = __instance.currentLevel; if ((Object)(object)currentLevel == (Object)null || !currentLevel.spawnEnemiesAndScrap) { return; } string text = currentLevel.levelID + ":" + StartOfRound.Instance.randomMapSeed; if (text == lastKey) { return; } lastKey = text; if (!MoonFeatures.MoonMatches(currentLevel, testMoons)) { Plugin.Log.LogInfo((object)("[DeanieTest] skipping, '" + currentLevel.PlanetName + "' not in TestMoons='" + testMoons + "'.")); return; } if (Object.FindObjectsOfType<EnemyAI>().Any((EnemyAI e) => (Object)(object)e.enemyType == (Object)(object)type)) { Plugin.Log.LogInfo((object)"[DeanieTest] a Deanie already exists, not spawning another."); return; } EntranceTeleport val = ((IEnumerable<EntranceTeleport>)Object.FindObjectsOfType<EntranceTeleport>()).FirstOrDefault((Func<EntranceTeleport, bool>)((EntranceTeleport e) => e.entranceId == 0 && !e.isEntranceToBuilding)); Vector3 origin = (((Object)(object)val != (Object)null) ? val.entrancePoint.position : ((__instance.insideAINodes.Length != 0) ? __instance.insideAINodes[0].transform.position : Vector3.zero)); GameObject val2 = (from n in __instance.insideAINodes where (Object)(object)n != (Object)null orderby Vector3.Distance(n.transform.position, origin) select n).Skip(1).FirstOrDefault(); if ((Object)(object)val2 == (Object)null) { Plugin.Log.LogError((object)"[DeanieTest] no insideAINodes, cannot spawn."); return; } Vector3 randomNavMeshPositionInRadius = __instance.GetRandomNavMeshPositionInRadius(val2.transform.position, 1.5f, default(NavMeshHit)); __instance.SpawnEnemyGameObject(randomNavMeshPositionInRadius, Random.Range(0f, 360f), -1, type); Plugin.Log.LogInfo((object)$"[DeanieTest] spawned 1 Deanie at {randomNavMeshPositionInRadius} (node '{((Object)val2).name}', {Vector3.Distance(randomNavMeshPositionInRadius, origin):F1} m from the main entrance) on '{currentLevel.PlanetName}'."); } catch (Exception ex) { Plugin.Log.LogError((object)("[DeanieTest] failed: " + ex)); } } } [HarmonyPatch(typeof(RoundManager), "RefreshEnemyVents")] internal static class TestSpawnerDoppel { private static string lastKey; [HarmonyPostfix] private static void Postfix(RoundManager __instance) { //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) try { EnemyType type = DoppelRegistration.DoppelType; string testMoons = DoppelRegistration.TestMoons; if ((Object)(object)type == (Object)null || string.IsNullOrEmpty(testMoons) || !((NetworkBehaviour)__instance).IsServer || !__instance.dungeonFinishedGeneratingForAllPlayers) { return; } SelectableLevel currentLevel = __instance.currentLevel; if ((Object)(object)currentLevel == (Object)null || !currentLevel.spawnEnemiesAndScrap) { return; } string text = currentLevel.levelID + ":" + StartOfRound.Instance.randomMapSeed; if (text == lastKey) { return; } lastKey = text; if (!MoonFeatures.MoonMatches(currentLevel, testMoons)) { Plugin.Log.LogInfo((object)("[DoppelTest] skipping, '" + currentLevel.PlanetName + "' not in TestMoons='" + testMoons + "'.")); return; } if (Object.FindObjectsOfType<EnemyAI>().Any((EnemyAI e) => (Object)(object)e.enemyType == (Object)(object)type)) { Plugin.Log.LogInfo((object)"[DoppelTest] a Doppel already exists."); return; } EntranceTeleport val = ((IEnumerable<EntranceTeleport>)Object.FindObjectsOfType<EntranceTeleport>()).FirstOrDefault((Func<EntranceTeleport, bool>)((EntranceTeleport e) => e.entranceId == 0 && !e.isEntranceToBuilding)); Vector3 origin = (((Object)(object)val != (Object)null) ? val.entrancePoint.position : ((__instance.insideAINodes.Length != 0) ? __instance.insideAINodes[0].transform.position : Vector3.zero)); GameObject val2 = (from n in __instance.insideAINodes where (Object)(object)n != (Object)null orderby Vector3.Distance(n.transform.position, origin) select n).Skip(2).FirstOrDefault(); if ((Object)(object)val2 == (Object)null) { Plugin.Log.LogError((object)"[DoppelTest] no insideAINodes."); return; } Vector3 randomNavMeshPositionInRadius = __instance.GetRandomNavMeshPositionInRadius(val2.transform.position, 1.5f, default(NavMeshHit)); __instance.SpawnEnemyGameObject(randomNavMeshPositionInRadius, Random.Range(0f, 360f), -1, type); Plugin.Log.LogInfo((object)$"[DoppelTest] spawned 1 Doppel at {randomNavMeshPositionInRadius} ({Vector3.Distance(randomNavMeshPositionInRadius, origin):F1} m from main entrance) on '{currentLevel.PlanetName}'."); } catch (Exception ex) { Plugin.Log.LogError((object)("[DoppelTest] failed: " + ex)); } } } [HarmonyPatch] internal static class VanillaAssetHooks { private static bool applied; [HarmonyPatch(typeof(StartOfRound), "Start")] [HarmonyPostfix] private static void StartOfRoundStart() { if (!((Object)(object)Plugin.Bundle == (Object)null)) { int num = 0; int num2 = 0; VanillaAssetRefs[] array = Plugin.Bundle.LoadAllAssets<VanillaAssetRefs>(); foreach (VanillaAssetRefs vanillaAssetRefs in array) { num += vanillaAssetRefs.Apply(); num2++; } Plugin.Log.LogInfo((object)string.Format("[Apollo11] VanillaAssetRefs applied from {0} manifest(s){1}, {2} missing; running totals ok={3} missing={4}", num2, applied ? " (re-applied)" : "", num, VanillaResolver.TotalOk, VanillaResolver.TotalFail)); applied = true; } } } [Serializable] public class VRef { public string target = ""; public string comp = ""; public int compIndex; public string prop = ""; public string src = ""; public string srcPath = ""; public string srcComp = ""; public int srcCompIndex; public string srcProp = ""; public string label = ""; } [DefaultExecutionOrder(-30000)] public class VanillaRefs : MonoBehaviour { public VRef[] refs = new VRef[0]; public VanillaAssetRefs[] assetManifests = new VanillaAssetRefs[0]; [NonSerialized] public bool resolved; private void Awake() { if (assetManifests != null) { VanillaAssetRefs[] array = assetManifests; foreach (VanillaAssetRefs vanillaAssetRefs in array) { if ((Object)(object)vanillaAssetRefs != (Object)null) { vanillaAssetRefs.Apply(); } } } Resolve(); } private void OnEnable() { if (!resolved) { Resolve(); } } public void Resolve() { if (resolved || refs == null) { return; } int num = 0; int num2 = 0; VRef[] array = refs; foreach (VRef vRef in array) { try { Transform val = VanillaResolver.FindPath(((Component)this).transform, vRef.target); if ((Object)(object)val == (Object)null) { num2++; VanillaResolver.Miss(((Object)this).name, vRef, "target path missing"); continue; } object component = VanillaResolver.GetComponent(((Component)val).gameObject, vRef.comp, vRef.compIndex); if (component == null) { num2++; VanillaResolver.Miss(((Object)this).name, vRef, "target component missing"); continue; } Object val2 = VanillaResolver.Lookup(vRef); if (val2 == (Object)null) { num2++; VanillaResolver.Miss(((Object)this).name, vRef, "source not found"); } else if (PropAccess.Set(component, vRef.prop, val2)) { num++; } else { num2++; VanillaResolver.Miss(((Object)this).name, vRef, "set failed"); } } catch (Exception ex) { num2++; VanillaResolver.Miss(((Object)this).name, vRef, ex.GetType().Name + ": " + ex.Message); } } resolved = num2 == 0 || VanillaResolver.GameReady; VanillaResolver.Report(((Object)this).name, num, num2, refs.Length); if (num2 == 0) { PostResolve(); } } private void PostResolve() { Animator[] componentsInChildren = ((Component)this).GetComponentsInChildren<Animator>(true); foreach (Animator val in componentsInChildren) { if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.runtimeAnimatorController) && !val.isInitialized && ((Behaviour)val).isActiveAndEnabled) { val.Rebind(); } } } } public class VanillaAssetRefs : ScriptableObject { [Serializable] public class Entry { public Object target; public VRef r = new VRef(); } public Entry[] entries = new Entry[0]; public int Apply() { int num = 0; int num2 = 0; Entry[] array = entries; foreach (Entry entry in array) { if (entry == null || entry.target == (Object)null) { continue; } try { Object val = VanillaResolver.Lookup(entry.r); if (val != (Object)null && PropAccess.Set(entry.target, entry.r.prop, val)) { num++; continue; } num2++; VanillaResolver.Miss(entry.target.name, entry.r, (val == (Object)null) ? "source not found" : "set failed"); } catch (Exception ex) { num2++; VanillaResolver.Miss(entry.target.name, entry.r, ex.Message); } } VanillaResolver.Report("asset manifest " + ((Object)this).name, num, num2, entries.Length); return num2; } } public static class VanillaResolver { private static readonly Dictionary<string, Object> cache = new Dictionary<string, Object>(); private static Dictionary<string, GameObject> prefabRoots; private static readonly Dictionary<Type, Dictionary<string, Object>> byType = new Dictionary<Type, Dictionary<string, Object>>(); private static readonly HashSet<string> reported = new HashSet<string>(); private static bool hooked; public static int TotalOk; public static int TotalFail; private static readonly Dictionary<string, Type> types = new Dictionary<string, Type>(); public static bool GameReady => (Object)(object)StartOfRound.Instance != (Object)null; public static Transform FindPath(Transform root, string path) { if (string.IsNullOrEmpty(path)) { return root; } Transform val = root; string[] array = path.Split('/'); foreach (string text in array) { if ((Object)(object)val == (Object)null) { return null; } int num = text.LastIndexOf('#'); if (num > 0 && int.TryParse(text.Substring(num + 1), out var result)) { Transform val2 = ((result < val.childCount) ? val.GetChild(result) : null); val = (((Object)(object)val2 != (Object)null && ((Object)val2).name == text.Substring(0, num)) ? val2 : null); } else { val = val.Find(text); } } return val; } private static void Hook() { if (!hooked) { hooked = true; SceneManager.sceneLoaded += delegate { Flush(); }; } } public static void Flush() { cache.Clear(); prefabRoots = null; byType.Clear(); } internal static void Miss(string owner, VRef r, string why) { string item = owner + "|" + r.target + "|" + r.prop + "|" + why; if (reported.Add(item)) { Debug.LogWarning((object)("[Apollo11] VanillaRefs MISS on '" + owner + "' " + r.target + " " + r.comp + "." + r.prop + " <- " + r.src + " " + r.srcPath + " " + r.srcComp + "." + r.srcProp + " ('" + r.label + "'): " + why)); } } internal static void Report(string owner, int ok, int fail, int total) { TotalOk += ok; TotalFail += fail; if (reported.Add("R|" + owner + "|" + fail)) { Debug.Log((object)string.Format("[Apollo11] VanillaRefs '{0}': {1}/{2} vanilla refs resolved from the game{3}", owner, ok, total, (fail > 0) ? (", " + fail + " MISSING") : "")); } } public static object GetComponent(GameObject go, string type, int index) { if (string.IsNullOrEmpty(type)) { return go; } int num = 0; Component[] components = go.GetComponents<Component>(); foreach (Component val in components) { if ((Object)(object)val == (Object)null) { continue; } Type type2 = ((object)val).GetType(); if (type2.FullName == type || type2.Name == type) { if (num == index) { return val; } num++; } } return null; } public static Object Lookup(VRef r) { Hook(); string key = r.src + "|" + r.srcPath + "|" + r.srcComp + "|" + r.srcCompIndex + "|" + r.srcProp; if (cache.TryGetValue(key, out var value) && value != (Object)null) { return value; } Object val = LookupUncached(r); if (val != (Object)null) { cache[key] = val; } return val; } private static Object LookupUncached(VRef r) { string text = r.src ?? ""; int num = text.IndexOf(':'); string text2 = ((num < 0) ? text : text.Substring(0, num)); string arg = ((num < 0) ? "" : text.Substring(num + 1)); object obj = null; switch (text2) { case "asset": { int num2 = arg.IndexOf(':'); Type type2 = FindType(arg.Substring(0, num2)); string n = arg.Substring(num2 + 1); if (type2 == null) { return null; } obj = ByName(type2, n); break; } case "mixer": { string[] parts = arg.Split('/'); return (Object)(object)((IEnumerable<AudioMixerGroup>)Resources.FindObjectsOfTypeAll<AudioMixerGroup>()).FirstOrDefault((Func<AudioMixerGroup, bool>)((AudioMixerGroup g) => Object.op_Implicit((Object)(object)g) && ((Object)g).name == parts[1] && Object.op_Implicit((Object)(object)g.audioMixer) && ((Object)g.audioMixer).name == parts[0])); } case "go": obj = PrefabRoot(arg); break; case "single": { Type type = FindType(arg); obj = ((type != null) ? Object.FindObjectOfType(type) : null); break; } case "item": obj = FindItem(arg)?.spawnPrefab; break; case "itemSO": obj = FindItem(arg); break; case "player": obj = (((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.allPlayerScripts != null && StartOfRound.Instance.allPlayerScripts.Length != 0) ? ((Component)StartOfRound.Instance.allPlayerScripts[0]).gameObject : null); break; case "level": obj = StartOfRound.Instance?.levels?.FirstOrDefault((Func<SelectableLevel, bool>)((SelectableLevel l) => Object.op_Implicit((Object)(object)l) && ((Object)l).name == arg))?.planetPrefab ?? ((IEnumerable<SelectableLevel>)Resources.FindObjectsOfTypeAll<SelectableLevel>()).FirstOrDefault((Func<SelectableLevel, bool>)((SelectableLevel l) => Object.op_Implicit((Object)(object)l) && ((Object)l).name == arg))?.planetPrefab; break; } if (obj == null) { return null; } object obj2 = obj; GameObject val = (GameObject)((obj is GameObject) ? obj : null); if (val != null) { Transform val2 = FindPath(val.transform, r.srcPath); if ((Object)(object)val2 == (Object)null) { return null; } obj2 = GetComponent(((Component)val2).gameObject, r.srcComp, r.srcCompIndex); } if (obj2 == null) { return null; } if (string.IsNullOrEmpty(r.srcProp)) { return (Object)((obj2 is Object) ? obj2 : null); } object obj3 = PropAccess.Get(obj2, r.srcProp); return (Object)((obj3 is Object) ? obj3 : null); } private static Item FindItem(string n) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) return (Item)(((object)(StartOfRound.Instance?.allItemsList?.itemsList)?.FirstOrDefault((Func<Item, bool>)((Item i) => Object.op_Implicit((Object)(object)i) && ((Object)i).name == n))) ?? ((object)(Item)ByName(typeof(Item), n))); } private static Object ByName(Type t, string n) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (!byType.TryGetValue(t, out var value)) { value = new Dictionary<string, Object>(); Object[] array = Resources.FindObjectsOfTypeAll(t); foreach (Object val in array) { if (!Object.op_Implicit(val) || value.ContainsKey(val.name)) { continue; } GameObject val2 = (GameObject)(object)((val is GameObject) ? val : null); if (val2 != null) { Scene scene = val2.scene; if (((Scene)(ref scene)).IsValid()) { continue; } } if (!(val is Component)) { value[val.name] = val; } } byType[t] = value; } if (!value.TryGetValue(n, out var value2)) { return null; } return value2; } private static GameObject PrefabRoot(string n) { //IL_00df: 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) NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton != (Object)null) { NetworkConfig networkConfig = singleton.NetworkConfig; object obj; if (networkConfig == null) { obj = null; } else { NetworkPrefabs prefabs = networkConfig.Prefabs; obj = ((prefabs != null) ? prefabs.Prefabs : null); } if (obj != null) { foreach (NetworkPrefab prefab in singleton.NetworkConfig.Prefabs.Prefabs) { if ((Object)(object)prefab?.Prefab != (Object)null && ((Object)prefab.Prefab).name == n) { return prefab.Prefab; } } } } if (prefabRoots == null) { prefabRoots = new Dictionary<string, GameObject>(); GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>(); foreach (GameObject val in array) { if (Object.op_Implicit((Object)(object)val) && (Object)(object)val.transform.parent == (Object)null) { Scene scene = val.scene; if (!((Scene)(ref scene)).IsValid() && !prefabRoots.ContainsKey(((Object)val).name)) { prefabRoots[((Object)val).name] = val; } } } } if (!prefabRoots.TryGetValue(n, out var value)) { return null; } return value; } public static Type FindType(string full) { if (types.TryGetValue(full, out var value)) { return value; } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { value = assembly.GetType(full, throwOnError: false); } catch { value = null; } if (value != null) { break; } } types[full] = value; return value; } } public static class PropAccess { private const BindingFlags F = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static (string head, int index, string rest) Split(string path) { int num = path.IndexOf('.'); string item = ((num < 0) ? path : path.Substring(0, num)); string text = ((num < 0) ? "" : path.Substring(num + 1)); int item2 = -1; if (text.StartsWith("Array.data[")) { int num2 = text.IndexOf(']'); item2 = int.Parse(text.Substring(11, num2 - 11)); text = ((text.Length > num2 + 2) ? text.Substring(num2 + 2) : ""); } return (head: item, index: item2, rest: text); } public static object Get(object owner, string path) { if (owner == null) { return null; } if (path.StartsWith("tex:")) { object obj = ((owner is Material) ? owner : null); if (obj == null) { return null; } return ((Material)obj).GetTexture(path.Substring(4)); } var (text, num, text2) = Split(path); if (TryBuiltinGet(owner, text, num, out var v)) { return v; } object obj2 = GetMember(owner, text); if (num >= 0) { obj2 = ((obj2 is IList list && num < list.Count) ? list[num] : null); } if (text2.Length <= 0) { return obj2; } return Get(obj2, text2); } public static bool Set(object owner, string path, object value) { if (owner == null) { return false; } if (path.StartsWith("tex:")) { Material val = (Material)((owner is Material) ? owner : null); if (!Object.op_Implicit((Object)(object)val)) { return false; } val.SetTexture(path.Substring(4), (Texture)((value is Texture) ? value : null)); return true; } var (text, num, text2) = Split(path); if (TrySpecialSet(owner, text, num, value, out var ok)) { return ok; } if (text2.Length == 0) { if (num < 0) { return SetMember(owner, text, value); } if (!(GetMember(owner, text) is IList list) || num >= list.Count) { return false; } list[num] = value; return true; } object member = GetMember(owner, text); if (num >= 0) { if (!(member is IList list2) || num >= list2.Count) { return false; } object obj = list2[num]; if (!Set(obj, text2, value)) { return false; } list2[num] = obj; return true; } if (member == null) { return false; } if (!Set(member, text2, value)) { return false; } if (member.GetType().IsValueType) { SetMember(owner, text, member); } return true; } private static bool TryBuiltinGet(object o, string head, int idx, out object v) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown v = null; MeshFilter val = (MeshFilter)((o is MeshFilter) ? o : null); Renderer val3; int num; if (val == null) { SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)((o is SkinnedMeshRenderer) ? o : null); if (val2 != null) { if (!(head == "m_Mesh")) { val3 = (Renderer)o; num = 2; goto IL_0100; } v = val2.sharedMesh; return true; } MeshCollider val4 = (MeshCollider)((o is MeshCollider) ? o : null); if (val4 == null) { val3 = (Renderer)((o is Renderer) ? o : null); if (val3 != null) { num = 4; goto IL_0100; } AudioSource val5 = (AudioSource)((o is AudioSource) ? o : null); if (val5 == null) { Animator val6 = (Animator)((o is Animator) ? o : null); if (val6 == null) { Light val7 = (Light)((o is Light) ? o : null); if (val7 != null && head == "m_Cookie") { v = val7.cookie; return true; } } else { if (head == "m_Controller") { v = val6.runtimeAnimatorController; return true; } Animator val8 = val6; if (head == "m_Avatar") { v = val8.avatar; return true; } } } else { if (head == "m_audioClip") { v = val5.clip; return true; } AudioSource val9 = val5; if (head == "OutputAudioMixerGroup") { v = val9.outputAudioMixerGroup; return true; } } } else if (head == "m_Mesh") { v = val4.sharedMesh; return true; } } else if (head == "m_Mesh") { v = val.sharedMesh; return true; } goto IL_01ed; IL_0100: if (head == "m_Materials") { goto IL_011b; } if (num != 2) { if (num != 4) { goto IL_011b; } SpriteRenderer val10 = (SpriteRenderer)((o is SpriteRenderer) ? o : null); if (val10 == null) { ParticleSystemRenderer val11 = (ParticleSystemRenderer)((o is ParticleSystemRenderer) ? o : null); if (val11 != null && head == "m_Mesh") { v = val11.mesh; return true; } } else if (head == "m_Sprite") { v = val10.sprite; return true; } } goto IL_01ed; IL_01ed: if (head.StartsWith("m_") && o is Component) { foreach (string item in Aliases(head)) { PropertyInfo property = o.GetType().GetProperty(item, BindingFlags.Instance | BindingFlags.Public); if (property != null && property.CanRead) { v = property.GetValue(o); if (idx >= 0) { v = ((v is IList list && idx < list.Count) ? list[idx] : null); } return true; } } } return false; IL_011b: Material[] sharedMaterials = val3.sharedMaterials; v = ((idx >= 0 && idx < sharedMaterials.Length) ? sharedMaterials[idx] : null); return true; } private static bool TrySpecialSet(object o, string head, int idx, object value, out bool ok) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown ok = true; MeshFilter val = (MeshFilter)((o is MeshFilter) ? o : null); Renderer val3; int num; if (val == null) { SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)((o is SkinnedMeshRenderer) ? o : null); if (val2 != null) { if (!(head == "m_Mesh")) { val3 = (Renderer)o; num = 2; goto IL_010d; } val2.sharedMesh = (Mesh)((value is Mesh) ? value : null); return true; } MeshCollider val4 = (MeshCollider)((o is MeshCollider) ? o : null); if (val4 == null) { val3 = (Renderer)((o is Renderer) ? o : null); if (val3 != null) { num = 4; goto IL_010d; } AudioSource val5 = (AudioSource)((o is AudioSource) ? o : null); if (val5 == null) { Animator val6 = (Animator)((o is Animator) ? o : null); if (val6 == null) { Light val7 = (Light)((o is Light) ? o : null); if (val7 != null && head == "m_Cookie") { val7.cookie = (Texture)((value is Texture) ? value : null); return true; } } else { if (head == "m_Controller") { val6.runtimeAnimatorController = (RuntimeAnimatorController)((value is RuntimeAnimatorController) ? value : null); return true; } Animator val8 = val6; if (head == "m_Avatar") { val8.avatar = (Avatar)((value is Avatar) ? value : null); return true; } } } else { if (head == "m_audioClip") { val5.clip = (AudioClip)((value is AudioClip) ? value : null); return true; } AudioSource val9 = val5; if (head == "OutputAudioMixerGroup") { val9.outputAudioMixerGroup = (AudioMixerGroup)((value is AudioMixerGroup) ? value : null); return true; } } } else if (head == "m_Mesh") { val4.sharedMesh = (Mesh)((value is Mesh) ? value : null); return true; } } else if (head == "m_Mesh") { val.sharedMesh = (Mesh)((value is Mesh) ? value : null); return true; } goto IL_0229; IL_0128: Material[] sharedMaterials = val3.sharedMaterials; if (idx < 0 || idx >= sharedMaterials.Length) { ok = false; return true; } sharedMaterials[idx] = (Material)((value is Material) ? value : null); val3.sharedMaterials = sharedMaterials; return true; IL_0229: if (head.StartsWith("m_") && o is Component) { foreach (string item in Aliases(head)) { PropertyInfo property = o.GetType().GetProperty(item, BindingFlags.Instance | BindingFlags.Public); if (property != null && property.CanWrite && idx < 0) { property.SetValue(o, value); return true; } } } ok = false; return false; IL_010d: if (head == "m_Materials") { goto IL_0128; } if (num != 2) { if (num != 4) { goto IL_0128; } SpriteRenderer val10 = (SpriteRenderer)((o is SpriteRenderer) ? o : null); if (val10 == null) { ParticleSystemRenderer val11 = (ParticleSystemRenderer)((o is ParticleSystemRenderer) ? o : null); if (val11 != null && head == "m_Mesh") { val11.mesh = (Mesh)((value is Mesh) ? value : null); return true; } } else if (head == "m_Sprite") { val10.sprite = (Sprite)((value is Sprite) ? value : null); return true; } } goto IL_0229; } private static IEnumerable<string> Aliases(string head) { string b = head.Substring(2); string lc = char.ToLowerInvariant(b[0]) + b.Substring(1); if (!(head == "m_fontAsset")) { if (head == "m_sharedMaterial") { yield return "fontSharedMaterial"; yield return "sharedMaterial"; } } else { yield return "font"; } yield return "shared" + b; yield return lc; yield return b; } private static object GetMember(object o, string n) { Type type = o.GetType(); while (type != null) { FieldInfo field = type.GetField(n, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field.GetValue(o); } type = type.BaseType; } PropertyInfo property = o.GetType().GetProperty(n, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(property != null) || !property.CanRead) { return null; } return property.GetValue(o); } private static bool SetMember(object o, string n, object v) { Type type = o.GetType(); while (type != null) { FieldInfo field = type.GetField(n, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { field.SetValue(o, v); return true; } type = type.BaseType; } PropertyInfo property = o.GetType().GetProperty(n, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null && property.CanWrite) { property.SetValue(o, v); return true; } return false; } } internal static class ZombieRegistration { internal static EnemyType ZombieType; internal static int Rarity = 20; internal static int VanillaRarity = 0; internal static int TestRarity = 1000; internal static int TestCount = 1; internal static string VanillaMoons = ""; internal static string TestMoons = ""; private static string lastKey; internal static void Register(AssetBundle bundle, ConfigFile cfg) { //IL_02ff: Unknown result type (might be due to invalid IL or missing references) EnemyType val = bundle.LoadAsset<EnemyType>("ZombieEnemy"); TerminalNode val2 = bundle.LoadAsset<TerminalNode>("ZombieTN"); TerminalKeyword val3 = bundle.LoadAsset<TerminalKeyword>("ZombieTK"); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"ZombieEnemy not in bundle (build with Apollo11BuildZombie) - Zombie disabled."); return; } NetworkPrefabs.RegisterNetworkPrefab(val.enemyPrefab); if (cfg.Bind<bool>("Zombie", "Enabled", true, "Add the Zombie (dead crewmate, arms out, slow, turns its victims).").Value) { Rarity = cfg.Bind<int>("Zombie", "Rarity", 20, "Spawn weight inside the Lunar Base on 11 Apollo.").Value; VanillaRarity = cfg.Bind<int>("Zombie", "VanillaRarity", 0, "Indoor spawn weight on the moons in VanillaMoons (0 = Apollo only).").Value; VanillaMoons = cfg.Bind<string>("Zombie", "VanillaMoons", "Experimentation,Assurance,Vow,Offense,March,Adamance,Rend,Dine,Titan,Artifice,Embrion", "Planet-name fragments (comma separated) or All, used when VanillaRarity > 0.").Value; val.MaxCount = cfg.Bind<int>("Zombie", "MaxCount", 3, "Max naturally spawned Zombies at once (risen victims don't use this cap).").Value; ZombieSettings.MaxTotal = cfg.Bind<int>("Zombie", "MaxTotal", 8, "Victims stop rising once this many Zombies are alive.").Value; ZombieSettings.SpawnFromKills = cfg.Bind<bool>("Zombie", "SpawnFromKills", true, "A player killed by a Zombie rises as a new Zombie in their suit.").Value; ZombieSettings.Speed = cfg.Bind<float>("Zombie", "Speed", 2.2f, "Walk speed (player walk is ~4.6).").Value; ZombieSettings.MaxHP = Math.Max(1, cfg.Bind<int>("Zombie", "HP", 4, "Health (shovel hit = 1, like the Masked).").Value); ZombieSettings.KillDuration = cfg.Bind<float>("Zombie", "KillDuration", 2.2f, "Seconds from grab to death.").Value; ZombieSettings.GroanIntervalMin = cfg.Bind<float>("Zombie", "GroanIntervalMin", 4f, "Min seconds between groans.").Value; ZombieSettings.GroanIntervalMax = cfg.Bind<float>("Zombie", "GroanIntervalMax", 9f, "Max seconds between groans.").Value; ZombieSettings.GroanVolume = cfg.Bind<float>("Zombie", "GroanVolume", 1f, "Groan volume.").Value; ZombieSettings.PaleTint = cfg.Bind<bool>("Zombie", "PaleTint", true, "Grey-green dead tint over the suit.").Value; bool value = cfg.Bind<bool>("Zombie", "TestForceSpawn", false, "TESTING: huge spawn weight + host spawns TestCount Zombies near the main entrance on TestMoons.").Value; TestRarity = cfg.Bind<int>("Zombie", "TestRarity", 1000, "Weight when TestForceSpawn is true.").Value; TestCount = cfg.Bind<int>("Zombie", "TestCount", 1, "Zombies spawned near the main entrance when TestForceSpawn is true.").Value; TestMoons = (value ? cfg.Bind<string>("Zombie", "TestMoons", "Apollo", "Planet-name fragments or All.").Value : ""); if (value) { val.probabilityCurve = AnimationCurve.Constant(0f, 1f, 1f); } ((EnemyAI)val.enemyPrefab.GetComponent<ZombieAI>()).enemyHP = ZombieSettings.MaxHP; Enemies.RegisterEnemy(val, Rarity, (LevelTypes)1, val2, val3); ZombieType = val; new Harmony("rfgames.apollo11mod.zombie").PatchAll(typeof(ZombieRegistration)); Plugin.Log.LogInfo((object)string.Format("Zombie registered (Apollo rarity {0}, vanilla {1}, max {2}{3}).", Rarity, VanillaRarity, val.MaxCount, value ? $", TEST weight {TestRarity} on '{TestMoons}'" : "")); } } [HarmonyPatch(typeof(RoundManager), "LoadNewLevel")] [HarmonyPrefix] private static void Inject(SelectableLevel newLevel) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown try { if ((Object)(object)ZombieType == (Object)null || (Object)(object)newLevel == (Object)null) { return; } int num = (MoonFeatures.MoonMatches(newLevel, TestMoons) ? TestRarity : (MoonFeatures.IsApollo(newLevel) ? Rarity : ((VanillaRarity > 0 && MoonFeatures.MoonMatches(newLevel, VanillaMoons)) ? VanillaRarity : 0))); SpawnableEnemyWithRarity val = ((IEnumerable<SpawnableEnemyWithRarity>)newLevel.Enemies).FirstOrDefault((Func<SpawnableEnemyWithRarity, bool>)((SpawnableEnemyWithRarity e) => e != null && (Object)(object)e.enemyType == (Object)(object)ZombieType)); if (num <= 0) { if (val != null) { newLevel.Enemies.Remove(val); } return; } if (val == null) { val = new SpawnableEnemyWithRarity(ZombieType, num); newLevel.Enemies.Add(val); } val.rarity = num; Plugin.Log.LogInfo((object)$"Zombie weight {num} on '{newLevel.PlanetName}'."); } catch (Exception ex) { Plugin.Log.LogError((object)("Zombie Inject: " + ex)); } } [HarmonyPatch(typeof(RoundManager), "RefreshEnemyVents")] [HarmonyPostfix] private static void TestSpawn(RoundManager __instance) { //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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_016f: 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_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)ZombieType == (Object)null || string.IsNullOrEmpty(TestMoons) || !((NetworkBehaviour)__instance).IsServer || !__instance.dungeonFinishedGeneratingForAllPlayers) { return; } SelectableLevel currentLevel = __instance.currentLevel; if ((Object)(object)currentLevel == (Object)null || !currentLevel.spawnEnemiesAndScrap || !MoonFeatures.MoonMatches(currentLevel, TestMoons)) { return; } string text = currentLevel.levelID + ":" + StartOfRound.Instance.randomMapSeed; if (!(text == lastKey)) { lastKey = text; EntranceTeleport val = ((IEnumerable<EntranceTeleport>)Object.FindObjectsOfType<EntranceTeleport>()).FirstOrDefault((Func<EntranceTeleport, bool>)((EntranceTeleport e) => e.entranceId == 0 && !e.isEntranceToBuilding)); Vector3 origin = (((Object)(object)val != (Object)null) ? val.entrancePoint.position : ((__instance.insideAINodes.Length != 0) ? __instance.insideAINodes[0].transform.position : Vector3.zero)); GameObject[] array = (from n in __instance.insideAINodes where (Object)(object)n != (Object)null orderby Vector3.Distance(n.transform.position, origin) select n).Skip(3).Take(Math.Max(1, TestCount)).ToArray(); foreach (GameObject val2 in array) { Vector3 randomNavMeshPositionInRadius = __instance.GetRandomNavMeshPositionInRadius(val2.transform.position, 1.5f, default(NavMeshHit)); __instance.SpawnEnemyGameObject(randomNavMeshPositionInRadius, Random.Range(0f, 360f), -1, ZombieType); Plugin.Log.LogInfo((object)$"[ZombieTest] spawned Zombie at {randomNavMeshPositionInRadius} ({Vector3.Distance(randomNavMeshPositionInRadius, origin):F1} m from main entrance)."); } } } catch (Exception ex) { Plugin.Log.LogError((object)("[ZombieTest] failed: " + ex)); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "rfgames.apollo11mod"; public const string PLUGIN_NAME = "Apollo 11"; public const string PLUGIN_VERSION = "1.0.4"; } } namespace Apollo11Mod.Moon { public class CraterHazard : MonoBehaviour { public Vector3 centre; public float innerR = 13f; public float outerR = 37f; public float killY; public float rimY; private float cooldown; private void Start() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) Debug.Log((object)$"[Apollo11] CraterHazard ring r {innerR}-{outerR} around {centre}, kill below y={killY:F1} (rim ~{rimY:F1})"); } private void OnTriggerEnter(Collider other) { Check(other); } private void OnTriggerStay(Collider other) { Check(other); } private void Check(Collider other) { PlayerControllerB val = (Object.op_Implicit((Object)(object)other) ? ((Component)other).GetComponentInParent<PlayerControllerB>() : null); if ((Object)(object)val != (Object)null && IsLocal(val)) { Kill(val, "trigger"); } } private static bool IsLocal(PlayerControllerB p) { if ((Object)(object)GameNetworkManager.Instance != (Object)null) { return (Object)(object)p == (Object)(object)GameNetworkManager.Instance.localPlayerController; } return false; } private void Update() { //IL_006b: Unknown result type (might be d