Decompiled source of ExperimentalEnemyInteractions v0.2.6
DLLs/fandovec03.NaturalSelection.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using NaturalSelection.EnemyPatches; using NaturalSelection.Generics; using NaturalSelectionLib; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("fandovec03.NaturalSelection")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.1.3.0")] [assembly: AssemblyInformationalVersion("0.1.3+a326e440374f6f62dce37af0fde11557d091c29d")] [assembly: AssemblyProduct("NaturalSelection")] [assembly: AssemblyTitle("fandovec03.NaturalSelection")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.3.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 NaturalSelection { [BepInPlugin("fandovec03.NaturalSelection", "NaturalSelection", "0.1.3")] public class Script : BaseUnityPlugin { internal static bool stableToggle; internal static float clampedAgentRadius; public static Script Instance { get; private set; } internal static ManualLogSource Logger { get; private set; } internal static Harmony? Harmony { get; set; } internal static MyModConfig BoundingConfig { get; set; } private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Instance = this; BoundingConfig = new MyModConfig(((BaseUnityPlugin)this).Config); stableToggle = BoundingConfig.stableMode.Value; clampedAgentRadius = Mathf.Clamp(BoundingConfig.agentRadiusModifier.Value, 0.1f, 1f); Patch(); Logger.LogInfo((object)"fandovec03.NaturalSelection v0.1.3 has loaded!"); } internal static void Patch() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown if (Harmony == null) { Harmony = new Harmony("fandovec03.NaturalSelection"); } Logger.LogInfo((object)"Patching NaturalSelection ..."); for (int i = 0; i < 100; i++) { Logger.LogError((object)("LOADING EXPERIMENTAL " + "NaturalSelection".ToUpper() + ", DOWNLOAD NATURAL SELECTION INSTEAD!")); } Harmony.PatchAll(typeof(AICollisionDetectPatch)); Harmony.PatchAll(typeof(EnemyAIPatch)); try { NaturalSelectionLib.LibrarySetup(Logger, BoundingConfig.spammyLogs.Value, BoundingConfig.debugUnspecified.Value); Logger.LogInfo((object)"Library successfully setup!"); } catch { Logger.LogError((object)"Failed to setup library!"); } Harmony.PatchAll(typeof(RoundManagerPatch)); if (BoundingConfig.loadSandworms.Value) { Harmony.PatchAll(typeof(SandWormAIPatch)); } if (BoundingConfig.loadBlob.Value) { Harmony.PatchAll(typeof(BlobAIPatch)); } if (BoundingConfig.loadHoardingBugs.Value) { Harmony.PatchAll(typeof(HoarderBugPatch)); } if (BoundingConfig.LoadBees.Value) { Harmony.PatchAll(typeof(BeeAIPatch)); } if (BoundingConfig.loadGiants.Value) { Harmony.PatchAll(typeof(ForestGiantPatch)); } if (!stableToggle) { if (BoundingConfig.loadNutcrackers.Value) { Harmony.PatchAll(typeof(NutcrackerAIPatch)); } if (BoundingConfig.loadSporeLizard.Value) { Harmony.PatchAll(typeof(PufferAIPatch)); } if (BoundingConfig.loadSpiders.Value) { Harmony.PatchAll(typeof(SandSpiderAIPatch)); } Logger.LogInfo((object)"Stable mode off. Loaded all patches."); } else { Logger.LogInfo((object)"Stable mode on. Excluded unstable and WIP patches from loading."); } Logger.LogInfo((object)"Finished patching NaturalSelection !"); } internal static void Unpatch() { Logger.LogDebug((object)"Unpatching..."); Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } Logger.LogDebug((object)"Finished unpatching!"); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "fandovec03.NaturalSelection"; public const string PLUGIN_NAME = "NaturalSelection"; public const string PLUGIN_VERSION = "0.1.3"; } } namespace NaturalSelection.Generics { internal class MyModConfig { public readonly ConfigEntry<bool> delayScriptsOnSpawn; public readonly ConfigEntry<float> delay; public readonly ConfigEntry<bool> stableMode; public readonly ConfigEntry<bool> spiderHuntHoardingbug; public readonly ConfigEntry<float> agentRadiusModifier; public readonly ConfigEntry<bool> IgnoreImmortalEnemies; public readonly ConfigEntry<bool> enableSpider; public readonly ConfigEntry<bool> enableSlime; public readonly ConfigEntry<bool> enableLeviathan; public readonly ConfigEntry<bool> enableSporeLizard; public readonly ConfigEntry<bool> enableRedBees; public readonly ConfigEntry<bool> enableNutcrackers; public readonly ConfigEntry<int> giantExtinguishChance; public readonly ConfigEntry<float> beesSetGiantsOnFireMinChance; public readonly ConfigEntry<float> beesSetGiantsOnFireMaxChance; public readonly ConfigEntry<bool> loadNutcrackers; public readonly ConfigEntry<bool> loadSpiders; public readonly ConfigEntry<bool> loadSandworms; public readonly ConfigEntry<bool> loadGiants; public readonly ConfigEntry<bool> loadHoardingBugs; public readonly ConfigEntry<bool> loadBlob; public readonly ConfigEntry<bool> LoadBees; public readonly ConfigEntry<bool> loadSporeLizard; public readonly ConfigEntry<bool> debugBool; public readonly ConfigEntry<bool> spammyLogs; public readonly ConfigEntry<bool> debugTriggerFlags; public readonly ConfigEntry<bool> debugRedBees; public readonly ConfigEntry<bool> debugSandworms; public readonly ConfigEntry<bool> debugHygrodere; public readonly ConfigEntry<bool> debugNutcrackers; public readonly ConfigEntry<bool> debugSpiders; public readonly ConfigEntry<bool> debugGiants; public readonly ConfigEntry<bool> debugUnspecified; public MyModConfig(ConfigFile cfg) { cfg.SaveOnConfigSet = false; delayScriptsOnSpawn = cfg.Bind<bool>("Experimental Fixes", "Delay enemy scripts on spawn", false, "Delay enemy scripts from taking effect on enemy spawns. Might fix invisible bees"); delay = cfg.Bind<float>("Experimental Fixes", "Delay", 0.2f, "Set the length of the delay"); stableMode = cfg.Bind<bool>("General Settings", "Toggle stable mode", true, "When true, the mod will exlude patches that are WIP or are experimental from loading"); IgnoreImmortalEnemies = cfg.Bind<bool>("General Settings", "Ignore Immortal Enemies", false, "All immortal enemies will be ignored by majority of entities"); agentRadiusModifier = cfg.Bind<float>("WIP", "Agent radius modifier", 0.6f, "Agent radius multiplier. Agent size is modified to make collisions more reliable. Lower multiplier makes final Agent radius smaller. \n \n [Values not between 0.1 and 1 are Clamped]"); agentRadiusModifier.Value = Mathf.Clamp(agentRadiusModifier.Value, 0.1f, 1f); spiderHuntHoardingbug = cfg.Bind<bool>("WIP", "Spider hunts Hoarding bugs", false, "Bunker spider chases and hunts hoarding bugs. DEV ONLY"); enableSpider = cfg.Bind<bool>("WIP", "Enable spider", false, "Mod applies changes Bunker Spider. DEV ONLY"); enableSlime = cfg.Bind<bool>("Entity settings", "Enable slime", true, "Mod applies changes Hygrodere. Slime now damages every entity it passes by."); enableLeviathan = cfg.Bind<bool>("Entity settings", "Enable leviathan", true, "Mod applies changes Earth leviathan. Leviathan now targets other creatures aswell."); enableSporeLizard = cfg.Bind<bool>("WIP", "Enable SporeLizard", false, "Mod applies changes Spore lizard. It is now mortal!"); enableRedBees = cfg.Bind<bool>("Entity settings", "Enable Red bees (Circuit bees)", true, "Mod applies changes red bees. They now defend nest from other mobs and kill everything in rampage!"); enableNutcrackers = cfg.Bind<bool>("WIP", "Enable Nutcrackers", false, "Mod applies changes to nutcrackers. DEV ONLY"); giantExtinguishChance = cfg.Bind<int>("Entity settings", "(Giant) Extinguish chance", 33, "[Accepts int values between 0 and 100] Chance of giants extinguishing themselves."); beesSetGiantsOnFireMinChance = cfg.Bind<float>("Entity settings", "(Bees) Ignite giants min chace", 1.5f, "[Accepts float values between 0 and 100]The minimum chance bees will set giant on fire on hit"); beesSetGiantsOnFireMaxChance = cfg.Bind<float>("Entity settings", "(Bees) Ignite giants max chace", 8f, "[Accepts float values between 0 and 100]The minimum chance bees will set giant on fire on hit"); loadSpiders = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load spider patches", true, "Load the spider patches. Do not touch."); loadBlob = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load slime patches", true, "Load the slime patches. Do not touch."); loadSandworms = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load leviathan patches", true, "Load the leviathan patches. Do not touch."); loadGiants = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load giant patches", true, "Load the giant patches. Do not touch."); LoadBees = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load circuit bees patches", true, "Load bees patches. Do not touch."); loadNutcrackers = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load nutcracker patches", true, "Load the nutcracker patches. Do not touch."); loadHoardingBugs = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load hoarding bugs patches", true, "Load the hoarding bug patches. Do not touch."); loadSporeLizard = cfg.Bind<bool>("Initialization settings (Not recommended)", "Load spore lizards patches", true, "Load the spore lizard patches. Do not touch."); debugBool = cfg.Bind<bool>("Debug", "Debug mode", false, "Enables debug mode for more debug logs."); spammyLogs = cfg.Bind<bool>("Debug", "Spammy logs", false, "Enables spammy logs for extra logs."); debugTriggerFlags = cfg.Bind<bool>("Debug", "Trigger flags", false, "Enables logs with trigger flag."); debugRedBees = cfg.Bind<bool>("Debug", "Log bees", false, "Enables logs for bees."); debugSandworms = cfg.Bind<bool>("Debug", "Log sandworms", false, "Enables logs for sandowrms."); debugHygrodere = cfg.Bind<bool>("Debug", "Log hydrogere", false, "Enables logs for hydrogere."); debugNutcrackers = cfg.Bind<bool>("Debug", "Log nutcrackers", false, "Enables logs for nutcrackers."); debugSpiders = cfg.Bind<bool>("Debug", "Log spiders", false, "Enables logs for spiders."); debugGiants = cfg.Bind<bool>("Debug", "Log giants", false, "Enables logs for giants."); debugUnspecified = cfg.Bind<bool>("Debug", "Log unspecified", false, "Enables logs for unspecified."); ClearOrphanedEntries(cfg); cfg.Save(); cfg.SaveOnConfigSet = true; } public void ClearOrphanedEntries(ConfigFile cfg) { PropertyInfo propertyInfo = AccessTools.Property(typeof(ConfigFile), "OrphanedEntries"); Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)propertyInfo.GetValue(cfg); dictionary.Clear(); } } [HarmonyPatch(typeof(RoundManager))] internal class RoundManagerPatch { private static float nextUpdate = 0f; private static Dictionary<Type, List<EnemyAI>> checkedTypes = new Dictionary<Type, List<EnemyAI>>(); public static float updateListInterval = 1f; private static bool canUpdate = true; private static bool logSpam = Script.BoundingConfig.spammyLogs.Value; private static bool logUnspecified = Script.BoundingConfig.debugUnspecified.Value; [HarmonyPatch("Update")] [HarmonyPrefix] private static void UpdatePatch() { if (!(Time.realtimeSinceStartup >= nextUpdate)) { return; } foreach (Type item in checkedTypes.Keys.ToList()) { NaturalSelectionLib.UpdateListInsideDictionrary(item, checkedTypes[item]); } checkedTypes.Clear(); nextUpdate = Time.realtimeSinceStartup + updateListInterval; } public static bool RequestUpdate(EnemyAI instance) { if (!checkedTypes.ContainsKey(((object)instance).GetType())) { checkedTypes.Add(((object)instance).GetType(), new List<EnemyAI>()); if (logUnspecified && logSpam) { Script.Logger.LogMessage((object)("/RoundManager/ request was Accepted. Requested by " + EnemyAIPatch.DebugStringHead(instance) + " at " + Time.realtimeSinceStartup)); } return true; } if (logUnspecified && logSpam) { Script.Logger.LogInfo((object)("/RoundManager/ request was Denied. Requested by " + EnemyAIPatch.DebugStringHead(instance) + " at " + Time.realtimeSinceStartup)); } return false; } public static void ScheduleGlobalListUpdate(EnemyAI instance, List<EnemyAI> list) { if (checkedTypes.ContainsKey(((object)instance).GetType())) { checkedTypes[((object)instance).GetType()] = list; } if (!NaturalSelectionLib.globalEnemyLists.ContainsKey(((object)instance).GetType())) { Script.Logger.LogError((object)(EnemyAIPatch.DebugStringHead(instance) + "global enemy list for this enemy does not exist! Creating a new one.")); NaturalSelectionLib.UpdateListInsideDictionrary(((object)instance).GetType(), checkedTypes[((object)instance).GetType()]); } } } } namespace NaturalSelection.EnemyPatches { internal class BeeValues { public bool start = Script.BoundingConfig.delayScriptsOnSpawn.Value; public EnemyAI? closestEnemy = null; public EnemyAI? targetEnemy = null; public Vector3 lastKnownEnemyPosition = Vector3.zero; public int customBehaviorStateIndex = 0; public float timeSinceHittingEnemy = 0f; public float LostLOSOfEnemy = 0f; public List<Type> enemyTypes = new List<Type>(); public float delayTimer = 0.2f; } [HarmonyPatch(typeof(RedLocustBees))] internal class BeeAIPatch { private static Dictionary<RedLocustBees, BeeValues> beeList = new Dictionary<RedLocustBees, BeeValues>(); private static bool logBees = Script.BoundingConfig.debugRedBees.Value; private static bool debugSpam = Script.BoundingConfig.spammyLogs.Value; private static float UpdateTimer = Script.BoundingConfig.delay.Value; [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch(RedLocustBees __instance) { if (!beeList.ContainsKey(__instance)) { beeList.Add(__instance, new BeeValues()); } BeeValues beeValues = beeList[__instance]; if (beeValues.enemyTypes.Count < 1) { beeValues.enemyTypes.Add(typeof(DocileLocustBeesAI)); beeValues.enemyTypes.Add(typeof(SandWormAI)); } } [HarmonyPatch("Update")] [HarmonyPostfix] private static void UpdatePatch(RedLocustBees __instance) { BeeValues beeValues = beeList[__instance]; if (beeValues.delayTimer > 0f) { beeValues.delayTimer -= Time.deltaTime; return; } if (RoundManagerPatch.RequestUpdate((EnemyAI)(object)__instance)) { RoundManagerPatch.ScheduleGlobalListUpdate((EnemyAI)(object)__instance, EnemyAIPatch.FilterEnemyList(EnemyAIPatch.GetOutsideEnemyList(EnemyAIPatch.GetCompleteList((EnemyAI)(object)__instance), (EnemyAI)(object)__instance), beeList[__instance].enemyTypes, (EnemyAI)(object)__instance, inverseToggle: true, Script.BoundingConfig.IgnoreImmortalEnemies.Value)); } if (NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()].Contains((EnemyAI)(object)__instance)) { if (logBees && debugSpam) { Script.Logger.LogError((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " FOUND ITSELF IN THE EnemyList! Removing...")); } NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()].Remove((EnemyAI)(object)__instance); } } [HarmonyPatch("DoAIInterval")] [HarmonyPrefix] private static bool DoAIIntervalPrefixPatch(RedLocustBees __instance) { //IL_0079: Unknown result type (might be due to invalid IL or missing references) BeeValues beeValues = beeList[__instance]; bool flag = true; if ((Object)(object)beeValues.targetEnemy != (Object)null && !((EnemyAI)__instance).movingTowardsTargetPlayer && ((EnemyAI)__instance).currentBehaviourStateIndex != 0) { if (logBees && debugSpam) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval: Prefix triggered false")); } if (((EnemyAI)__instance).moveTowardsDestination) { ((EnemyAI)__instance).agent.SetDestination(((EnemyAI)__instance).destination); } ((EnemyAI)__instance).SyncPositionToClients(); return false; } if (logBees && debugSpam) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval: Prefix triggered true")); } return true; } [HarmonyPatch("DoAIInterval")] [HarmonyPostfix] private static void DoAIIntervalPostfixPatch(RedLocustBees __instance) { //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_037d: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_052d: Unknown result type (might be due to invalid IL or missing references) //IL_053d: Unknown result type (might be due to invalid IL or missing references) //IL_0829: Unknown result type (might be due to invalid IL or missing references) //IL_082e: Unknown result type (might be due to invalid IL or missing references) //IL_0838: Unknown result type (might be due to invalid IL or missing references) //IL_083d: Unknown result type (might be due to invalid IL or missing references) //IL_0842: Unknown result type (might be due to invalid IL or missing references) //IL_087b: Unknown result type (might be due to invalid IL or missing references) //IL_043f: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_0b50: Unknown result type (might be due to invalid IL or missing references) //IL_0b7e: Unknown result type (might be due to invalid IL or missing references) //IL_096a: Unknown result type (might be due to invalid IL or missing references) //IL_097a: Unknown result type (might be due to invalid IL or missing references) //IL_0628: Unknown result type (might be due to invalid IL or missing references) //IL_0656: Unknown result type (might be due to invalid IL or missing references) //IL_09a2: Unknown result type (might be due to invalid IL or missing references) //IL_0e03: Unknown result type (might be due to invalid IL or missing references) //IL_0dc1: Unknown result type (might be due to invalid IL or missing references) //IL_0d01: Unknown result type (might be due to invalid IL or missing references) //IL_0d06: Unknown result type (might be due to invalid IL or missing references) //IL_0d0d: Unknown result type (might be due to invalid IL or missing references) //IL_09fa: Unknown result type (might be due to invalid IL or missing references) bool flag = true; BeeValues beeValues = beeList[__instance]; switch (((EnemyAI)__instance).currentBehaviourStateIndex) { case 0: { EnemyAI val4 = null; if (EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 360f, 16, 1f).Count > 0) { if (NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()].Contains((EnemyAI)(object)__instance)) { if (logBees && debugSpam) { Script.Logger.LogError((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " FOUND ITSELF IN THE EnemyList before LOSEnemy! Removing...")); } NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()].Remove((EnemyAI)(object)__instance); } val4 = EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 360f, 16, 1f).Keys.First(); if (logBees) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case0: Checked LOS for enemies. Enemy found: " + EnemyAIPatch.DebugStringHead(val4))); } if (logBees && debugSpam) { foreach (KeyValuePair<EnemyAI, float> enemiesInLO in EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 360f, 16, 1f)) { if (logBees && debugSpam) { Script.Logger.LogError((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " FOUND ITSELF IN THE EnemyList before LOSEnemy! Removing...")); } NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()].Remove((EnemyAI)(object)__instance); } val4 = EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 360f, 16, 1f).Keys.First(); if (logBees) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case0: Checked LOS for enemies. Enemy found: " + EnemyAIPatch.DebugStringHead(val4))); } if (logBees && debugSpam) { foreach (KeyValuePair<EnemyAI, float> enemiesInLO2 in EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 360f, 16, 1f)) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Checking the LOSList: " + EnemyAIPatch.DebugStringHead(enemiesInLO2.Key) + ", Distance: " + enemiesInLO2.Value)); if ((Object)(object)enemiesInLO2.Key == (Object)(object)__instance) { Script.Logger.LogError((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " FOUND ITSELF IN THE LOSList: " + EnemyAIPatch.DebugStringHead(enemiesInLO2.Key) + ", Distance: " + enemiesInLO2.Value)); } } } } } if (__instance.wasInChase) { __instance.wasInChase = false; } if (Vector3.Distance(((Component)__instance).transform.position, __instance.lastKnownHivePosition) > 2f) { ((EnemyAI)__instance).SetDestinationToPosition(__instance.lastKnownHivePosition, true); } if (__instance.IsHiveMissing()) { ((EnemyAI)__instance).SwitchToBehaviourState(2); beeValues.customBehaviorStateIndex = 2; if (logBees) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case0: HIVE IS MISSING! CustomBehaviorStateIndex changed: " + beeValues.customBehaviorStateIndex)); } } else if ((Object)(object)val4 != (Object)null && Vector3.Distance(((Component)val4).transform.position, ((Component)__instance.hive).transform.position) < (float)__instance.defenseDistance) { ((EnemyAI)__instance).SetDestinationToPosition(((Component)val4).transform.position, true); if (logBees) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case0: Moving towards " + (object)val4)); } beeValues.customBehaviorStateIndex = 1; ((EnemyAI)__instance).SwitchToBehaviourState(1); __instance.syncedLastKnownHivePosition = false; __instance.SyncLastKnownHivePositionServerRpc(__instance.lastKnownHivePosition); beeValues.LostLOSOfEnemy = 0f; if (logBees) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case0: CustomBehaviorStateIndex changed: " + beeValues.customBehaviorStateIndex)); } } break; } case 1: { if (((Object)(object)((EnemyAI)__instance).targetPlayer != (Object)null && ((EnemyAI)__instance).movingTowardsTargetPlayer) || (!((Object)(object)beeValues.targetEnemy == (Object)null) && !beeValues.targetEnemy.isEnemyDead && !(Vector3.Distance(((Component)beeValues.targetEnemy).transform.position, ((Component)__instance.hive).transform.position) > (float)__instance.defenseDistance + 5f))) { break; } bool flag3 = false; Dictionary<EnemyAI, float> enemiesInLOS2 = EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 360f, 16, 1f); EnemyAI val3 = null; if (enemiesInLOS2.Count > 0) { val3 = enemiesInLOS2.Keys.First(); } if (logBees) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: " + ((object)val3)?.ToString() + " is closest to hive.")); } if ((Object)(object)val3 != (Object)null && (Object)(object)beeValues.targetEnemy != (Object)(object)val3) { flag3 = true; __instance.wasInChase = false; beeValues.targetEnemy = val3; ((EnemyAI)__instance).SetDestinationToPosition(((Component)beeValues.targetEnemy).transform.position, true); ((EnemyAI)__instance).StopSearch(__instance.searchForHive, true); __instance.syncedLastKnownHivePosition = false; beeValues.LostLOSOfEnemy = 0f; __instance.SyncLastKnownHivePositionServerRpc(__instance.lastKnownHivePosition); if (logBees) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: Targeting " + ((object)val3)?.ToString() + ". Synced hive position")); } } else { if (!((Object)(object)beeValues.targetEnemy != (Object)null)) { break; } ((EnemyAI)__instance).agent.acceleration = 16f; if (!flag3 && EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 360f, 16, 2f).Count == 0) { beeValues.targetEnemy = null; } __instance.wasInChase = false; if (__instance.IsHiveMissing()) { beeValues.customBehaviorStateIndex = 2; ((EnemyAI)__instance).SwitchToBehaviourState(2); if (logBees) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case1: HIVE IS MISSING! CustomBehaviorStateIndex changed: " + beeValues.customBehaviorStateIndex)); } } else { beeValues.customBehaviorStateIndex = 0; ((EnemyAI)__instance).SwitchToBehaviourState(0); if (logBees) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case1: CustomBehaviorStateIndex changed: " + beeValues.customBehaviorStateIndex)); } } } break; } case 2: { if ((Object)(object)((EnemyAI)__instance).targetPlayer != (Object)null || ((EnemyAI)__instance).movingTowardsTargetPlayer) { if (logBees && debugSpam) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: target player found or moving towards target player")); } break; } if (__instance.IsHivePlacedAndInLOS()) { if (__instance.wasInChase) { __instance.wasInChase = false; } __instance.lastKnownHivePosition = ((Component)__instance.hive).transform.position + Vector3.up * 0.5f; if (logBees) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: IsHivePlacedAndInLOS triggered")); } EnemyAI val = null; Collider[] array = Physics.OverlapSphere(((Component)__instance.hive).transform.position, (float)__instance.defenseDistance, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)2); if (array != null && array.Length != 0) { for (int i = 0; i < array.Length; i++) { if (((Component)array[i]).gameObject.tag == "Enemy" && !((Object)(object)((Component)array[i]).gameObject.GetComponent<EnemyAICollisionDetect>().mainScript == (Object)(object)__instance)) { val = ((Component)array[i]).gameObject.GetComponent<EnemyAICollisionDetect>().mainScript; if (logBees) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: CollisionArray triggered. Enemy found: " + EnemyAIPatch.DebugStringHead(val))); } break; } } } if ((Object)(object)val != (Object)null && Vector3.Distance(((Component)val).transform.position, ((Component)__instance.hive).transform.position) < (float)__instance.defenseDistance) { ((EnemyAI)__instance).SetDestinationToPosition(((Component)val).transform.position, true); if (logBees) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: Moving towards: " + (object)val)); } beeValues.customBehaviorStateIndex = 1; ((EnemyAI)__instance).SwitchToBehaviourState(1); __instance.syncedLastKnownHivePosition = false; __instance.SyncLastKnownHivePositionServerRpc(__instance.lastKnownHivePosition); beeValues.LostLOSOfEnemy = 0f; if (logBees) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: CustomBehaviorStateIndex changed: " + beeValues.customBehaviorStateIndex)); } } else { beeValues.customBehaviorStateIndex = 0; ((EnemyAI)__instance).SwitchToBehaviourState(0); if (logBees) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: CustomBehaviorStateIndex changed: " + beeValues.customBehaviorStateIndex)); } } break; } bool flag2 = false; Dictionary<EnemyAI, float> enemiesInLOS = EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 360f, 16, 1f); EnemyAI val2 = null; if (enemiesInLOS.Count > 0) { val2 = enemiesInLOS.Keys.First(); } if (logBees) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: " + ((object)val2)?.ToString() + " is closest to hive.")); } if ((Object)(object)val2 != (Object)null && (Object)(object)beeValues.targetEnemy != (Object)(object)val2) { flag2 = true; __instance.wasInChase = false; beeValues.targetEnemy = val2; ((EnemyAI)__instance).SetDestinationToPosition(((Component)beeValues.targetEnemy).transform.position, true); ((EnemyAI)__instance).StopSearch(__instance.searchForHive, true); __instance.syncedLastKnownHivePosition = false; beeValues.LostLOSOfEnemy = 0f; __instance.SyncLastKnownHivePositionServerRpc(__instance.lastKnownHivePosition); if (logBees) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: Targeting " + ((object)val2)?.ToString() + ". Synced hive position")); } break; } if ((Object)(object)beeValues.targetEnemy != (Object)null) { ((EnemyAI)__instance).agent.acceleration = 16f; if (!flag2 && EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 360f, 16, 2f).Count == 0) { if (logBees && debugSpam) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: lost LOS of " + ((object)beeValues.targetEnemy)?.ToString() + ", started timer.")); } beeValues.LostLOSOfEnemy += ((EnemyAI)__instance).AIIntervalTime; if (beeValues.LostLOSOfEnemy >= 4.5f) { beeValues.targetEnemy = null; beeValues.LostLOSOfEnemy = 0f; if (logBees) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: lost LOS of " + ((object)beeValues.targetEnemy)?.ToString() + ", Stopped and reset timer.")); } } } else { __instance.wasInChase = true; beeValues.lastKnownEnemyPosition = ((Component)beeValues.targetEnemy).transform.position; ((EnemyAI)__instance).SetDestinationToPosition(beeValues.lastKnownEnemyPosition, true); beeValues.LostLOSOfEnemy = 0f; if (logBees) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: lost " + (object)beeValues.targetEnemy)); } } break; } ((EnemyAI)__instance).agent.acceleration = 13f; if (__instance.searchForHive.inProgress) { break; } if (logBees) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: set new search for hive")); } if (__instance.wasInChase) { ((EnemyAI)__instance).StartSearch(beeValues.lastKnownEnemyPosition, __instance.searchForHive); if (logBees) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: Started search for hive.")); } } else { ((EnemyAI)__instance).StartSearch(((Component)__instance).transform.position, __instance.searchForHive); if (logBees) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "case2: Started search for hive.")); } } break; } } } public static void OnCustomEnemyCollision(RedLocustBees __instance, EnemyAI mainscript2) { //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Expected O, but got Unknown if (!beeList.ContainsKey(__instance)) { return; } if ((beeList[__instance].timeSinceHittingEnemy > 1.7f && ((EnemyAI)__instance).currentBehaviourStateIndex > 0) || (beeList[__instance].timeSinceHittingEnemy > 1.3f && ((EnemyAI)__instance).currentBehaviourStateIndex == 2 && !mainscript2.isEnemyDead)) { mainscript2.HitEnemy(1, (PlayerControllerB)null, true, -1); beeList[__instance].timeSinceHittingEnemy = 0f; if (!(mainscript2 is ForestGiantAI) || mainscript2.currentBehaviourStateIndex == 2) { return; } float num = Random.Range(0f, 100f); float num2 = 0f; num2 = ((((EnemyAI)__instance).currentBehaviourStateIndex == 2) ? Script.BoundingConfig.beesSetGiantsOnFireMaxChance.Value : Script.BoundingConfig.beesSetGiantsOnFireMinChance.Value); if (logBees) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "OnCustomEnemyCollision: Giant hit. Chance to set on fire: " + num2)); } if (num <= num2) { if (logBees) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "OnCustomEnemyCollision: SET GIANT ON FIRE! Random number: " + num)); } ForestGiantAI val = (ForestGiantAI)mainscript2; val.timeAtStartOfBurning = Time.realtimeSinceStartup; ((EnemyAI)val).SwitchToBehaviourState(2); } } else { beeList[__instance].timeSinceHittingEnemy += Time.deltaTime; } } } internal class BlobData { public float timeSinceHittingLocalMonster = 0f; public EnemyAI? closestEnemy = null; } [HarmonyPatch(typeof(BlobAI))] public class BlobAIPatch { private static List<EnemyAI> whiteList = new List<EnemyAI>(); private static Dictionary<BlobAI, BlobData> slimeList = new Dictionary<BlobAI, BlobData>(); private static bool logBlob = Script.BoundingConfig.debugHygrodere.Value; [HarmonyPatch("Start")] [HarmonyPrefix] private static void StartPatch(BlobAI __instance) { if (!slimeList.ContainsKey(__instance)) { slimeList.Add(__instance, new BlobData()); } } [HarmonyPatch("DoAIInterval")] [HarmonyPrefix] private static bool DoAIIntervalPrefixPatch(BlobAI __instance) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) BlobData blobData = slimeList[__instance]; if ((Object)(object)blobData.closestEnemy != (Object)null && Vector3.Distance(((Component)__instance).transform.position, ((Component)((EnemyAI)__instance).GetClosestPlayer(false, false, false)).transform.position) > Vector3.Distance(((Component)__instance).transform.position, ((Component)blobData.closestEnemy).transform.position)) { if (((EnemyAI)__instance).moveTowardsDestination) { ((EnemyAI)__instance).agent.SetDestination(((EnemyAI)__instance).destination); } ((EnemyAI)__instance).SyncPositionToClients(); if (((EnemyAI)__instance).movingTowardsTargetPlayer) { ((EnemyAI)__instance).movingTowardsTargetPlayer = false; } if (__instance.searchForPlayers.inProgress) { ((EnemyAI)__instance).StopSearch(__instance.searchForPlayers, true); } if ((Object)(object)blobData.closestEnemy != (Object)null) { ((EnemyAI)__instance).SetDestinationToPosition(((Component)blobData.closestEnemy).transform.position, true); } return false; } return true; } [HarmonyPatch("Update")] [HarmonyPrefix] private static void BlobUpdatePatch(BlobAI __instance) { BlobData blobData = slimeList[__instance]; blobData.timeSinceHittingLocalMonster += Time.deltaTime; if (RoundManagerPatch.RequestUpdate((EnemyAI)(object)__instance)) { RoundManagerPatch.ScheduleGlobalListUpdate((EnemyAI)(object)__instance, EnemyAIPatch.FilterEnemyList(EnemyAIPatch.GetInsideEnemyList(EnemyAIPatch.GetCompleteList((EnemyAI)(object)__instance, FilterThemselves: true, 1), (EnemyAI)(object)__instance), null, (EnemyAI)(object)__instance)); } blobData.closestEnemy = EnemyAIPatch.FindClosestEnemy(NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], blobData.closestEnemy, (EnemyAI)(object)__instance, includeTheDead: true); } public static void OnCustomEnemyCollision(BlobAI __instance, EnemyAI mainscript2) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) BlobData blobData = slimeList[__instance]; if (!(blobData.timeSinceHittingLocalMonster > 1.5f)) { return; } if (mainscript2.isEnemyDead && !IsEnemyImmortal.EnemyIsImmortal(mainscript2) && Vector3.Distance(((Component)__instance).transform.position, ((Component)mainscript2).transform.position) <= 2.8f) { mainscript2.thisNetworkObject.Despawn(true); ((EnemyAI)__instance).creatureVoice.PlayOneShot(__instance.killPlayerSFX); } else { if (mainscript2.isEnemyDead || mainscript2 is NutcrackerEnemyAI || mainscript2 is CaveDwellerAI) { return; } blobData.timeSinceHittingLocalMonster = 0f; if (mainscript2 is FlowermanAI) { FlowermanAI val = (FlowermanAI)(object)((mainscript2 is FlowermanAI) ? mainscript2 : null); if ((Object)(object)val != (Object)null) { float angerMeter = val.angerMeter; bool isInAngerMode = val.isInAngerMode; ((EnemyAI)val).HitEnemy(1, (PlayerControllerB)null, true, -1); if (mainscript2.enemyHP <= 0) { mainscript2.KillEnemyOnOwnerClient(false); } ((EnemyAI)val).targetPlayer = null; ((EnemyAI)val).movingTowardsTargetPlayer = false; val.isInAngerMode = false; val.angerMeter = angerMeter; val.isInAngerMode = isInAngerMode; return; } } if (mainscript2 is HoarderBugAI) { HoarderBugAI val2 = (HoarderBugAI)(object)((mainscript2 is HoarderBugAI) ? mainscript2 : null); if ((Object)(object)val2 != (Object)null) { HoarderBugPatch.CustomOnHit(1, (EnemyAI)(object)__instance, playHitSFX: true, val2); if (mainscript2.enemyHP <= 0) { mainscript2.KillEnemyOnOwnerClient(false); } } } else { blobData.timeSinceHittingLocalMonster = 0f; mainscript2.HitEnemy(1, (PlayerControllerB)null, true, -1); if (mainscript2.enemyHP <= 0) { mainscript2.KillEnemyOnOwnerClient(false); } } } } } public class OnCollideWithUniversal { private static bool enableSpider = Script.BoundingConfig.enableSpider.Value; private static bool enableSlime = Script.BoundingConfig.enableSlime.Value; private static bool logUnspecified = Script.BoundingConfig.debugUnspecified.Value; private static bool logSpider = Script.BoundingConfig.debugSpiders.Value; private static bool debugSpam = Script.BoundingConfig.spammyLogs.Value; public static void Collide(string text, EnemyAI? mainscript, EnemyAI? mainscript2) { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Expected O, but got Unknown //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Expected O, but got Unknown //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Expected O, but got Unknown if (logUnspecified) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead(mainscript) + "Hit collider of " + EnemyAIPatch.DebugStringHead(mainscript2) + ", Tag: " + text)); } if (!((Object)(object)mainscript != (Object)null) || text == "Player") { } if (!((Object)(object)mainscript != (Object)null) || !((Object)(object)mainscript2 != (Object)null)) { return; } if (mainscript is SandSpiderAI && !(mainscript2 is SandSpiderAI) && (Object)(object)mainscript2 != (Object)null && enableSpider) { SandSpiderAI val = (SandSpiderAI)mainscript; if (logSpider) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead(mainscript) + " timeSinceHittingPlayer: " + val.timeSinceHittingPlayer)); } if (val.timeSinceHittingPlayer > 1f) { val.timeSinceHittingPlayer = 0f; ((EnemyAI)val).creatureSFX.PlayOneShot(val.attackSFX); if (mainscript2 is HoarderBugAI) { if (mainscript2.enemyHP > 2) { mainscript2.HitEnemy(2, (PlayerControllerB)null, true, -1); } else if (mainscript2.enemyHP > 0) { mainscript2.HitEnemy(1, (PlayerControllerB)null, true, -1); } } if (mainscript2 is PufferAI) { if (mainscript2.enemyHP > 2) { PufferAIPatch.CustomOnHit(2, mainscript, playHitSFX: true, (PufferAI)mainscript2); } else if (mainscript2.enemyHP > 0) { PufferAIPatch.CustomOnHit(1, mainscript, playHitSFX: true, (PufferAI)mainscript2); } } if (logSpider) { Script.Logger.LogMessage((object)(EnemyAIPatch.DebugStringHead(mainscript) + " Hit " + EnemyAIPatch.DebugStringHead(mainscript2) + ", Tag: " + text)); } } } if (mainscript is BlobAI && !(mainscript2 is BlobAI) && (Object)(object)mainscript2 != (Object)null && enableSlime) { BlobAIPatch.OnCustomEnemyCollision((BlobAI)mainscript, mainscript2); } if (mainscript is RedLocustBees && !(mainscript2 is RedLocustBees) && (Object)(object)mainscript2 != (Object)null) { BeeAIPatch.OnCustomEnemyCollision((RedLocustBees)mainscript, mainscript2); } } } [HarmonyPatch(typeof(EnemyAICollisionDetect), "OnTriggerStay")] public class AICollisionDetectPatch { private static bool Prefix(Collider other, EnemyAICollisionDetect __instance) { EnemyAICollisionDetect component = ((Component)other).gameObject.GetComponent<EnemyAICollisionDetect>(); if ((Object)(object)__instance != (Object)null) { if (((Component)other).CompareTag("Player") && !__instance.mainScript.isEnemyDead) { OnCollideWithUniversal.Collide("Player", null, null); return true; } if (((Component)other).CompareTag("Enemy") && (Object)(object)component != (Object)null && (Object)(object)component.mainScript != (Object)(object)__instance.mainScript && !IsEnemyImmortal.EnemyIsImmortal(component.mainScript) && !__instance.mainScript.isEnemyDead) { OnCollideWithUniversal.Collide("Enemy", __instance.mainScript, component.mainScript); return true; } } return true; } } public class IsEnemyImmortal { public static bool EnemyIsImmortal(EnemyAI instance) { if (instance is NutcrackerEnemyAI && instance.currentBehaviourStateIndex == 0) { return true; } if (instance is JesterAI) { return true; } if (instance is BlobAI) { return true; } if (instance is SpringManAI) { return true; } if (instance is SandWormAI) { return true; } if (instance is ButlerBeesEnemyAI) { return true; } return false; } } [HarmonyPatch(typeof(EnemyAI))] internal class EnemyAIPatch { private static bool debugUnspecified = Script.BoundingConfig.debugUnspecified.Value; private static bool debugSpam = Script.BoundingConfig.spammyLogs.Value; private static bool debugTriggerFlag = Script.BoundingConfig.debugTriggerFlags.Value; [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPostfix(EnemyAI __instance) { if (debugSpam && debugUnspecified) { Script.Logger.LogInfo((object)"Called Setup library!"); } __instance.agent.radius = __instance.agent.radius * Script.clampedAgentRadius; } public static string DebugStringHead(EnemyAI? instance) { return NaturalSelectionLib.DebugStringHead(instance); } public static List<EnemyAI> GetCompleteList(EnemyAI instance, bool FilterThemselves = true, int includeOrReturnThedDead = 0) { if (debugSpam && debugTriggerFlag && debugUnspecified) { Script.Logger.LogInfo((object)"Called library GetCompleteList!"); } return NaturalSelectionLib.GetCompleteList(instance, FilterThemselves, includeOrReturnThedDead); } public static List<EnemyAI> GetOutsideEnemyList(List<EnemyAI> importEnemyList, EnemyAI instance) { if (debugSpam && debugTriggerFlag && debugUnspecified) { Script.Logger.LogInfo((object)"Called library GetOutsideEnemyList!"); } return NaturalSelectionLib.GetOutsideEnemyList(importEnemyList, instance); } public static List<EnemyAI> GetInsideEnemyList(List<EnemyAI> importEnemyList, EnemyAI instance) { if (debugSpam && debugTriggerFlag && debugUnspecified) { Script.Logger.LogInfo((object)"Called library GetInsideEnemyList!"); } return NaturalSelectionLib.GetInsideEnemyList(importEnemyList, instance); } public static EnemyAI? FindClosestEnemy(List<EnemyAI> importEnemyList, EnemyAI? importClosestEnemy, EnemyAI instance, bool includeTheDead = false) { if (debugSpam && debugTriggerFlag && debugUnspecified) { Script.Logger.LogInfo((object)"Called library findClosestEnemy!"); } return NaturalSelectionLib.FindClosestEnemy(importEnemyList, importClosestEnemy, instance, includeTheDead); } public static List<EnemyAI> FilterEnemyList(List<EnemyAI> importEnemyList, List<Type>? targetTypes, EnemyAI instance, bool inverseToggle = false, bool filterOutImmortal = true) { if (debugSpam && debugTriggerFlag && debugUnspecified) { Script.Logger.LogInfo((object)"Called library filterEnemyList!"); } return NaturalSelectionLib.FilterEnemyList(importEnemyList, targetTypes, instance, inverseToggle, filterOutImmortal); } public static Dictionary<EnemyAI, float> GetEnemiesInLOS(EnemyAI instance, List<EnemyAI> importEnemyList, float width = 45f, int importRange = 0, float proximityAwareness = -1f) { if (debugSpam && debugTriggerFlag && debugUnspecified) { Script.Logger.LogInfo((object)"Called library GetEnemiesInLOS!"); } return NaturalSelectionLib.GetEnemiesInLOS(instance, importEnemyList, width, importRange, proximityAwareness); } public static int ReactToHit(int force = 0, EnemyAI? enemyAI = null, PlayerControllerB? player = null) { if (force > 0) { return 1; } if (force > 1) { return 2; } return 0; } } public class ReversePatchEnemy : EnemyAI { public override void Update() { ((EnemyAI)this).Update(); } } internal class GiantData { public bool logGiant = Script.BoundingConfig.debugGiants.Value; private static bool debugSpam = Script.BoundingConfig.spammyLogs.Value; public bool? extinguish = null; } [HarmonyPatch(typeof(ForestGiantAI))] internal class ForestGiantPatch { private static Dictionary<ForestGiantAI, GiantData> giantDictionary = new Dictionary<ForestGiantAI, GiantData>(); [HarmonyPatch("Start")] [HarmonyPostfix] private static void startPostfix(ForestGiantAI __instance) { if (!giantDictionary.ContainsKey(__instance)) { giantDictionary.Add(__instance, new GiantData()); } } [HarmonyPatch("KillEnemy")] [HarmonyPrefix] public static void KillEnemyPatchPrefix(ForestGiantAI __instance, out bool __state) { GiantData giantData = giantDictionary[__instance]; if (__instance.burningParticlesContainer.activeSelf) { __state = true; } else { __state = false; } if (giantData.logGiant) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " state status: " + __state)); } } [HarmonyPatch("KillEnemy")] [HarmonyPostfix] private static void KillEnemyPatchPostfix(ForestGiantAI __instance, bool __state) { GiantData giantData = giantDictionary[__instance]; if (__state) { __instance.burningParticlesContainer.SetActive(true); } else { __instance.burningParticlesContainer.SetActive(false); } if (giantData.logGiant) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " state status2: " + __state)); } } [HarmonyPatch("Update")] [HarmonyPrefix] private static bool UpdatePrefix(ForestGiantAI __instance) { GiantData giantData = giantDictionary[__instance]; if (((EnemyAI)__instance).currentBehaviourStateIndex == 2 && ((NetworkBehaviour)__instance).IsOwner && Time.realtimeSinceStartup - __instance.timeAtStartOfBurning > 9.5f && ((EnemyAI)__instance).enemyHP > 20 && !giantData.extinguish.HasValue) { int num = Random.Range(0, 100); if (num <= 33) { ((EnemyAI)__instance).enemyHP = ((EnemyAI)__instance).enemyHP - 20; __instance.burningParticlesContainer.SetActive(false); __instance.giantBurningAudio.Stop(); ((EnemyAI)__instance).creatureAnimator.SetBool("burning", false); ((EnemyAI)__instance).SwitchToBehaviourState(0); giantData.extinguish = true; if (giantData.logGiant) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " successfully extinguished itself. Skipping Update. Rolled " + num)); } return false; } giantData.extinguish = false; if (giantData.logGiant) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " failed to extinguish itself. rolled " + num)); } } return true; } [HarmonyPatch("Update")] [HarmonyPostfix] private static void UpdatePostfix(ForestGiantAI __instance) { if (((EnemyAI)__instance).isEnemyDead && Time.realtimeSinceStartup - __instance.timeAtStartOfBurning < 20f && ((EnemyAI)__instance).currentBehaviourStateIndex == 2) { if (!__instance.giantBurningAudio.isPlaying) { __instance.giantBurningAudio.Play(); } __instance.giantBurningAudio.volume = Mathf.Min(__instance.giantBurningAudio.volume + Time.deltaTime * 0.5f, 1f); } else if (((EnemyAI)__instance).isEnemyDead && Time.realtimeSinceStartup - __instance.timeAtStartOfBurning > 26f) { __instance.burningParticlesContainer.SetActive(false); } } } internal class HoarderBugValues { public EnemyAI? targetEnemy = null; public EnemyAI? closestEnemy = null; public bool alertedByEnemy = false; public List<EnemyAI> enemies = new List<EnemyAI>(); public List<EnemyAI> enemiesInLOS = new List<EnemyAI>(); } [HarmonyPatch(typeof(HoarderBugAI))] internal class HoarderBugPatch { private static Dictionary<HoarderBugAI, HoarderBugValues> hoarderBugList = new Dictionary<HoarderBugAI, HoarderBugValues>(); public static void CustomOnHit(int force, EnemyAI enemyWhoHit, bool playHitSFX, HoarderBugAI __instance) { ((EnemyAI)__instance).enemyHP = ((EnemyAI)__instance).enemyHP - force; Script.Logger.LogDebug((object)"Hoarderbug CustomHit Triggered"); ((EnemyAI)__instance).creatureVoice.PlayOneShot(__instance.hitPlayerSFX); RoundManager.PlayRandomClip(((EnemyAI)__instance).creatureVoice, __instance.angryScreechSFX, true, 1f, 0, 1000); ((EnemyAI)__instance).SwitchToBehaviourState(1); if (((EnemyAI)__instance).enemyHP <= 0) { ((EnemyAI)__instance).KillEnemy(false); } } } internal class NutcrackerData { public EnemyAI? closestEnemy = null; public EnemyAI? targetEnemy = null; public bool SeeMovingEnemy = false; public Vector3 lastSeenEnemyPosition = Vector3.zero; public float TimeSinceSeeingMonster = 0f; public float TimeSinceHittingMonster = 0f; } [HarmonyPatch(typeof(NutcrackerEnemyAI))] internal class NutcrackerAIPatch { private static List<EnemyAI> enemyList = new List<EnemyAI>(); private static Dictionary<NutcrackerEnemyAI, NutcrackerData> NutcrackerData = new Dictionary<NutcrackerEnemyAI, NutcrackerData>(); private static bool enableNucracker = Script.BoundingConfig.enableNutcrackers.Value; private static bool debugSpam = Script.BoundingConfig.spammyLogs.Value; private static bool debugNutcrackers = Script.BoundingConfig.debugNutcrackers.Value; public static bool CheckLOSForMonsters(Vector3 monsterPosition, NutcrackerEnemyAI __instance, float width = 45f, int range = 60, int proximityAwareness = 60) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) if (Vector3.Distance(monsterPosition, ((EnemyAI)__instance).eye.position) < (float)range && !Physics.Linecast(((EnemyAI)__instance).eye.position, monsterPosition, StartOfRound.Instance.collidersAndRoomMaskAndDefault)) { Vector3 val = monsterPosition - ((EnemyAI)__instance).eye.position; if (Vector3.Angle(((EnemyAI)__instance).eye.forward, val) < width || (proximityAwareness != -1 && Vector3.Distance(((EnemyAI)__instance).eye.position, monsterPosition) < (float)proximityAwareness)) { return true; } } return false; } [HarmonyPatch("Start")] [HarmonyPostfix] private static void UpdatePatch(NutcrackerEnemyAI __instance) { if (!NutcrackerData.ContainsKey(__instance)) { NutcrackerData.Add(__instance, new NutcrackerData()); } } [HarmonyPatch("Update")] [HarmonyPostfix] private static void NutcrackerUpdatePostfix(NutcrackerEnemyAI __instance) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: 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_0332: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) if (!enableNucracker) { return; } NutcrackerData nutcrackerData = NutcrackerData[__instance]; enemyList = EnemyAIPatch.GetOutsideEnemyList(EnemyAIPatch.GetCompleteList((EnemyAI)(object)__instance), (EnemyAI)(object)__instance); nutcrackerData.closestEnemy = EnemyAIPatch.FindClosestEnemy(enemyList, nutcrackerData.closestEnemy, (EnemyAI)(object)__instance); Vector3 velocity; if (((EnemyAI)__instance).currentBehaviourStateIndex == 1 && (Object)(object)nutcrackerData.closestEnemy != (Object)null) { if (__instance.isInspecting && CheckLOSForMonsters(((Component)nutcrackerData.closestEnemy).transform.position, __instance, 70f, 60, 1)) { velocity = nutcrackerData.closestEnemy.agent.velocity; if (((Vector3)(ref velocity)).magnitude > 0f) { __instance.isInspecting = false; nutcrackerData.SeeMovingEnemy = true; __instance.lastSeenPlayerPos = ((Component)nutcrackerData.closestEnemy).transform.position; } } } else { if (((EnemyAI)__instance).currentBehaviourStateIndex != 2) { return; } if (nutcrackerData.SeeMovingEnemy) { __instance.StopInspection(); } ((EnemyAI)__instance).SwitchToBehaviourState(2); if (__instance.lostPlayerInChase) { __instance.targetTorsoDegrees = 0; } else { __instance.SetTargetDegreesToPosition(nutcrackerData.lastSeenEnemyPosition); } if (!((Object)(object)nutcrackerData.targetEnemy != (Object)null)) { return; } if (((EnemyAI)__instance).CheckLineOfSightForPosition(((Component)nutcrackerData.targetEnemy).transform.position, 70f, 60, 1f, (Transform)null)) { nutcrackerData.TimeSinceSeeingMonster = 0f; nutcrackerData.lastSeenEnemyPosition = ((Component)nutcrackerData.targetEnemy).transform.position; ((EnemyAI)__instance).creatureAnimator.SetBool("AimDown", Vector3.Distance(nutcrackerData.lastSeenEnemyPosition, ((Component)__instance).transform.position) < 2f && nutcrackerData.lastSeenEnemyPosition.y < 1f); } if (!((EnemyAI)__instance).CheckLineOfSightForPosition(((Component)nutcrackerData.targetEnemy).transform.position, 70f, 25, 1f, (Transform)null)) { return; } if (Object.op_Implicit((Object)(object)nutcrackerData.targetEnemy) && nutcrackerData.TimeSinceSeeingMonster < 8f && __instance.timeSinceSeeingTarget < 8f) { if (__instance.timeSinceFiringGun > 0.75f && !__instance.reloadingGun && !__instance.aimingGun && nutcrackerData.TimeSinceHittingMonster > 1f && Vector3.Angle(__instance.gun.shotgunRayPoint.forward, ((Component)nutcrackerData.targetEnemy).transform.position - __instance.gun.shotgunRayPoint.position) < 30f) { __instance.timeSinceFiringGun = 0f; ((EnemyAI)__instance).agent.speed = 0f; __instance.AimGunServerRpc(((Component)__instance).transform.position); } if (__instance.lostPlayerInChase) { __instance.SetLostPlayerInChaseServerRpc(false); } nutcrackerData.TimeSinceSeeingMonster = 0f; nutcrackerData.lastSeenEnemyPosition = ((Component)nutcrackerData.targetEnemy).transform.position; } else { velocity = nutcrackerData.targetEnemy.agent.velocity; if (((Vector3)(ref velocity)).magnitude > 0f) { nutcrackerData.TimeSinceSeeingMonster = 0f; } } } } [HarmonyPatch("DoAIInterval")] [HarmonyPostfix] private static void DoAIIntervalPatch(NutcrackerEnemyAI __instance) { //IL_009b: Unknown result type (might be due to invalid IL or missing references) if (!enableNucracker) { return; } NutcrackerData nutcrackerData = NutcrackerData[__instance]; if (((EnemyAI)__instance).currentBehaviourStateIndex != 2 || !((Object)(object)nutcrackerData.targetEnemy != (Object)null)) { return; } if (nutcrackerData.TimeSinceSeeingMonster < 0.5f && __instance.timeSinceSeeingTarget < 0.5f) { if (__instance.attackSearch.inProgress) { ((EnemyAI)__instance).StopSearch(__instance.attackSearch, true); } __instance.reachedStrafePosition = false; ((EnemyAI)__instance).SetDestinationToPosition(((Component)nutcrackerData.targetEnemy).transform.position, false); ((EnemyAI)__instance).agent.stoppingDistance = 1f; ((EnemyAI)__instance).moveTowardsDestination = true; } if (nutcrackerData.TimeSinceSeeingMonster > 12f && __instance.timeSinceSeeingTarget > 12f) { ((EnemyAI)__instance).SwitchToBehaviourState(1); } } } internal class PufferData { public int reactionToHit = 0; public EnemyAI? targetEnemy = null; } [HarmonyPatch(typeof(PufferAI))] internal class PufferAIPatch { private static bool enableSporeLizard = Script.BoundingConfig.enableSporeLizard.Value; private static Dictionary<PufferAI, PufferData> pufferList = new Dictionary<PufferAI, PufferData>(); [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPostfix(PufferAI __instance) { if (!pufferList.ContainsKey(__instance)) { pufferList.Add(__instance, new PufferData()); } } [HarmonyPatch("DoAIInterval")] [HarmonyPrefix] private static bool PrefixAIInterval(PufferAI __instance) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) PufferData pufferData = pufferList[__instance]; if (((EnemyAI)__instance).currentBehaviourStateIndex == 2 && (Object)(object)pufferData.targetEnemy != (Object)null && Vector3.Distance(((Component)__instance.closestSeenPlayer).transform.position, ((Component)__instance).transform.position) < Vector3.Distance(((Component)pufferData.targetEnemy).transform.position, ((Component)__instance).transform.position)) { if (((EnemyAI)__instance).moveTowardsDestination) { ((EnemyAI)__instance).agent.SetDestination(((EnemyAI)__instance).destination); } ((EnemyAI)__instance).SyncPositionToClients(); return false; } return true; } [HarmonyPatch("DoAIInterval")] [HarmonyPostfix] private static void PostfixAIInterval(PufferAI __instance) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) PufferData pufferData = pufferList[__instance]; if (((EnemyAI)__instance).currentBehaviourStateIndex == 2 && (Object)(object)pufferData.targetEnemy != (Object)null && Vector3.Distance(((Component)__instance.closestSeenPlayer).transform.position, ((Component)__instance).transform.position) < Vector3.Distance(((Component)pufferData.targetEnemy).transform.position, ((Component)__instance).transform.position)) { ((EnemyAI)__instance).SetDestinationToPosition(((Component)pufferData.targetEnemy).transform.position, true); } else { pufferData.reactionToHit = 0; } } public static void CustomOnHit(int force, EnemyAI enemyWhoHit, bool playHitSFX, PufferAI instance) { if (enableSporeLizard) { PufferData pufferData = pufferList[instance]; ((EnemyAI)instance).creatureAnimator.SetBool("alerted", true); ((EnemyAI)instance).enemyHP = ((EnemyAI)instance).enemyHP - force; Script.Logger.LogDebug((object)"SpodeLizard CustomHit Triggered"); HitEnemyTest(force, enemyWhoHit, playHitSFX, instance); ((EnemyAI)instance).SwitchToBehaviourState(2); if (((EnemyAI)instance).enemyHP <= 0) { ((EnemyAI)instance).KillEnemy(true); } } } public static void HitEnemyTest(int force, EnemyAI enemyWhoHit, bool playHitSFX, PufferAI instance) { int num = EnemyAIPatch.ReactToHit(force); if (enemyWhoHit is SandSpiderAI) { pufferList[instance].reactionToHit = 2; } else { pufferList[instance].reactionToHit = 1; } } } internal class SpiderData { public EnemyAI? closestEnemy = null; public EnemyAI? targetEnemy = null; public List<EnemyAI> knownEnemy = new List<EnemyAI>(); public List<EnemyAI> deadEnemyBodies = new List<EnemyAI>(); public float LookAtEnemyTimer = 0f; public Dictionary<EnemyAI, float> enemiesInLOSDictionary = new Dictionary<EnemyAI, float>(); } [HarmonyPatch] internal class Reversepatch { [HarmonyReversePatch(/*Could not decode attribute arguments.*/)] [HarmonyPatch(typeof(EnemyAI), "Update")] public static void ReverseUpdate(SandSpiderAI instance) { } } [HarmonyPatch(typeof(SandSpiderAI))] internal class SandSpiderAIPatch { private static float refreshCDtimeSpider = 1f; private static bool enableSpider = Script.BoundingConfig.enableSpider.Value; private static bool spiderHuntHoardingbug = Script.BoundingConfig.spiderHuntHoardingbug.Value; private static Dictionary<SandSpiderAI, SpiderData> spiderList = new Dictionary<SandSpiderAI, SpiderData>(); private static bool debugSpider = Script.BoundingConfig.debugSpiders.Value; private static bool debugSpam = Script.BoundingConfig.spammyLogs.Value; [HarmonyPatch("Start")] [HarmonyPrefix] private static void StartPatch(SandSpiderAI __instance) { if (!spiderList.ContainsKey(__instance)) { spiderList.Add(__instance, new SpiderData()); SpiderData spiderData = spiderList[__instance]; } } [HarmonyPatch("Update")] [HarmonyPrefix] private static bool UpdatePrefixPatch(SandSpiderAI __instance) { //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_040a: Unknown result type (might be due to invalid IL or missing references) //IL_041a: Unknown result type (might be due to invalid IL or missing references) //IL_047b: Unknown result type (might be due to invalid IL or missing references) //IL_05a6: Unknown result type (might be due to invalid IL or missing references) //IL_04c4: Unknown result type (might be due to invalid IL or missing references) //IL_04d4: Unknown result type (might be due to invalid IL or missing references) //IL_04ea: Unknown result type (might be due to invalid IL or missing references) //IL_04fa: Unknown result type (might be due to invalid IL or missing references) //IL_0613: Unknown result type (might be due to invalid IL or missing references) //IL_0626: Unknown result type (might be due to invalid IL or missing references) //IL_0631: Unknown result type (might be due to invalid IL or missing references) //IL_0641: Unknown result type (might be due to invalid IL or missing references) //IL_07aa: Unknown result type (might be due to invalid IL or missing references) //IL_0695: Unknown result type (might be due to invalid IL or missing references) //IL_069a: Unknown result type (might be due to invalid IL or missing references) //IL_069d: Unknown result type (might be due to invalid IL or missing references) //IL_06de: Unknown result type (might be due to invalid IL or missing references) //IL_06ee: Unknown result type (might be due to invalid IL or missing references) //IL_08b6: Unknown result type (might be due to invalid IL or missing references) //IL_08c1: Unknown result type (might be due to invalid IL or missing references) //IL_075e: Unknown result type (might be due to invalid IL or missing references) //IL_0769: Unknown result type (might be due to invalid IL or missing references) //IL_08dd: Unknown result type (might be due to invalid IL or missing references) //IL_08e8: Unknown result type (might be due to invalid IL or missing references) if (!enableSpider) { return true; } SpiderData spiderData = spiderList[__instance]; if (RoundManagerPatch.RequestUpdate((EnemyAI)(object)__instance)) { RoundManagerPatch.ScheduleGlobalListUpdate((EnemyAI)(object)__instance, EnemyAIPatch.GetInsideEnemyList(EnemyAIPatch.GetCompleteList((EnemyAI)(object)__instance), (EnemyAI)(object)__instance)); } spiderData.enemiesInLOSDictionary = EnemyAIPatch.GetEnemiesInLOS((EnemyAI)(object)__instance, NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], 80f, 15, 2f); if (spiderData.enemiesInLOSDictionary.Count > 0) { foreach (KeyValuePair<EnemyAI, float> item in spiderData.enemiesInLOSDictionary) { if (item.Key.isEnemyDead) { if (debugSpider) { Script.Logger.LogWarning((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Update Postfix: " + ((object)item.Key)?.ToString() + " is Dead! Checking deadEnemyBodies list and skipping...")); } if (!spiderData.deadEnemyBodies.Contains(item.Key)) { spiderData.deadEnemyBodies.Add(item.Key); if (debugSpider) { Script.Logger.LogWarning((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Update Postfix: " + ((object)item.Key)?.ToString() + " added to deadEnemyBodies list")); } } } else if (spiderData.knownEnemy.Contains(item.Key)) { if (debugSpider && debugSpam) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Update Postfix: " + ((object)item.Key)?.ToString() + " is already in knownEnemyList")); } } else { if (debugSpider) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Update Postfix: Adding " + ((object)item.Key)?.ToString() + " to knownEnemyList")); } spiderData.knownEnemy.Add(item.Key); } } for (int i = 0; i < spiderData.knownEnemy.Count; i++) { if (spiderData.knownEnemy[i].isEnemyDead) { if (debugSpider) { Script.Logger.LogWarning((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Update Postfix: Removed " + ((object)spiderData.knownEnemy[i])?.ToString() + " from knownEnemyList")); } spiderData.knownEnemy.Remove(spiderData.knownEnemy[i]); } } } __instance.SyncMeshContainerPositionToClients(); __instance.CalculateMeshMovement(); switch (((EnemyAI)__instance).currentBehaviourStateIndex) { case 0: spiderData.closestEnemy = EnemyAIPatch.FindClosestEnemy(spiderData.knownEnemy, spiderData.closestEnemy, (EnemyAI)(object)__instance); if ((Object)(object)spiderData.closestEnemy != (Object)null && ((EnemyAI)__instance).CheckLineOfSightForPosition(((Component)spiderData.closestEnemy).transform.position, 80f, 15, 2f, ((EnemyAI)__instance).eye) && !spiderData.closestEnemy.isEnemyDead) { spiderData.targetEnemy = spiderData.closestEnemy; if (debugSpider) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case0/ Set " + ((object)spiderData.closestEnemy)?.ToString() + " as TargetEnemy")); } ((EnemyAI)__instance).SwitchToBehaviourState(2); if (debugSpider) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case0/ Set state to " + ((EnemyAI)__instance).currentBehaviourStateIndex)); } __instance.chaseTimer = 12.5f; __instance.watchFromDistance = Vector3.Distance(((Component)__instance.meshContainer).transform.position, ((Component)spiderData.closestEnemy).transform.position) > 8f; } break; case 2: if ((Object)(object)((EnemyAI)__instance).targetPlayer != (Object)null) { break; } if ((Object)(object)spiderData.targetEnemy != (Object)(object)spiderData.closestEnemy && (Object)(object)spiderData.closestEnemy != (Object)null && ((EnemyAI)__instance).CheckLineOfSightForPosition(((Component)spiderData.closestEnemy).transform.position, 80f, 15, 2f, ((EnemyAI)__instance).eye)) { if (spiderData.targetEnemy is HoarderBugAI && !(spiderData.closestEnemy is HoarderBugAI) && Vector3.Distance(__instance.meshContainer.position, ((Component)spiderData.targetEnemy).transform.position) * 1.2f < Vector3.Distance(__instance.meshContainer.position, ((Component)spiderData.closestEnemy).transform.position)) { spiderData.targetEnemy = spiderData.closestEnemy; } else { spiderData.targetEnemy = spiderData.closestEnemy; } } if ((Object)(object)spiderData.targetEnemy == (Object)null) { if (debugSpider) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2-0/ Stopping chasing: " + (object)spiderData.targetEnemy)); } spiderData.targetEnemy = null; __instance.StopChasing(false); break; } if (__instance.onWall) { ((EnemyAI)__instance).SetDestinationToPosition(((Component)spiderData.targetEnemy).transform.position, false); ((EnemyAI)__instance).agent.speed = 4.25f; __instance.spiderSpeed = 4.25f; if (debugSpider) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2/ onWall")); } break; } if (__instance.watchFromDistance && (Object)(object)((EnemyAI)__instance).GetClosestPlayer(true, false, false) != (Object)null && Vector3.Distance(__instance.meshContainerPosition, ((Component)((EnemyAI)__instance).GetClosestPlayer(true, false, false)).transform.position) > Vector3.Distance(__instance.meshContainerPosition, ((Component)spiderData.targetEnemy).transform.position)) { if (spiderData.LookAtEnemyTimer <= 0f) { spiderData.LookAtEnemyTimer = 3f; ((EnemyAI)__instance).movingTowardsTargetPlayer = false; __instance.overrideSpiderLookRotation = true; Vector3 position = ((Component)spiderData.targetEnemy).transform.position; __instance.SetSpiderLookAtPosition(position); } else { spiderData.LookAtEnemyTimer -= Time.deltaTime; } __instance.spiderSpeed = 0f; ((EnemyAI)__instance).agent.speed = 0f; if (Physics.Linecast(__instance.meshContainer.position, ((Component)spiderData.targetEnemy).transform.position, StartOfRound.Instance.collidersAndRoomMaskAndDefault)) { if (debugSpider) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2-1/ Stopping chasing: " + (object)spiderData.targetEnemy)); } spiderData.targetEnemy = null; __instance.StopChasing(false); } else if (Vector3.Distance(((Component)spiderData.targetEnemy).transform.position, __instance.meshContainer.position) < 5f || ((EnemyAI)__instance).stunNormalizedTimer > 0f) { __instance.watchFromDistance = false; } break; } ((EnemyAI)__instance).SetDestinationToPosition(((Component)spiderData.targetEnemy).transform.position, false); if ((Object)(object)spiderData.targetEnemy == (Object)null || spiderData.targetEnemy.isEnemyDead) { if (debugSpider) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2-2/ Stopping chasing: " + (object)spiderData.targetEnemy)); } if ((Object)(object)spiderData.targetEnemy != (Object)null) { try { spiderData.deadEnemyBodies.Add(spiderData.targetEnemy); spiderData.knownEnemy.Remove(spiderData.targetEnemy); if (debugSpider) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2-2/ Moved dead enemy to separate list")); } } catch { Script.Logger.LogError((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2-2/ Enemy does not exist!")); } } spiderData.targetEnemy = null; __instance.StopChasing(false); } else { if (!(Vector3.Distance(((Component)spiderData.targetEnemy).transform.position, __instance.homeNode.position) > 12f) || !(Vector3.Distance(((Component)spiderData.targetEnemy).transform.position, __instance.meshContainer.position) > 5f)) { break; } __instance.chaseTimer -= Time.deltaTime; if (__instance.chaseTimer <= 0f) { if (debugSpider) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "Update Postfix: /case2-3/ Stopping chasing: " + (object)spiderData.targetEnemy)); } spiderData.targetEnemy = null; __instance.StopChasing(false); } } break; } if (refreshCDtimeSpider <= 0f) { if (debugSpider && debugSpam) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "watchFromDistance: " + __instance.watchFromDistance)); Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "overrideSpiderLookRotation: " + __instance.overrideSpiderLookRotation)); Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "moveTowardsDestination: " + ((EnemyAI)__instance).moveTowardsDestination)); Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "movingTowardsTargetPlayer: " + ((EnemyAI)__instance).movingTowardsTargetPlayer)); } refreshCDtimeSpider = 0.5f; } else { refreshCDtimeSpider -= Time.deltaTime; } if ((Object)(object)spiderData.targetEnemy != (Object)null && !Object.op_Implicit((Object)(object)((EnemyAI)__instance).targetPlayer) && ((EnemyAI)__instance).currentBehaviourStateIndex == 2) { Reversepatch.ReverseUpdate(__instance); if (((EnemyAI)__instance).updateDestinationInterval >= 0f) { ((EnemyAI)__instance).updateDestinationInterval = ((EnemyAI)__instance).updateDestinationInterval - Time.deltaTime; } else { ((EnemyAI)__instance).updateDestinationInterval = ((EnemyAI)__instance).AIIntervalTime + Random.Range(-0.015f, 0.015f); ((EnemyAI)__instance).DoAIInterval(); } __instance.timeSinceHittingPlayer += Time.deltaTime; return false; } return true; } [HarmonyPatch("DoAIInterval")] [HarmonyPrefix] private static bool DoAIIntervalPrefix(SandSpiderAI __instance) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) if (!spiderHuntHoardingbug) { return true; } SpiderData spiderData = spiderList[__instance]; if ((Object)(object)spiderData.targetEnemy != (Object)null && !Object.op_Implicit((Object)(object)((EnemyAI)__instance).targetPlayer) && ((EnemyAI)__instance).currentBehaviourStateIndex == 2) { if (((EnemyAI)__instance).moveTowardsDestination) { ((EnemyAI)__instance).agent.SetDestination(((EnemyAI)__instance).destination); } ((EnemyAI)__instance).SyncPositionToClients(); if (debugSpider && debugSpam) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval Prefix: false")); } return false; } if (debugSpider && debugSpam) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval Prefix: true")); } return true; } [HarmonyPatch("DoAIInterval")] [HarmonyPostfix] private static void DoAIIntervalPostfix(SandSpiderAI __instance) { //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) SpiderData spiderData = spiderList[__instance]; switch (((EnemyAI)__instance).currentBehaviourStateIndex) { case 0: if (debugSpider && debugSpam) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval Postfix: /case0/ nothing")); } break; case 1: { if (debugSpider && debugSpam) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval Postfix: /case1/")); } List<EnemyAI> list = spiderData.enemiesInLOSDictionary.Keys.ToList(); if (__instance.reachedWallPosition) { for (int i = 0; i < list.Count; i++) { if (Vector3.Distance(__instance.meshContainer.position, ((Component)list[i]).transform.position) < 5f || list[i] is HoarderBugAI) { ChaseEnemy(__instance, list[i]); if (debugSpider) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval Postfix: /case1/ Chasing enemy: " + (object)list[i])); } break; } if (Vector3.Distance(__instance.meshContainer.position, ((Component)list[i]).transform.position) < 10f) { Vector3 position = ((Component)list[i]).transform.position; float num = Vector3.Dot(position - __instance.meshContainer.position, __instance.wallNormal); Vector3 val = position - num * __instance.wallNormal; __instance.meshContainerTargetRotation = Quaternion.LookRotation(val, __instance.wallNormal); __instance.overrideSpiderLookRotation = true; if (debugSpider) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval Postfix: /case1/ Moving off-wall to enemy: " + (object)list[i])); } break; } } } __instance.overrideSpiderLookRotation = false; break; } case 2: if (!((Object)(object)spiderData.targetEnemy != (Object)null)) { break; } if (spiderData.targetEnemy.isEnemyDead) { if (debugSpider) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval Postfix: /case2/ Stopping chasing: " + (object)spiderData.targetEnemy)); } spiderData.targetEnemy = null; __instance.StopChasing(false); } else if (__instance.watchFromDistance) { ((EnemyAI)__instance).SetDestinationToPosition(((Component)((EnemyAI)__instance).ChooseClosestNodeToPosition(((Component)spiderData.targetEnemy).transform.position, false, 4)).transform.position, false); if (debugSpider) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "DoAIInterval Postfix: /case2/ Set destination to: " + (object)spiderData.targetEnemy)); } } break; } } private static void ChaseEnemy(SandSpiderAI ins, EnemyAI target, SandSpiderWebTrap? triggeredWeb = null) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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) SpiderData spiderData = spiderList[ins]; if ((((EnemyAI)ins).currentBehaviourStateIndex != 2 && ins.watchFromDistance) || Vector3.Distance(((Component)target).transform.position, ins.homeNode.position) < 25f || Vector3.Distance(ins.meshContainer.position, ((Component)target).transform.position) < 15f) { ins.watchFromDistance = false; spiderData.targetEnemy = target; ins.chaseTimer = 12.5f; ((EnemyAI)ins).SwitchToBehaviourState(2); if (debugSpider) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)ins) + "ChaseEnemy: Switched state to: " + ((EnemyAI)ins).currentBehaviourStateIndex)); } } } } internal class SpiderWebValues { public struct EnemyInfo { internal EnemyAI enemyAI { get; set; } internal float enterAgentSpeed { get; set; } internal float enterAnimationSpeed { get; set; } public EnemyInfo(EnemyAI enemy, float enterAgentSpeed, float enterAnimationSpeed) { enemyAI = enemy; this.enterAgentSpeed = enterAgentSpeed; this.enterAnimationSpeed = enterAnimationSpeed; } } public Dictionary<EnemyAI, EnemyInfo> collidingEnemy = new Dictionary<EnemyAI, EnemyInfo>(); } [HarmonyPatch(typeof(SandSpiderWebTrap))] internal class SandSpiderWebTrapPatch { private static Dictionary<SandSpiderWebTrap, SpiderWebValues> spiderWebs = new Dictionary<SandSpiderWebTrap, SpiderWebValues>(); [HarmonyPatch("Awake")] [HarmonyPostfix] private static void AwakePostfix(SandSpiderWebTrap __instance) { if (!spiderWebs.ContainsKey(__instance)) { spiderWebs.Add(__instance, new SpiderWebValues()); } } [HarmonyPatch("OnTriggerStay")] [HarmonyPostfix] private static void OnTriggerStayPatch(Collider other, SandSpiderWebTrap __instance) { SpiderWebValues spiderWebValues = spiderWebs[__instance]; EnemyAI mainScript = ((Component)other).gameObject.GetComponent<EnemyAICollisionDetect>().mainScript; if (Script.BoundingConfig.debugSpiders.Value) { Script.Logger.LogInfo((object)(((object)__instance)?.ToString() + " Triggered")); } if ((Object)(object)mainScript != (Object)null) { if (Script.BoundingConfig.debugSpiders.Value) { Script.Logger.LogInfo((object)(((object)__instance)?.ToString() + " Collided with " + (object)mainScript)); } if (!spiderWebValues.collidingEnemy.ContainsKey(mainScript)) { spiderWebValues.collidingEnemy.Add(mainScript, new SpiderWebValues.EnemyInfo(mainScript, mainScript.agent.speed, mainScript.creatureAnimator.speed)); if (Script.BoundingConfig.debugSpiders.Value) { Script.Logger.LogInfo((object)(((object)__instance)?.ToString() + " Added " + ((object)mainScript)?.ToString() + " to collidingEnemy")); } } mainScript.agent.speed = spiderWebValues.collidingEnemy[mainScript].enterAgentSpeed / 3f; mainScript.creatureAnimator.speed = spiderWebValues.collidingEnemy[mainScript].enterAnimationSpeed / 3f; if (Script.BoundingConfig.debugSpiders.Value) { Script.Logger.LogInfo((object)(((object)__instance)?.ToString() + " Slowed down " + (object)mainScript)); } if (!__instance.webAudio.isPlaying) { __instance.webAudio.Play(); __instance.webAudio.PlayOneShot(__instance.mainScript.hitWebSFX); } } if ((Object)(object)mainScript == (Object)null) { spiderWebValues.collidingEnemy.Clear(); if (Script.BoundingConfig.debugSpiders.Value) { Script.Logger.LogInfo((object)(((object)__instance)?.ToString() + " Cleared " + ((object)mainScript)?.ToString() + " from collidingEnemy")); } if (__instance.webAudio.isPlaying && (Object)(object)__instance.currentTrappedPlayer == (Object)null) { __instance.webAudio.Stop(); } } } [HarmonyPatch("Update")] [HarmonyPrefix] private static bool UpdatePrefix(SandSpiderWebTrap __instance, out bool __state) { SpiderWebValues spiderWebValues = spiderWebs[__instance]; if ((Object)(object)__instance.currentTrappedPlayer != (Object)null) { __state = false; return true; } if (spiderWebValues.collidingEnemy.Count > 0) { __state = true; return false; } __state = false; return true; } [HarmonyPatch("Update")] [HarmonyPostfix] private static void UpdatePostfix(SandSpiderWebTrap __instance, bool __state) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) if (__state) { SpiderWebValues spiderWebValues = spiderWebs[__instance]; if (spiderWebValues.collidingEnemy.Count > 0) { __instance.leftBone.LookAt(((Component)spiderWebValues.collidingEnemy.First().Key).transform.position); __instance.rightBone.LookAt(((Component)spiderWebValues.collidingEnemy.First().Key).transform.position); } else { __instance.leftBone.LookAt(__instance.centerOfWeb); __instance.rightBone.LookAt(__instance.centerOfWeb); } ((Component)__instance).transform.localScale = Vector3.Lerp(((Component)__instance).transform.localScale, new Vector3(1f, 1f, __instance.zScale), 8f * Time.deltaTime); } } } internal class ExtendedSandWormAIData { public float refreshCDtime = 0.5f; public EnemyAI? closestEnemy = null; public EnemyAI? targetEnemy = null; public int targetingEntity = 0; } [HarmonyPatch] internal class ReversepatchWorm { [HarmonyReversePatch(/*Could not decode attribute arguments.*/)] [HarmonyPatch(typeof(EnemyAI), "Update")] public static void WormReverseUpdate(SandWormAI instance) { } } [HarmonyPatch(typeof(SandWormAI))] internal class SandWormAIPatch { private static List<Type> targetedTypes = new List<Type>(); private static bool debugSandworm = Script.BoundingConfig.debugSandworms.Value; private static bool debugSpam = Script.BoundingConfig.spammyLogs.Value; private static bool triggerFlag = Script.BoundingConfig.debugTriggerFlags.Value; private static Dictionary<SandWormAI, ExtendedSandWormAIData> sandworms = new Dictionary<SandWormAI, ExtendedSandWormAIData>(); [HarmonyPatch("Start")] [HarmonyPrefix] private static void SandWormStartPatch(SandWormAI __instance) { if (!sandworms.ContainsKey(__instance)) { sandworms.Add(__instance, new ExtendedSandWormAIData()); if (targetedTypes.Count == 0) { targetedTypes.Add(typeof(BaboonBirdAI)); targetedTypes.Add(typeof(ForestGiantAI)); targetedTypes.Add(typeof(MouthDogAI)); targetedTypes.Add(typeof(BushWolfEnemy)); targetedTypes.Add(typeof(RadMechAI)); } } } [HarmonyPatch("Update")] [HarmonyPrefix] private static bool SandWormPrefixUpdatePatch(SandWormAI __instance) { ExtendedSandWormAIData extendedSandWormAIData = sandworms[__instance]; if (extendedSandWormAIData.refreshCDtime <= 0f) { if (RoundManagerPatch.RequestUpdate((EnemyAI)(object)__instance)) { RoundManagerPatch.ScheduleGlobalListUpdate((EnemyAI)(object)__instance, EnemyAIPatch.FilterEnemyList(EnemyAIPatch.GetOutsideEnemyList(EnemyAIPatch.GetCompleteList((EnemyAI)(object)__instance), (EnemyAI)(object)__instance), targetedTypes, (EnemyAI)(object)__instance)); } extendedSandWormAIData.closestEnemy = EnemyAIPatch.FindClosestEnemy(NaturalSelectionLib.globalEnemyLists[((object)__instance).GetType()], extendedSandWormAIData.closestEnemy, (EnemyAI)(object)__instance); extendedSandWormAIData.refreshCDtime = 0.2f; } if (extendedSandWormAIData.refreshCDtime > 0f) { extendedSandWormAIData.refreshCDtime -= Time.deltaTime; } switch (extendedSandWormAIData.targetingEntity) { case 0: if (__instance.inEmergingState || __instance.emerged) { return false; } break; case 1: if (!((Object)(object)extendedSandWormAIData.targetEnemy != (Object)null) || ((EnemyAI)__instance).movingTowardsTargetPlayer) { break; } if (((EnemyAI)__instance).updateDestinationInterval >= 0f) { ((EnemyAI)__instance).updateDestinationInterval = ((EnemyAI)__instance).updateDestinationInterval - Time.deltaTime; } else { if (debugSandworm && debugSpam) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " calling DoAIInterval")); } ((EnemyAI)__instance).DoAIInterval(); ((EnemyAI)__instance).updateDestinationInterval = ((EnemyAI)__instance).AIIntervalTime + Random.Range(-0.015f, 0.015f); } return false; } if (debugSandworm && triggerFlag) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Prefix/2/ targetEnemy: " + ((object)extendedSandWormAIData.targetEnemy)?.ToString() + ", target: " + (object)extendedSandWormAIData.targetEnemy)); } return true; } [HarmonyPatch("Update")] [HarmonyPostfix] private static void SandWormPostfixUpdatePatch(SandWormAI __instance) { //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) ExtendedSandWormAIData extendedSandWormAIData = sandworms[__instance]; if (!Script.BoundingConfig.enableLeviathan.Value) { return; } if (debugSandworm && debugSpam) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Postfix targetingEntity: " + extendedSandWormAIData.targetingEntity)); } switch (extendedSandWormAIData.targetingEntity) { case 0: if (!((EnemyAI)__instance).movingTowardsTargetPlayer && !__instance.inEmergingState && !__instance.emerged && ((EnemyAI)__instance).creatureSFX.isPlaying) { ((EnemyAI)__instance).creatureSFX.Stop(); if (debugSandworm) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " stopping Sounds")); } } break; case 1: if (debugSandworm && (Object)(object)extendedSandWormAIData.closestEnemy != (Object)null) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + "closestEnemy is " + EnemyAIPatch.DebugStringHead(extendedSandWormAIData.closestEnemy) + ", isEnemyDead: " + extendedSandWormAIData.closestEnemy.isEnemyDead + " /3/")); } if (((EnemyAI)__instance).movingTowardsTargetPlayer) { break; } if (!((EnemyAI)__instance).creatureSFX.isPlaying && !__instance.inEmergingState && !__instance.emerged) { int num = Random.Range(0, __instance.ambientRumbleSFX.Length); ((EnemyAI)__instance).creatureSFX.clip = __instance.ambientRumbleSFX[num]; ((EnemyAI)__instance).creatureSFX.Play(); if (debugSandworm) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Started playing sounds")); } } if (!((NetworkBehaviour)__instance).IsOwner) { break; } if ((Object)(object)extendedSandWormAIData.targetEnemy == (Object)null) { if (debugSandworm) { Script.Logger.LogError((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " TargetEnemy is null! TargetingEntity set to false /Trigger 1/")); } extendedSandWormAIData.targetingEntity = 0; break; } if (Vector3.Distance(((Component)extendedSandWormAIData.targetEnemy).transform.position, ((Component)__instance).transform.position) > 22f) { __instance.chaseTimer += Time.deltaTime; if (debugSandworm && debugSpam) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " updated chaseTimer: " + __instance.chaseTimer)); } } else { __instance.chaseTimer = 0f; if (debugSandworm) { Script.Logger.LogDebug((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Reset chasetimer")); } } if (__instance.chaseTimer > 6f) { if (debugSandworm) { Script.Logger.LogInfo((object)(EnemyAIPatch.DebugStringHead((EnemyAI?)(object)__instance) + " Chasing for too long. targetEnemy set to null")); } extendedSandWormAIData.targetingEntity = 0; extendedSandWormAIData.targetEnemy = null; } break; } } [HarmonyPatch("DoAIInterval")] [HarmonyPrefix] private static bool SandWormDoAIIntervalPrefix(SandWormAI __instance) { //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_051d: Unknown result
DLLs/fandovec03.NaturalSelectionLib.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Fandovec03")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Personal Library with functions for getting, sorting and filtering enemies")] [assembly: AssemblyFileVersion("0.4.1.0")] [assembly: AssemblyInformationalVersion("0.4.1-alpha3+fc400a91e6007e7808bd45c22ac5a15d9f39c575")] [assembly: AssemblyProduct("NaturalSelectionLib")] [assembly: AssemblyTitle("fandovec03.NaturalSelectionLib")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/Fandovec03/NaturalSelectionLib.git")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.4.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 NaturalSelectionLib { [BepInPlugin("fandovec03.NaturalSelectionLib", "NaturalSelectionLib", "0.4.1-alpha3")] public class NaturalSelectionLib : BaseUnityPlugin { public static bool debugUnspecified = false; public static bool debugSpam = false; public static ManualLogSource LibraryLogger = new ManualLogSource("NaturalSelectionLib"); private static Dictionary<Type, List<EnemyAI>> globalEnemyLists = new Dictionary<Type, List<EnemyAI>>(); public static void UpdateListInsideDictionrary(Type instanceType, List<EnemyAI> list) { List<Type> list2 = new List<Type>(); if (!globalEnemyLists.ContainsKey(instanceType)) { globalEnemyLists.Add(instanceType, new List<EnemyAI>()); if (debugSpam && debugUnspecified) { LibraryLogger.LogInfo((object)("/updateListInsideDictionary/ created new list for " + instanceType)); } } else { globalEnemyLists[instanceType] = list; if (debugSpam && debugUnspecified) { LibraryLogger.LogInfo((object)("/updateListInsideDictionary/ updating list for " + instanceType)); } } if (!list2.Contains(instanceType)) { list2.Add(instanceType); } } public static void LibrarySetup(ManualLogSource importLogger, bool spammyLogs = false, bool Unspecified = false) { LibraryLogger = importLogger; debugSpam = spammyLogs; debugUnspecified = Unspecified; } public static string DebugStringHead(EnemyAI? __instance) { if (!Object.op_Implicit((Object)(object)__instance)) { return "Unknown instance: "; } return ((__instance != null) ? ((Object)__instance).name : null) + ", ID: " + ((__instance != null) ? new int?(((Object)__instance).GetInstanceID()) : null) + ": "; } public static List<EnemyAI> GetCompleteList(EnemyAI instance, bool filterThemselves = true, int includeOrReturnTheDead = 0) { List<EnemyAI> spawnedEnemies = RoundManager.Instance.SpawnedEnemies; for (int i = 0; i < spawnedEnemies.Count; i++) { if ((Object)(object)spawnedEnemies[i] == (Object)(object)instance) { if (debugUnspecified && debugSpam) { LibraryLogger.LogWarning((object)(DebugStringHead(instance) + " Found itself in the list. Removing...")); } spawnedEnemies.RemoveAt(i); } else if (((object)spawnedEnemies[i]).GetType() == ((object)instance).GetType() && filterThemselves) { if (debugUnspecified && debugSpam) { LibraryLogger.LogWarning((object)(DebugStringHead(instance) + " Found its type in the list. Removing...")); } spawnedEnemies.RemoveAt(i); } else { if (!spawnedEnemies[i].isEnemyDead) { continue; } switch (includeOrReturnTheDead) { case 0: if (debugUnspecified && debugSpam) { LibraryLogger.LogInfo((object)(DebugStringHead(instance) + " Found dead enemy in the list. Removing...")); } spawnedEnemies.RemoveAt(i); break; case 1: if (debugUnspecified && debugSpam) { LibraryLogger.LogInfo((object)(DebugStringHead(instance) + " Found dead enemy in the list. Proceeding...")); } break; case 2: if (debugUnspecified && debugSpam) { LibraryLogger.LogInfo((object)(DebugStringHead(instance) + " Found living enemy in the list. Removing..")); } spawnedEnemies.RemoveAt(i); break; } } } return spawnedEnemies; } public static List<EnemyAI> GetOutsideEnemyList(List<EnemyAI> importEnemyList, EnemyAI instance) { List<EnemyAI> list = new List<EnemyAI>(); foreach (EnemyAI importEnemy in importEnemyList) { if (importEnemy.isOutside && (Object)(object)importEnemy != (Object)(object)instance) { list.Add(importEnemy); if (debugUnspecified && debugSpam) { LibraryLogger.LogDebug((object)(DebugStringHead(instance) + " Added " + DebugStringHead(importEnemy) + "...")); } } } return list; } public static List<EnemyAI> GetInsideEnemyList(List<EnemyAI> importEnemyList, EnemyAI instance) { List<EnemyAI> list = new List<EnemyAI>(); foreach (EnemyAI importEnemy in importEnemyList) { if (!importEnemy.isOutside && (Object)(object)importEnemy != (Object)(object)instance) { list.Add(importEnemy); if (debugUnspecified && debugSpam) { LibraryLogger.LogDebug((object)(DebugStringHead(instance) + " Added " + DebugStringHead(importEnemy) + "...")); } } } return list; } public static EnemyAI? FindClosestEnemy(List<EnemyAI> importEnemyList, EnemyAI? importClosestEnemy, EnemyAI __instance, bool includeTheDead = false) { //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) //IL_0475: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_04d1: Unknown result type (might be due to invalid IL or missing references) //IL_04e1: Unknown result type (might be due to invalid IL or missing references) //IL_04ec: Unknown result type (might be due to invalid IL or missing references) //IL_0575: Unknown result type (might be due to invalid IL or missing references) //IL_0580: Unknown result type (might be due to invalid IL or missing references) EnemyAI val = importClosestEnemy; foreach (EnemyAI importEnemy in importEnemyList) { if (debugUnspecified) { LibraryLogger.LogInfo((object)(DebugStringHead(__instance) + "/FindClosestEnemy/ item " + DebugStringHead(importEnemy) + " inside importEnemyList. IsEnemyDead: " + importEnemy.isEnemyDead)); } } if (debugUnspecified && (Object)(object)importClosestEnemy != (Object)null) { LibraryLogger.LogInfo((object)(DebugStringHead(__instance) + "/FindClosestEnemy/ " + DebugStringHead(importClosestEnemy) + " inside importClosestEnemy. IsEnemyDead: " + importClosestEnemy.isEnemyDead)); } if (debugUnspecified) { LibraryLogger.LogInfo((object)(DebugStringHead(__instance) + "/FindClosestEnemy/ " + DebugStringHead(__instance) + " inside instance.")); } if (importEnemyList.Count < 1) { if (debugUnspecified) { LibraryLogger.LogWarning((object)(DebugStringHead(__instance) + "importEnemyList is empty!")); } if ((Object)(object)importClosestEnemy != (Object)null && importClosestEnemy.isEnemyDead) { if (!includeTheDead) { if (debugUnspecified && debugSpam) { LibraryLogger.LogError((object)(DebugStringHead(__instance) + DebugStringHead(importClosestEnemy) + " is dead and importEnemyList is empty! Setting importClosestEnemy to null...")); } } else if (debugUnspecified && debugSpam) { LibraryLogger.LogInfo((object)(DebugStringHead(__instance) + DebugStringHead(importClosestEnemy) + " is dead and importEnemyList is empty! The dead enemy will be included. ")); } } return null; } for (int i = 0; i < importEnemyList.Count; i++) { if ((Object)(object)val == (Object)null) { if (debugUnspecified && debugSpam) { LibraryLogger.LogInfo((object)(DebugStringHead(__instance) + "No enemy assigned. Assigning new closestEnemy....")); } for (int j = i; j < importEnemyList.Count; j++) { if (importEnemyList[j].isEnemyDead && !includeTheDead) { if (debugUnspecified && debugSpam) { LibraryLogger.LogWarning((object)(DebugStringHead(__instance) + "Found dead enemy. Skipping....")); } continue; } if (debugUnspecified && debugSpam) { LibraryLogger.LogInfo((object)(DebugStringHead(__instance) + "New closestEnemy found!")); } val = importEnemyList[j]; break; } continue; } if (val.isEnemyDead) { if (!includeTheDead) { if (debugUnspecified && debugSpam) { LibraryLogger.LogError((object)(DebugStringHead(__instance) + ", " + DebugStringHead(__instance) + " is dead! Assigning new tempClosestEnemy from importEnemyList...")); } val = importEnemyList[i]; continue; } if (debugUnspecified && debugSpam) { LibraryLogger.LogInfo((object)(DebugStringHead(__instance) + DebugStringHead(importClosestEnemy) + " is dead! The dead enemy will be included. ")); } } if ((Object)(object)val == (Object)(object)importEnemyList[i]) { if (debugUnspecified && debugSpam) { LibraryLogger.LogWarning((object)(DebugStringHead(__instance) + ((object)importEnemyList[i])?.ToString() + ", ID: " + ((Object)importEnemyList[i]).GetInstanceID() + " is already assigned as closestEnemy")); } } else if ((Object)(object)importEnemyList[i] == (Object)null) { if (debugUnspecified) { LibraryLogger.LogError((object)(DebugStringHead(__instance) + "Enemy not found! Skipping...")); } } else if (Vector3.Distance(((Component)__instance).transform.position, ((Component)importEnemyList[i]).transform.position) < Vector3.Distance(((Component)__instance).transform.position, ((Component)val).transform.position)) { val = importEnemyList[i]; if (debugUnspecified && debugSpam) { LibraryLogger.LogDebug((object)(Vector3.Distance(((Component)__instance).transform.position, ((Component)importEnemyList[i]).transform.position) < Vector3.Distance(((Component)__instance).transform.position, ((Component)val).transform.position))); } if (debugUnspecified) { LibraryLogger.LogInfo((object)(DebugStringHead(__instance) + "Assigned " + ((object)importEnemyList[i])?.ToString() + ", ID: " + ((Object)importEnemyList[i]).GetInstanceID() + " as new closestEnemy. Distance: " + Vector3.Distance(((Component)__instance).transform.position, ((Component)val).transform.position))); } } } if (debugUnspecified && debugSpam) { LibraryLogger.LogWarning((object)(DebugStringHead(__instance) + "findClosestEnemy returning " + DebugStringHead(val))); } return val; } public static List<EnemyAI> FilterEnemyList(List<EnemyAI> importEnemyList, List<Type>? targetTypes, EnemyAI instance, bool inverseToggle = false, bool filterOutImmortal = true) { List<EnemyAI> list = new List<EnemyAI>(); for (int i = 0; i < importEnemyList.Count; i++) { if ((Object)(object)importEnemyList[i] == (Object)(object)instance) { if (debugUnspecified) { LibraryLogger.LogWarning((object)(DebugStringHead(instance) + "Found itself in importEnemyList! Skipping...")); } continue; } if (targetTypes != null && ((!inverseToggle && targetTypes.Contains(((object)importEnemyList[i]).GetType())) || (inverseToggle && !targetTypes.Contains(((object)importEnemyList[i]).GetType())))) { if (debugUnspecified) { LibraryLogger.LogDebug((object)(DebugStringHead(instance) + "Enemy of type " + ((object)importEnemyList[i]).GetType()?.ToString() + " passed the filter. inverseToggle: " + inverseToggle)); } list.Add(importEnemyList[i]); } else if (targetTypes != null && debugUnspecified && debugSpam && debugUnspecified) { LibraryLogger.LogInfo((object)(DebugStringHead(instance) + "Caught and filtered out Enemy of type " + ((object)importEnemyList[i]).GetType())); } if (filterOutImmortal && !importEnemyList[i].enemyType.canDie) { if (debugUnspecified) { LibraryLogger.LogInfo((object)(DebugStringHead(instance) + "Caught and filtered out immortal Enemy of type " + ((object)importEnemyList[i]).GetType())); } } else if (targetTypes == null) { list.Add(importEnemyList[i]); if (debugUnspecified) { LibraryLogger.LogInfo((object)(DebugStringHead(instance) + "TargetTypes is empty. Added enemy of type " + ((object)importEnemyList[i]).GetType()?.ToString() + " to filteredList by default")); } } } return list; } public static Dictionary<EnemyAI, float> GetEnemiesInLOS(EnemyAI instance, List<EnemyAI> importEnemyList, float width = 45f, int importRange = 0, float proximityAwareness = -1f) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0232: 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) List<EnemyAI> list = new List<EnemyAI>(); Dictionary<EnemyAI, float> tempDictionary = new Dictionary<EnemyAI, float>(); float num = importRange; if (instance.isOutside && !instance.enemyType.canSeeThroughFog && (int)TimeOfDay.Instance.currentLevelWeather == 3) { num = Mathf.Clamp(importRange, 0, 30); } foreach (EnemyAI importEnemy in importEnemyList) { if (!((Object)(object)importEnemy != (Object)null)) { continue; } if (debugUnspecified && debugSpam) { if (importEnemy.isEnemyDead) { LibraryLogger.LogInfo((object)(DebugStringHead(instance) + "/GetEnemiesInLOS/: " + ((object)importEnemy)?.ToString() + " is dead")); } LibraryLogger.LogInfo((object)(DebugStringHead(instance) + "/GetEnemiesInLOS/: Added " + ((object)importEnemy)?.ToString() + " to tempList")); } list.Add(importEnemy); } if (list != null && list.Count > 0) { for (int i = 0; i < list.Count; i++) { if ((Object)(object)list[i] == (Object)null) { if (debugUnspecified) { LibraryLogger.LogWarning((object)(DebugStringHead(instance) + "/GetEnemiesInLOS/: Enemy not found! Removing from tempList")); } list.RemoveAt(i); continue; } Vector3 position = ((Component)list[i]).transform.position; if (!(Vector3.Distance(position, instance.eye.position) < num) || Physics.Linecast(instance.eye.position, position, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1) || !instance.CheckLineOfSightForPosition(position, width, (int)num, proximityAwareness, instance.eye)) { continue; } if (!tempDictionary.ContainsKey(list[i])) { tempDictionary.Add(list[i], Vector3.Distance(((Component)instance).transform.position, position)); if (debugUnspecified && debugSpam && debugUnspecified) { LibraryLogger.LogDebug((object)(DebugStringHead(instance) + "/GetEnemiesInLOS/: Added " + ((object)list[i])?.ToString() + " to tempDictionary")); } } if (tempDictionary.ContainsKey(list[i]) && debugUnspecified && debugSpam && debugUnspecified) { LibraryLogger.LogWarning((object)(DebugStringHead(instance) + "/GetEnemiesInLOS/:" + ((object)list[i])?.ToString() + " is already in tempDictionary")); } } } if (tempDictionary.Count > 1) { tempDictionary.OrderBy<KeyValuePair<EnemyAI, float>, Dictionary<EnemyAI, float>.ValueCollection>((KeyValuePair<EnemyAI, float> value) => tempDictionary.Values); if (debugUnspecified) { foreach (KeyValuePair<EnemyAI, float> item in tempDictionary) { if (debugUnspecified && debugSpam) { LibraryLogger.LogDebug((object)(DebugStringHead(instance) + "/GetEnemiesInLOS/: Final list: " + tempDictionary[item.Key])); } } } } return tempDictionary; } } public static class MyPluginInfo { public const string PLUGIN_GUID = "fandovec03.NaturalSelectionLib"; public const string PLUGIN_NAME = "NaturalSelectionLib"; public const string PLUGIN_VERSION = "0.4.1-alpha3"; } }