using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using TMPro; using UnityEngine; using UnityEngine.AI; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("REPOJP")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("4.0.0.0")] [assembly: AssemblyInformationalVersion("4.0.0")] [assembly: AssemblyProduct("EliteEnemyVariants")] [assembly: AssemblyTitle("EliteEnemyVariants")] [assembly: AssemblyVersion("4.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 REPOJP.EliteEnemyVariants { internal static class AdapterPatchValidator { internal static void Validate(EliteArchetype archetype) { switch (archetype) { case EliteArchetype.Animal: Fields(typeof(EnemyAnimal), "currentState", "stateTimer", "havocTimer", "playerTarget"); Methods(typeof(EnemyAnimal), "UpdateState"); break; case EliteArchetype.BirthdayBoy: Fields(typeof(EnemyBirthdayBoy), "currentState", "stateTimer", "secondStateTimer", "photonView", "balloons"); Methods(typeof(EnemyBirthdayBoy), "CheckForPoppedBalloons", "UpdatePlayerTarget", "UpdateState"); break; case EliteArchetype.CleanupCrew: Fields(typeof(EnemyBombThrower), "currentState", "stateTimer", "headCooldown", "headAttackCooldown", "meleeCooldown", "playerTarget"); Methods(typeof(EnemyBombThrower), "UpdateState"); break; case EliteArchetype.Bowtie: Fields(typeof(EnemyBowtie), "currentState", "stateTimer", "attacks"); Methods(typeof(EnemyBowtie), "UpdateState"); break; case EliteArchetype.Peeper: Fields(typeof(EnemyCeilingEye), "currentState", "eyeDamageWaitTimer", "eyeDamageTimer", "targetPlayer", "photonView"); Methods(typeof(EnemyCeilingEye), "UpdateState", "TargetPlayerRPC"); break; case EliteArchetype.ApexPredator: Fields(typeof(EnemyDuck), "currentState", "stateTimer", "chaseTimer", "playerTarget"); Methods(typeof(EnemyDuck), "UpdateState"); break; case EliteArchetype.Elsa: Fields(typeof(EnemyElsa), "currentState", "stateTimer", "angryTimer", "chaseTimer", "playerTarget", "photonView"); Methods(typeof(EnemyElsa), "UpdateState", "UpdatePlayerTargetRPC"); break; case EliteArchetype.Mentalist: Fields(typeof(EnemyFloater), "currentState", "stateTimer", "attackCount"); Methods(typeof(EnemyFloater), "UpdateState"); break; case EliteArchetype.Headman: Fields(typeof(Enemy), "CurrentState", "DisableChaseTimer"); Fields(typeof(EnemyStateChase), "StateTimer"); break; case EliteArchetype.Headgrab: Fields(typeof(EnemyHeadGrabber), "currentState", "stateTimer", "attackCooldown", "headTargetCooldown", "attacksInRow", "headTargetActive"); break; case EliteArchetype.HeartHugger: Fields(typeof(EnemyHeartHugger), "currentState", "stateTimer", "attacksInARow"); Methods(typeof(EnemyHeartHugger), "StateSet", "LeaveStart"); break; case EliteArchetype.Hidden: Fields(typeof(EnemyHidden), "currentState", "stateTimer", "maxMoveTimer", "agentDestination"); break; case EliteArchetype.Oogly: Fields(typeof(EnemyOogly), "currentState", "stateTimer", "attackCooldownTimer", "targetPlayer", "roamDestination", "currentRoamTarget", "headWorldTargetRotation"); Methods(typeof(EnemyOogly), "StateSet", "InitializeFlightSystem", "SetHeadTargetRotation"); break; case EliteArchetype.Robe: Fields(typeof(EnemyRobe), "currentState", "idleBreakTimer", "chaseTime", "targetPlayer", "isOnScreen"); Methods(typeof(EnemyRobe), "UpdateState", "MoveTowardPlayer"); break; case EliteArchetype.Reaper: Fields(typeof(EnemyRunner), "currentState", "stateTimer", "targetPlayer", "stateImpulse", "targetPosition", "agentSpeedCurrent"); Methods(typeof(EnemyRunner), "UpdateState", "StateAttackPlayer", "OnVision", "RotationLogic"); break; case EliteArchetype.Loom: Fields(typeof(EnemyShadow), "currentState", "stateTimer", "playerTarget"); Methods(typeof(EnemyShadow), "UpdatePlayerTarget", "StateChooseTarget"); break; case EliteArchetype.Spewer: Fields(typeof(EnemySlowMouth), "currentState", "stateTimer", "idlePukeCooldown", "possessCooldown", "attachedTimer"); Methods(typeof(EnemySlowMouth), "OnVision", "UpdatePlayerTarget"); break; case EliteArchetype.Trudge: Fields(typeof(EnemySlowWalker), "currentState", "stateTimer", "targetPlayer"); Methods(typeof(EnemySlowWalker), "UpdateState"); break; case EliteArchetype.Tick: Fields(typeof(EnemyTick), "currentState", "stateTimer", "suckTimer"); break; case EliteArchetype.Bella: Fields(typeof(EnemyTricycle), "currentState", "stateTimer", "attackCooldown"); Methods(typeof(EnemyTricycle), "SetState"); break; case EliteArchetype.Chef: Fields(typeof(EnemyTumbler), "currentState", "stateTimer", "roamWaitTimer", "targetPlayer"); Methods(typeof(EnemyTumbler), "UpdateState"); break; case EliteArchetype.Upscream: Fields(typeof(EnemyUpscream), "currentState", "stateTimer", "roamWaitTimer", "attacks", "targetPlayer"); Methods(typeof(EnemyUpscream), "UpdateState"); break; case EliteArchetype.Rugrat: Fields(typeof(EnemyValuableThrower), "currentState", "stateTimer", "attacks", "playerTarget", "valuableTarget"); Methods(typeof(EnemyValuableThrower), "UpdateState", "StateGetValuable", "StateGoToTarget"); Methods(typeof(EnemyJump), "StuckTrigger"); Methods(typeof(SemiFunc), "EnemyCartJump"); break; case EliteArchetype.Clown: Fields(typeof(EnemyBeamer), "aimHorizontalTarget", "aimHorizontalResult", "laserRange", "aimVerticalTarget"); Methods(typeof(EnemyBeamer), "RotationLogic", "VerticalAimLogic"); break; case EliteArchetype.ShadowChild: Fields(typeof(EnemyThinMan), "enemy", "playerTarget", "teleportPosition"); Methods(typeof(EnemyThinMan), "UpdateState", "SetTarget"); break; case EliteArchetype.Huntsman: Fields(typeof(EnemyHunter), "investigatePoint", "investigateAimHorizontal", "investigateAimVertical"); Methods(typeof(EnemyHunter), "AimLogic", "ShootRPC"); Methods(typeof(EnemyDirector), "SetInvestigate"); break; case EliteArchetype.Gambit: Fields(typeof(EnemySpinny), "reachedPoint"); Methods(typeof(EnemySpinny), "UpdateState", "JumpIfStuck", "RouletteGoingOn"); Methods(typeof(EnemyStateStunned), "Set"); break; case EliteArchetype.Banger: Methods(typeof(EnemyBang), "FuseLogic", "UpdateState", "ExplodeRPC"); break; case EliteArchetype.Gnome: Fields(typeof(EnemyGnome), "attackAngle"); Fields(typeof(EnemyGnomeDirector), "stateImpulse", "playerTarget", "valuableTarget"); Methods(typeof(EnemyGnome), "UpdateState", "StateNoticeDelay", "AttackPositionLogic", "StateAttackDone"); Methods(typeof(EnemyGnomeDirector), "UpdateState", "CanAttack", "StateAttackSet"); break; } Type type = archetype switch { EliteArchetype.Animal => typeof(EnemyAnimal), EliteArchetype.BirthdayBoy => typeof(EnemyBirthdayBoy), EliteArchetype.CleanupCrew => typeof(EnemyBombThrower), EliteArchetype.Bowtie => typeof(EnemyBowtie), EliteArchetype.Peeper => typeof(EnemyCeilingEye), EliteArchetype.ApexPredator => typeof(EnemyDuck), EliteArchetype.Elsa => typeof(EnemyElsa), EliteArchetype.Mentalist => typeof(EnemyFloater), EliteArchetype.Headman => typeof(Enemy), EliteArchetype.Headgrab => typeof(EnemyHeadGrabber), EliteArchetype.HeartHugger => typeof(EnemyHeartHugger), EliteArchetype.Hidden => typeof(EnemyHidden), EliteArchetype.Oogly => typeof(EnemyOogly), EliteArchetype.Robe => typeof(EnemyRobe), EliteArchetype.Reaper => typeof(EnemyRunner), EliteArchetype.Loom => typeof(EnemyShadow), EliteArchetype.Spewer => typeof(EnemySlowMouth), EliteArchetype.Trudge => typeof(EnemySlowWalker), EliteArchetype.Tick => typeof(EnemyTick), EliteArchetype.Bella => typeof(EnemyTricycle), EliteArchetype.Chef => typeof(EnemyTumbler), EliteArchetype.Upscream => typeof(EnemyUpscream), EliteArchetype.Rugrat => typeof(EnemyValuableThrower), _ => null, }; if (type != null) { Methods(type, "Update"); } } private static void Fields(Type type, params string[] names) { foreach (string text in names) { if (AccessTools.Field(type, text) == null) { throw new MissingFieldException(type.FullName, text); } } } private static void Methods(Type type, params string[] names) { foreach (string text in names) { if (AccessTools.Method(type, text, (Type[])null, (Type[])null) == null) { throw new MissingMethodException(type.FullName, text); } } } } [HarmonyPatch] internal static class BangerElitePatches { private static readonly Action UpdateState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyBang), "UpdateState", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { state.AdapterState = new BangerRuntimeState(); } internal static void Tick(EliteState state) { } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyBang), "FuseLogic")] private static bool FuseLogicPrefix(EnemyBang __instance) { //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) if (!EliteRegistry.TryGet((Component?)(object)__instance, out EliteState state)) { return true; } if (!SemiFunc.IsMasterClientOrSingleplayer()) { return true; } if (!GameFieldAccess.BangFuseActive(__instance)) { GetRuntime(state).PreviousFuseActive = false; return false; } EliteEnemyConfig settings = EliteEnemyVariantsPlugin.Instance.Settings; BangerRuntimeState runtime = GetRuntime(state); if (!runtime.PreviousFuseActive) { runtime.PreviousFuseActive = true; runtime.FuseStartedAt = Time.time; runtime.LastSyncAt = float.NegativeInfinity; } if (!EnemyBangDirector.instance.debugNoFuseProgress) { float num = Mathf.Max(0.5f, settings.BangerFuseSeconds.Value); if (HasNearVisibleTarget(state, settings.BangerNearTargetDistance.Value)) { num = Mathf.Min(num, Mathf.Max(0.5f, settings.BangerNearTargetFuseSeconds.Value)); } GameFieldAccess.SetBangFuseLerp(__instance, GameFieldAccess.BangFuseLerp(__instance) + Time.deltaTime / num); } GameFieldAccess.SetBangFuseLerp(__instance, Mathf.Clamp01(GameFieldAccess.BangFuseLerp(__instance))); if (GameManager.Multiplayer() && Time.time >= runtime.LastSyncAt + settings.BangerFuseSyncIntervalSeconds.Value) { runtime.LastSyncAt = Time.time; GameFieldAccess.BangPhotonView(__instance).RPC("FuseRPC", (RpcTarget)1, new object[2] { true, GameFieldAccess.BangFuseLerp(__instance) }); } if (GameFieldAccess.BangFuseLerp(__instance) < 1f) { return false; } if (GameManager.Multiplayer()) { GameFieldAccess.BangPhotonView(__instance).RPC("ExplodeRPC", (RpcTarget)0, Array.Empty()); } else { AccessTools.Method(typeof(EnemyBang), "ExplodeRPC", (Type[])null, (Type[])null).Invoke(__instance, new object[1] { (object)default(PhotonMessageInfo) }); } UpdateState(__instance, (State)11); GameFieldAccess.Parent(GameFieldAccess.BangEnemy(__instance)).Despawn(); runtime.PreviousFuseActive = false; return false; } private static bool HasNearVisibleTarget(EliteState state, float maxDistance) { //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) PlayerAvatar val = GameFieldAccess.TargetPlayer(state.Enemy); if ((Object)(object)val == (Object)null || GameFieldAccess.PlayerDisabled(val)) { float num = float.MaxValue; foreach (PlayerAvatar item in SemiFunc.PlayerGetList()) { if (!((Object)(object)item == (Object)null) && !GameFieldAccess.PlayerDisabled(item)) { float num2 = Vector3.Distance(state.Enemy.CenterTransform.position, ((Component)item).transform.position); if (num2 < num) { num = num2; val = item; } } } } if ((Object)(object)val == (Object)null) { return false; } PlayerVisionTarget playerVisionTarget = val.PlayerVisionTarget; Vector3? obj; if (playerVisionTarget == null) { obj = null; } else { Transform visionTransform = playerVisionTarget.VisionTransform; obj = ((visionTransform != null) ? new Vector3?(visionTransform.position) : ((Vector3?)null)); } Vector3 val2 = (Vector3)(((??)obj) ?? ((Component)val).transform.position) - state.Enemy.CenterTransform.position; if (((Vector3)(ref val2)).magnitude > maxDistance) { return false; } return !Physics.Raycast(state.Enemy.CenterTransform.position, ((Vector3)(ref val2)).normalized, ((Vector3)(ref val2)).magnitude, LayerMask.op_Implicit(GameFieldAccess.VisionMask(state.Enemy)), (QueryTriggerInteraction)1); } private static BangerRuntimeState GetRuntime(EliteState state) { BangerRuntimeState bangerRuntimeState = state.AdapterState as BangerRuntimeState; if (bangerRuntimeState == null) { bangerRuntimeState = (BangerRuntimeState)(state.AdapterState = new BangerRuntimeState()); } return bangerRuntimeState; } } [HarmonyPatch] internal static class ClownElitePatches { private static readonly FieldRef AimHorizontalTarget = AccessTools.FieldRefAccess("aimHorizontalTarget"); private static readonly FieldRef AimHorizontalResult = AccessTools.FieldRefAccess("aimHorizontalResult"); private static readonly FieldRef LaserRange = AccessTools.FieldRefAccess("laserRange"); private static readonly FieldRef AimVerticalTarget = AccessTools.FieldRefAccess("aimVerticalTarget"); internal static void OnSpawn(EliteState state) { state.AdapterState = new ClownRuntimeState(); } internal static void Tick(EliteState state) { //IL_0017: 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_001e: 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_0023: Invalid comparison between Unknown and I4 //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Invalid comparison between Unknown and I4 //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Invalid comparison between Unknown and I4 //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Invalid comparison between Unknown and I4 //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Invalid comparison between Unknown and I4 //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) EnemyBeamer component = ((Component)state.Enemy).GetComponent(); if ((Object)(object)component == (Object)null) { return; } State currentState = component.currentState; bool flag = currentState - 4 <= 2; ClownRuntimeState runtime = GetRuntime(state); if (!flag) { runtime.AttackInitialized = false; runtime.TargetSwitched = false; runtime.SpinChecked = false; runtime.Spinning = false; return; } EliteEnemyConfig settings = EliteEnemyVariantsPlugin.Instance.Settings; LaserRange.Invoke(component) = settings.ClownBeamRange.Value; PlayerAvatar val = GameFieldAccess.BeamerTarget(component); if ((Object)(object)val != (Object)null) { runtime.LastTargetPosition = (((Object)(object)val.PlayerVisionTarget != (Object)null && (Object)(object)val.PlayerVisionTarget.VisionTransform != (Object)null) ? val.PlayerVisionTarget.VisionTransform.position : ((Component)val).transform.position); } if ((int)component.currentState == 5 && !runtime.AttackInitialized) { runtime.AttackInitialized = true; float value = settings.ClownBeamDurationMin.Value; float value2 = settings.ClownBeamDurationMax.Value; component.stateTimer = Mathf.Lerp(value, value2, StableUnit(state.Key, 17)); } if (settings.ClownWalkWhileAttacking.Value && (Object)(object)val != (Object)null) { EnemyNavMeshAgent val2 = GameFieldAccess.NavMeshAgent(state.Enemy); val2.Stop(0f); val2.SetDestination(((Component)val).transform.position); val2.OverrideAgent(GameFieldAccess.NavDefaultSpeed(val2), GameFieldAccess.NavDefaultAcceleration(val2), 0.1f); } if (settings.ClownTargetSwitch.Value && (int)component.currentState == 5 && !runtime.TargetSwitched && TryFindAlternateTarget(component, LaserRange.Invoke(component), out PlayerAvatar result)) { runtime.TargetSwitched = true; GameFieldAccess.SetBeamerTarget(component, result); state.Enemy.SetChaseTarget(result); if (GameManager.Multiplayer()) { GameFieldAccess.BeamerPhotonView(component).RPC("UpdatePlayerTargetRPC", (RpcTarget)1, new object[1] { result.photonView.ViewID }); } } if (!runtime.SpinChecked && (int)component.currentState == 5) { runtime.SpinChecked = true; float value3 = settings.ClownSpinChancePercent.Value; runtime.Spinning = StableUnit(state.Key, 41) * 100f < value3; runtime.SpinRemaining = (runtime.Spinning ? 180f : 0f); runtime.SpinYaw = ((Component)component).transform.eulerAngles.y; } if ((int)component.currentState == 5 && (Object)(object)GameFieldAccess.BeamerTarget(component) == (Object)null && runtime.LastTargetPosition != Vector3.zero && !runtime.Spinning) { runtime.Spinning = true; runtime.SpinRemaining = 180f; runtime.SpinYaw = ((Component)component).transform.eulerAngles.y; } } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyBeamer), "RotationLogic")] private static void RotationLogicPrefix(EnemyBeamer __instance) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: 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_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) if (!EliteRegistry.TryGet((Component?)(object)__instance, out EliteState state)) { return; } State currentState = __instance.currentState; if (currentState - 4 > 2) { return; } ClownRuntimeState runtime = GetRuntime(state); PlayerAvatar val = GameFieldAccess.BeamerTarget(__instance); ? val2; if (!((Object)(object)val != (Object)null)) { val2 = runtime.LastTargetPosition; } else { PlayerVisionTarget playerVisionTarget = val.PlayerVisionTarget; Vector3? obj; if (playerVisionTarget == null) { obj = null; } else { Transform visionTransform = playerVisionTarget.VisionTransform; obj = ((visionTransform != null) ? new Vector3?(visionTransform.position) : ((Vector3?)null)); } val2 = ((??)obj) ?? ((Component)val).transform.position; } Vector3 val3 = (Vector3)val2 - __instance.bottomTransform.position; if (((Vector3)(ref val3)).sqrMagnitude > 0.001f && !runtime.Spinning) { Quaternion val4 = Quaternion.LookRotation(val3); AimHorizontalTarget.Invoke(__instance) = Quaternion.Euler(0f, ((Quaternion)(ref val4)).eulerAngles.y, 0f); AimHorizontalResult.Invoke(__instance) = 0f; } __instance.horizontalRotationSpring.speed = EliteEnemyVariantsPlugin.Instance.Settings.ClownTrackSpeed.Value; } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyBeamer), "RotationLogic")] private static void RotationLogicPostfix(EnemyBeamer __instance) { //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) if (!EliteRegistry.TryGet((Component?)(object)__instance, out EliteState state)) { return; } ClownRuntimeState runtime = GetRuntime(state); if (!runtime.Spinning || runtime.SpinRemaining <= 0f) { PlayerAvatar val = GameFieldAccess.BeamerTarget(__instance); if ((Object)(object)val != (Object)null) { PlayerVisionTarget playerVisionTarget = val.PlayerVisionTarget; Vector3? obj; if (playerVisionTarget == null) { obj = null; } else { Transform visionTransform = playerVisionTarget.VisionTransform; obj = ((visionTransform != null) ? new Vector3?(visionTransform.position) : ((Vector3?)null)); } Vector3 val2 = (Vector3)(((??)obj) ?? ((Component)val).transform.position) - ((Component)__instance).transform.position; if (((Vector3)(ref val2)).sqrMagnitude > 0.001f) { Quaternion val3 = Quaternion.LookRotation(val2); Quaternion val4 = Quaternion.Euler(0f, ((Quaternion)(ref val3)).eulerAngles.y, 0f); ((Component)__instance).transform.rotation = Quaternion.RotateTowards(((Component)__instance).transform.rotation, val4, EliteEnemyVariantsPlugin.Instance.Settings.ClownTrackSpeed.Value * Time.deltaTime); } } } else { float num = Mathf.Min(runtime.SpinRemaining, EliteEnemyVariantsPlugin.Instance.Settings.ClownSpinSpeedDegPerSec.Value * Time.deltaTime); runtime.SpinYaw = Mathf.Repeat(runtime.SpinYaw + num, 360f); runtime.SpinRemaining -= num; ((Component)__instance).transform.rotation = Quaternion.Euler(0f, runtime.SpinYaw, 0f); if (runtime.SpinRemaining <= 0f) { runtime.Spinning = false; } } } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyBeamer), "VerticalAimLogic")] private static void VerticalAimLogicPostfix(EnemyBeamer __instance) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_008a: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) PlayerAvatar val = GameFieldAccess.BeamerTarget(__instance); EliteState state; bool flag = !EliteRegistry.TryGet((Component?)(object)__instance, out state) || (Object)(object)val == (Object)null; if (!flag) { State currentState = __instance.currentState; bool flag2 = currentState - 4 <= 2; flag = !flag2; } if (!flag) { PlayerVisionTarget playerVisionTarget = val.PlayerVisionTarget; Vector3? obj; if (playerVisionTarget == null) { obj = null; } else { Transform visionTransform = playerVisionTarget.VisionTransform; obj = ((visionTransform != null) ? new Vector3?(visionTransform.position) : ((Vector3?)null)); } Vector3 val2 = (Vector3)(((??)obj) ?? ((Component)val).transform.position) - __instance.laserRayTransform.position; if (!(((Vector3)(ref val2)).sqrMagnitude <= 0.001f)) { Quaternion val3 = Quaternion.LookRotation(val2); Quaternion val4 = Quaternion.Inverse(((Object)(object)__instance.aimVerticalTransform.parent != (Object)null) ? __instance.aimVerticalTransform.parent.rotation : Quaternion.identity) * val3; val4 = Quaternion.Euler(((Quaternion)(ref val4)).eulerAngles.x, 0f, 0f); float value = EliteEnemyVariantsPlugin.Instance.Settings.ClownTrackSpeed.Value; AimVerticalTarget.Invoke(__instance) = Quaternion.RotateTowards(AimVerticalTarget.Invoke(__instance), val4, value * Time.deltaTime); __instance.aimVerticalTransform.localRotation = AimVerticalTarget.Invoke(__instance); __instance.laserRayTransform.localRotation = AimVerticalTarget.Invoke(__instance); } } } private static ClownRuntimeState GetRuntime(EliteState state) { ClownRuntimeState clownRuntimeState = state.AdapterState as ClownRuntimeState; if (clownRuntimeState == null) { clownRuntimeState = (ClownRuntimeState)(state.AdapterState = new ClownRuntimeState()); } return clownRuntimeState; } private static bool TryFindAlternateTarget(EnemyBeamer clown, float range, out PlayerAvatar result) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) result = null; List list = new List(); foreach (PlayerAvatar item in SemiFunc.PlayerGetList()) { if (!((Object)(object)item == (Object)null) && !GameFieldAccess.PlayerDisabled(item) && !((Object)(object)item == (Object)(object)GameFieldAccess.BeamerTarget(clown))) { PlayerVisionTarget playerVisionTarget = item.PlayerVisionTarget; Vector3? obj; if (playerVisionTarget == null) { obj = null; } else { Transform visionTransform = playerVisionTarget.VisionTransform; obj = ((visionTransform != null) ? new Vector3?(visionTransform.position) : ((Vector3?)null)); } Vector3 val = (Vector3)(((??)obj) ?? ((Component)item).transform.position) - clown.bottomTransform.position; if (!(((Vector3)(ref val)).magnitude > range) && !Physics.Raycast(clown.bottomTransform.position, ((Vector3)(ref val)).normalized, ((Vector3)(ref val)).magnitude, LayerMask.op_Implicit(GameFieldAccess.VisionMask(GameFieldAccess.BeamerEnemy(clown))), (QueryTriggerInteraction)1)) { list.Add(item); } } } if (list.Count == 0) { return false; } int index = Mathf.Abs(((Object)clown).GetInstanceID()) % list.Count; result = list[index]; return true; } private static float StableUnit(int key, int salt) { int num = key * 1103515245 + salt * 12345; return (float)(uint)((num ^ (num >>> 16)) & 0xFFFFFF) / 16777216f; } } internal static class DedicatedBehaviorSupport { internal static void OnSpawn(EliteState state) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) state.AdapterState = new DedicatedEnemyRuntimeState { SpawnInitialized = true, LastPosition = ((Component)state.Enemy).transform.position }; } internal static DedicatedEnemyRuntimeState Runtime(EliteState state) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = state.AdapterState as DedicatedEnemyRuntimeState; if (dedicatedEnemyRuntimeState == null) { dedicatedEnemyRuntimeState = (DedicatedEnemyRuntimeState)(state.AdapterState = new DedicatedEnemyRuntimeState { SpawnInitialized = true, LastPosition = ((Component)state.Enemy).transform.position }); } return dedicatedEnemyRuntimeState; } internal static bool IsValidTarget(PlayerAvatar? player) { if ((Object)(object)player != (Object)null) { return !GameFieldAccess.PlayerDisabled(player); } return false; } internal static bool TryFindNearestPlayer(Vector3 origin, float maxDistance, out PlayerAvatar result, PlayerAvatar? exclude = null, Enemy? lineOfSightEnemy = null) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) result = null; float num = maxDistance; foreach (PlayerAvatar item in SemiFunc.PlayerGetList()) { if (IsValidTarget(item) && !((Object)(object)item == (Object)(object)exclude)) { PlayerVisionTarget playerVisionTarget = item.PlayerVisionTarget; Vector3? obj; if (playerVisionTarget == null) { obj = null; } else { Transform visionTransform = playerVisionTarget.VisionTransform; obj = ((visionTransform != null) ? new Vector3?(visionTransform.position) : ((Vector3?)null)); } Vector3 val = (Vector3)(((??)obj) ?? ((Component)item).transform.position) - origin; float magnitude = ((Vector3)(ref val)).magnitude; if (!(magnitude > num) && (!((Object)(object)lineOfSightEnemy != (Object)null) || !(magnitude > 0.01f) || !Physics.Raycast(origin, val / magnitude, magnitude, LayerMask.op_Implicit(GameFieldAccess.VisionMask(lineOfSightEnemy)), (QueryTriggerInteraction)1))) { num = magnitude; result = item; } } } return (Object)(object)result != (Object)null; } internal static void TrackState(DedicatedEnemyRuntimeState runtime, int currentState) { runtime.PreviousState = currentState; } internal static void Run(T instance, EliteArchetype archetype, Action action) where T : Component { if (!SemiFunc.IsMasterClientOrSingleplayer() || !EliteRegistry.TryGet((Component?)(object)instance, out EliteState state) || state.Archetype != archetype || !state.Spawned || state.AdapterTickFaulted) { return; } try { action(state, instance); } catch (Exception arg) { state.AdapterTickFaulted = true; EliteEnemyVariantsPlugin.ModLogger.LogError((object)("Disabled dedicated behavior for " + EnemyDisplayNameResolver.Get(archetype) + " " + $"until its next spawn because its AI postfix failed: {arg}")); } } internal static float WindupRate(EliteState state) { return EliteEnemyVariantsPlugin.Instance.Settings.BehaviorWindupRate.Value; } internal static float CooldownRate(EliteState state) { return EliteEnemyVariantsPlugin.Instance.Settings.BehaviorCooldownRate.Value; } internal static float Retention(EliteState state) { return EliteEnemyVariantsPlugin.Instance.Settings.BehaviorChaseRetention.Value; } internal static void Countdown(T instance, FieldRef field, float rate) { float num = field.Invoke(instance); if (rate > 1f && num > 0f) { field.Invoke(instance) = Mathf.Max(0f, num - Time.deltaTime * (rate - 1f)); } } internal static void Countup(T instance, FieldRef field, float rate) { if (rate > 1f) { field.Invoke(instance) = field.Invoke(instance) + Time.deltaTime * (rate - 1f); } } internal static void RetainCountup(T instance, FieldRef field, float retention) { float num = field.Invoke(instance); if (retention > 0f && num > 0f) { field.Invoke(instance) = Mathf.Max(0f, num - Time.deltaTime * retention); } } internal static void RetainCountdown(T instance, FieldRef field, float retention) { float num = field.Invoke(instance); if (retention > 0f && num > 0f) { field.Invoke(instance) = num + Time.deltaTime * retention; } } } [HarmonyPatch] internal static class AnimalElitePatches { private static readonly Action UpdateState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyAnimal), "UpdateState", (Type[])null, (Type[])null), (object)null, true); private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly FieldRef HavocTimer = AccessTools.FieldRefAccess("havocTimer"); private static readonly FieldRef PlayerTarget = AccessTools.FieldRefAccess("playerTarget"); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemyAnimal animal) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Invalid comparison between Unknown and I4 //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Invalid comparison between Unknown and I4 //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected I4, but got Unknown DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); if ((int)animal.currentState == 4) { DedicatedBehaviorSupport.Countdown(animal, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } else if ((int)animal.currentState == 6) { DedicatedBehaviorSupport.Countdown(animal, HavocTimer, DedicatedBehaviorSupport.CooldownRate(state)); } if (dedicatedEnemyRuntimeState.PreviousState == 6 && (int)animal.currentState == 7 && !dedicatedEnemyRuntimeState.ExtraActionUsed && DedicatedBehaviorSupport.IsValidTarget(PlayerTarget.Invoke(animal))) { dedicatedEnemyRuntimeState.ExtraActionUsed = true; UpdateState(animal, (State)5); } if ((int)animal.currentState == 4 && dedicatedEnemyRuntimeState.PreviousState != 4) { dedicatedEnemyRuntimeState.ExtraActionUsed = false; } DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)animal.currentState); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyAnimal), "Update")] private static void UpdatePostfix(EnemyAnimal __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Animal, (Action)Tick); } } [HarmonyPatch] internal static class BirthdayBoyElitePatches { private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly FieldRef SecondStateTimer = AccessTools.FieldRefAccess("secondStateTimer"); private static readonly FieldRef PhotonViewRef = AccessTools.FieldRefAccess("photonView"); private static readonly Action UpdatePlayerTarget = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyBirthdayBoy), "UpdatePlayerTarget", (Type[])null, (Type[])null), (object)null, true); private static readonly Action UpdateState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyBirthdayBoy), "UpdateState", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemyBirthdayBoy enemy) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 if ((int)enemy.currentState == 8) { DedicatedBehaviorSupport.Countdown(enemy, SecondStateTimer, DedicatedBehaviorSupport.WindupRate(state)); } else if ((int)enemy.currentState == 13) { DedicatedBehaviorSupport.RetainCountdown(enemy, StateTimer, DedicatedBehaviorSupport.Retention(state)); } } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyBirthdayBoy), "Update")] private static void UpdatePostfix(EnemyBirthdayBoy __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.BirthdayBoy, (Action)Tick); } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyBirthdayBoy), "CheckForPoppedBalloons")] private static void CheckForPoppedBalloonsPrefix(EnemyBirthdayBoy __instance, ref PlayerAvatar? __state) { __state = null; if (!SemiFunc.IsMasterClientOrSingleplayer() || !EliteRegistry.TryGet((Component?)(object)__instance, out EliteState _)) { return; } foreach (GameObject value in __instance.balloons.Values) { BirthdayBoyBalloon val = (((Object)(object)value != (Object)null) ? value.GetComponentInChildren() : null); if ((Object)(object)val != (Object)null && val.popped && DedicatedBehaviorSupport.IsValidTarget(val.popper)) { __state = val.popper; break; } } } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyBirthdayBoy), "CheckForPoppedBalloons")] private static void CheckForPoppedBalloonsPostfix(EnemyBirthdayBoy __instance, PlayerAvatar? __state) { if (SemiFunc.IsMasterClientOrSingleplayer() && !((Object)(object)__state == (Object)null) && EliteRegistry.TryGet((Component?)(object)__instance, out EliteState _)) { UpdatePlayerTarget(__instance, __state); if (GameManager.Multiplayer()) { PhotonViewRef.Invoke(__instance).RPC("UpdatePlayerTargetRPC", (RpcTarget)1, new object[1] { __state.photonView.ViewID }); } StateTimer.Invoke(__instance) = 20f; UpdateState(__instance, (State)13); } } } [HarmonyPatch] internal static class CleanupCrewElitePatches { private static readonly FieldRef CurrentState = AccessTools.FieldRefAccess("currentState"); private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly FieldRef HeadCooldown = AccessTools.FieldRefAccess("headCooldown"); private static readonly FieldRef HeadAttackCooldown = AccessTools.FieldRefAccess("headAttackCooldown"); private static readonly FieldRef MeleeCooldown = AccessTools.FieldRefAccess("meleeCooldown"); private static readonly FieldRef PlayerTarget = AccessTools.FieldRefAccess("playerTarget"); private static readonly Action UpdateState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyBombThrower), "UpdateState", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemyBombThrower enemy) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); if ((int)CurrentState.Invoke(enemy) == 4) { DedicatedBehaviorSupport.Countdown(enemy, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } float rate = DedicatedBehaviorSupport.CooldownRate(state); DedicatedBehaviorSupport.Countdown(enemy, HeadCooldown, rate); DedicatedBehaviorSupport.Countdown(enemy, HeadAttackCooldown, rate); DedicatedBehaviorSupport.Countdown(enemy, MeleeCooldown, rate); if (dedicatedEnemyRuntimeState.PreviousState == 8 && (int)CurrentState.Invoke(enemy) == 7 && !dedicatedEnemyRuntimeState.ExtraActionUsed && DedicatedBehaviorSupport.IsValidTarget(PlayerTarget.Invoke(enemy)) && Vector3.Distance(((Component)enemy).transform.position, ((Component)PlayerTarget.Invoke(enemy)).transform.position) <= 4f) { dedicatedEnemyRuntimeState.ExtraActionUsed = true; UpdateState(enemy, (State)9); } if ((int)CurrentState.Invoke(enemy) == 4 && dedicatedEnemyRuntimeState.PreviousState != 4) { dedicatedEnemyRuntimeState.ExtraActionUsed = false; } DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)CurrentState.Invoke(enemy)); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyBombThrower), "Update")] private static void UpdatePostfix(EnemyBombThrower __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.CleanupCrew, (Action)Tick); } } [HarmonyPatch] internal static class BowtieElitePatches { private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly Action UpdateState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyBowtie), "UpdateState", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemyBowtie enemy) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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) //IL_0053: Invalid comparison between Unknown and I4 //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Invalid comparison between Unknown and I4 //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Invalid comparison between Unknown and I4 //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected I4, but got Unknown DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); if ((int)enemy.currentState == 4) { DedicatedBehaviorSupport.Countdown(enemy, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } else if ((int)enemy.currentState == 6) { DedicatedBehaviorSupport.Countdown(enemy, StateTimer, DedicatedBehaviorSupport.CooldownRate(state)); } bool flag = dedicatedEnemyRuntimeState.PreviousState == 6; if (flag) { State currentState = enemy.currentState; bool flag2 = (((int)currentState == 1 || (int)currentState == 7) ? true : false); flag = flag2; } if (flag && !dedicatedEnemyRuntimeState.ExtraActionUsed) { dedicatedEnemyRuntimeState.ExtraActionUsed = true; UpdateState(enemy, (State)5); } if ((int)enemy.currentState == 4 && dedicatedEnemyRuntimeState.PreviousState != 4) { dedicatedEnemyRuntimeState.ExtraActionUsed = false; } DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)enemy.currentState); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyBowtie), "Update")] private static void UpdatePostfix(EnemyBowtie __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Bowtie, (Action)Tick); } } [HarmonyPatch] internal static class PeeperElitePatches { private static readonly FieldRef DamageWaitTimer = AccessTools.FieldRefAccess("eyeDamageWaitTimer"); private static readonly FieldRef DamageTimer = AccessTools.FieldRefAccess("eyeDamageTimer"); private static readonly FieldRef PlayerTarget = AccessTools.FieldRefAccess("targetPlayer"); private static readonly FieldRef PhotonViewRef = AccessTools.FieldRefAccess("photonView"); private static readonly Action UpdateState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyCeilingEye), "UpdateState", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemyCeilingEye enemy) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Invalid comparison between Unknown and I4 //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected I4, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); if ((int)enemy.currentState == 3) { DedicatedBehaviorSupport.Countdown(enemy, DamageWaitTimer, DedicatedBehaviorSupport.WindupRate(state)); DedicatedBehaviorSupport.Countdown(enemy, DamageTimer, DedicatedBehaviorSupport.CooldownRate(state)); } if (dedicatedEnemyRuntimeState.PreviousState == 3 && (int)enemy.currentState == 2 && !dedicatedEnemyRuntimeState.ExtraActionUsed && DedicatedBehaviorSupport.TryFindNearestPlayer(enemy.eyeTransform.position, 20f, out PlayerAvatar result, PlayerTarget.Invoke(enemy), state.Enemy)) { dedicatedEnemyRuntimeState.ExtraActionUsed = true; PlayerTarget.Invoke(enemy) = result; if (GameManager.Multiplayer()) { PhotonViewRef.Invoke(enemy).RPC("TargetPlayerRPC", (RpcTarget)1, new object[1] { result.photonView.ViewID }); } UpdateState(enemy, (State)3); } if ((int)enemy.currentState == 0) { dedicatedEnemyRuntimeState.ExtraActionUsed = false; } DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)enemy.currentState); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyCeilingEye), "Update")] private static void UpdatePostfix(EnemyCeilingEye __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Peeper, (Action)Tick); } } [HarmonyPatch] internal static class ApexPredatorElitePatches { private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly FieldRef ChaseTimer = AccessTools.FieldRefAccess("chaseTimer"); private static readonly FieldRef PlayerTarget = AccessTools.FieldRefAccess("playerTarget"); private static readonly Action UpdateState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyDuck), "UpdateState", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemyDuck enemy) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Invalid comparison between Unknown and I4 //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Invalid comparison between Unknown and I4 //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected I4, but got Unknown DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); State currentState = enemy.currentState; if (((int)currentState == 4 || currentState - 11 <= 1) ? true : false) { DedicatedBehaviorSupport.Countdown(enemy, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } currentState = enemy.currentState; if (currentState - 13 <= 2) { DedicatedBehaviorSupport.RetainCountup(enemy, ChaseTimer, DedicatedBehaviorSupport.Retention(state)); } bool flag = (int)enemy.currentState == 16; if (flag) { int previousState = dedicatedEnemyRuntimeState.PreviousState; bool flag2 = (uint)(previousState - 13) <= 2u; flag = flag2; } if (flag && !dedicatedEnemyRuntimeState.ExtraActionUsed && DedicatedBehaviorSupport.IsValidTarget(PlayerTarget.Invoke(enemy))) { dedicatedEnemyRuntimeState.ExtraActionUsed = true; UpdateState(enemy, (State)11); } if ((int)enemy.currentState == 4 && dedicatedEnemyRuntimeState.PreviousState != 4) { dedicatedEnemyRuntimeState.ExtraActionUsed = false; } DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)enemy.currentState); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyDuck), "Update")] private static void UpdatePostfix(EnemyDuck __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.ApexPredator, (Action)Tick); } } [HarmonyPatch] internal static class ElsaElitePatches { private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly FieldRef AngryTimer = AccessTools.FieldRefAccess("angryTimer"); private static readonly FieldRef ChaseTimer = AccessTools.FieldRefAccess("chaseTimer"); private static readonly FieldRef PlayerTarget = AccessTools.FieldRefAccess("playerTarget"); private static readonly FieldRef PhotonViewRef = AccessTools.FieldRefAccess("photonView"); private static readonly Action UpdateState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyElsa), "UpdateState", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemyElsa enemy) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Invalid comparison between Unknown and I4 //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Invalid comparison between Unknown and I4 //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Invalid comparison between Unknown and I4 //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Invalid comparison between Unknown and I4 //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected I4, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); if ((int)enemy.currentState == 5) { DedicatedBehaviorSupport.Countdown(enemy, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } State currentState = enemy.currentState; if (currentState - 6 <= 2) { DedicatedBehaviorSupport.Countup(enemy, AngryTimer, DedicatedBehaviorSupport.WindupRate(state)); } currentState = enemy.currentState; if ((currentState - 18 <= 1 || (int)currentState == 22) ? true : false) { DedicatedBehaviorSupport.RetainCountup(enemy, ChaseTimer, DedicatedBehaviorSupport.Retention(state)); } if ((int)enemy.currentState == 25 && dedicatedEnemyRuntimeState.PreviousState != 25 && !dedicatedEnemyRuntimeState.ExtraActionUsed && DedicatedBehaviorSupport.TryFindNearestPlayer(((Component)enemy).transform.position, 15f, out PlayerAvatar result, PlayerTarget.Invoke(enemy), state.Enemy)) { dedicatedEnemyRuntimeState.ExtraActionUsed = true; PlayerTarget.Invoke(enemy) = result; GameFieldAccess.SetTargetPlayer(state.Enemy, result); GameFieldAccess.SetTargetPlayerViewId(state.Enemy, result.photonView.ViewID); if (GameManager.Multiplayer()) { PhotonViewRef.Invoke(enemy).RPC("UpdatePlayerTargetRPC", (RpcTarget)1, new object[1] { result.photonView.ViewID }); } ChaseTimer.Invoke(enemy) = 0f; UpdateState(enemy, (State)18); } if ((int)enemy.currentState == 5 && dedicatedEnemyRuntimeState.PreviousState != 5) { dedicatedEnemyRuntimeState.ExtraActionUsed = false; } DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)enemy.currentState); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyElsa), "Update")] private static void UpdatePostfix(EnemyElsa __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Elsa, (Action)Tick); } } [HarmonyPatch] internal static class MentalistElitePatches { private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly Action UpdateState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyFloater), "UpdateState", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemyFloater enemy) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0041: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Invalid comparison between Unknown and I4 //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Invalid comparison between Unknown and I4 //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected I4, but got Unknown DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); State currentState = enemy.currentState; if (((int)currentState == 4 || currentState - 7 <= 1) ? true : false) { DedicatedBehaviorSupport.Countdown(enemy, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } bool flag = dedicatedEnemyRuntimeState.PreviousState == 9; if (flag) { currentState = enemy.currentState; bool flag2 = (((int)currentState == 1 || (int)currentState == 11) ? true : false); flag = flag2; } if (flag && !dedicatedEnemyRuntimeState.ExtraActionUsed) { dedicatedEnemyRuntimeState.ExtraActionUsed = true; UpdateState(enemy, (State)8); } if ((int)enemy.currentState == 4 && dedicatedEnemyRuntimeState.PreviousState != 4) { dedicatedEnemyRuntimeState.ExtraActionUsed = false; } DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)enemy.currentState); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyFloater), "Update")] private static void UpdatePostfix(EnemyFloater __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Mentalist, (Action)Tick); } } [HarmonyPatch] internal static class HeadmanElitePatches { private static readonly FieldRef DisableChaseTimer = AccessTools.FieldRefAccess("DisableChaseTimer"); private static readonly FieldRef ChaseStateTimer = AccessTools.FieldRefAccess("StateTimer"); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, Enemy enemy) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: 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_00c9: Invalid comparison between Unknown and I4 //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Invalid comparison between Unknown and I4 //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Invalid comparison between Unknown and I4 //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected I4, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); if ((int)enemy.CurrentState == 8) { enemy.CurrentState = (EnemyState)3; } else if ((int)enemy.CurrentState == 4 && dedicatedEnemyRuntimeState.PreviousState != 4 && (Object)(object)GameFieldAccess.StateChase(enemy) != (Object)null) { EnemyStateChase val = GameFieldAccess.StateChase(enemy); ChaseStateTimer.Invoke(val) = Mathf.Max(ChaseStateTimer.Invoke(val), 10f); } else if (dedicatedEnemyRuntimeState.PreviousState == 4 && (int)enemy.CurrentState == 5 && !dedicatedEnemyRuntimeState.ExtraActionUsed) { PlayerAvatar val2 = GameFieldAccess.TargetPlayer(enemy); if (DedicatedBehaviorSupport.IsValidTarget(val2) && Vector3.Distance(((Component)enemy).transform.position, ((Component)val2).transform.position) <= 30f) { dedicatedEnemyRuntimeState.ExtraActionUsed = true; enemy.CurrentState = (EnemyState)3; } } EnemyState currentState = enemy.CurrentState; if (((int)currentState == 2 || (int)currentState == 7) ? true : false) { dedicatedEnemyRuntimeState.ExtraActionUsed = false; } DedicatedBehaviorSupport.Countdown(enemy, DisableChaseTimer, DedicatedBehaviorSupport.CooldownRate(state)); DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)enemy.CurrentState); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(Enemy), "Update")] private static void UpdatePostfix(Enemy __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Headman, (Action)Tick); } } [HarmonyPatch] internal static class HeadgrabElitePatches { private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly FieldRef AttackCooldown = AccessTools.FieldRefAccess("attackCooldown"); private static readonly FieldRef HeadTargetCooldown = AccessTools.FieldRefAccess("headTargetCooldown"); private static readonly FieldRef AttacksInRow = AccessTools.FieldRefAccess("attacksInRow"); private static readonly FieldRef HeadTargetActive = AccessTools.FieldRefAccess("headTargetActive"); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemyHeadGrabber enemy) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Invalid comparison between Unknown and I4 //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Invalid comparison between Unknown and I4 //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected I4, but got Unknown DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); if ((int)enemy.currentState == 7) { DedicatedBehaviorSupport.Countdown(enemy, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } float rate = DedicatedBehaviorSupport.CooldownRate(state); DedicatedBehaviorSupport.Countdown(enemy, AttackCooldown, rate); DedicatedBehaviorSupport.Countdown(enemy, HeadTargetCooldown, rate); if ((int)enemy.currentState == 8 && !HeadTargetActive.Invoke(enemy) && AttacksInRow.Invoke(enemy) > 3 && StateTimer.Invoke(enemy) <= Time.deltaTime * 2f && !dedicatedEnemyRuntimeState.ExtraActionUsed) { dedicatedEnemyRuntimeState.ExtraActionUsed = true; AttacksInRow.Invoke(enemy) = 3; } if ((int)enemy.currentState == 7 && dedicatedEnemyRuntimeState.PreviousState != 7) { dedicatedEnemyRuntimeState.ExtraActionUsed = false; } DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)enemy.currentState); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyHeadGrabber), "Update")] private static void UpdatePostfix(EnemyHeadGrabber __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Headgrab, (Action)Tick); } } [HarmonyPatch] internal static class HeartHuggerElitePatches { private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly FieldRef AttacksInRow = AccessTools.FieldRefAccess("attacksInARow"); private static readonly Action StateSet = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyHeartHugger), "StateSet", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemyHeartHugger enemy) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 State currentState = enemy.currentState; if (((int)currentState == 4 || (int)currentState == 6 || (int)currentState == 9) ? true : false) { DedicatedBehaviorSupport.Countup(enemy, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } } [HarmonyPrefix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyHeartHugger), "LeaveStart")] private static bool LeaveStartPrefix(EnemyHeartHugger __instance) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 if (!SemiFunc.IsMasterClientOrSingleplayer() || !EliteRegistry.TryGet((Component?)(object)__instance, out EliteState state)) { return true; } DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); if ((int)__instance.currentState != 10 || dedicatedEnemyRuntimeState.ExtraActionUsed) { return true; } dedicatedEnemyRuntimeState.ExtraActionUsed = true; AttacksInRow.Invoke(__instance) = 0; StateSet(__instance, (State)5); return false; } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyHeartHugger), "Update")] private static void UpdatePostfix(EnemyHeartHugger __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.HeartHugger, (Action)Tick); } } [HarmonyPatch] internal static class HiddenElitePatches { private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly FieldRef MaxMoveTimer = AccessTools.FieldRefAccess("maxMoveTimer"); private static readonly FieldRef AgentDestination = AccessTools.FieldRefAccess("agentDestination"); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemyHidden enemy) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Invalid comparison between Unknown and I4 //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Expected I4, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); State currentState = enemy.currentState; if (((int)currentState == 4 || (int)currentState == 6 || (int)currentState == 9) ? true : false) { DedicatedBehaviorSupport.Countdown(enemy, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } if ((int)enemy.currentState == 7) { DedicatedBehaviorSupport.RetainCountdown(enemy, MaxMoveTimer, DedicatedBehaviorSupport.Retention(state)); float num = Vector3.Distance(dedicatedEnemyRuntimeState.LastPosition, ((Component)enemy).transform.position); dedicatedEnemyRuntimeState.StuckTimer = ((num < 0.05f) ? (dedicatedEnemyRuntimeState.StuckTimer + Time.deltaTime) : 0f); dedicatedEnemyRuntimeState.LastPosition = ((Component)enemy).transform.position; if (dedicatedEnemyRuntimeState.StuckTimer >= 1.5f && !dedicatedEnemyRuntimeState.ExtraActionUsed) { LevelPoint val = SemiFunc.LevelPointGetPlayerDistance(((Component)enemy).transform.position, 20f, 80f, false); NavMeshHit val2 = default(NavMeshHit); if ((Object)(object)val != (Object)null && NavMesh.SamplePosition(((Component)val).transform.position, ref val2, 5f, -1)) { AgentDestination.Invoke(enemy) = ((NavMeshHit)(ref val2)).position; GameFieldAccess.NavMeshAgent(state.Enemy).SetDestination(((NavMeshHit)(ref val2)).position); dedicatedEnemyRuntimeState.ExtraActionUsed = true; } dedicatedEnemyRuntimeState.StuckTimer = 0f; } } else { dedicatedEnemyRuntimeState.StuckTimer = 0f; dedicatedEnemyRuntimeState.LastPosition = ((Component)enemy).transform.position; } if ((int)enemy.currentState == 4 && dedicatedEnemyRuntimeState.PreviousState != 4) { dedicatedEnemyRuntimeState.ExtraActionUsed = false; } DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)enemy.currentState); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyHidden), "Update")] private static void UpdatePostfix(EnemyHidden __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Hidden, (Action)Tick); } } [HarmonyPatch] internal static class OoglyElitePatches { private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly FieldRef AttackCooldown = AccessTools.FieldRefAccess("attackCooldownTimer"); private static readonly FieldRef PlayerTarget = AccessTools.FieldRefAccess("targetPlayer"); private static readonly Action StateSet = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyOogly), "StateSet", (Type[])null, (Type[])null), (object)null, true); private static readonly Action InitializeFlightSystem = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyOogly), "InitializeFlightSystem", (Type[])null, (Type[])null), (object)null, true); private static readonly FieldRef RoamDestination = AccessTools.FieldRefAccess("roamDestination"); private static readonly FieldRef CurrentRoamTarget = AccessTools.FieldRefAccess("currentRoamTarget"); private static readonly FieldRef HeadWorldTargetRotation = AccessTools.FieldRefAccess("headWorldTargetRotation"); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); EnemyOogly component = ((Component)state.Enemy).GetComponent(); if (!((Object)(object)component == (Object)null)) { component.minFlightHeight = 0.75f; component.preferredHeight = 2f; component.maxFlightHeight = 8f; InitializeFlightSystem(component); DedicatedBehaviorSupport.Runtime(state).NextActionAt = Time.time + EliteEnemyVariantsPlugin.Instance.Settings.OoglyLowPatrolIntervalSeconds.Value; } } private static void Tick(EliteState state, EnemyOogly enemy) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Invalid comparison between Unknown and I4 //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected I4, but got Unknown DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); DedicatedBehaviorSupport.Countdown(enemy, AttackCooldown, DedicatedBehaviorSupport.CooldownRate(state)); if ((int)enemy.currentState == 5) { DedicatedBehaviorSupport.Countup(enemy, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } if (dedicatedEnemyRuntimeState.PreviousState == 6 && (int)enemy.currentState == 3 && !dedicatedEnemyRuntimeState.ExtraActionUsed && DedicatedBehaviorSupport.IsValidTarget(PlayerTarget.Invoke(enemy))) { dedicatedEnemyRuntimeState.ExtraActionUsed = true; StateSet(enemy, (State)5); } if ((int)enemy.currentState == 5) { int previousState = dedicatedEnemyRuntimeState.PreviousState; if (previousState != 6 && previousState != 3) { dedicatedEnemyRuntimeState.ExtraActionUsed = false; } } TickLowPatrol(state, enemy, dedicatedEnemyRuntimeState); DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)enemy.currentState); } private static void TickLowPatrol(EliteState state, EnemyOogly enemy, DedicatedEnemyRuntimeState runtime) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_003f: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) Vector3 result; if ((int)enemy.currentState != 4) { runtime.AlternateMode = false; runtime.StuckTimer = 0f; } else if (runtime.AlternateMode) { runtime.StuckTimer += Time.deltaTime; if (Vector3.Distance(enemy.rb.position, CurrentRoamTarget.Invoke(enemy)) <= 1.25f || runtime.StuckTimer >= 8f) { runtime.AlternateMode = false; runtime.StuckTimer = 0f; runtime.NextActionAt = Time.time + EliteEnemyVariantsPlugin.Instance.Settings.OoglyLowPatrolIntervalSeconds.Value; } else { RoamDestination.Invoke(enemy) = CurrentRoamTarget.Invoke(enemy); } } else if (!(Time.time < runtime.NextActionAt) && TryChooseLowPatrolPoint(enemy, out result)) { CurrentRoamTarget.Invoke(enemy) = result; RoamDestination.Invoke(enemy) = result; runtime.AlternateMode = true; runtime.StuckTimer = 0f; } } private static bool TryChooseLowPatrolPoint(EnemyOogly enemy, out Vector3 result) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) result = default(Vector3); PlayerAvatar val = null; float num = 30f; foreach (PlayerAvatar item in SemiFunc.PlayerGetList()) { if (DedicatedBehaviorSupport.IsValidTarget(item)) { float num2 = Vector3.Distance(enemy.rb.position, ((Component)item).transform.position); if (num2 < num) { num = num2; val = item; } } } List list = SemiFunc.LevelPointGetWithinDistance(((Object)(object)val != (Object)null) ? ((Component)val).transform.position : enemy.rb.position, 2f, 16f); if (list == null) { return false; } float value = EliteEnemyVariantsPlugin.Instance.Settings.OoglyLowPatrolHeight.Value; RaycastHit val2 = default(RaycastHit); foreach (LevelPoint item2 in list) { if (!((Object)(object)item2 == (Object)null) && Physics.Raycast(((Component)item2).transform.position + Vector3.up * 3f, Vector3.down, ref val2, 6f, LayerMask.GetMask(new string[1] { "Default" }), (QueryTriggerInteraction)1)) { Vector3 val3 = ((RaycastHit)(ref val2)).point + Vector3.up * value; if (!Physics.CheckSphere(val3, 0.4f, LayerMask.op_Implicit(enemy.environmentMask), (QueryTriggerInteraction)1)) { result = val3; return true; } } } return false; } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyOogly), "Update")] private static void UpdatePostfix(EnemyOogly __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Oogly, (Action)Tick); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyOogly), "SetHeadTargetRotation")] private static void SetHeadTargetRotationPostfix(EnemyOogly __instance) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClientOrSingleplayer() && EliteRegistry.TryGet((Component?)(object)__instance, out EliteState state) && (int)__instance.currentState == 4 && DedicatedBehaviorSupport.Runtime(state).AlternateMode && !((Object)(object)__instance.headTransform == (Object)null)) { Vector3 val = CurrentRoamTarget.Invoke(__instance) - __instance.headTransform.position; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = ((Component)__instance).transform.forward; val.y = 0f; } if (((Vector3)(ref val)).sqrMagnitude > 0.01f) { HeadWorldTargetRotation.Invoke(__instance) = Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up); } } } } [HarmonyPatch] internal static class RobeElitePatches { private static readonly FieldRef ChaseTime = AccessTools.FieldRefAccess("chaseTime"); private static readonly FieldRef IdleBreakTimer = AccessTools.FieldRefAccess("idleBreakTimer"); private static readonly FieldRef PlayerTarget = AccessTools.FieldRefAccess("targetPlayer"); private static readonly FieldRef IsOnScreen = AccessTools.FieldRefAccess("isOnScreen"); private static readonly Action UpdateState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyRobe), "UpdateState", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemyRobe enemy) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Invalid comparison between Unknown and I4 //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected I4, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Invalid comparison between Unknown and I4 DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); DedicatedBehaviorSupport.Countdown(enemy, IdleBreakTimer, DedicatedBehaviorSupport.CooldownRate(state)); if ((int)enemy.currentState == 4) { DedicatedBehaviorSupport.RetainCountup(enemy, ChaseTime, DedicatedBehaviorSupport.Retention(state)); } PlayerAvatar val = PlayerTarget.Invoke(enemy); bool flag = dedicatedEnemyRuntimeState.PreviousState == 4; if (flag) { State currentState = enemy.currentState; bool flag2 = (((int)currentState == 9 || (int)currentState == 13) ? true : false); flag = flag2; } if (flag && !dedicatedEnemyRuntimeState.ExtraActionUsed && DedicatedBehaviorSupport.IsValidTarget(val) && GameFieldAccess.OnScreen(state.Enemy).GetOnScreen(val)) { dedicatedEnemyRuntimeState.ExtraActionUsed = true; UpdateState(enemy, (State)4); } DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)enemy.currentState); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyRobe), "Update")] private static void UpdatePostfix(EnemyRobe __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Robe, (Action)Tick); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyRobe), "MoveTowardPlayer")] private static void MoveTowardPlayerPostfix(EnemyRobe __instance) { if (SemiFunc.IsMasterClientOrSingleplayer() && !IsOnScreen.Invoke(__instance) && EliteRegistry.TryGet((Component?)(object)__instance, out EliteState state)) { float value = EliteEnemyVariantsPlugin.Instance.Settings.RobeUnseenMoveSpeed.Value; EnemyNavMeshAgent val = GameFieldAccess.NavMeshAgent(state.Enemy); val.OverrideAgent(value, GameFieldAccess.NavDefaultAcceleration(val), 0.2f); GameFieldAccess.Rigidbody(state.Enemy).OverrideFollowPosition(1f, value, -1f); } } } [HarmonyPatch] internal static class ReaperElitePatches { private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly FieldRef PlayerTarget = AccessTools.FieldRefAccess("targetPlayer"); private static readonly FieldRef StateImpulse = AccessTools.FieldRefAccess("stateImpulse"); private static readonly FieldRef TargetPosition = AccessTools.FieldRefAccess("targetPosition"); private static readonly FieldRef AgentSpeedCurrent = AccessTools.FieldRefAccess("agentSpeedCurrent"); private static readonly Action UpdateState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyRunner), "UpdateState", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemyRunner enemy) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Invalid comparison between Unknown and I4 //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected I4, but got Unknown DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); State currentState = enemy.currentState; if (((int)currentState == 6 || (int)currentState == 10) ? true : false) { DedicatedBehaviorSupport.Countdown(enemy, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } else if ((int)enemy.currentState == 7 && !dedicatedEnemyRuntimeState.AlternateMode) { DedicatedBehaviorSupport.RetainCountdown(enemy, StateTimer, DedicatedBehaviorSupport.Retention(state)); } if (dedicatedEnemyRuntimeState.PreviousState == 7 && (int)enemy.currentState == 4 && !dedicatedEnemyRuntimeState.ExtraActionUsed && dedicatedEnemyRuntimeState.LastTargetViewId != 0) { dedicatedEnemyRuntimeState.ExtraActionUsed = true; dedicatedEnemyRuntimeState.AlternateMode = true; dedicatedEnemyRuntimeState.NextActionAt = Time.time + 4f; UpdateState(enemy, (State)7); } bool flag = (int)enemy.currentState == 6; if (flag) { int previousState = dedicatedEnemyRuntimeState.PreviousState; bool flag2 = (uint)(previousState - 1) <= 4u; flag = flag2; } if (flag) { dedicatedEnemyRuntimeState.ExtraActionUsed = false; dedicatedEnemyRuntimeState.AlternateMode = false; } DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)enemy.currentState); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyRunner), "OnVision")] private static void OnVisionPostfix(EnemyRunner __instance) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) if (!SemiFunc.IsMasterClientOrSingleplayer() || !EliteRegistry.TryGet((Component?)(object)__instance, out EliteState state)) { return; } PlayerAvatar val = PlayerTarget.Invoke(__instance); if (DedicatedBehaviorSupport.IsValidTarget(val)) { DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); dedicatedEnemyRuntimeState.LastPosition = ((Component)val).transform.position; dedicatedEnemyRuntimeState.LastTargetViewId = val.photonView.ViewID; if (dedicatedEnemyRuntimeState.AlternateMode) { dedicatedEnemyRuntimeState.AlternateMode = false; dedicatedEnemyRuntimeState.ExtraActionUsed = false; StateTimer.Invoke(__instance) = Mathf.Max(StateTimer.Invoke(__instance), 2f); } } } [HarmonyPrefix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyRunner), "StateAttackPlayer")] private static bool StateAttackPlayerPrefix(EnemyRunner __instance) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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 (!SemiFunc.IsMasterClientOrSingleplayer() || !EliteRegistry.TryGet((Component?)(object)__instance, out EliteState state)) { return true; } DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); if (!dedicatedEnemyRuntimeState.AlternateMode) { return true; } if (StateImpulse.Invoke(__instance)) { StateImpulse.Invoke(__instance) = false; StateTimer.Invoke(__instance) = 4f; AgentSpeedCurrent.Invoke(__instance) = 3f; GameFieldAccess.NavMeshAgent(state.Enemy).Warp(__instance.feetTransform.position, false); GameFieldAccess.NavMeshAgent(state.Enemy).ResetPath(); } Vector3 lastPosition = dedicatedEnemyRuntimeState.LastPosition; TargetPosition.Invoke(__instance) = lastPosition; EnemyNavMeshAgent val = GameFieldAccess.NavMeshAgent(state.Enemy); val.SetDestination(lastPosition); val.OverrideAgent(4f, Mathf.Max(10f, GameFieldAccess.NavDefaultAcceleration(val)), 0.2f); StateTimer.Invoke(__instance) -= Time.deltaTime; bool num = Vector3.Distance(__instance.feetTransform.position, lastPosition) <= 1.25f; bool flag = StateTimer.Invoke(__instance) <= 0f || GameFieldAccess.NotMovingTimer(GameFieldAccess.Rigidbody(state.Enemy)) > 2f; if (num || flag) { dedicatedEnemyRuntimeState.AlternateMode = false; UpdateState(__instance, (State)4); } return false; } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyRunner), "RotationLogic")] private static void RotationLogicPostfix(EnemyRunner __instance) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClientOrSingleplayer() && EliteRegistry.TryGet((Component?)(object)__instance, out EliteState state) && DedicatedBehaviorSupport.Runtime(state).AlternateMode) { Vector3 val = DedicatedBehaviorSupport.Runtime(state).LastPosition - ((Component)__instance).transform.position; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude > 0.01f) { ((Component)__instance).transform.rotation = Quaternion.RotateTowards(((Component)__instance).transform.rotation, Quaternion.LookRotation(val, Vector3.up), 720f * Time.deltaTime); } } } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyRunner), "Update")] private static void UpdatePostfix(EnemyRunner __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Reaper, (Action)Tick); } } [HarmonyPatch] internal static class LoomElitePatches { private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly FieldRef PlayerTarget = AccessTools.FieldRefAccess("playerTarget"); private static readonly Action UpdatePlayerTarget = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyShadow), "UpdatePlayerTarget", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemyShadow enemy) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Invalid comparison between Unknown and I4 //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Invalid comparison between Unknown and I4 //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected I4, but got Unknown DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); if ((int)enemy.currentState == 6 && DedicatedBehaviorSupport.IsValidTarget(PlayerTarget.Invoke(enemy))) { dedicatedEnemyRuntimeState.LastTargetViewId = PlayerTarget.Invoke(enemy).photonView.ViewID; dedicatedEnemyRuntimeState.ExtraActionUsed = false; } if ((int)enemy.currentState == 1) { DedicatedBehaviorSupport.Countdown(enemy, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } else if ((int)enemy.currentState == 6) { DedicatedBehaviorSupport.Countdown(enemy, StateTimer, DedicatedBehaviorSupport.CooldownRate(state)); } DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)enemy.currentState); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyShadow), "StateChooseTarget")] private static void StateChooseTargetPostfix(EnemyShadow __instance) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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) if (!SemiFunc.IsMasterClientOrSingleplayer() || !EliteRegistry.TryGet((Component?)(object)__instance, out EliteState state)) { return; } DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); PlayerAvatar val = PlayerTarget.Invoke(__instance); if (!dedicatedEnemyRuntimeState.ExtraActionUsed && DedicatedBehaviorSupport.IsValidTarget(val)) { if (val.photonView.ViewID == dedicatedEnemyRuntimeState.LastTargetViewId && DedicatedBehaviorSupport.TryFindNearestPlayer(((Component)__instance).transform.position, 999f, out PlayerAvatar result, val)) { UpdatePlayerTarget(__instance, result); val = result; } dedicatedEnemyRuntimeState.ExtraActionUsed = true; if (val.photonView.ViewID != dedicatedEnemyRuntimeState.LastTargetViewId && Vector3.Distance(((Component)__instance).transform.position, ((Component)val).transform.position) > 30f) { TeleportNearTarget(state, val); } } } private static void TeleportNearTarget(EliteState state, PlayerAvatar target) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) List list = SemiFunc.LevelPointGetWithinDistance(((Component)target).transform.position, 8f, 28f); if (list == null) { return; } NavMeshHit val = default(NavMeshHit); foreach (LevelPoint item in list) { if (!((Object)(object)item == (Object)null) && NavMesh.SamplePosition(((Component)item).transform.position, ref val, 4f, -1) && !(Vector3.Distance(((NavMeshHit)(ref val)).position, ((Component)target).transform.position) > 30f) && !SemiFunc.EnemyPhysObjectBoundingBoxCheck(((Component)state.Enemy).transform.position, ((NavMeshHit)(ref val)).position, GameFieldAccess.Rigidbody(state.Enemy).rb, false, 1.2f)) { state.Enemy.EnemyTeleported(((NavMeshHit)(ref val)).position); break; } } } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyShadow), "Update")] private static void UpdatePostfix(EnemyShadow __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Loom, (Action)Tick); } } [HarmonyPatch] internal static class SpewerElitePatches { private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly FieldRef IdlePukeCooldown = AccessTools.FieldRefAccess("idlePukeCooldown"); private static readonly FieldRef PossessCooldown = AccessTools.FieldRefAccess("possessCooldown"); private static readonly FieldRef AttachedTimer = AccessTools.FieldRefAccess("attachedTimer"); private static readonly Action UpdatePlayerTarget = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemySlowMouth), "UpdatePlayerTarget", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemySlowMouth enemy) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Invalid comparison between Unknown and I4 //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Invalid comparison between Unknown and I4 if ((int)enemy.currentState == 7) { DedicatedBehaviorSupport.Countdown(enemy, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } float rate = DedicatedBehaviorSupport.CooldownRate(state); DedicatedBehaviorSupport.Countdown(enemy, IdlePukeCooldown, rate); DedicatedBehaviorSupport.Countdown(enemy, PossessCooldown, rate); if ((int)enemy.currentState == 9) { AttachedTimer.Invoke(enemy) = Mathf.Min(AttachedTimer.Invoke(enemy), 75f); enemy.UpdateState((State)10); } else if ((int)enemy.currentState == 10) { AttachedTimer.Invoke(enemy) -= Time.deltaTime; if (AttachedTimer.Invoke(enemy) <= 0f) { enemy.UpdateState((State)11); } } } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemySlowMouth), "OnVision")] private static void OnVisionPostfix(EnemySlowMouth __instance) { if (SemiFunc.IsMasterClientOrSingleplayer() && EliteRegistry.TryGet((Component?)(object)__instance, out EliteState _)) { PlayerAvatar onVisionTriggeredPlayer = GameFieldAccess.Vision(((Component)__instance).GetComponent()).onVisionTriggeredPlayer; if (DedicatedBehaviorSupport.IsValidTarget(onVisionTriggeredPlayer) && !((Object)(object)((Component)onVisionTriggeredPlayer.playerAvatarVisuals).GetComponentInChildren() != (Object)null)) { UpdatePlayerTarget(__instance, onVisionTriggeredPlayer); PossessCooldown.Invoke(__instance) = 0f; __instance.UpdateState((State)8); } } } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemySlowMouth), "Update")] private static void UpdatePostfix(EnemySlowMouth __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Spewer, (Action)Tick); } } [HarmonyPatch] internal static class TrudgeElitePatches { private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly FieldRef PlayerTarget = AccessTools.FieldRefAccess("targetPlayer"); private static readonly Action UpdateState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemySlowWalker), "UpdateState", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemySlowWalker enemy) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected I4, but got Unknown DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); if ((int)enemy.currentState == 4) { DedicatedBehaviorSupport.Countdown(enemy, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } if (dedicatedEnemyRuntimeState.PreviousState == 7 && (int)enemy.currentState == 1 && !dedicatedEnemyRuntimeState.ExtraActionUsed && DedicatedBehaviorSupport.IsValidTarget(PlayerTarget.Invoke(enemy))) { dedicatedEnemyRuntimeState.ExtraActionUsed = true; UpdateState(enemy, (State)5); } bool flag = (int)enemy.currentState == 4; if (flag) { int previousState = dedicatedEnemyRuntimeState.PreviousState; bool flag2 = (uint)(previousState - 1) <= 2u; flag = flag2; } if (flag) { dedicatedEnemyRuntimeState.ExtraActionUsed = false; } DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)enemy.currentState); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemySlowWalker), "Update")] private static void UpdatePostfix(EnemySlowWalker __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Trudge, (Action)Tick); } } [HarmonyPatch] internal static class TickElitePatches { private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly FieldRef SuckTimer = AccessTools.FieldRefAccess("suckTimer"); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void TickBehavior(EliteState state, EnemyTick enemy) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 if ((int)enemy.currentState == 4) { DedicatedBehaviorSupport.Countdown(enemy, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } else if ((int)enemy.currentState == 6) { DedicatedBehaviorSupport.Countdown(enemy, SuckTimer, DedicatedBehaviorSupport.CooldownRate(state)); } } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyTick), "Update")] private static void UpdatePostfix(EnemyTick __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Tick, (Action)TickBehavior); } } [HarmonyPatch] internal static class BellaElitePatches { private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly FieldRef AttackCooldown = AccessTools.FieldRefAccess("attackCooldown"); private static readonly Action SetState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyTricycle), "SetState", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemyTricycle enemy) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_0023: Invalid comparison between Unknown and I4 //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Invalid comparison between Unknown and I4 //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Invalid comparison between Unknown and I4 //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected I4, but got Unknown DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); DedicatedBehaviorSupport.Countdown(enemy, AttackCooldown, DedicatedBehaviorSupport.CooldownRate(state)); State currentState = enemy.currentState; if (currentState - 8 <= 2) { DedicatedBehaviorSupport.Countup(enemy, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } if (dedicatedEnemyRuntimeState.PreviousState == 14 && (int)enemy.currentState == 15 && !dedicatedEnemyRuntimeState.ExtraActionUsed) { dedicatedEnemyRuntimeState.ExtraActionUsed = true; SetState(enemy, (State)8); } if ((int)enemy.currentState == 5 && dedicatedEnemyRuntimeState.PreviousState != 5) { dedicatedEnemyRuntimeState.ExtraActionUsed = false; } DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)enemy.currentState); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyTricycle), "Update")] private static void UpdatePostfix(EnemyTricycle __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Bella, (Action)Tick); } } [HarmonyPatch] internal static class ChefElitePatches { private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly FieldRef RoamWaitTimer = AccessTools.FieldRefAccess("roamWaitTimer"); private static readonly FieldRef PlayerTarget = AccessTools.FieldRefAccess("targetPlayer"); private static readonly Action UpdateState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyTumbler), "UpdateState", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemyTumbler enemy) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Invalid comparison between Unknown and I4 //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Invalid comparison between Unknown and I4 //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Expected I4, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); State currentState = enemy.currentState; if (((int)currentState == 3 || (int)currentState == 6) ? true : false) { DedicatedBehaviorSupport.Countdown(enemy, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } DedicatedBehaviorSupport.Countdown(enemy, RoamWaitTimer, DedicatedBehaviorSupport.CooldownRate(state)); if ((int)enemy.currentState == 7 && DedicatedBehaviorSupport.IsValidTarget(PlayerTarget.Invoke(enemy))) { if (dedicatedEnemyRuntimeState.PreviousState != 7) { dedicatedEnemyRuntimeState.NextActionAt = Time.time + 6f; } Rigidbody rb = GameFieldAccess.Rigidbody(state.Enemy).rb; Vector3 val = ((Component)PlayerTarget.Invoke(enemy)).transform.position - rb.position; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude > 0.01f) { ((Vector3)(ref val)).Normalize(); Vector3 velocity = rb.velocity; velocity.y = 0f; Vector3 val2 = Vector3.ClampMagnitude(val * 18f - velocity, 72f * Time.deltaTime); rb.AddForce(val2, (ForceMode)2); rb.AddTorque(Vector3.Cross(Vector3.up, val) * 25f * Time.deltaTime, (ForceMode)2); } if (Time.time >= dedicatedEnemyRuntimeState.NextActionAt) { UpdateState(enemy, (State)8); } } if (dedicatedEnemyRuntimeState.PreviousState == 8 && (int)enemy.currentState == 9 && !dedicatedEnemyRuntimeState.ExtraActionUsed && DedicatedBehaviorSupport.IsValidTarget(PlayerTarget.Invoke(enemy))) { dedicatedEnemyRuntimeState.ExtraActionUsed = true; UpdateState(enemy, (State)6); } if ((int)enemy.currentState == 3 && dedicatedEnemyRuntimeState.PreviousState != 3) { dedicatedEnemyRuntimeState.ExtraActionUsed = false; } DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)enemy.currentState); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyTumbler), "Update")] private static void UpdatePostfix(EnemyTumbler __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Chef, (Action)Tick); } } [HarmonyPatch] internal static class UpscreamElitePatches { private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly FieldRef RoamWaitTimer = AccessTools.FieldRefAccess("roamWaitTimer"); private static readonly FieldRef PlayerTarget = AccessTools.FieldRefAccess("targetPlayer"); private static readonly Action UpdateState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyUpscream), "UpdateState", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemyUpscream enemy) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_0048: Invalid comparison between Unknown and I4 //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Invalid comparison between Unknown and I4 //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Invalid comparison between Unknown and I4 //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Invalid comparison between Unknown and I4 //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Invalid comparison between Unknown and I4 //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected I4, but got Unknown DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); if ((int)enemy.currentState == 4) { DedicatedBehaviorSupport.Countdown(enemy, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } DedicatedBehaviorSupport.Countdown(enemy, RoamWaitTimer, DedicatedBehaviorSupport.CooldownRate(state)); bool flag = dedicatedEnemyRuntimeState.PreviousState == 6; if (flag) { State currentState = enemy.currentState; bool flag2 = (((int)currentState == 1 || (int)currentState == 7) ? true : false); flag = flag2; } if (flag && !dedicatedEnemyRuntimeState.ExtraActionUsed && DedicatedBehaviorSupport.IsValidTarget(PlayerTarget.Invoke(enemy))) { dedicatedEnemyRuntimeState.ExtraActionUsed = true; dedicatedEnemyRuntimeState.AlternateMode = true; dedicatedEnemyRuntimeState.NextActionAt = Time.time + 8f; UpdateState(enemy, (State)5); } if (dedicatedEnemyRuntimeState.AlternateMode && (int)enemy.currentState == 5) { float num = dedicatedEnemyRuntimeState.NextActionAt - Time.time; if (num <= 0f || !DedicatedBehaviorSupport.IsValidTarget(PlayerTarget.Invoke(enemy))) { dedicatedEnemyRuntimeState.AlternateMode = false; UpdateState(enemy, (State)7); } else { StateTimer.Invoke(enemy) = Mathf.Max(StateTimer.Invoke(enemy), num); EnemyNavMeshAgent val = GameFieldAccess.NavMeshAgent(state.Enemy); val.OverrideAgent(7f, Mathf.Max(15f, GameFieldAccess.NavDefaultAcceleration(val)), 0.2f); } } else if (dedicatedEnemyRuntimeState.AlternateMode && (int)enemy.currentState == 6) { dedicatedEnemyRuntimeState.AlternateMode = false; } if ((int)enemy.currentState == 4 && dedicatedEnemyRuntimeState.PreviousState != 4) { dedicatedEnemyRuntimeState.ExtraActionUsed = false; dedicatedEnemyRuntimeState.AlternateMode = false; } DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)enemy.currentState); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyUpscream), "Update")] private static void UpdatePostfix(EnemyUpscream __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Upscream, (Action)Tick); } } [HarmonyPatch] internal static class RugratElitePatches { private static readonly FieldRef StateTimer = AccessTools.FieldRefAccess("stateTimer"); private static readonly FieldRef PlayerTarget = AccessTools.FieldRefAccess("playerTarget"); private static readonly FieldRef ValuableTarget = AccessTools.FieldRefAccess("valuableTarget"); private static readonly Action UpdateState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyValuableThrower), "UpdateState", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { DedicatedBehaviorSupport.OnSpawn(state); } private static void Tick(EliteState state, EnemyValuableThrower enemy) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Invalid comparison between Unknown and I4 //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected I4, but got Unknown DedicatedEnemyRuntimeState dedicatedEnemyRuntimeState = DedicatedBehaviorSupport.Runtime(state); if ((int)enemy.currentState == 4) { DedicatedBehaviorSupport.Countdown(enemy, StateTimer, DedicatedBehaviorSupport.WindupRate(state)); } if (dedicatedEnemyRuntimeState.PreviousState == 9 && (int)enemy.currentState == 10 && !dedicatedEnemyRuntimeState.ExtraActionUsed && DedicatedBehaviorSupport.IsValidTarget(PlayerTarget.Invoke(enemy))) { dedicatedEnemyRuntimeState.ExtraActionUsed = true; UpdateState(enemy, (State)5); } if ((int)enemy.currentState == 4 && dedicatedEnemyRuntimeState.PreviousState != 4) { dedicatedEnemyRuntimeState.ExtraActionUsed = false; } DedicatedBehaviorSupport.TrackState(dedicatedEnemyRuntimeState, (int)enemy.currentState); } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyValuableThrower), "StateGetValuable")] private static void StateGetValuablePostfix(EnemyValuableThrower __instance) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) if (!SemiFunc.IsMasterClientOrSingleplayer() || !EliteRegistry.TryGet((Component?)(object)__instance, out EliteState _) || !DedicatedBehaviorSupport.IsValidTarget(PlayerTarget.Invoke(__instance))) { return; } PhysGrabObject val = null; float num = float.MinValue; Collider[] array = Physics.OverlapSphere(((Component)PlayerTarget.Invoke(__instance)).transform.position, 10f, LayerMask.GetMask(new string[1] { "PhysGrabObject" })); NavMeshHit val4 = default(NavMeshHit); for (int i = 0; i < array.Length; i++) { ValuableObject componentInParent = ((Component)array[i]).GetComponentInParent(); PhysGrabObject val2 = (((Object)(object)componentInParent != (Object)null) ? GameFieldAccess.ValuablePhysGrabObject(componentInParent) : null); PhysGrabObjectImpactDetector val3 = (((Object)(object)val2 != (Object)null) ? GameFieldAccess.ImpactDetector(val2) : null); if ((Object)(object)componentInParent == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null || GameFieldAccess.IsIndestructible(val3) || !NavMesh.SamplePosition(((Component)val2).transform.position, ref val4, 2f, -1)) { continue; } NavMeshPath val5 = new NavMeshPath(); if (NavMesh.CalculatePath(((Component)__instance).transform.position, ((NavMeshHit)(ref val4)).position, -1, val5) && (int)val5.status == 0) { float num2 = GameFieldAccess.ValuableDollarValue(componentInParent); if (num2 > num) { num = num2; val = val2; } } } if ((Object)(object)val != (Object)null) { ValuableTarget.Invoke(__instance) = val; } } [HarmonyPrefix] [HarmonyPatch(typeof(SemiFunc), "EnemyCartJump")] private static bool EnemyCartJumpPrefix(Enemy enemy) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 EnemyValuableThrower val = (((Object)(object)enemy != (Object)null) ? ((Component)enemy).GetComponent() : null); EliteState state; if (!((Object)(object)val == (Object)null) && (int)val.currentState == 6) { return !EliteRegistry.TryGet((Component?)(object)val, out state); } return true; } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyJump), "StuckTrigger")] private static bool StuckTriggerPrefix(EnemyJump __instance) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 EnemyValuableThrower component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || (int)component.currentState != 6 || !EliteRegistry.TryGet((Component?)(object)component, out EliteState _)) { return true; } __instance.StuckReset(); return false; } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyValuableThrower), "Update")] private static void UpdatePostfix(EnemyValuableThrower __instance) { DedicatedBehaviorSupport.Run(__instance, EliteArchetype.Rugrat, (Action)Tick); } } [HarmonyPatch] internal static class GambitElitePatches { private static readonly Action UpdateState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemySpinny), "UpdateState", (Type[])null, (Type[])null), (object)null, true); private static readonly Action JumpIfStuck = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemySpinny), "JumpIfStuck", (Type[])null, (Type[])null), (object)null, true); private static readonly FieldRef ReachedPoint = AccessTools.FieldRefAccess("reachedPoint"); internal static void OnSpawn(EliteState state) { //IL_0041: 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) EnemySpinny component = ((Component)state.Enemy).GetComponent(); if ((Object)(object)component != (Object)null) { component.spinDurationSeconds = EliteEnemyVariantsPlugin.Instance.Settings.GambitRouletteDurationSeconds.Value; } state.AdapterState = new GambitRuntimeState { LastPosition = ((Component)state.Enemy).transform.position }; } internal static void Tick(EliteState state) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0175: 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_01af: 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_01d9: Unknown result type (might be due to invalid IL or missing references) EnemySpinny component = ((Component)state.Enemy).GetComponent(); if ((Object)(object)component == (Object)null) { return; } GambitRuntimeState runtime = GetRuntime(state); State currentState = component.currentState; bool flag = currentState - 8 <= 3; bool flag2 = flag || ((int)component.currentState == 7 && ReachedPoint.Invoke(component)); if (!component.RouletteGoingOn()) { runtime.EscapeActive = false; runtime.StuckTimer = 0f; runtime.EscapeAttempt = 0; runtime.LastPosition = ((Component)component).transform.position; } else { if (!flag2) { return; } if ((Object)(object)component.playerTarget == (Object)null || GameFieldAccess.PlayerDisabled(component.playerTarget)) { UpdateState(component, (State)12); return; } if (!runtime.EscapeActive) { runtime.EscapeActive = TryChooseEscapePoint(component, runtime.EscapeAttempt++, out runtime.EscapePoint); runtime.LastPosition = ((Component)component).transform.position; } if (runtime.EscapeActive) { EnemyNavMeshAgent val = GameFieldAccess.NavMeshAgent(state.Enemy); val.Stop(0f); val.SetDestination(runtime.EscapePoint); val.OverrideAgent(Mathf.Max(6f, GameFieldAccess.NavDefaultSpeed(val)), Mathf.Max(20f, GameFieldAccess.NavDefaultAcceleration(val)), 0.2f); GameFieldAccess.Rigidbody(state.Enemy).OverrideFollowPosition(0.2f, 10f, 1f); float num = Vector3.Distance(runtime.LastPosition, ((Component)component).transform.position); runtime.StuckTimer = ((num < 0.05f) ? (runtime.StuckTimer + Time.deltaTime) : 0f); runtime.LastPosition = ((Component)component).transform.position; if (runtime.StuckTimer >= 2f) { JumpIfStuck(component, arg2: true); } bool num2 = Vector3.Distance(((Component)component).transform.position, runtime.EscapePoint) <= 1.25f; bool flag3 = runtime.StuckTimer >= 2f; if (num2 || flag3) { val.ResetPath(); val.Stop(0f); runtime.EscapeActive = false; runtime.StuckTimer = 0f; } } } } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyStateStunned), "Set")] private static bool EnemyStateStunnedSetPrefix(EnemyStateStunned __instance) { EnemySpinny component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || !EliteEnemyVariantsPlugin.Instance.Settings.GambitRouletteStunImmune.Value || !component.RouletteGoingOn()) { return true; } EliteState state; return !EliteRegistry.TryGet((Component?)(object)component, out state); } private static bool TryChooseEscapePoint(EnemySpinny gambit, int index, out Vector3 result) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)gambit).transform.position - ((Component)gambit.playerTarget).transform.position; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = ((Component)gambit).transform.forward; } ((Vector3)(ref val)).Normalize(); float num = ((index % 2 == 0) ? 1f : (-1f)); float num2 = 25f + (float)(index % 5) * 28f; NavMeshPath val2 = new NavMeshPath(); float num3 = 0f; Vector3 val3 = default(Vector3); NavMeshHit val5 = default(NavMeshHit); for (int i = 0; i < 10; i++) { float num4 = num * num2 + (float)i * 36f; Vector3 val4 = Quaternion.Euler(0f, num4, 0f) * val; if (NavMesh.SamplePosition(((Component)gambit).transform.position + val4 * (10f + (float)(i % 3) * 3f), ref val5, 5f, -1) && NavMesh.CalculatePath(((Component)gambit).transform.position, ((NavMeshHit)(ref val5)).position, -1, val2) && (int)val2.status == 0 && val2.corners.Length >= 2) { float num5 = 0f; for (int j = 1; j < val2.corners.Length; j++) { num5 += Vector3.Distance(val2.corners[j - 1], val2.corners[j]); } if (num5 > num3) { num3 = num5; val3 = ((NavMeshHit)(ref val5)).position; } } } if (num3 >= 2f) { result = val3; return true; } result = default(Vector3); return false; } private static GambitRuntimeState GetRuntime(EliteState state) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) GambitRuntimeState gambitRuntimeState = state.AdapterState as GambitRuntimeState; if (gambitRuntimeState == null) { gambitRuntimeState = (GambitRuntimeState)(state.AdapterState = new GambitRuntimeState { LastPosition = ((Component)state.Enemy).transform.position }); } return gambitRuntimeState; } } [HarmonyPatch] internal static class GnomeElitePatches { private static readonly FieldRef AttackAngle = AccessTools.FieldRefAccess("attackAngle"); private static readonly FieldRef DirectorIndex = AccessTools.FieldRefAccess("directorIndex"); private static readonly FieldRef OverlapCheckTimer = AccessTools.FieldRefAccess("overlapCheckTimer"); private static readonly FieldRef OverlapCheckCooldown = AccessTools.FieldRefAccess("overlapCheckCooldown"); private static readonly FieldRef OverlapCheckPrevious = AccessTools.FieldRefAccess("overlapCheckPrevious"); private static readonly FieldRef DirectorStateImpulse = AccessTools.FieldRefAccess("stateImpulse"); private static readonly FieldRef DirectorPlayerTarget = AccessTools.FieldRefAccess("playerTarget"); private static readonly FieldRef DirectorValuableTarget = AccessTools.FieldRefAccess("valuableTarget"); private static readonly Action UpdateGnomeState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyGnome), "UpdateState", (Type[])null, (Type[])null), (object)null, true); private static readonly Action UpdateDirectorState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyGnomeDirector), "UpdateState", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { if (!((Object)(object)((Component)state.Enemy).GetComponent() == (Object)null) && !((Object)(object)GameFieldAccess.Jump(state.Enemy) == (Object)null)) { GnomeRuntimeState runtime = GetRuntime(state); if (!runtime.StatsApplied) { float value = EliteEnemyVariantsPlugin.Instance.Settings.GnomeJumpMultiplier.Value; EnemyJump obj = GameFieldAccess.Jump(state.Enemy); obj.surfaceJumpForceUp *= value; obj.surfaceJumpForceSide *= value; obj.stuckJumpForceUp *= value; obj.stuckJumpForceSide *= value; obj.gapJumpForceUp *= value; obj.gapJumpForceForward *= value; runtime.StatsApplied = true; } } } internal static void Tick(EliteState state) { } internal static void Cleanup(EliteState state) { } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyGnome), "StateNoticeDelay")] private static bool StateNoticeDelayPrefix(EnemyGnome __instance) { if (!EliteEnemyVariantsPlugin.Instance.Settings.GnomeZeroNoticeDelay.Value || !EliteRegistry.TryGet((Component?)(object)__instance, out EliteState _)) { return true; } UpdateGnomeState(__instance, (State)3); return false; } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyGnome), "AttackPositionLogic")] private static bool AttackPositionLogicPrefix(EnemyGnome __instance, ref Vector3 __result) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) if (!EliteRegistry.TryGet((Component?)(object)__instance, out EliteState _) || (Object)(object)EnemyGnomeDirector.instance == (Object)null) { return true; } EliteEnemyConfig settings = EliteEnemyVariantsPlugin.Instance.Settings; float value = settings.GnomeAttackOrbitSpeed.Value; float value2 = settings.GnomeAttackRadius.Value; float num = AttackAngle.Invoke(__instance); num += ((DirectorIndex.Invoke(__instance) % 2 == 0) ? 0f : MathF.PI); __result = GameFieldAccess.GnomeAttackPosition(EnemyGnomeDirector.instance) + new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)) * value2; AttackAngle.Invoke(__instance) += Time.deltaTime * value; return false; } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyGnome), "StateAttackDone")] private static void StateAttackDonePostfix(EnemyGnome __instance) { if (EliteEnemyVariantsPlugin.Instance.Settings.GnomeZeroAttackCooldown.Value && EliteRegistry.TryGet((Component?)(object)__instance, out EliteState _)) { GameFieldAccess.SetGnomeAttackCooldown(__instance, 0f); } } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyGnomeDirector), "CanAttack")] private static bool CanAttackPrefix(EnemyGnomeDirector __instance, EnemyGnome _gnome, ref bool __result) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Invalid comparison between Unknown and I4 //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Invalid comparison between Unknown and I4 if (!EliteRegistry.TryGet((Component?)(object)_gnome, out EliteState _)) { return true; } if (GameFieldAccess.GnomeAttackCooldown(_gnome) > 0f || GameFieldAccess.IsJumping(GameFieldAccess.Jump(_gnome.enemy))) { __result = false; return false; } EliteEnemyConfig settings = EliteEnemyVariantsPlugin.Instance.Settings; float value = settings.GnomeAttackRadius.Value; if ((int)__instance.currentState == 5) { int num = 0; foreach (EnemyGnome gnome in __instance.gnomes) { bool flag = (Object)(object)gnome != (Object)null && (Object)(object)gnome != (Object)(object)_gnome; if (flag) { State currentState = gnome.currentState; bool flag2 = currentState - 8 <= 1; flag = flag2; } if (flag) { num++; } } if (num >= settings.GnomeConcurrentAttackers.Value) { __result = false; return false; } __result = Vector3.Distance(((Component)GameFieldAccess.Rigidbody(_gnome.enemy)).transform.position, GameFieldAccess.GnomeAttackPosition(__instance)) <= value; return false; } PhysGrabObject val = DirectorValuableTarget.Invoke(__instance); if ((Object)(object)val == (Object)null) { __result = false; return false; } OverlapCheckCooldown.Invoke(_gnome) = 1f; if (OverlapCheckTimer.Invoke(_gnome) <= 0f) { OverlapCheckTimer.Invoke(_gnome) = 0.5f; OverlapCheckPrevious.Invoke(_gnome) = false; Collider[] array = Physics.OverlapSphere(((Component)GameFieldAccess.Rigidbody(_gnome.enemy)).transform.position, value, LayerMask.GetMask(new string[1] { "PhysGrabObject" })); for (int i = 0; i < array.Length; i++) { ValuableObject componentInParent = ((Component)array[i]).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null && (Object)(object)GameFieldAccess.ValuablePhysGrabObject(componentInParent) == (Object)(object)val) { OverlapCheckPrevious.Invoke(_gnome) = true; break; } } } __result = OverlapCheckPrevious.Invoke(_gnome); return false; } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyGnomeDirector), "StateAttackSet")] private static bool StateAttackSetPrefix(EnemyGnomeDirector __instance) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) if (!TryGetDirectorState(__instance, out EliteState _)) { return true; } if (!DirectorStateImpulse.Invoke(__instance)) { return false; } DirectorStateImpulse.Invoke(__instance) = false; DirectorValuableTarget.Invoke(__instance) = null; PlayerAvatar val = DirectorPlayerTarget.Invoke(__instance); if ((Object)(object)val == (Object)null) { UpdateDirectorState(__instance, (State)0); return false; } float num = float.MinValue; float value = EliteEnemyVariantsPlugin.Instance.Settings.GnomeValuablePriorityRadius.Value; Collider[] array = Physics.OverlapSphere(((Component)val).transform.position, value, LayerMask.GetMask(new string[1] { "PhysGrabObject" })); for (int i = 0; i < array.Length; i++) { ValuableObject componentInParent = ((Component)array[i]).GetComponentInParent(); PhysGrabObject val2 = (((Object)(object)componentInParent != (Object)null) ? GameFieldAccess.ValuablePhysGrabObject(componentInParent) : null); PhysGrabObjectImpactDetector val3 = (((Object)(object)val2 != (Object)null) ? GameFieldAccess.ImpactDetector(val2) : null); if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null) && !GameFieldAccess.IsIndestructible(val3) && !(GameFieldAccess.ValuableDollarValue(componentInParent) <= num)) { num = GameFieldAccess.ValuableDollarValue(componentInParent); DirectorValuableTarget.Invoke(__instance) = val2; } } UpdateDirectorState(__instance, (State)(((Object)(object)DirectorValuableTarget.Invoke(__instance) != (Object)null) ? 6 : 5)); return false; } private static bool TryGetDirectorState(EnemyGnomeDirector director, out EliteState state) { foreach (EnemyGnome gnome in director.gnomes) { if ((Object)(object)gnome != (Object)null && EliteRegistry.TryGet((Component?)(object)gnome, out state)) { return true; } } state = null; return false; } private static GnomeRuntimeState GetRuntime(EliteState state) { GnomeRuntimeState gnomeRuntimeState = state.AdapterState as GnomeRuntimeState; if (gnomeRuntimeState == null) { gnomeRuntimeState = (GnomeRuntimeState)(state.AdapterState = new GnomeRuntimeState()); } return gnomeRuntimeState; } } [HarmonyPatch] internal static class HuntsmanElitePatches { private static readonly FieldRef InvestigatePoint = AccessTools.FieldRefAccess("investigatePoint"); private static readonly FieldRef InvestigateAimHorizontal = AccessTools.FieldRefAccess("investigateAimHorizontal"); private static readonly FieldRef InvestigateAimVertical = AccessTools.FieldRefAccess("investigateAimVertical"); internal static void OnSpawn(EliteState state) { state.AdapterState = new HuntsmanRuntimeState(); } internal static void Tick(EliteState state) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Invalid comparison between Unknown and I4 //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Invalid comparison between Unknown and I4 //IL_0071: Unknown result type (might be due to invalid IL or missing references) EnemyHunter component = ((Component)state.Enemy).GetComponent(); if ((Object)(object)component == (Object)null || state.Enemy.IsStunned()) { return; } HuntsmanRuntimeState runtime = GetRuntime(state); State currentState = component.currentState; if ((int)currentState != 5 && (int)currentState != 6) { runtime.AccuracyRolled = false; runtime.MissThisShot = false; } if (runtime.PendingInvestigate) { currentState = component.currentState; if ((int)currentState != 5 && (int)currentState != 6) { runtime.PendingInvestigate = false; GameFieldAccess.StateInvestigate(state.Enemy).Set(runtime.PendingInvestigatePoint, runtime.PendingInvestigatePathfindOnly); } } } [HarmonyPostfix] [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPatch(typeof(EnemyHunter), "AimLogic")] private static void AimLogicPostfix(EnemyHunter __instance) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: 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_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: 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_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: 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_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_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: 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_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) if (!SemiFunc.IsMasterClientOrSingleplayer() || !EliteRegistry.TryGet((Component?)(object)__instance, out EliteState state)) { return; } HuntsmanRuntimeState runtime = GetRuntime(state); Vector3 position = __instance.gunAimTransform.position; Vector3 val = InvestigatePoint.Invoke(__instance); float num = Vector3.Distance(position, val); float num2 = Mathf.InverseLerp(5f, 45f, num); if (!runtime.AccuracyRolled) { runtime.AccuracyRolled = true; runtime.MissThisShot = Random.value < num2 * 0.3f; float num3 = ((Random.value < 0.5f) ? (-1f) : 1f); float num4 = Mathf.Lerp(1.5f, 2.25f, num2); float num5 = Random.Range(-0.5f, 0.5f); runtime.MissYaw = num3 * Mathf.Atan2(num4, Mathf.Max(1f, num)) * 57.29578f; runtime.MissPitch = Mathf.Atan2(num5, Mathf.Max(1f, num)) * 57.29578f; Vector3 val2 = val - position; val2.y = 0f; Vector3 val3 = ((((Vector3)(ref val2)).sqrMagnitude > 0.01f) ? Vector3.Cross(Vector3.up, ((Vector3)(ref val2)).normalized) : __instance.gunAimTransform.right); runtime.MissImpactPoint = val + val3 * (num3 * num4) + Vector3.up * num5; } if (runtime.MissThisShot) { Vector3 val4 = val - position; if (!(((Vector3)(ref val4)).sqrMagnitude < 0.01f)) { ((Vector3)(ref val4)).Normalize(); val4 = Quaternion.AngleAxis(runtime.MissYaw, Vector3.up) * val4; Vector3 val5 = Vector3.Cross(Vector3.up, val4); Vector3 normalized = ((Vector3)(ref val5)).normalized; val4 = Quaternion.AngleAxis(runtime.MissPitch, normalized) * val4; Quaternion val6 = Quaternion.LookRotation(val4, Vector3.up); InvestigateAimHorizontal.Invoke(__instance) = Quaternion.Euler(0f, ((Quaternion)(ref val6)).eulerAngles.y, 0f); float x = ((Quaternion)(ref val6)).eulerAngles.x; x = ((x < 180f) ? Mathf.Clamp(x, 0f, 45f) : Mathf.Clamp(x, 315f, 360f)); InvestigateAimVertical.Invoke(__instance) = Quaternion.Euler(x, 0f, 0f); } } } [HarmonyPrefix] [HarmonyPatch(typeof(PhotonView), "RPC", new Type[] { typeof(string), typeof(RpcTarget), typeof(object[]) })] private static void PhotonViewRpcPrefix(PhotonView __instance, string methodName, object[] parameters) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (!SemiFunc.IsMasterClientOrSingleplayer() || methodName != "ShootRPC" || parameters == null || parameters.Length == 0) { return; } EnemyHunter component = ((Component)__instance).GetComponent(); if (component != null && EliteRegistry.TryGet((Component?)(object)component, out EliteState state)) { HuntsmanRuntimeState runtime = GetRuntime(state); if (runtime.MissThisShot) { parameters[0] = runtime.MissImpactPoint; } } } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyHunter), "ShootRPC")] private static void ShootRpcPrefix(EnemyHunter __instance, ref Vector3 _hitPosition) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClientOrSingleplayer() && EliteRegistry.TryGet((Component?)(object)__instance, out EliteState state)) { HuntsmanRuntimeState runtime = GetRuntime(state); if (runtime.MissThisShot) { _hitPosition = runtime.MissImpactPoint; } } } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyDirector), "SetInvestigate")] private static void EnemyDirectorSetInvestigatePostfix(Vector3 position, float radius, bool pathfindOnly) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Invalid comparison between Unknown and I4 //IL_00c9: 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_00fe: Unknown result type (might be due to invalid IL or missing references) if (!SemiFunc.IsMasterClientOrSingleplayer()) { return; } float value = EliteEnemyVariantsPlugin.Instance.Settings.HuntsmanSoundInvestigateRange.Value; foreach (EliteState state in EliteRegistry.States) { if (!state.Spawned || state.Archetype != EliteArchetype.Huntsman || (Object)(object)state.Enemy == (Object)null || !GameFieldAccess.HasStateInvestigate(state.Enemy)) { continue; } float num = Vector3.Distance(position, ((Component)state.Enemy).transform.position); if (num > value) { continue; } EnemyHunter component = ((Component)state.Enemy).GetComponent(); if ((Object)(object)component == (Object)null) { continue; } State currentState = component.currentState; if (currentState - 5 <= 1) { HuntsmanRuntimeState runtime = GetRuntime(state); runtime.PendingInvestigate = true; runtime.PendingInvestigatePoint = position; runtime.PendingInvestigatePathfindOnly = pathfindOnly; } else { EnemyStateInvestigate val = GameFieldAccess.StateInvestigate(state.Enemy); if (!(num / Mathf.Max(0.01f, val.rangeMultiplier) < radius)) { val.Set(position, pathfindOnly); } } } } private static HuntsmanRuntimeState GetRuntime(EliteState state) { HuntsmanRuntimeState huntsmanRuntimeState = state.AdapterState as HuntsmanRuntimeState; if (huntsmanRuntimeState == null) { huntsmanRuntimeState = (HuntsmanRuntimeState)(state.AdapterState = new HuntsmanRuntimeState()); } return huntsmanRuntimeState; } } [HarmonyPatch] internal static class ShadowChildElitePatches { private static readonly FieldRef EnemyRef = AccessTools.FieldRefAccess("enemy"); private static readonly FieldRef PlayerTarget = AccessTools.FieldRefAccess("playerTarget"); private static readonly FieldRef TeleportPosition = AccessTools.FieldRefAccess("teleportPosition"); private static readonly Action UpdateState = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyThinMan), "UpdateState", (Type[])null, (Type[])null), (object)null, true); private static readonly Action SetTarget = AccessTools.MethodDelegate>(AccessTools.Method(typeof(EnemyThinMan), "SetTarget", (Type[])null, (Type[])null), (object)null, true); internal static void OnSpawn(EliteState state) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) state.AdapterState = new ShadowChildRuntimeState { LastPosition = ((Component)state.Enemy).transform.position }; } internal static void Tick(EliteState state) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Invalid comparison between Unknown and I4 //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Invalid comparison between Unknown and I4 //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Expected I4, but got Unknown //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) EnemyThinMan component = ((Component)state.Enemy).GetComponent(); if ((Object)(object)component == (Object)null) { return; } ShadowChildRuntimeState runtime = GetRuntime(state); if (state.Enemy.IsStunned() || (int)component.currentState == 7) { ResetRuntime(runtime, ((Component)component).transform.position); return; } PlayerAvatar val = PlayerTarget.Invoke(component); if ((Object)(object)val != (Object)null && (Object)(object)val.photonView != (Object)null && val.photonView.ViewID != runtime.LastTargetViewId) { runtime.PreviousTargetViewId = runtime.LastTargetViewId; runtime.LastTargetViewId = val.photonView.ViewID; } EnemyOnScreen val2 = GameFieldAccess.OnScreen(state.Enemy); bool flag = (Object)(object)val2 != (Object)null && GameFieldAccess.OnScreenAny(val2); foreach (PlayerAvatar item in SemiFunc.PlayerGetList()) { if ((Object)(object)item != (Object)null && !GameFieldAccess.PlayerDisabled(item) && GameFieldAccess.OnScreen(state.Enemy).GetOnScreen(item)) { flag = true; break; } } if (flag && !DedicatedBehaviorSupport.IsValidTarget(val) && DedicatedBehaviorSupport.TryFindNearestPlayer(((Component)component).transform.position, EliteEnemyVariantsPlugin.Instance.Settings.ShadowApproachRadius.Value, out PlayerAvatar result, null, state.Enemy)) { SetTarget(component, result); val = result; } bool flag2 = flag && DedicatedBehaviorSupport.IsValidTarget(val); if (flag2) { State currentState = component.currentState; bool flag3 = (int)currentState <= 1; flag2 = flag3; } if (flag2) { runtime.LookAccumulation += Time.deltaTime; float value = EliteEnemyVariantsPlugin.Instance.Settings.ShadowEyeContactSeconds.Value; if (runtime.LookAccumulation >= value) { UpdateState(component, (State)2); runtime.LookAccumulation = 0f; } } else { runtime.LookAccumulation = Mathf.Max(0f, runtime.LookAccumulation - Time.deltaTime * 0.5f); } flag2 = !flag; if (flag2) { State currentState = component.currentState; bool flag3 = (int)currentState <= 1; flag2 = flag3; } if (flag2 && TryChooseApproachTarget(state, runtime, out PlayerAvatar result2)) { if ((Object)(object)val != (Object)(object)result2) { SetTarget(component, result2); val = result2; } float value2 = EliteEnemyVariantsPlugin.Instance.Settings.ShadowApproachSpeed.Value; NavMeshHit val3 = default(NavMeshHit); if (NavMesh.SamplePosition(Vector3.MoveTowards(TeleportPosition.Invoke(component), ((Component)result2).transform.position, value2 * Time.deltaTime), ref val3, 1f, -1)) { TeleportPosition.Invoke(component) = ((NavMeshHit)(ref val3)).position; } } float num = Vector3.Distance(runtime.LastPosition, ((Component)component).transform.position); runtime.StuckTimer = ((num < 0.05f) ? (runtime.StuckTimer + Time.deltaTime) : 0f); runtime.LastPosition = ((Component)component).transform.position; if (runtime.StuckTimer >= 2f && (Object)(object)val != (Object)null) { Vector3 val4 = Vector3.Cross(Vector3.up, ((Component)val).transform.position - ((Component)component).transform.position); Vector3 normalized = ((Vector3)(ref val4)).normalized; NavMeshHit val5 = default(NavMeshHit); if (NavMesh.SamplePosition(((Component)val).transform.position + normalized * 2f, ref val5, 2f, -1)) { TeleportPosition.Invoke(component) = ((NavMeshHit)(ref val5)).position; } runtime.StuckTimer = 0f; } runtime.PreviousState = (int)component.currentState; } private static bool TryChooseApproachTarget(EliteState state, ShadowChildRuntimeState runtime, out PlayerAvatar result) { //IL_0042: 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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_0127: Unknown result type (might be due to invalid IL or missing references) result = null; float value = EliteEnemyVariantsPlugin.Instance.Settings.ShadowApproachRadius.Value; PlayerAvatar val = PlayerTarget.Invoke(((Component)state.Enemy).GetComponent()); if (DedicatedBehaviorSupport.IsValidTarget(val) && Vector3.Distance(((Component)state.Enemy).transform.position, ((Component)val).transform.position) <= value) { result = val; return true; } float num = float.MaxValue; foreach (PlayerAvatar item in SemiFunc.PlayerGetList()) { if (!((Object)(object)item == (Object)null) && !GameFieldAccess.PlayerDisabled(item)) { float num2 = Vector3.Distance(((Component)state.Enemy).transform.position, ((Component)item).transform.position); if (num2 <= value && num2 < num) { num = num2; result = item; } } } if ((Object)(object)result != (Object)null) { return true; } foreach (PlayerAvatar item2 in SemiFunc.PlayerGetList()) { if (!((Object)(object)item2 == (Object)null) && !GameFieldAccess.PlayerDisabled(item2)) { float num3 = Vector3.Distance(((Component)state.Enemy).transform.position, ((Component)item2).transform.position); if (num3 <= value && num3 < num) { num = num3; result = item2; } } } return (Object)(object)result != (Object)null; } private static ShadowChildRuntimeState GetRuntime(EliteState state) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) ShadowChildRuntimeState shadowChildRuntimeState = state.AdapterState as ShadowChildRuntimeState; if (shadowChildRuntimeState == null) { shadowChildRuntimeState = (ShadowChildRuntimeState)(state.AdapterState = new ShadowChildRuntimeState { LastPosition = ((Component)state.Enemy).transform.position }); } return shadowChildRuntimeState; } private static void ResetRuntime(ShadowChildRuntimeState runtime, Vector3 position) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) runtime.LookAccumulation = 0f; runtime.StuckTimer = 0f; runtime.LastTargetViewId = 0; runtime.PreviousTargetViewId = 0; runtime.LastPosition = position; } } [HarmonyPatch] internal static class CommonEnemyPatches { [HarmonyPrefix] [HarmonyPatch(typeof(EnemyOnScreen), "GetOnScreen")] private static void EnemyOnScreenGetOnScreenPrefix(EnemyOnScreen __instance, PlayerAvatar _playerAvatar) { if ((Object)(object)_playerAvatar != (Object)null && (Object)(object)_playerAvatar.photonView != (Object)null) { __instance.PlayerAdded(_playerAvatar.photonView.ViewID); } } [HarmonyPrefix] [HarmonyPatch(typeof(SemiFunc), "LevelPointListPurgeObstructed", new Type[] { typeof(List), typeof(CapsuleCollider) })] private static bool LevelPointListPurgeObstructedPrefix(List _levelPoints, CapsuleCollider _capsuleCollider, ref List __result) { if ((Object)(object)_capsuleCollider != (Object)null) { return true; } __result = _levelPoints?.FindAll((LevelPoint point) => (Object)(object)point != (Object)null) ?? new List(); return false; } [HarmonyPostfix] [HarmonyPatch(typeof(Enemy), "Start")] private static void EnemyStartPostfix(Enemy __instance) { EliteRegistry.RegisterCandidate(__instance); } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyParent), "SpawnRPC")] private static void EnemyParentSpawnRpcPrefix(EnemyParent __instance) { EliteRegistry.SelectOnFirstSpawn(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyParent), "SpawnRPC")] private static void EnemyParentSpawnRpcPostfix(EnemyParent __instance) { EliteRegistry.OnSpawnComplete(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyParent), "DespawnRPC")] private static void EnemyParentDespawnRpcPostfix(EnemyParent __instance) { EliteRegistry.OnDespawn(__instance); } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyParent), "SpawnedTimerSet")] private static bool EnemyParentSpawnedTimerSetPrefix(EnemyParent __instance, float _time) { if (_time > 0f || !TestSpawnCommands.TryGetTimerDespawnProtection(__instance, out var remainingSeconds)) { return true; } __instance.SpawnedTimerReset(); __instance.SpawnedTimerPause(remainingSeconds); TestSpawnCommands.ReportBlockedTimerDespawn(__instance, remainingSeconds); return false; } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyHealth), "HurtRPC")] private static void EnemyHealthHurtRpcPostfix(EnemyHealth __instance) { if (SemiFunc.IsMasterClientOrSingleplayer()) { EliteRegistry.MarkHurt(__instance); } } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyHealth), "Heal")] private static void EnemyHealthHealPrefix(EnemyHealth __instance, int _amount) { if (_amount > 0 && GameFieldAccess.HealthCurrent(__instance) < __instance.health && SemiFunc.IsMasterClientOrSingleplayer()) { EliteRegistry.MarkRealHeal(__instance); } } [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPrefix] [HarmonyPatch(typeof(EnemyNavMeshAgent), "UpdateAgent")] private static void EnemyNavMeshAgentUpdateAgentPrefix(EnemyNavMeshAgent __instance, ref float speed, ref float acceleration) { if (!CompatibilityGuard.CommonSpeedDisabled && EliteRegistry.TryGet((Component?)(object)__instance, out EliteState state)) { float normalMoveMultiplier = EliteRegistry.GetNormalMoveMultiplier(state); speed = Mathf.Max(0.1f, speed * normalMoveMultiplier); acceleration = Mathf.Max(0f, acceleration * normalMoveMultiplier); } } [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPrefix] [HarmonyPatch(typeof(EnemyNavMeshAgent), "OverrideAgent")] private static void EnemyNavMeshAgentOverrideAgentPrefix(EnemyNavMeshAgent __instance, ref float speed, ref float acceleration) { if (!CompatibilityGuard.CommonSpeedDisabled && EliteRegistry.TryGet((Component?)(object)__instance, out EliteState state)) { float attackMoveMultiplier = EliteRegistry.GetAttackMoveMultiplier(state); speed = Mathf.Max(0.1f, speed * attackMoveMultiplier); acceleration = Mathf.Max(0f, acceleration * attackMoveMultiplier); } } [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPrefix] [HarmonyPatch(typeof(EnemyRigidbody), "OverrideFollowPosition")] private static void EnemyRigidbodyOverrideFollowPositionPrefix(EnemyRigidbody __instance, ref float speed) { if (!CompatibilityGuard.CommonSpeedDisabled && EliteRegistry.TryGet((Component?)(object)__instance, out EliteState state)) { speed = Mathf.Max(0.1f, speed * EliteRegistry.GetRigidbodyMoveMultiplier(state)); } } [HarmonyAfter(new string[] { "REPOJP.StagePhysicsEvents", "REPOJP.RoleShuffle" })] [HarmonyPrefix] [HarmonyPatch(typeof(EnemyRigidbody), "OverrideFollowRotation")] private static void EnemyRigidbodyOverrideFollowRotationPrefix(EnemyRigidbody __instance, ref float speed) { if (!CompatibilityGuard.CommonSpeedDisabled && EliteRegistry.TryGet((Component?)(object)__instance, out EliteState state)) { speed = Mathf.Max(0.1f, speed * EliteRegistry.GetRigidbodyMoveMultiplier(state)); } } } internal static class StageFluxCompatibility { internal const string PluginGuid = "REPOJP.StagePhysicsEvents"; } internal static class RoleShuffleCompatibility { internal const string PluginGuid = "REPOJP.RoleShuffle"; } internal static class CompatibilityGuard { private static readonly Dictionary ConflictingAdapters = new Dictionary { [EliteArchetype.Clown] = "REPOJP.ClownBeamTrackingEnhancements", [EliteArchetype.ShadowChild] = "REPOJP.ShadowChildEnhancements", [EliteArchetype.Huntsman] = "REPOJP.HuntsmanEyesOpened", [EliteArchetype.Gambit] = "REPOJP.GambitEnhancements", [EliteArchetype.Banger] = "REPOJP.GnomeBangerEnhancements", [EliteArchetype.Gnome] = "REPOJP.GnomeBangerEnhancements" }; private static readonly HashSet DisabledAdapters = new HashSet(); internal static bool CommonSpeedDisabled { get; private set; } internal static void Refresh(ManualLogSource logger) { DisabledAdapters.Clear(); foreach (var (eliteArchetype2, text2) in ConflictingAdapters) { if (Chainloader.PluginInfos.ContainsKey(text2)) { DisabledAdapters.Add(eliteArchetype2); logger.LogWarning((object)(EnemyDisplayNameResolver.Get(eliteArchetype2) + " adapter disabled because conflicting plugin '" + text2 + "' is loaded.")); } } CommonSpeedDisabled = Chainloader.PluginInfos.ContainsKey("REPOJP.EnemySpeedUp"); if (CommonSpeedDisabled) { logger.LogWarning((object)"Common movement multipliers disabled because REPOJP.EnemySpeedUp is loaded."); } logger.LogInfo((object)(string.Format("Stage Flux detected: {0}; ", Chainloader.PluginInfos.ContainsKey("REPOJP.StagePhysicsEvents")) + string.Format("Role Shuffle detected: {0}.", Chainloader.PluginInfos.ContainsKey("REPOJP.RoleShuffle")))); } internal static bool IsAdapterEnabled(EliteArchetype archetype) { return !DisabledAdapters.Contains(archetype); } internal static void DisableAdapter(EliteArchetype archetype, Exception exception, ManualLogSource logger) { DisabledAdapters.Add(archetype); logger.LogError((object)$"{EnemyDisplayNameResolver.Get(archetype)} adapter disabled after patch validation failed: {exception}"); } } internal sealed class EnemyChanceSettings { internal ConfigEntry Enabled { get; } internal ConfigEntry ChancePercent { get; } internal EnemyChanceSettings(ConfigFile config, string section) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown Enabled = config.Bind(section, "Enabled", true, "Enable " + section + " enhancement selection."); ChancePercent = config.Bind(section, "ChancePercent", -1f, new ConfigDescription("-1 uses the common enhanced chance.", (AcceptableValueBase)(object)new AcceptableValueRange(-1f, 100f), Array.Empty())); } } internal sealed class EliteEnemyConfig { private readonly Dictionary _expandedEnemyChances = new Dictionary(); internal ConfigEntry Enabled { get; } internal ConfigEntry VanillaEnemiesOnly { get; } internal ConfigEntry ExcludeShop { get; } internal ConfigEntry ExcludeArena { get; } internal ConfigEntry DebugLog { get; } internal ConfigEntry ConfigSchemaVersion { get; } internal ConfigEntry EnableTestCommands { get; } internal ConfigEntry TestSpawnMaxGroups { get; } internal ConfigEntry EnhancedChancePercent { get; } internal ConfigEntry MaxEnhancedPerLevel { get; } internal ConfigEntry SelectionSeed { get; } internal long SelectionSeedValue { get { if (!long.TryParse(SelectionSeed.Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) || result <= 0) { return 0L; } return result; } } internal ConfigEntry GnomeCapCountsMembers { get; } internal ConfigEntry HealthMultiplier { get; } internal ConfigEntry NavMoveMultiplier { get; } internal ConfigEntry NavAttackMoveMultiplier { get; } internal ConfigEntry RigidbodyMoveMultiplier { get; } internal ConfigEntry EnableVanillaPulse { get; } internal ConfigEntry PulseCycleSeconds { get; } internal ConfigEntry PulseGapSeconds { get; } internal ConfigEntry DelayAfterHurtSeconds { get; } internal ConfigEntry DelayAfterRealHealSeconds { get; } internal ConfigEntry BehaviorWindupRate { get; } internal ConfigEntry BehaviorCooldownRate { get; } internal ConfigEntry BehaviorChaseRetention { get; } internal EnemyChanceSettings Clown { get; } internal ConfigEntry ClownTrackSpeed { get; } internal ConfigEntry ClownBeamRange { get; } internal ConfigEntry ClownBeamDurationMin { get; } internal ConfigEntry ClownBeamDurationMax { get; } internal ConfigEntry ClownWalkWhileAttacking { get; } internal ConfigEntry ClownTargetSwitch { get; } internal ConfigEntry ClownSpinChancePercent { get; } internal ConfigEntry ClownSpinSpeedDegPerSec { get; } internal EnemyChanceSettings ShadowChild { get; } internal ConfigEntry ShadowEyeContactSeconds { get; } internal ConfigEntry ShadowApproachRadius { get; } internal ConfigEntry ShadowApproachSpeed { get; } internal EnemyChanceSettings Huntsman { get; } internal ConfigEntry HuntsmanSoundInvestigateRange { get; } internal EnemyChanceSettings Gambit { get; } internal ConfigEntry GambitRouletteDurationSeconds { get; } internal ConfigEntry GambitRouletteStunImmune { get; } internal EnemyChanceSettings Banger { get; } internal ConfigEntry BangerFuseSeconds { get; } internal ConfigEntry BangerNearTargetFuseSeconds { get; } internal ConfigEntry BangerNearTargetDistance { get; } internal ConfigEntry BangerFuseSyncIntervalSeconds { get; } internal EnemyChanceSettings Gnome { get; } internal ConfigEntry GnomeHealth { get; } internal ConfigEntry GnomeAttackOrbitSpeed { get; } internal ConfigEntry GnomeJumpMultiplier { get; } internal ConfigEntry GnomeAttackRadius { get; } internal ConfigEntry GnomeZeroNoticeDelay { get; } internal ConfigEntry GnomeZeroAttackCooldown { get; } internal ConfigEntry GnomeValuablePriorityRadius { get; } internal ConfigEntry GnomeConcurrentAttackers { get; } internal ConfigEntry OoglyLowPatrolHeight { get; } internal ConfigEntry OoglyLowPatrolIntervalSeconds { get; } internal ConfigEntry RobeUnseenMoveSpeed { get; } internal EliteEnemyConfig(ConfigFile config) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Expected O, but got Unknown //IL_06de: Unknown result type (might be due to invalid IL or missing references) //IL_06e8: Expected O, but got Unknown //IL_07cd: Unknown result type (might be due to invalid IL or missing references) //IL_07d7: Expected O, but got Unknown EliteEnemyConfigMigration.Apply(config); ConfigSchemaVersion = config.Bind("Migration", "ConfigVersion", 3, new ConfigDescription("Internal config migration schema. Do not edit manually.", (AcceptableValueBase)null, new object[1] { "HideFromREPOConfig" })); Enabled = config.Bind("General", "Enabled", true, "Master switch."); VanillaEnemiesOnly = config.Bind("General", "VanillaEnemiesOnly", true, "Only select the 29 audited vanilla enemy types."); ExcludeShop = config.Bind("General", "ExcludeShop", true, "Disable selection in shop levels."); ExcludeArena = config.Bind("General", "ExcludeArena", true, "Disable selection in arena levels."); DebugLog = config.Bind("General", "DebugLog", false, "Enable verbose diagnostic logging."); EnableTestCommands = config.Bind("Testing", "EnableTestCommands", true, "Enable host-only eevspawn and eevlist commands in the normal in-game chat."); TestSpawnMaxGroups = config.Bind("Testing", "MaxSpawnGroupsPerCommand", 10, new ConfigDescription("Maximum setup groups spawned by one command.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 50), Array.Empty())); EnhancedChancePercent = Percent(config, "Selection", "EnhancedChancePercent", 35f); MaxEnhancedPerLevel = config.Bind("Selection", "MaxEnhancedPerLevel", 3, new ConfigDescription("Maximum enhanced enemies per level.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 100), Array.Empty())); SelectionSeed = config.Bind("Selection", "SelectionSeed", "0", "Numeric text. 0, negative, or invalid values use a fresh per-stage seed; positive 64-bit values are reproducible."); GnomeCapCountsMembers = config.Bind("Selection", "GnomeCapCountsMembers", true, "Count every Gnome member against the enhanced cap."); HealthMultiplier = Multiplier(config, "Common", "HealthMultiplier", 1.5f); NavMoveMultiplier = Multiplier(config, "Common", "NavMoveMultiplier", 1.15f); NavAttackMoveMultiplier = Multiplier(config, "Common", "NavAttackMoveMultiplier", 1.2f); RigidbodyMoveMultiplier = Multiplier(config, "Common", "RigidbodyMoveMultiplier", 1.15f); EnableVanillaPulse = config.Bind("Visual", "EnableVanillaPulse", true, "Use two vanilla green heal flashes to identify enhanced enemies."); PulseCycleSeconds = Seconds(config, "Visual", "PulseCycleSeconds", 2.5f, 0.5f, 30f); PulseGapSeconds = Seconds(config, "Visual", "PulseGapSeconds", 0.22f, 0.05f, 1f); DelayAfterHurtSeconds = Seconds(config, "Visual", "DelayAfterHurtSeconds", 0.8f, 0f, 10f); DelayAfterRealHealSeconds = Seconds(config, "Visual", "DelayAfterRealHealSeconds", 0.8f, 0f, 10f); BehaviorWindupRate = Multiplier(config, "Behavior", "WindupRate", 1.35f); BehaviorCooldownRate = Multiplier(config, "Behavior", "CooldownRate", 1.3f); BehaviorChaseRetention = Number(config, "Behavior", "ChaseRetention", 0.25f, 0f, 0.95f); AddExpandedChance(config, EliteArchetype.Animal); AddExpandedChance(config, EliteArchetype.BirthdayBoy); AddExpandedChance(config, EliteArchetype.CleanupCrew); AddExpandedChance(config, EliteArchetype.Bowtie); AddExpandedChance(config, EliteArchetype.Peeper); AddExpandedChance(config, EliteArchetype.ApexPredator); AddExpandedChance(config, EliteArchetype.Elsa); AddExpandedChance(config, EliteArchetype.Mentalist); AddExpandedChance(config, EliteArchetype.Headman); AddExpandedChance(config, EliteArchetype.Headgrab); AddExpandedChance(config, EliteArchetype.HeartHugger); AddExpandedChance(config, EliteArchetype.Hidden); AddExpandedChance(config, EliteArchetype.Oogly); AddExpandedChance(config, EliteArchetype.Robe); AddExpandedChance(config, EliteArchetype.Reaper); AddExpandedChance(config, EliteArchetype.Loom); AddExpandedChance(config, EliteArchetype.Spewer); AddExpandedChance(config, EliteArchetype.Trudge); AddExpandedChance(config, EliteArchetype.Tick); AddExpandedChance(config, EliteArchetype.Bella); AddExpandedChance(config, EliteArchetype.Chef); AddExpandedChance(config, EliteArchetype.Upscream); AddExpandedChance(config, EliteArchetype.Rugrat); Clown = new EnemyChanceSettings(config, "Clown"); ClownTrackSpeed = Number(config, "Clown", "TrackSpeed", 15f, 1f, 300f); ClownBeamRange = Number(config, "Clown", "BeamRange", 10f, 1f, 100f); ClownBeamDurationMin = Seconds(config, "Clown", "BeamDurationMin", 1f, 0.1f, 30f); ClownBeamDurationMax = Seconds(config, "Clown", "BeamDurationMax", 2f, 0.1f, 30f); ClownWalkWhileAttacking = config.Bind("Clown", "WalkWhileAttacking", true, "Move toward the current target while beaming."); ClownTargetSwitch = config.Bind("Clown", "TargetSwitch", true, "Allow one target switch per attack."); ClownSpinChancePercent = Percent(config, "Clown", "SpinChancePercent", 10f); ClownSpinSpeedDegPerSec = Number(config, "Clown", "SpinSpeedDegPerSec", 300f, 30f, 3000f); ShadowChild = new EnemyChanceSettings(config, "Shadow Child"); ShadowEyeContactSeconds = Seconds(config, "Shadow Child", "EyeContactSeconds", 3f, 0.2f, 30f); ShadowApproachRadius = Number(config, "Shadow Child", "ApproachRadius", 50f, 1f, 200f); ShadowApproachSpeed = Number(config, "Shadow Child", "ApproachSpeed", 4f, 0.1f, 30f); Huntsman = new EnemyChanceSettings(config, "Huntsman"); HuntsmanSoundInvestigateRange = Number(config, "Huntsman", "SoundInvestigateRange", 45f, 1f, 500f); Gambit = new EnemyChanceSettings(config, "Gambit"); GambitRouletteDurationSeconds = Seconds(config, "Gambit", "RouletteDurationSeconds", 5f, 1f, 30f); GambitRouletteStunImmune = config.Bind("Gambit", "RouletteStunImmune", true, "Ignore stun only while roulette is active."); Banger = new EnemyChanceSettings(config, "Banger"); BangerFuseSeconds = Seconds(config, "Banger", "FuseSeconds", 5f, 0.5f, 30f); BangerNearTargetFuseSeconds = Seconds(config, "Banger", "NearTargetFuseSeconds", 3.5f, 0.5f, 30f); BangerNearTargetDistance = Number(config, "Banger", "NearTargetDistance", 6f, 0.5f, 50f); BangerFuseSyncIntervalSeconds = Seconds(config, "Banger", "FuseSyncIntervalSeconds", 0.5f, 0.1f, 5f); Gnome = new EnemyChanceSettings(config, "Gnome"); GnomeHealth = config.Bind("Gnome", "Health", 25, new ConfigDescription("Enhanced Gnome health.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 10000), Array.Empty())); GnomeAttackOrbitSpeed = Number(config, "Gnome", "AttackOrbitSpeed", 4f, 0.1f, 30f); GnomeJumpMultiplier = Multiplier(config, "Gnome", "JumpMultiplier", 1.5f); GnomeAttackRadius = Number(config, "Gnome", "AttackRadius", 1.1f, 0.1f, 10f); GnomeZeroNoticeDelay = config.Bind("Gnome", "ZeroNoticeDelay", true, "Remove the enhanced group's notice delay."); GnomeZeroAttackCooldown = config.Bind("Gnome", "ZeroAttackCooldown", true, "Remove the enhanced group's re-attack cooldown."); GnomeValuablePriorityRadius = Number(config, "Gnome", "ValuablePriorityRadius", 5f, 0f, 50f); GnomeConcurrentAttackers = config.Bind("Gnome", "ConcurrentAttackers", 2, new ConfigDescription("Maximum simultaneous enhanced Gnome attackers.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 8), Array.Empty())); OoglyLowPatrolHeight = Number(config, "Oogly", "LowPatrolHeight", 1f, 0.5f, 4f); OoglyLowPatrolIntervalSeconds = Seconds(config, "Oogly", "LowPatrolIntervalSeconds", 10f, 3f, 60f); RobeUnseenMoveSpeed = Number(config, "Robe", "UnseenMoveSpeed", 8f, 1f, 25f); config.Save(); } internal EnemyChanceSettings ChanceFor(EliteArchetype archetype) { if (_expandedEnemyChances.TryGetValue(archetype, out EnemyChanceSettings value)) { return value; } return archetype switch { EliteArchetype.Clown => Clown, EliteArchetype.ShadowChild => ShadowChild, EliteArchetype.Huntsman => Huntsman, EliteArchetype.Gambit => Gambit, EliteArchetype.Banger => Banger, EliteArchetype.Gnome => Gnome, _ => Clown, }; } private void AddExpandedChance(ConfigFile config, EliteArchetype archetype) { _expandedEnemyChances.Add(archetype, new EnemyChanceSettings(config, EnemyDisplayNameResolver.Get(archetype))); } private static ConfigEntry Percent(ConfigFile config, string section, string key, float value) { return Number(config, section, key, value, 0f, 100f); } private static ConfigEntry Multiplier(ConfigFile config, string section, string key, float value) { return Number(config, section, key, value, 0.1f, 10f); } private static ConfigEntry Seconds(ConfigFile config, string section, string key, float value, float min, float max) { return Number(config, section, key, value, min, max); } private static ConfigEntry Number(ConfigFile config, string section, string key, float value, float min, float max) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown return config.Bind(section, key, value, new ConfigDescription(key, (AcceptableValueBase)(object)new AcceptableValueRange(min, max), Array.Empty())); } } internal static class EliteEnemyConfigMigration { internal const int CurrentSchemaVersion = 3; private static readonly string[] EnemySections = new string[29] { "Animal", "Birthday Boy", "Cleanup Crew", "Bowtie", "Peeper", "Apex Predator", "Elsa", "Mentalist", "Headman", "Headgrab", "Heart Hugger", "Hidden", "Oogly", "Robe", "Reaper", "Loom", "Spewer", "Trudge", "Tick", "Bella", "Chef", "Upscream", "Rugrat", "Clown", "Shadow Child", "Huntsman", "Gambit", "Banger", "Gnome" }; private static readonly ConfigDefinition SchemaDefinition = new ConfigDefinition("Migration", "ConfigVersion"); internal static void Apply(ConfigFile config) { string configFilePath = config.ConfigFilePath; string text = configFilePath + ".elite-enemy-variants.tmp"; try { Dictionary dictionary = ReadValues(configFilePath); if (dictionary.Count == 0 && !File.Exists(configFilePath)) { return; } int num = ReadSchemaVersion(dictionary); if (num > 3) { EliteEnemyVariantsPlugin.ModLogger.LogWarning((object)($"Config schema {num} is newer than supported schema " + $"{3}; values were loaded without migration.")); return; } int num2 = 0; if (num < 2) { num2 += TransferIfMissing(dictionary, "Huntsman", "ApexSightDistance", "Huntsman", "ApexFollowUpMaxDistance"); } if (num < 3) { num2 += MergeTierChances(dictionary, "Selection", "EnhancedChancePercent", 32f, 3f); string[] enemySections = EnemySections; foreach (string section in enemySections) { num2 += MergeTierChances(dictionary, section, "ChancePercent", -1f, -1f); } num2 += TransferIfMissing(dictionary, "Banger", "ApexNearTargetFuseSeconds", "Banger", "NearTargetFuseSeconds"); num2 += TransferIfMissing(dictionary, "Banger", "ApexNearTargetDistance", "Banger", "NearTargetDistance"); num2 += TransferIfMissing(dictionary, "Gnome", "ApexConcurrentAttackers", "Gnome", "ConcurrentAttackers"); RemoveObsoleteTierSettings(dictionary); } bool num3 = num != 3; dictionary[SchemaDefinition] = 3.ToString(CultureInfo.InvariantCulture); if (!num3 && num2 == 0) { return; } if (File.Exists(configFilePath) && dictionary.Count > 1) { string text2 = configFilePath + $".pre-schema-{3}.bak"; if (!File.Exists(text2)) { File.Copy(configFilePath, text2, overwrite: false); } } WriteValues(text, dictionary); File.Copy(text, configFilePath, overwrite: true); File.Delete(text); config.Reload(); EliteEnemyVariantsPlugin.ModLogger.LogInfo((object)($"Config migrated from schema {num} to {3}; " + $"{num2} renamed value(s) transferred and all existing values retained.")); } catch (Exception arg) { TryDelete(text); EliteEnemyVariantsPlugin.ModLogger.LogWarning((object)$"Config migration was skipped and the original file was retained: {arg}"); } } internal static int TransferIfMissing(IDictionary values, string oldSection, string oldKey, string newSection, string newKey) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown ConfigDefinition key = new ConfigDefinition(oldSection, oldKey); ConfigDefinition key2 = new ConfigDefinition(newSection, newKey); if (!values.TryGetValue(key, out string value) || values.ContainsKey(key2)) { return 0; } values[key2] = value; return 1; } private static int MergeTierChances(IDictionary values, string section, string newKey, float defaultElite, float defaultApex) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown ConfigDefinition key = new ConfigDefinition(section, newKey); if (values.ContainsKey(key)) { return 0; } float num = ReadFloat(values, section, "EliteChancePercent", defaultElite); float num2 = ReadFloat(values, section, "ApexChancePercent", defaultApex); values[key] = ((num < 0f && num2 < 0f) ? (-1f) : Math.Min(100f, Math.Max(0f, num) + Math.Max(0f, num2))).ToString(CultureInfo.InvariantCulture); return 1; } private static float ReadFloat(IDictionary values, string section, string key, float fallback) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown if (!values.TryGetValue(new ConfigDefinition(section, key), out string value) || !float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return fallback; } return result; } private static void RemoveObsoleteTierSettings(IDictionary values) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Expected O, but got Unknown values.Remove(new ConfigDefinition("Selection", "EliteChancePercent")); values.Remove(new ConfigDefinition("Selection", "ApexChancePercent")); values.Remove(new ConfigDefinition("Selection", "MaxApexPerLevel")); string[] enemySections = EnemySections; foreach (string text in enemySections) { values.Remove(new ConfigDefinition(text, "EliteChancePercent")); values.Remove(new ConfigDefinition(text, "ApexChancePercent")); } enemySections = new string[33] { "Apex|HealthMultiplier", "Apex|NavMoveMultiplier", "Apex|NavAttackMoveMultiplier", "Apex|RigidbodyMoveMultiplier", "Visual|ApexPulseCycleSeconds", "Visual|ApexPulseGapSeconds", "Behavior|ApexWindupRate", "Behavior|ApexCooldownRate", "Behavior|ApexChaseRetention", "Clown|ApexTrackSpeed", "Clown|ApexBeamRange", "Clown|ApexBeamDurationMin", "Clown|ApexBeamDurationMax", "Clown|ApexSpinChancePercent", "Shadow Child|ApexEyeContactSeconds", "Shadow Child|ApexApproachSpeed", "Shadow Child|ApexRememberedTargets", "Huntsman|ApexFollowUpMaxDistance", "Huntsman|ApexBurstShots", "Huntsman|ApexBurstGapSeconds", "Huntsman|ApexLeadSeconds", "Gambit|ApexEscapeWaypoints", "Gambit|ApexAttackMoveMultiplier", "Gambit|ApexMaxCarrySeconds", "Gambit|ReleaseGrabDistance", "Gambit|PersistCarryToGoal", "Banger|ApexNearTargetFuseSeconds", "Banger|ApexNearTargetDistance", "Gnome|ApexHealth", "Gnome|ApexAttackOrbitSpeed", "Gnome|ApexJumpMultiplier", "Gnome|ApexAttackRadius", "Gnome|ApexConcurrentAttackers" }; for (int i = 0; i < enemySections.Length; i++) { string[] array = enemySections[i].Split('|'); values.Remove(new ConfigDefinition(array[0], array[1])); } } private static Dictionary ReadValues(string path) { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown Dictionary dictionary = new Dictionary(); if (!File.Exists(path)) { return dictionary; } string text = string.Empty; string[] array = File.ReadAllLines(path); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.Length == 0 || text2.StartsWith("#", StringComparison.Ordinal)) { continue; } if (text2.StartsWith("[", StringComparison.Ordinal) && text2.EndsWith("]", StringComparison.Ordinal)) { text = text2.Substring(1, text2.Length - 2); continue; } int num = text2.IndexOf('='); if (num > 0) { string text3 = text2.Substring(0, num).Trim(); string value = text2.Substring(num + 1).Trim(); dictionary[new ConfigDefinition(text, text3)] = value; } } return dictionary; } private static int ReadSchemaVersion(IReadOnlyDictionary values) { if (!values.TryGetValue(SchemaDefinition, out string value) || !int.TryParse(value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return 0; } return Math.Max(0, result); } private static void WriteValues(string path, IReadOnlyDictionary values) { List list = new List { $"## EliteEnemyVariants configuration schema {3}", "## Existing and unknown settings are retained during migration.", string.Empty }; foreach (IGrouping> item in from pair in values.OrderBy, string>((KeyValuePair pair) => pair.Key.Section, StringComparer.Ordinal).ThenBy, string>((KeyValuePair pair) => pair.Key.Key, StringComparer.Ordinal) group pair by pair.Key.Section) { list.Add("[" + item.Key + "]"); list.Add(string.Empty); foreach (KeyValuePair item2 in item) { list.Add(item2.Key.Key + " = " + item2.Value); } list.Add(string.Empty); } File.WriteAllLines(path, list, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); } private static void TryDelete(string path) { try { if (File.Exists(path)) { File.Delete(path); } } catch { } } } [BepInPlugin("REPOJP.EliteEnemyVariants", "Elite Enemy Variants", "4.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class EliteEnemyVariantsPlugin : BaseUnityPlugin { public const string PluginGuid = "REPOJP.EliteEnemyVariants"; public const string PluginName = "Elite Enemy Variants"; public const string PluginVersion = "4.0.0"; public const string RepoConfigGuid = "nickklmao.repoconfig"; private Harmony? _harmony; private readonly List _adapterHarmonies = new List(); private GameObject? _runtimeObject; internal static EliteEnemyVariantsPlugin Instance { get; private set; } internal static ManualLogSource ModLogger { get; private set; } internal EliteEnemyConfig Settings { get; private set; } internal EliteRuntimeController Runtime { get; private set; } private void Awake() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown Instance = this; ModLogger = ((BaseUnityPlugin)this).Logger; Settings = new EliteEnemyConfig(((BaseUnityPlugin)this).Config); SelectionInvariantChecks.Run(); CompatibilityGuard.Refresh(((BaseUnityPlugin)this).Logger); ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); _runtimeObject = new GameObject("EliteEnemyVariants_Runtime"); ((Object)_runtimeObject).hideFlags = (HideFlags)61; _runtimeObject.transform.SetParent(((Component)this).transform, false); Runtime = _runtimeObject.AddComponent(); Runtime.Initialize(Settings); _harmony = new Harmony("REPOJP.EliteEnemyVariants"); try { _harmony.PatchAll(typeof(CommonEnemyPatches)); _harmony.PatchAll(typeof(LifecyclePatches)); _harmony.PatchAll(typeof(TestCommandChatResponsePatch)); ApplyAdapterPatch(EliteArchetype.Animal, typeof(AnimalElitePatches)); ApplyAdapterPatch(EliteArchetype.BirthdayBoy, typeof(BirthdayBoyElitePatches)); ApplyAdapterPatch(EliteArchetype.CleanupCrew, typeof(CleanupCrewElitePatches)); ApplyAdapterPatch(EliteArchetype.Bowtie, typeof(BowtieElitePatches)); ApplyAdapterPatch(EliteArchetype.Peeper, typeof(PeeperElitePatches)); ApplyAdapterPatch(EliteArchetype.ApexPredator, typeof(ApexPredatorElitePatches)); ApplyAdapterPatch(EliteArchetype.Elsa, typeof(ElsaElitePatches)); ApplyAdapterPatch(EliteArchetype.Mentalist, typeof(MentalistElitePatches)); ApplyAdapterPatch(EliteArchetype.Headman, typeof(HeadmanElitePatches)); ApplyAdapterPatch(EliteArchetype.Headgrab, typeof(HeadgrabElitePatches)); ApplyAdapterPatch(EliteArchetype.HeartHugger, typeof(HeartHuggerElitePatches)); ApplyAdapterPatch(EliteArchetype.Hidden, typeof(HiddenElitePatches)); ApplyAdapterPatch(EliteArchetype.Oogly, typeof(OoglyElitePatches)); ApplyAdapterPatch(EliteArchetype.Robe, typeof(RobeElitePatches)); ApplyAdapterPatch(EliteArchetype.Reaper, typeof(ReaperElitePatches)); ApplyAdapterPatch(EliteArchetype.Loom, typeof(LoomElitePatches)); ApplyAdapterPatch(EliteArchetype.Spewer, typeof(SpewerElitePatches)); ApplyAdapterPatch(EliteArchetype.Trudge, typeof(TrudgeElitePatches)); ApplyAdapterPatch(EliteArchetype.Tick, typeof(TickElitePatches)); ApplyAdapterPatch(EliteArchetype.Bella, typeof(BellaElitePatches)); ApplyAdapterPatch(EliteArchetype.Chef, typeof(ChefElitePatches)); ApplyAdapterPatch(EliteArchetype.Upscream, typeof(UpscreamElitePatches)); ApplyAdapterPatch(EliteArchetype.Rugrat, typeof(RugratElitePatches)); ApplyAdapterPatch(EliteArchetype.Clown, typeof(ClownElitePatches)); ApplyAdapterPatch(EliteArchetype.ShadowChild, typeof(ShadowChildElitePatches)); ApplyAdapterPatch(EliteArchetype.Huntsman, typeof(HuntsmanElitePatches)); ApplyAdapterPatch(EliteArchetype.Gambit, typeof(GambitElitePatches)); ApplyAdapterPatch(EliteArchetype.Banger, typeof(BangerElitePatches)); ApplyAdapterPatch(EliteArchetype.Gnome, typeof(GnomeElitePatches)); SceneManager.activeSceneChanged += ActiveSceneChanged; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Elite Enemy Variants v4.0.0 loaded. Host-only gameplay mode enabled."); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Failed to apply Harmony patches: {arg}"); _harmony.UnpatchSelf(); ((Behaviour)Runtime).enabled = false; } } private void OnDestroy() { SceneManager.activeSceneChanged -= ActiveSceneChanged; Runtime?.Shutdown(); Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } foreach (Harmony adapterHarmony in _adapterHarmonies) { adapterHarmony.UnpatchSelf(); } _adapterHarmonies.Clear(); if ((Object)(object)_runtimeObject != (Object)null) { Object.Destroy((Object)(object)_runtimeObject); } } private static void ActiveSceneChanged(Scene previous, Scene current) { EliteRegistry.ClearStage(); } private void ApplyAdapterPatch(EliteArchetype archetype, Type patchType) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown if (!CompatibilityGuard.IsAdapterEnabled(archetype)) { return; } Harmony val = new Harmony(string.Format("{0}.{1}", "REPOJP.EliteEnemyVariants", archetype)); try { AdapterPatchValidator.Validate(archetype); val.PatchAll(patchType); _adapterHarmonies.Add(val); } catch (Exception exception) { val.UnpatchSelf(); CompatibilityGuard.DisableAdapter(archetype, exception, ((BaseUnityPlugin)this).Logger); } } } internal enum EliteArchetype { Animal, BirthdayBoy, CleanupCrew, Bowtie, Peeper, ApexPredator, Elsa, Mentalist, Headman, Headgrab, HeartHugger, Hidden, Oogly, Robe, Reaper, Loom, Spewer, Trudge, Tick, Bella, Chef, Upscream, Rugrat, Clown, ShadowChild, Huntsman, Gambit, Banger, Gnome } internal enum EnhancementTier { Normal, Enhanced } internal readonly struct SelectionPolicy { internal readonly float EnhancedChancePercent; internal readonly int MaxEnhancedPerLevel; internal SelectionPolicy(float enhancedChancePercent, int maxEnhancedPerLevel) { EnhancedChancePercent = enhancedChancePercent; MaxEnhancedPerLevel = maxEnhancedPerLevel; } } internal readonly struct SelectionCandidate { internal readonly int Key; internal readonly EliteArchetype Archetype; internal readonly bool Enabled; internal readonly int CapCost; internal SelectionCandidate(int key, EliteArchetype archetype, bool enabled, int capCost = 1) { Key = key; Archetype = archetype; Enabled = enabled; CapCost = capCost; } } internal readonly struct SelectionCounters { internal readonly int Enhanced; internal SelectionCounters(int enhanced) { Enhanced = enhanced; } } internal sealed class EliteState { internal int Key; internal Enemy Enemy; internal EliteArchetype Archetype; internal EnhancementTier Tier; internal bool Selected; internal bool Spawned; internal int BaseHealth; internal float LastHurtAt = float.NegativeInfinity; internal float LastRealHealAt = float.NegativeInfinity; internal float NextPulseAt; internal float NextPulseCycleAt; internal int PulsePart; internal object? AdapterState; internal bool AdapterTickFaulted; internal bool IsEnhanced => Tier != EnhancementTier.Normal; } internal sealed class ClownRuntimeState { internal bool AttackInitialized; internal bool TargetSwitched; internal bool SpinChecked; internal bool Spinning; internal float SpinRemaining; internal float SpinYaw; internal Vector3 LastTargetPosition; } internal sealed class ShadowChildRuntimeState { internal float LookAccumulation; internal Vector3 LastPosition; internal float StuckTimer; internal int LastTargetViewId; internal int PreviousTargetViewId; internal int PreviousState = -1; } internal sealed class HuntsmanRuntimeState { internal bool PendingInvestigate; internal Vector3 PendingInvestigatePoint; internal bool PendingInvestigatePathfindOnly; internal bool AccuracyRolled; internal bool MissThisShot; internal float MissYaw; internal float MissPitch; internal Vector3 MissImpactPoint; } internal sealed class GambitRuntimeState { internal bool EscapeActive; internal Vector3 EscapePoint; internal float StuckTimer; internal Vector3 LastPosition; internal int EscapeAttempt; } internal sealed class BangerRuntimeState { internal float FuseStartedAt; internal float LastSyncAt; internal bool PreviousFuseActive; } internal sealed class GnomeRuntimeState { internal bool StatsApplied; } internal sealed class DedicatedEnemyRuntimeState { internal bool SpawnInitialized; internal int PreviousState = -1; internal bool ExtraActionUsed; internal float StuckTimer; internal Vector3 LastPosition; internal int LastTargetViewId; internal float NextActionAt; internal bool AlternateMode; } internal static class EliteRegistry { private static readonly Dictionary StatesByEnemy = new Dictionary(); private static readonly Dictionary GnomeGroupTiers = new Dictionary(); private static readonly List StateSnapshot = new List(); private static ulong _stageSeed; private static int _stageOrdinal; private static int _enhancedCount; private static bool _stageSeedReady; internal static IReadOnlyList States { get { StateSnapshot.Clear(); StateSnapshot.AddRange(StatesByEnemy.Values); return StateSnapshot; } } internal static void BeginStage() { if (!_stageSeedReady) { _stageOrdinal++; _stageSeed = SelectionRollSource.CreateStageSeed(EliteEnemyVariantsPlugin.Instance.Settings.SelectionSeedValue, _stageOrdinal); _stageSeedReady = true; DebugLog($"Stage selection seed initialized: {_stageSeed}."); } } internal static void RegisterCandidate(Enemy enemy) { if (IsHostEnabled() && !((Object)(object)enemy == (Object)null) && !StatesByEnemy.ContainsKey(((Object)enemy).GetInstanceID()) && EnemyDisplayNameResolver.TryResolve(enemy, out var archetype)) { int selectionKey = GetSelectionKey(enemy, archetype); EliteState eliteState = new EliteState { Key = selectionKey, Enemy = enemy, Archetype = archetype, Tier = EnhancementTier.Normal, BaseHealth = ((!GameFieldAccess.HasHealth(enemy)) ? 1 : Math.Max(1, GameFieldAccess.Health(enemy).health)) }; StatesByEnemy.Add(((Object)enemy).GetInstanceID(), eliteState); if (archetype == EliteArchetype.Gnome && GnomeGroupTiers.TryGetValue(selectionKey, out var value)) { eliteState.Selected = true; eliteState.Tier = value; PrepareHealth(eliteState); } } } internal static void SelectOnFirstSpawn(EnemyParent parent) { if (!IsHostEnabled() || !IsEligibleLevel() || (Object)(object)parent == (Object)null) { return; } Enemy componentInChildren = ((Component)parent).GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { return; } RegisterCandidate(componentInChildren); if (!StatesByEnemy.TryGetValue(((Object)componentInChildren).GetInstanceID(), out EliteState state)) { return; } if (state.Archetype == EliteArchetype.Gnome && (Object)(object)EnemyGnomeDirector.instance != (Object)null) { state.Key = int.MinValue ^ ((Object)EnemyGnomeDirector.instance).GetInstanceID(); if (!state.Selected && GnomeGroupTiers.TryGetValue(state.Key, out var value)) { state.Selected = true; state.Tier = value; } } if (state.Selected) { PrepareHealth(state); return; } if (!_stageSeedReady) { BeginStage(); } EliteEnemyConfig settings = EliteEnemyVariantsPlugin.Instance.Settings; EnemyChanceSettings enemyChanceSettings = settings.ChanceFor(state.Archetype); float enhancedChancePercent = ((enemyChanceSettings.ChancePercent.Value < 0f) ? settings.EnhancedChancePercent.Value : enemyChanceSettings.ChancePercent.Value); bool enabled = enemyChanceSettings.Enabled.Value && CompatibilityGuard.IsAdapterEnabled(state.Archetype); int num = ((state.Archetype != EliteArchetype.Gnome || !settings.GnomeCapCountsMembers.Value) ? 1 : Math.Max(1, CountGnomeMembers())); EnhancementTier enhancementTier = EliteSelector.SelectTier(new SelectionCandidate(state.Key, state.Archetype, enabled, num), new SelectionPolicy(enhancedChancePercent, settings.MaxEnhancedPerLevel.Value), new SelectionCounters(_enhancedCount), _stageSeed); if (state.Archetype == EliteArchetype.Gnome) { GnomeGroupTiers[state.Key] = enhancementTier; foreach (EliteState item in StatesByEnemy.Values.Where((EliteState item) => item.Archetype == EliteArchetype.Gnome && item.Key == state.Key)) { item.Selected = true; item.Tier = enhancementTier; PrepareHealth(item); } } else { state.Selected = true; state.Tier = enhancementTier; PrepareHealth(state); } if (enhancementTier != EnhancementTier.Normal) { _enhancedCount += num; } DebugLog($"Selected {EnemyDisplayNameResolver.Get(state.Archetype)} key={state.Key}: {enhancementTier}; " + $"enhanced={_enhancedCount}."); } internal static void OnSpawnComplete(EnemyParent parent) { if (!IsHostEnabled() || (Object)(object)parent == (Object)null) { return; } Enemy componentInChildren = ((Component)parent).GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null || !StatesByEnemy.TryGetValue(((Object)componentInChildren).GetInstanceID(), out EliteState value) || !value.IsEnhanced) { return; } value.Spawned = true; value.PulsePart = 0; value.NextPulseAt = Time.time; value.NextPulseCycleAt = Time.time + GetPulseCycle(value); value.AdapterTickFaulted = false; try { EnemyAdapterRuntime.OnSpawn(value); } catch (Exception arg) { value.AdapterTickFaulted = true; EliteEnemyVariantsPlugin.ModLogger.LogError((object)("Disabled enhanced behavior for " + EnemyDisplayNameResolver.Get(value.Archetype) + " " + $"until its next spawn because OnSpawn failed: {arg}")); } } internal static bool ForceTierForTest(Enemy enemy, EnhancementTier tier) { if (!IsHostEnabled() || (Object)(object)enemy == (Object)null) { return false; } RegisterCandidate(enemy); if (!StatesByEnemy.TryGetValue(((Object)enemy).GetInstanceID(), out EliteState state)) { return false; } state.Selected = true; state.Tier = tier; if (state.Archetype == EliteArchetype.Gnome) { state.Key = GetSelectionKey(enemy, state.Archetype); GnomeGroupTiers[state.Key] = tier; foreach (EliteState item in StatesByEnemy.Values.Where((EliteState item) => item.Archetype == EliteArchetype.Gnome && item.Key == state.Key)) { item.Selected = true; item.Tier = tier; PrepareHealth(item); } } else { PrepareHealth(state); } DebugLog($"Test command forced {EnemyDisplayNameResolver.Get(state.Archetype)} key={state.Key}: {tier}."); return true; } internal static void OnDespawn(EnemyParent parent) { if (!((Object)(object)parent == (Object)null)) { Enemy componentInChildren = ((Component)parent).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null && StatesByEnemy.TryGetValue(((Object)componentInChildren).GetInstanceID(), out EliteState value)) { value.Spawned = false; value.PulsePart = 0; EnemyAdapterRuntime.Cleanup(value); } } } internal static void MarkHurt(EnemyHealth health) { if (TryGet((Component?)(object)health, out EliteState state)) { state.LastHurtAt = Time.time; } } internal static void MarkRealHeal(EnemyHealth health) { if (TryGet((Component?)(object)health, out EliteState state)) { state.LastRealHealAt = Time.time; } } internal static bool TryGet(Enemy? enemy, out EliteState state) { if ((Object)(object)enemy != (Object)null && StatesByEnemy.TryGetValue(((Object)enemy).GetInstanceID(), out state)) { return state.IsEnhanced; } state = null; return false; } internal static bool TryGet(Component? component, out EliteState state) { Enemy val = (((Object)(object)component != (Object)null) ? component.GetComponent() : null); if (val == null) { val = (((Object)(object)component != (Object)null) ? component.GetComponentInParent() : null); } return TryGet(val, out state); } internal static bool IsEnhanced(Enemy? enemy) { EliteState state; return TryGet(enemy, out state); } internal static float GetNormalMoveMultiplier(EliteState state) { return EliteEnemyVariantsPlugin.Instance.Settings.NavMoveMultiplier.Value; } internal static float GetAttackMoveMultiplier(EliteState state) { return EliteEnemyVariantsPlugin.Instance.Settings.NavAttackMoveMultiplier.Value; } internal static float GetRigidbodyMoveMultiplier(EliteState state) { return EliteEnemyVariantsPlugin.Instance.Settings.RigidbodyMoveMultiplier.Value; } internal static void ClearStage() { foreach (EliteState value in StatesByEnemy.Values) { EnemyAdapterRuntime.Cleanup(value); } StatesByEnemy.Clear(); GnomeGroupTiers.Clear(); StateSnapshot.Clear(); TestSpawnCommands.ClearStage(); _enhancedCount = 0; _stageSeedReady = false; } private static void PrepareHealth(EliteState state) { if (GameFieldAccess.HasHealth(state.Enemy) && state.Tier != EnhancementTier.Normal) { EliteEnemyConfig settings = EliteEnemyVariantsPlugin.Instance.Settings; int health; if (state.Archetype == EliteArchetype.Gnome) { health = settings.GnomeHealth.Value; } else { float value = settings.HealthMultiplier.Value; health = Mathf.Max(1, Mathf.RoundToInt((float)state.BaseHealth * value)); } GameFieldAccess.Health(state.Enemy).health = health; } } private static int GetSelectionKey(Enemy enemy, EliteArchetype archetype) { if (archetype == EliteArchetype.Gnome && (Object)(object)EnemyGnomeDirector.instance != (Object)null) { return int.MinValue ^ ((Object)EnemyGnomeDirector.instance).GetInstanceID(); } PhotonView val = GameFieldAccess.PhotonView(enemy); if (GameManager.Multiplayer() && (Object)(object)val != (Object)null && val.ViewID != 0) { return val.ViewID; } return -1 - ((Object)enemy).GetInstanceID(); } private static int CountGnomeMembers() { return EnemyGnomeDirector.instance?.gnomes?.Count((EnemyGnome item) => (Object)(object)item != (Object)null) ?? 1; } private static bool IsEligibleLevel() { EliteEnemyConfig settings = EliteEnemyVariantsPlugin.Instance.Settings; if (settings.ExcludeShop.Value && SemiFunc.RunIsShop()) { return false; } if (settings.ExcludeArena.Value && SemiFunc.RunIsArena()) { return false; } if (!SemiFunc.RunIsLobby()) { return !SemiFunc.RunIsLobbyMenu(); } return false; } private static bool IsHostEnabled() { if ((Object)(object)EliteEnemyVariantsPlugin.Instance != (Object)null && EliteEnemyVariantsPlugin.Instance.Settings.Enabled.Value) { return SemiFunc.IsMasterClientOrSingleplayer(); } return false; } private static float GetPulseCycle(EliteState state) { return EliteEnemyVariantsPlugin.Instance.Settings.PulseCycleSeconds.Value; } private static void DebugLog(string message) { if (EliteEnemyVariantsPlugin.Instance.Settings.DebugLog.Value) { EliteEnemyVariantsPlugin.ModLogger.LogInfo((object)message); } } } internal sealed class EliteRuntimeController : MonoBehaviour { private EliteEnemyConfig _config; internal void Initialize(EliteEnemyConfig config) { _config = config; } internal void Shutdown() { EliteRegistry.ClearStage(); } private void Update() { TestSpawnCommands.Tick(); if (!_config.Enabled.Value || !SemiFunc.IsMasterClientOrSingleplayer()) { return; } foreach (EliteState state in EliteRegistry.States) { if ((Object)(object)state.Enemy == (Object)null || !state.Spawned) { continue; } if (!state.AdapterTickFaulted) { try { EnemyAdapterRuntime.Tick(state); } catch (Exception arg) { state.AdapterTickFaulted = true; EliteEnemyVariantsPlugin.ModLogger.LogError((object)("Disabled enhanced behavior for " + EnemyDisplayNameResolver.Get(state.Archetype) + " " + $"until its next spawn because Tick failed: {arg}")); } } TickPulse(state); } } private void TickPulse(EliteState state) { if (!_config.EnableVanillaPulse.Value || !state.IsEnhanced || (Object)(object)state.Enemy == (Object)null || !GameFieldAccess.HasHealth(state.Enemy)) { return; } EnemyHealth val = GameFieldAccess.Health(state.Enemy); EnemyParent val2 = GameFieldAccess.Parent(state.Enemy); if ((Object)(object)val == (Object)null || GameFieldAccess.IsDead(val) || (Object)(object)val2 == (Object)null || !GameFieldAccess.ParentSpawned(val2)) { return; } float num = Mathf.Max(state.LastHurtAt + _config.DelayAfterHurtSeconds.Value, state.LastRealHealAt + _config.DelayAfterRealHealSeconds.Value); if (Time.time < num) { state.NextPulseAt = Mathf.Max(state.NextPulseAt, num); state.NextPulseCycleAt = Mathf.Max(state.NextPulseCycleAt, num); } else { if (Time.time < state.NextPulseAt) { return; } SendHealFlash(state.Enemy); float value = _config.PulseGapSeconds.Value; float value2 = _config.PulseCycleSeconds.Value; state.PulsePart++; if (state.PulsePart < 2) { state.NextPulseAt = Time.time + value; return; } state.PulsePart = 0; while (state.NextPulseCycleAt <= Time.time) { state.NextPulseCycleAt += value2; } state.NextPulseAt = state.NextPulseCycleAt; state.NextPulseCycleAt += value2; } } private static void SendHealFlash(Enemy enemy) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (GameManager.Multiplayer()) { GameFieldAccess.PhotonView(enemy).RPC("HealRPC", (RpcTarget)0, Array.Empty()); } else { GameFieldAccess.Health(enemy).HealRPC(default(PhotonMessageInfo)); } } } internal static class EliteSelector { internal static EnhancementTier SelectTier(in SelectionCandidate candidate, in SelectionPolicy policy, in SelectionCounters counters, ulong stageSelectionSeed) { if (!candidate.Enabled || candidate.CapCost <= 0) { return EnhancementTier.Normal; } float num = Mathf.Clamp(policy.EnhancedChancePercent, 0f, 100f); if (SelectionRollSource.RollPercent(stageSelectionSeed, candidate.Key) < num) { if (counters.Enhanced + candidate.CapCost > policy.MaxEnhancedPerLevel) { return EnhancementTier.Normal; } return EnhancementTier.Enhanced; } return EnhancementTier.Normal; } } internal static class EnemyAdapterRuntime { internal static void OnSpawn(EliteState state) { switch (state.Archetype) { case EliteArchetype.Animal: AnimalElitePatches.OnSpawn(state); break; case EliteArchetype.BirthdayBoy: BirthdayBoyElitePatches.OnSpawn(state); break; case EliteArchetype.CleanupCrew: CleanupCrewElitePatches.OnSpawn(state); break; case EliteArchetype.Bowtie: BowtieElitePatches.OnSpawn(state); break; case EliteArchetype.Peeper: PeeperElitePatches.OnSpawn(state); break; case EliteArchetype.ApexPredator: ApexPredatorElitePatches.OnSpawn(state); break; case EliteArchetype.Elsa: ElsaElitePatches.OnSpawn(state); break; case EliteArchetype.Mentalist: MentalistElitePatches.OnSpawn(state); break; case EliteArchetype.Headman: HeadmanElitePatches.OnSpawn(state); break; case EliteArchetype.Headgrab: HeadgrabElitePatches.OnSpawn(state); break; case EliteArchetype.HeartHugger: HeartHuggerElitePatches.OnSpawn(state); break; case EliteArchetype.Hidden: HiddenElitePatches.OnSpawn(state); break; case EliteArchetype.Oogly: OoglyElitePatches.OnSpawn(state); break; case EliteArchetype.Robe: RobeElitePatches.OnSpawn(state); break; case EliteArchetype.Reaper: ReaperElitePatches.OnSpawn(state); break; case EliteArchetype.Loom: LoomElitePatches.OnSpawn(state); break; case EliteArchetype.Spewer: SpewerElitePatches.OnSpawn(state); break; case EliteArchetype.Trudge: TrudgeElitePatches.OnSpawn(state); break; case EliteArchetype.Tick: TickElitePatches.OnSpawn(state); break; case EliteArchetype.Bella: BellaElitePatches.OnSpawn(state); break; case EliteArchetype.Chef: ChefElitePatches.OnSpawn(state); break; case EliteArchetype.Upscream: UpscreamElitePatches.OnSpawn(state); break; case EliteArchetype.Rugrat: RugratElitePatches.OnSpawn(state); break; case EliteArchetype.Clown: ClownElitePatches.OnSpawn(state); break; case EliteArchetype.ShadowChild: ShadowChildElitePatches.OnSpawn(state); break; case EliteArchetype.Huntsman: HuntsmanElitePatches.OnSpawn(state); break; case EliteArchetype.Gambit: GambitElitePatches.OnSpawn(state); break; case EliteArchetype.Banger: BangerElitePatches.OnSpawn(state); break; case EliteArchetype.Gnome: GnomeElitePatches.OnSpawn(state); break; } } internal static void Tick(EliteState state) { switch (state.Archetype) { case EliteArchetype.Clown: ClownElitePatches.Tick(state); break; case EliteArchetype.ShadowChild: ShadowChildElitePatches.Tick(state); break; case EliteArchetype.Huntsman: HuntsmanElitePatches.Tick(state); break; case EliteArchetype.Gambit: GambitElitePatches.Tick(state); break; case EliteArchetype.Banger: BangerElitePatches.Tick(state); break; case EliteArchetype.Gnome: GnomeElitePatches.Tick(state); break; } } internal static void Cleanup(EliteState state) { if (state.Archetype == EliteArchetype.Gnome) { GnomeElitePatches.Cleanup(state); } else { state.AdapterState = null; } } } internal static class EnemyDisplayNameResolver { internal static bool TryResolve(Enemy enemy, out EliteArchetype archetype) { if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Animal; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.BirthdayBoy; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.CleanupCrew; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Bowtie; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Peeper; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.ApexPredator; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Elsa; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Mentalist; return true; } if ((Object)(object)((Component)enemy).GetComponentInChildren(true) != (Object)null) { archetype = EliteArchetype.Headman; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Headgrab; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.HeartHugger; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Hidden; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Oogly; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Robe; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Reaper; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Loom; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Spewer; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Trudge; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Tick; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Bella; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Chef; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Upscream; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Rugrat; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Clown; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.ShadowChild; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Huntsman; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Gambit; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Banger; return true; } if ((Object)(object)((Component)enemy).GetComponent() != (Object)null) { archetype = EliteArchetype.Gnome; return true; } archetype = EliteArchetype.Animal; return false; } internal static string Get(EliteArchetype archetype) { return archetype switch { EliteArchetype.Animal => "Animal", EliteArchetype.BirthdayBoy => "Birthday Boy", EliteArchetype.CleanupCrew => "Cleanup Crew", EliteArchetype.Bowtie => "Bowtie", EliteArchetype.Peeper => "Peeper", EliteArchetype.ApexPredator => "Apex Predator", EliteArchetype.Elsa => "Elsa", EliteArchetype.Mentalist => "Mentalist", EliteArchetype.Headman => "Headman", EliteArchetype.Headgrab => "Headgrab", EliteArchetype.HeartHugger => "Heart Hugger", EliteArchetype.Hidden => "Hidden", EliteArchetype.Oogly => "Oogly", EliteArchetype.Robe => "Robe", EliteArchetype.Reaper => "Reaper", EliteArchetype.Loom => "Loom", EliteArchetype.Spewer => "Spewer", EliteArchetype.Trudge => "Trudge", EliteArchetype.Tick => "Tick", EliteArchetype.Bella => "Bella", EliteArchetype.Chef => "Chef", EliteArchetype.Upscream => "Upscream", EliteArchetype.Rugrat => "Rugrat", EliteArchetype.Clown => "Clown", EliteArchetype.ShadowChild => "Shadow Child", EliteArchetype.Huntsman => "Huntsman", EliteArchetype.Gambit => "Gambit", EliteArchetype.Banger => "Banger", EliteArchetype.Gnome => "Gnome", _ => "Unknown", }; } } internal static class GameFieldAccess { private static readonly FieldRef EnemyPhotonView = AccessTools.FieldRefAccess("PhotonView"); private static readonly FieldRef EnemyParent = AccessTools.FieldRefAccess("EnemyParent"); private static readonly FieldRef EnemyVisionMask = AccessTools.FieldRefAccess("VisionMask"); private static readonly FieldRef EnemyVision = AccessTools.FieldRefAccess("Vision"); private static readonly FieldRef EnemyOnScreen = AccessTools.FieldRefAccess("OnScreen"); private static readonly FieldRef EnemyRigidbody = AccessTools.FieldRefAccess("Rigidbody"); private static readonly FieldRef EnemyNavMeshAgent = AccessTools.FieldRefAccess("NavMeshAgent"); private static readonly FieldRef EnemyStateInvestigate = AccessTools.FieldRefAccess("StateInvestigate"); private static readonly FieldRef EnemyStateChase = AccessTools.FieldRefAccess("StateChase"); private static readonly FieldRef EnemyHasStateInvestigate = AccessTools.FieldRefAccess("HasStateInvestigate"); private static readonly FieldRef EnemyJump = AccessTools.FieldRefAccess("Jump"); private static readonly FieldRef EnemyHealth = AccessTools.FieldRefAccess("Health"); private static readonly FieldRef EnemyHasHealth = AccessTools.FieldRefAccess("HasHealth"); private static readonly FieldRef EnemyTargetPlayerAvatar = AccessTools.FieldRefAccess("TargetPlayerAvatar"); private static readonly FieldRef EnemyTargetPlayerViewId = AccessTools.FieldRefAccess("TargetPlayerViewID"); private static readonly FieldRef OnScreenAnyRef = AccessTools.FieldRefAccess("OnScreenAny"); private static readonly FieldRef HealthCurrentRef = AccessTools.FieldRefAccess("healthCurrent"); private static readonly FieldRef HealthDeadRef = AccessTools.FieldRefAccess("dead"); private static readonly FieldRef PlayerDisabledRef = AccessTools.FieldRefAccess("isDisabled"); private static readonly FieldRef PlayerTumbleRef = AccessTools.FieldRefAccess("tumble"); private static readonly FieldRef TumblePhysGrabObjectRef = AccessTools.FieldRefAccess("physGrabObject"); private static readonly FieldRef ValuablePhysGrabObjectRef = AccessTools.FieldRefAccess("physGrabObject"); private static readonly FieldRef ValuableDollarValueRef = AccessTools.FieldRefAccess("dollarValueCurrent"); private static readonly FieldRef PhysGrabImpactDetectorRef = AccessTools.FieldRefAccess("impactDetector"); private static readonly FieldRef PhysGrabVelocityRef = AccessTools.FieldRefAccess("rbVelocity"); private static readonly FieldRef ImpactIndestructibleRef = AccessTools.FieldRefAccess("isIndestructible"); private static readonly FieldRef ParentSetupDoneRef = AccessTools.FieldRefAccess("SetupDone"); private static readonly FieldRef ParentSpawnedRef = AccessTools.FieldRefAccess("Spawned"); private static readonly FieldRef ParentFirstSpawnPointRef = AccessTools.FieldRefAccess("firstSpawnPoint"); private static readonly FieldRef ParentFirstSpawnPointUsedRef = AccessTools.FieldRefAccess("firstSpawnPointUsed"); private static readonly FieldRef DirectorSpawnIdlePauseTimerRef = AccessTools.FieldRefAccess("spawnIdlePauseTimer"); private static readonly FieldRef NavDefaultSpeedRef = AccessTools.FieldRefAccess("DefaultSpeed"); private static readonly FieldRef NavDefaultAccelerationRef = AccessTools.FieldRefAccess("DefaultAcceleration"); private static readonly FieldRef RigidbodyNotMovingTimerRef = AccessTools.FieldRefAccess("notMovingTimer"); private static readonly FieldRef JumpingRef = AccessTools.FieldRefAccess("jumping"); private static readonly FieldRef BeamerEnemyRef = AccessTools.FieldRefAccess("enemy"); private static readonly FieldRef BeamerPhotonViewRef = AccessTools.FieldRefAccess("photonView"); private static readonly FieldRef BeamerPlayerTargetRef = AccessTools.FieldRefAccess("playerTarget"); private static readonly FieldRef BangEnemyRef = AccessTools.FieldRefAccess("enemy"); private static readonly FieldRef BangPhotonViewRef = AccessTools.FieldRefAccess("photonView"); private static readonly FieldRef BangFuseLerpRef = AccessTools.FieldRefAccess("fuseLerp"); private static readonly FieldRef BangFuseActiveRef = AccessTools.FieldRefAccess("fuseActive"); private static readonly FieldRef GnomeAttackCooldownRef = AccessTools.FieldRefAccess("attackCooldown"); private static readonly FieldRef GnomeAttackPositionRef = AccessTools.FieldRefAccess("attackPosition"); internal static PhotonView PhotonView(Enemy enemy) { return EnemyPhotonView.Invoke(enemy); } internal static EnemyParent Parent(Enemy enemy) { return EnemyParent.Invoke(enemy); } internal static LayerMask VisionMask(Enemy enemy) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) return EnemyVisionMask.Invoke(enemy); } internal static EnemyVision Vision(Enemy enemy) { return EnemyVision.Invoke(enemy); } internal static EnemyOnScreen OnScreen(Enemy enemy) { return EnemyOnScreen.Invoke(enemy); } internal static EnemyRigidbody Rigidbody(Enemy enemy) { return EnemyRigidbody.Invoke(enemy); } internal static EnemyNavMeshAgent NavMeshAgent(Enemy enemy) { return EnemyNavMeshAgent.Invoke(enemy); } internal static EnemyStateInvestigate StateInvestigate(Enemy enemy) { return EnemyStateInvestigate.Invoke(enemy); } internal static EnemyStateChase StateChase(Enemy enemy) { return EnemyStateChase.Invoke(enemy); } internal static bool HasStateInvestigate(Enemy enemy) { return EnemyHasStateInvestigate.Invoke(enemy); } internal static EnemyJump Jump(Enemy enemy) { return EnemyJump.Invoke(enemy); } internal static EnemyHealth Health(Enemy enemy) { return EnemyHealth.Invoke(enemy); } internal static bool HasHealth(Enemy enemy) { return EnemyHasHealth.Invoke(enemy); } internal static PlayerAvatar TargetPlayer(Enemy enemy) { return EnemyTargetPlayerAvatar.Invoke(enemy); } internal static int TargetPlayerViewId(Enemy enemy) { return EnemyTargetPlayerViewId.Invoke(enemy); } internal static void SetTargetPlayer(Enemy enemy, PlayerAvatar player) { EnemyTargetPlayerAvatar.Invoke(enemy) = player; } internal static void SetTargetPlayerViewId(Enemy enemy, int viewId) { EnemyTargetPlayerViewId.Invoke(enemy) = viewId; } internal static bool OnScreenAny(EnemyOnScreen onScreen) { return OnScreenAnyRef.Invoke(onScreen); } internal static int HealthCurrent(EnemyHealth health) { return HealthCurrentRef.Invoke(health); } internal static bool IsDead(EnemyHealth health) { return HealthDeadRef.Invoke(health); } internal static bool PlayerDisabled(PlayerAvatar player) { return PlayerDisabledRef.Invoke(player); } internal static PlayerTumble? Tumble(PlayerAvatar player) { return PlayerTumbleRef.Invoke(player); } internal static PhysGrabObject? TumblePhysGrabObject(PlayerTumble tumble) { return TumblePhysGrabObjectRef.Invoke(tumble); } internal static PhysGrabObject? ValuablePhysGrabObject(ValuableObject valuable) { return ValuablePhysGrabObjectRef.Invoke(valuable); } internal static float ValuableDollarValue(ValuableObject valuable) { return ValuableDollarValueRef.Invoke(valuable); } internal static PhysGrabObjectImpactDetector? ImpactDetector(PhysGrabObject physGrab) { return PhysGrabImpactDetectorRef.Invoke(physGrab); } internal static Vector3 PhysGrabVelocity(PhysGrabObject physGrab) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) return PhysGrabVelocityRef.Invoke(physGrab); } internal static bool IsIndestructible(PhysGrabObjectImpactDetector impact) { return ImpactIndestructibleRef.Invoke(impact); } internal static bool ParentSpawned(EnemyParent parent) { return ParentSpawnedRef.Invoke(parent); } internal static void SetParentSetupDone(EnemyParent parent, bool value) { ParentSetupDoneRef.Invoke(parent) = value; } internal static void SetParentFirstSpawnPoint(EnemyParent parent, LevelPoint point) { ParentFirstSpawnPointRef.Invoke(parent) = point; } internal static void SetParentFirstSpawnPointUsed(EnemyParent parent, bool value) { ParentFirstSpawnPointUsedRef.Invoke(parent) = value; } internal static void EndEnemySpawnIdlePause(EnemyDirector director) { DirectorSpawnIdlePauseTimerRef.Invoke(director) = 0f; } internal static float NavDefaultSpeed(EnemyNavMeshAgent nav) { return NavDefaultSpeedRef.Invoke(nav); } internal static float NavDefaultAcceleration(EnemyNavMeshAgent nav) { return NavDefaultAccelerationRef.Invoke(nav); } internal static float NotMovingTimer(EnemyRigidbody rigidbody) { return RigidbodyNotMovingTimerRef.Invoke(rigidbody); } internal static bool IsJumping(EnemyJump jump) { return JumpingRef.Invoke(jump); } internal static Enemy BeamerEnemy(EnemyBeamer beamer) { return BeamerEnemyRef.Invoke(beamer); } internal static PhotonView BeamerPhotonView(EnemyBeamer beamer) { return BeamerPhotonViewRef.Invoke(beamer); } internal static PlayerAvatar BeamerTarget(EnemyBeamer beamer) { return BeamerPlayerTargetRef.Invoke(beamer); } internal static void SetBeamerTarget(EnemyBeamer beamer, PlayerAvatar target) { BeamerPlayerTargetRef.Invoke(beamer) = target; } internal static Enemy BangEnemy(EnemyBang bang) { return BangEnemyRef.Invoke(bang); } internal static PhotonView BangPhotonView(EnemyBang bang) { return BangPhotonViewRef.Invoke(bang); } internal static float BangFuseLerp(EnemyBang bang) { return BangFuseLerpRef.Invoke(bang); } internal static void SetBangFuseLerp(EnemyBang bang, float value) { BangFuseLerpRef.Invoke(bang) = value; } internal static bool BangFuseActive(EnemyBang bang) { return BangFuseActiveRef.Invoke(bang); } internal static float GnomeAttackCooldown(EnemyGnome gnome) { return GnomeAttackCooldownRef.Invoke(gnome); } internal static void SetGnomeAttackCooldown(EnemyGnome gnome, float value) { GnomeAttackCooldownRef.Invoke(gnome) = value; } internal static Vector3 GnomeAttackPosition(EnemyGnomeDirector director) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) return GnomeAttackPositionRef.Invoke(director); } } [HarmonyPatch] internal static class LifecyclePatches { [HarmonyPostfix] [HarmonyPatch(typeof(LevelGenerator), "GenerateDone")] private static void LevelGeneratorGenerateDonePostfix() { if (SemiFunc.IsMasterClientOrSingleplayer()) { EliteRegistry.BeginStage(); } } [HarmonyPrefix] [HarmonyPatch(typeof(RunManager), "ChangeLevel")] private static void RunManagerChangeLevelPrefix() { EliteRegistry.ClearStage(); } } internal static class SelectionInvariantChecks { internal static void Run() { SelectionCandidate candidate = new SelectionCandidate(12345, EliteArchetype.Clown, enabled: true); SelectionCandidate candidate2 = new SelectionCandidate(12345, EliteArchetype.Clown, enabled: false); ulong num = 1234605616436508552uL; AssertTier(candidate2, new SelectionPolicy(100f, 3), new SelectionCounters(0), num, EnhancementTier.Normal, "disabled candidate"); AssertTier(candidate, new SelectionPolicy(0f, 3), new SelectionCounters(0), num, EnhancementTier.Normal, "zero percent"); AssertTier(candidate, new SelectionPolicy(100f, 3), new SelectionCounters(0), num, EnhancementTier.Enhanced, "enhanced 100 percent"); AssertTier(candidate, new SelectionPolicy(100f, 0), new SelectionCounters(0), num, EnhancementTier.Normal, "enhanced cap"); float num2 = SelectionRollSource.RollPercent(num, candidate.Key); float num3 = SelectionRollSource.RollPercent(num, candidate.Key); if (num2 != num3 || num2 < 0f || num2 >= 100f) { throw new InvalidOperationException("Stable selection roll invariant failed."); } TestEnemyCatalogEntry[] entries = TestEnemyCatalog.Entries; int length = Enum.GetValues(typeof(EliteArchetype)).Length; if (entries.Length != length) { throw new InvalidOperationException($"Test enemy catalog has {entries.Length} entries; expected {length}."); } HashSet hashSet = new HashSet(); for (int i = 0; i < entries.Length; i++) { if (entries[i].Id != i + 1 || !hashSet.Add(entries[i].Archetype)) { throw new InvalidOperationException($"Test enemy catalog invariant failed at index {i}."); } } } private static void AssertTier(SelectionCandidate candidate, SelectionPolicy policy, SelectionCounters counters, ulong seed, EnhancementTier expected, string name) { EnhancementTier enhancementTier = EliteSelector.SelectTier(in candidate, in policy, in counters, seed); if (enhancementTier != expected) { throw new InvalidOperationException($"Selection invariant '{name}' failed: expected {expected}, got {enhancementTier}."); } } } internal static class SelectionRollSource { internal static ulong CreateStageSeed(long configuredSeed, int stageOrdinal) { return Mix((ulong)(((configuredSeed > 0) ? configuredSeed : (DateTime.UtcNow.Ticks ^ ((long)Environment.TickCount << 32))) ^ ((uint)stageOrdinal * -7046029254386353131L))); } internal static float RollPercent(ulong stageSeed, int candidateKey) { float num = (float)((double)(Mix(stageSeed ^ (ulong)((uint)candidateKey * -2960836687051489901L)) >> 11) * 1.1102230246251565E-14); if (!(num >= 100f)) { return num; } return 99.99999f; } private static ulong Mix(ulong value) { value += 11400714819323198485uL; value = (value ^ (value >> 30)) * 13787848793156543929uL; value = (value ^ (value >> 27)) * 10723151780598845931uL; return value ^ (value >> 31); } } internal readonly struct TestEnemyCatalogEntry { internal readonly int Id; internal readonly EliteArchetype Archetype; internal readonly string DisplayName; internal TestEnemyCatalogEntry(int id, EliteArchetype archetype) { Id = id; Archetype = archetype; DisplayName = EnemyDisplayNameResolver.Get(archetype); } } internal static class TestEnemyCatalog { internal static readonly TestEnemyCatalogEntry[] Entries = new TestEnemyCatalogEntry[29] { Entry(1, EliteArchetype.Animal), Entry(2, EliteArchetype.ApexPredator), Entry(3, EliteArchetype.Banger), Entry(4, EliteArchetype.Bella), Entry(5, EliteArchetype.BirthdayBoy), Entry(6, EliteArchetype.Bowtie), Entry(7, EliteArchetype.Chef), Entry(8, EliteArchetype.CleanupCrew), Entry(9, EliteArchetype.Clown), Entry(10, EliteArchetype.Elsa), Entry(11, EliteArchetype.Gambit), Entry(12, EliteArchetype.Gnome), Entry(13, EliteArchetype.Headgrab), Entry(14, EliteArchetype.Headman), Entry(15, EliteArchetype.HeartHugger), Entry(16, EliteArchetype.Hidden), Entry(17, EliteArchetype.Huntsman), Entry(18, EliteArchetype.Loom), Entry(19, EliteArchetype.Mentalist), Entry(20, EliteArchetype.Oogly), Entry(21, EliteArchetype.Peeper), Entry(22, EliteArchetype.Reaper), Entry(23, EliteArchetype.Robe), Entry(24, EliteArchetype.Rugrat), Entry(25, EliteArchetype.ShadowChild), Entry(26, EliteArchetype.Spewer), Entry(27, EliteArchetype.Tick), Entry(28, EliteArchetype.Trudge), Entry(29, EliteArchetype.Upscream) }; internal static bool TryResolve(string value, out TestEnemyCatalogEntry entry) { if (int.TryParse(value.Trim(), out var result)) { TestEnemyCatalogEntry[] entries = Entries; for (int i = 0; i < entries.Length; i++) { TestEnemyCatalogEntry testEnemyCatalogEntry = entries[i]; if (testEnemyCatalogEntry.Id == result) { entry = testEnemyCatalogEntry; return true; } } } else { string text = Normalize(value); TestEnemyCatalogEntry[] entries = Entries; for (int i = 0; i < entries.Length; i++) { TestEnemyCatalogEntry testEnemyCatalogEntry2 = entries[i]; if (Normalize(testEnemyCatalogEntry2.DisplayName) == text) { entry = testEnemyCatalogEntry2; return true; } } } entry = default(TestEnemyCatalogEntry); return false; } private static TestEnemyCatalogEntry Entry(int id, EliteArchetype archetype) { return new TestEnemyCatalogEntry(id, archetype); } private static string Normalize(string value) { return new string(value.Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray()); } } internal static class TestSpawnCommands { private const string SpawnCommandName = "eevspawn"; private const string ShortSpawnCommandName = "eevs"; private const string ListCommandName = "eevlist"; private const string ShortListCommandName = "eevl"; private const float InitialDespawnTimeoutSeconds = 2f; private const float TestSpawnProtectionSeconds = 900f; private static readonly MethodInfo EnemyParentSpawnMethod = AccessTools.DeclaredMethod(typeof(EnemyParent), "Spawn", (Type[])null, (Type[])null); private static DebugCommandHandler? _registeredHandler; private static readonly Dictionary ProtectedParents = new Dictionary(); private static readonly HashSet ReportedBlockedTimerDespawns = new HashSet(); private static string? _responseText; private static Color _responseColor; private static Color _restoreChatColor = Color.white; private static float _responseUntil; private static bool _restoreColorCaptured; private static bool _responseWasShown; internal static void Tick() { RegisterIfAvailable(); } private static void RegisterIfAvailable() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014d: 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 DebugCommandHandler instance = DebugCommandHandler.instance; if (!((Object)(object)instance == (Object)null) && instance != _registeredHandler) { instance.Register(new ChatCommand("eevspawn", "Spawn a forced Normal or Enhanced enemy by display name or ID", (Action)ExecuteSpawn, (Func>)SuggestSpawn, (Func)CanInterceptCommands, false)); instance.Register(new ChatCommand("eevs", "Short alias for /eevspawn", (Action)ExecuteSpawn, (Func>)SuggestSpawn, (Func)CanInterceptCommands, false)); instance.Register(new ChatCommand("eevlist", "List stable Elite Enemy Variants enemy IDs (page 1-3)", (Action)ExecuteList, (Func>)SuggestList, (Func)CanInterceptCommands, false)); instance.Register(new ChatCommand("eevl", "Short alias for /eevlist", (Action)ExecuteList, (Func>)SuggestList, (Func)CanInterceptCommands, false)); _registeredHandler = instance; } } internal static void RenderChatResponse() { //IL_00a0: 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) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(_responseText)) { return; } ChatManager instance = ChatManager.instance; ChatUI instance2 = ChatUI.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null || (Object)(object)instance2.chatText == (Object)null) { return; } if (instance.StateIsActive()) { ClearChatResponse(instance2); } else if (Time.unscaledTime >= _responseUntil) { ClearChatResponse(instance2); } else if (!instance.StateIsSend() && !instance.StateIsPossessed()) { if (!_restoreColorCaptured) { _restoreChatColor = ((Graphic)instance2.chatText).color; _restoreColorCaptured = true; } ((TMP_Text)instance2.chatText).text = _responseText; ((Graphic)instance2.chatText).color = _responseColor; ((SemiUI)instance2).Show(); if (!_responseWasShown) { ((SemiUI)instance2).SemiUITextFlashColor(_responseColor, 0.2f); ((SemiUI)instance2).SemiUISpringScale(0.05f, 5f, 0.2f); _responseWasShown = true; } } } private static bool CanInterceptCommands() { EliteEnemyVariantsPlugin instance = EliteEnemyVariantsPlugin.Instance; if ((Object)(object)instance != (Object)null && instance.Settings.EnableTestCommands.Value) { return SemiFunc.IsMasterClientOrSingleplayer(); } return false; } private static bool CanUseCommands() { EliteEnemyVariantsPlugin instance = EliteEnemyVariantsPlugin.Instance; if (CanInterceptCommands() && instance.Settings.Enabled.Value && !SemiFunc.RunIsLobbyMenu() && !SemiFunc.RunIsLobby() && (Object)(object)LevelGenerator.Instance != (Object)null && LevelGenerator.Instance.Generated) { return (Object)(object)EnemyDirector.instance != (Object)null; } return false; } private static void ExecuteSpawn(bool isDebugConsole, string[] args) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: 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_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) if (!CanUseCommands()) { Respond("Enemy summons require the enabled host mod and a generated gameplay level.", Color.red, 8f); return; } if (args.Length < 1) { Respond("Usage: /eevs [normal|enhanced|e] [count]", Color.red, 8f); return; } EnhancementTier tier; int num = (TryParseTier(args[0], out tier) ? 1 : 0); if (num >= args.Length) { Respond("Usage: /eevs [normal|enhanced|e] [count]", Color.red, 8f); return; } int num2 = 1; int num3 = args.Length; if (args.Length - num >= 2 && int.TryParse(args[^1], out var result)) { num2 = result; num3--; } int value = EliteEnemyVariantsPlugin.Instance.Settings.TestSpawnMaxGroups.Value; if (num2 < 1 || num2 > value) { Respond($"Count must be between 1 and {value}.", Color.red, 6f); return; } string text = string.Join(" ", args.Skip(num).Take(num3 - num)); if (!TestEnemyCatalog.TryResolve(text, out var entry)) { Respond("Unknown enemy '" + text + "'. Use /eevl 1-3.", Color.red, 8f); return; } EnemySetup val = FindSetup(entry.Archetype); if ((Object)(object)val == (Object)null) { Respond(entry.DisplayName + " is not present in the loaded enemy pools.", Color.red, 8f); return; } LevelPoint val2 = SemiFunc.LevelPointsGetClosestToLocalPlayer(); if ((Object)(object)val2 == (Object)null) { Respond("No level point is available near the local player.", Color.red, 8f); return; } int num4 = 0; int num5 = 0; for (int i = 0; i < num2; i++) { foreach (PrefabRef spawnObject in val.spawnObjects) { if (spawnObject == null || !((PrefabRef)(object)spawnObject).IsValid()) { continue; } GameObject val3 = ((GameManager.instance.gameMode != 0) ? PhotonNetwork.InstantiateRoomObject(((PrefabRef)(object)spawnObject).ResourcePath, ((Component)val2).transform.position, Quaternion.identity, (byte)0, (object[])null) : Object.Instantiate(((PrefabRef)(object)spawnObject).Prefab, ((Component)val2).transform.position, Quaternion.identity)); if ((Object)(object)val3 == (Object)null) { continue; } num5++; Enemy componentInChildren = val3.GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null && EnemyDisplayNameResolver.TryResolve(componentInChildren, out var archetype) && archetype == entry.Archetype && EliteRegistry.ForceTierForTest(componentInChildren, tier)) { num4++; } EnemyParent component = val3.GetComponent(); if ((Object)(object)component != (Object)null) { GameFieldAccess.SetParentFirstSpawnPoint(component, val2); GameFieldAccess.SetParentFirstSpawnPointUsed(component, value: false); GameFieldAccess.SetParentSetupDone(component, value: true); if (componentInChildren != null) { componentInChildren.EnemyTeleported(((Component)val2).transform.position); } ((MonoBehaviour)EliteEnemyVariantsPlugin.Instance).StartCoroutine(CompleteInitialTestSpawn(component)); } } } if (num4 == 0 && tier != EnhancementTier.Normal) { Respond($"Spawned {num5} room object(s), but no {entry.DisplayName} tier could be forced.", Color.red, 8f); return; } string text2 = tier.ToString(); Respond($"Spawned {num2} {text2} {entry.Id}: {entry.DisplayName} group(s) " + $"({num4} enemy object(s)).", Color.green, 8f); EliteEnemyVariantsPlugin.ModLogger.LogInfo((object)($"Test command spawned {num2} {text2} {entry.DisplayName} group(s); " + $"roomObjects={num5}, forcedEnemies={num4}.")); } private static IEnumerator CompleteInitialTestSpawn(EnemyParent parent) { float timeoutAt = Time.realtimeSinceStartup + 2f; while ((Object)(object)parent != (Object)null && GameFieldAccess.ParentSpawned(parent) && Time.realtimeSinceStartup < timeoutAt) { yield return null; } if ((Object)(object)parent == (Object)null) { yield break; } if (GameFieldAccess.ParentSpawned(parent)) { EliteEnemyVariantsPlugin.ModLogger.LogWarning((object)"Test summon did not reach EnemyParent's initial despawn before the timeout; the vanilla lifecycle will finish the spawn instead."); yield break; } try { EnemyParentSpawnMethod.Invoke(parent, null); if (!GameFieldAccess.ParentSpawned(parent)) { EliteEnemyVariantsPlugin.ModLogger.LogWarning((object)"Test summon could not complete its first vanilla spawn; its normal retry lifecycle remains active."); yield break; } ProtectFromTimerDespawn(parent); if ((Object)(object)EnemyDirector.instance != (Object)null) { GameFieldAccess.EndEnemySpawnIdlePause(EnemyDirector.instance); } } catch (Exception arg) { EliteEnemyVariantsPlugin.ModLogger.LogError((object)$"Failed to complete test summon through EnemyParent.Spawn: {arg}"); } } internal static bool TryGetTimerDespawnProtection(EnemyParent parent, out float remainingSeconds) { remainingSeconds = 0f; if ((Object)(object)parent == (Object)null || !ProtectedParents.TryGetValue(((Object)parent).GetInstanceID(), out var value)) { return false; } remainingSeconds = value - Time.time; if (remainingSeconds <= 0f) { ProtectedParents.Remove(((Object)parent).GetInstanceID()); ReportedBlockedTimerDespawns.Remove(((Object)parent).GetInstanceID()); return false; } Enemy componentInChildren = ((Component)parent).GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { return false; } if (GameFieldAccess.HasHealth(componentInChildren)) { EnemyHealth val = GameFieldAccess.Health(componentInChildren); if ((Object)(object)val == (Object)null || GameFieldAccess.IsDead(val) || GameFieldAccess.HealthCurrent(val) <= 0) { return false; } } if (EnemyDisplayNameResolver.TryResolve(componentInChildren, out var archetype)) { return archetype != EliteArchetype.Peeper; } return true; } internal static void ReportBlockedTimerDespawn(EnemyParent parent, float remainingSeconds) { if (ReportedBlockedTimerDespawns.Add(((Object)parent).GetInstanceID())) { EliteEnemyVariantsPlugin.ModLogger.LogInfo((object)$"Blocked an AI timer despawn for a test summon; protection remaining={remainingSeconds:F1}s."); } } internal static void ClearStage() { ProtectedParents.Clear(); ReportedBlockedTimerDespawns.Clear(); } private static void ProtectFromTimerDespawn(EnemyParent parent) { ProtectedParents[((Object)parent).GetInstanceID()] = Time.time + 900f; ReportedBlockedTimerDespawns.Remove(((Object)parent).GetInstanceID()); parent.SpawnedTimerPause(900f); } private static void ExecuteList(bool isDebugConsole, string[] args) { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) int result = 1; if (args.Length != 0 && (!int.TryParse(args[0], out result) || result < 1 || result > 3)) { Respond("Usage: /eevl [1|2|3]", Color.red, 6f); return; } IEnumerable source = TestEnemyCatalog.Entries.Skip((result - 1) * 10).Take(10); string text = $"Enemy IDs {result}/3\n" + string.Join("\n", source.Select((TestEnemyCatalogEntry entry) => $"{entry.Id}: {entry.DisplayName}")); Respond(text, Color.white, 15f); EliteEnemyVariantsPlugin.ModLogger.LogInfo((object)text.Replace('\n', ' ')); } private static List SuggestSpawn(bool isDebugConsole, string partial, string[] args) { string[] source = new string[3] { "normal", "enhanced", "e" }; if (args.Length == 0) { return source.ToList(); } bool flag = source.Contains(args[0].ToLowerInvariant()); if (args.Length == 1 && !flag) { string value = args[0].ToLowerInvariant(); List list = source.Where((string tier) => tier.StartsWith(value)).ToList(); if (list.Count > 0) { return list; } } string tierPrefix = (flag ? (args[0].ToLowerInvariant() + " ") : string.Empty); string target = string.Join(" ", args.Skip(flag ? 1 : 0)); return (from entry in TestEnemyCatalog.Entries where string.IsNullOrWhiteSpace(target) || entry.Id.ToString().StartsWith(target, StringComparison.OrdinalIgnoreCase) || entry.DisplayName.StartsWith(target, StringComparison.OrdinalIgnoreCase) select $"{tierPrefix}{entry.Id}").ToList(); } private static List SuggestList(bool isDebugConsole, string partial, string[] args) { return new string[3] { "1", "2", "3" }.Where((string page) => args.Length == 0 || page.StartsWith(args[0], StringComparison.OrdinalIgnoreCase)).ToList(); } private static bool TryParseTier(string value, out EnhancementTier tier) { switch (value.ToLowerInvariant()) { case "normal": tier = EnhancementTier.Normal; return true; case "enhanced": case "e": tier = EnhancementTier.Enhanced; return true; default: tier = EnhancementTier.Enhanced; return false; } } private static EnemySetup? FindSetup(EliteArchetype archetype) { foreach (EnemySetup item in (from setup in EnemyDirector.instance.enemiesDifficulty1.Concat(EnemyDirector.instance.enemiesDifficulty2).Concat(EnemyDirector.instance.enemiesDifficulty3) where (Object)(object)setup != (Object)null select setup).Distinct()) { foreach (PrefabRef spawnObject in item.spawnObjects) { GameObject obj = ((PrefabRef)(object)spawnObject)?.Prefab; Enemy val = ((obj != null) ? obj.GetComponentInChildren(true) : null); if ((Object)(object)val != (Object)null && EnemyDisplayNameResolver.TryResolve(val, out var archetype2) && archetype2 == archetype) { return item; } } } return null; } private static void Respond(string text, Color color, float duration) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) _responseText = text; _responseColor = color; _responseUntil = Time.unscaledTime + duration; _responseWasShown = false; EliteEnemyVariantsPlugin.ModLogger.LogInfo((object)text.Replace('\n', ' ')); } private static void ClearChatResponse(ChatUI chat) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) ((TMP_Text)chat.chatText).text = string.Empty; if (_restoreColorCaptured) { ((Graphic)chat.chatText).color = _restoreChatColor; } ((SemiUI)chat).Hide(); _responseText = null; _responseUntil = 0f; _restoreColorCaptured = false; _responseWasShown = false; } } [HarmonyPatch(typeof(ChatManager), "Update")] internal static class TestCommandChatResponsePatch { [HarmonyPostfix] private static void Postfix() { TestSpawnCommands.RenderChatResponse(); } } }