Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Mutators Addon v0.3.0
BepInEx/plugins/GastrodonGroup-Mutators_Addon/MutatorsAddon.dll
Decompiled 3 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GastrodonGroup.MutatorsAddon.Behaviours; using GastrodonGroup.MutatorsAddon.MutatorDefinitions.BadDog; using GastrodonGroup.MutatorsAddon.MutatorDefinitions.ParentsFriends; using GastrodonGroup.MutatorsAddon.Patches; using HarmonyLib; using Microsoft.CodeAnalysis; using Mutators.Enums; using Mutators.Managers; using Mutators.Mutators; using Mutators.Settings; using REPOLib.Modules; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("GastrodonGroup")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.3.0.0")] [assembly: AssemblyInformationalVersion("0.3.0+051b8320446f469bde6263c6ab843cac5c7aa1a5")] [assembly: AssemblyProduct("MutatorsAddon")] [assembly: AssemblyTitle("MutatorsAddon")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.3.0.0")] [module: UnverifiableCode] [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 GastrodonGroup.MutatorsAddon { [BepInDependency("Xepos.REPO-Mutators", "1.0.3")] [BepInPlugin("GastrodonGroup.MutatorsAddon", "Mutators Addon", "0.3.0")] public class MutatorsAddonPlugin : BaseUnityPlugin { internal static MutatorsAddonPlugin Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; RegisterBadDog(); RegisterWrongWayMap(); RegisterSilentStalkers(); RegisterParentsFriends(); Logger.LogInfo((object)string.Format("{0} v{1} has loaded! Build: {2}", ((BaseUnityPlugin)this).Info.Metadata.GUID, ((BaseUnityPlugin)this).Info.Metadata.Version, "2026-07-26 19:57")); } private static void RegisterParentsFriends() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown ParentsFriendsMutator.BindConfig(((BaseUnityPlugin)Instance).Config); IMutator val = (IMutator)new Mutator((AbstractMutatorSettings)(object)ParentsFriendsMutator.Settings, typeof(ParentsFriendsPatch), (MutatorDifficulty)2, (IList<Func<bool>>)null, false); MutatorManager.Instance.RegisterMutator(val); Logger.LogInfo((object)"Registered mutator: Parents Friends"); } private static void RegisterWrongWayMap() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown IMutator val = (IMutator)new Mutator((AbstractMutatorSettings)new GenericMutatorSettings("GastrodonGroup.MutatorsAddon", "MAP-side Down", "The minimap screen is rotated 180 degrees", ((BaseUnityPlugin)Instance).Config), typeof(WrongWayMapPatch), (MutatorDifficulty)3, (IList<Func<bool>>)null, false); MutatorManager.Instance.RegisterMutator(val); Logger.LogInfo((object)"Registered mutator: MAP-side Down"); } private static void RegisterSilentStalkers() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown IMutator val = (IMutator)new Mutator((AbstractMutatorSettings)new GenericMutatorSettings("GastrodonGroup.MutatorsAddon", "Silent Stalkers", "You cannot hear the enemy sounds", ((BaseUnityPlugin)Instance).Config), typeof(SilentStalkersPatch), (MutatorDifficulty)2, (IList<Func<bool>>)null, false); MutatorManager.Instance.RegisterMutator(val); Logger.LogInfo((object)"Registered mutator: Silent Stalkers"); } private static void RegisterBadDog() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown BadDogMutator.BindConfig(((BaseUnityPlugin)Instance).Config); IMutator val = (IMutator)new Mutator((AbstractMutatorSettings)(object)BadDogMutator.Settings, typeof(BadDogPatch), (MutatorDifficulty)3, (IList<Func<bool>>)null, false); MutatorManager.Instance.RegisterMutator(val); Logger.LogInfo((object)"Registered mutator: Watchdog Out!"); } } internal static class PluginInfo { internal const string PLUGIN_GUID = "GastrodonGroup.MutatorsAddon"; internal const string PLUGIN_NAME = "Mutators Addon"; internal const string PLUGIN_VERSION = "0.3.0"; internal const string THUNDERSTORE_PACKAGE_NAME = "Mutators_Addon"; } internal static class BuildInfo { internal const string Timestamp = "2026-07-26 19:57"; } } namespace GastrodonGroup.MutatorsAddon.Patches { internal class BadDogPatch { private const string ElsaEnemyName = "Elsa"; private const string ElsaSetupName = "Enemy - Elsa"; [HarmonyPostfix] [HarmonyPriority(99)] [HarmonyPatch(typeof(EnemyDirector), "AmountSetup")] private static void EnemyDirectorAmountSetupPostfix(EnemyDirector __instance) { if (!SemiFunc.IsMasterClientOrSingleplayer()) { return; } IList<EnemySetup> enemyList = __instance.enemyList; if (enemyList.Any((EnemySetup setup) => setup.spawnObjects.Select((PrefabRef so) => ((PrefabRef<GameObject>)(object)so).Prefab.GetComponent<EnemyParent>()).Any((EnemyParent ep) => (Object)(object)ep != (Object)null && ep.enemyName == "Elsa"))) { return; } EnemySetup val = ((IEnumerable<EnemySetup>)Enemies.AllEnemies).FirstOrDefault((Func<EnemySetup, bool>)((EnemySetup setup) => ((Object)setup).name == "Enemy - Elsa")); if (!Object.op_Implicit((Object)(object)val)) { return; } IList<EnemySetup> list = enemyList.Where(delegate(EnemySetup setup) { IEnumerable<EnemyParent> source = from so in setup.spawnObjects select ((PrefabRef<GameObject>)(object)so).Prefab.GetComponent<EnemyParent>() into ep where (Object)(object)ep != (Object)null select ep; return source.All((EnemyParent ep) => (int)ep.difficulty == 0) && source.All((EnemyParent ep) => ep.enemyName != "Elsa"); }).ToList(); if (list.Count == 0) { MutatorsAddonPlugin.Logger.LogWarning((object)"No suitable enemies found to replace with Elsa"); return; } EnemySetup item = list[Random.Range(0, list.Count)]; if (enemyList.Remove(item)) { enemyList.Add(val); } } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyElsa), "Update")] private static void EnemyElsaUpdatePrefix(EnemyElsa __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_0025: 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: Invalid comparison between Unknown and I4 //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Invalid comparison between Unknown and I4 //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Invalid comparison between Unknown and I4 if (!SemiFunc.IsMasterClientOrSingleplayer()) { return; } BadDogBehaviour badDogBehaviour = ((Component)__instance).GetComponent<BadDogBehaviour>() ?? ((Component)__instance).gameObject.AddComponent<BadDogBehaviour>(); State currentState = __instance.currentState; if (currentState - 6 <= 2) { if (badDogBehaviour.CanNotice()) { __instance.UpdateState((State)24); } } else if ((int)__instance.currentState == 25) { badDogBehaviour.PendingLeaveAfterShrink = true; } else if ((int)__instance.currentState == 1 && badDogBehaviour.PendingLeaveAfterShrink) { badDogBehaviour.PendingLeaveAfterShrink = false; __instance.playerTarget = null; __instance.UpdateState((State)16); badDogBehaviour.NoticeCooldown = BadDogMutator.Settings.TransformCooldown; } } } internal class ParentsFriendsPatch { private const string LoomEnemyName = "Loom"; private const string LoomSetupName = "Enemy - Shadow"; private const string HuntsmanEnemyName = "Huntsman"; private const string HuntsmanSetupName = "Enemy - Hunter"; private static readonly string[] ProtectedEnemyNames = new string[2] { "Loom", "Huntsman" }; private const float LoomLeaveSpeed = 2.5f; private const float LoomLeaveAcceleration = 30f; private const float LoomLeaveOverrideTime = 0.1f; [HarmonyPostfix] [HarmonyPriority(99)] [HarmonyPatch(typeof(EnemyDirector), "AmountSetup")] private static void EnemyDirectorAmountSetupPostfix(EnemyDirector __instance) { if (SemiFunc.IsMasterClientOrSingleplayer()) { EnsureAtLeastOne(__instance, "Huntsman", "Enemy - Hunter"); EnsureAtLeastOne(__instance, "Loom", "Enemy - Shadow"); } } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyShadow), "Awake")] private static void EnemyShadowAwakePostfix(EnemyShadow __instance) { EnsureLoomBehaviour(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyHunter), "Awake")] private static void EnemyHunterAwakePostfix(EnemyHunter __instance) { EnsureHunterBehaviour(__instance); } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyShadow), "HandLogic")] private static void EnemyShadowHandLogicClientReachPrefix(EnemyShadow __instance, bool ___closeEnoughToReachOut, ref bool ___seesTarget) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0020: Invalid comparison between Unknown and I4 //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 if (!SemiFunc.IsMasterClientOrSingleplayer() && !((Object)(object)((Component)__instance).GetComponent<ParentsFriendsLoomBehaviour>() == (Object)null)) { State currentState = __instance.currentState; if (((int)currentState == 3 || (int)currentState == 7) && ___closeEnoughToReachOut && Object.op_Implicit((Object)(object)__instance.playerTarget)) { ___seesTarget = true; } } } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyHunter), "AimLogic")] private static bool EnemyHunterAimLogicPrefix(EnemyHunter __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)__instance.currentState != 5) { return true; } ParentsFriendsHunterBehaviour component = ((Component)__instance).GetComponent<ParentsFriendsHunterBehaviour>(); if ((Object)(object)component == (Object)null || !component.AimLocked) { return true; } return false; } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyHunter), "AimLogic")] private static void EnemyHunterAimLogicPostfix(EnemyHunter __instance) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 if (SemiFunc.IsMasterClientOrSingleplayer() && (int)__instance.currentState == 5) { ParentsFriendsHunterBehaviour component = ((Component)__instance).GetComponent<ParentsFriendsHunterBehaviour>(); if (!((Object)(object)component == (Object)null) && !component.AimLocked) { component.AimLocked = true; component.PendingAimTimerScale = true; } } } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyHunter), "StateAim")] private static void EnemyHunterStateAimPostfix(EnemyHunter __instance, ref float ___stateTimer) { if (SemiFunc.IsMasterClientOrSingleplayer()) { ParentsFriendsHunterBehaviour component = ((Component)__instance).GetComponent<ParentsFriendsHunterBehaviour>(); if (!((Object)(object)component == (Object)null) && component.PendingAimTimerScale) { float num = Mathf.Clamp(ParentsFriendsMutator.Settings.HuntsmanAimSpeedMult, 0.05f, 1f); ___stateTimer /= num; component.PendingAimTimerScale = false; } } } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyHunter), "StateShoot")] private static void EnemyHunterStateShootClearAimLockPrefix(EnemyHunter __instance) { ClearHunterAimLock(__instance); } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyHunter), "StateStun")] private static void EnemyHunterStateStunClearAimLockPrefix(EnemyHunter __instance) { ClearHunterAimLock(__instance); } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyHunter), "StateLeave")] private static void EnemyHunterStateLeaveClearAimLockPrefix(EnemyHunter __instance) { ClearHunterAimLock(__instance); } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyHunter), "StateDespawn")] private static void EnemyHunterStateDespawnClearAimLockPrefix(EnemyHunter __instance) { ClearHunterAimLock(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyShadow), "StateLeave")] private static void EnemyShadowStateLeavePostfix(EnemyShadow __instance) { if (SemiFunc.IsMasterClientOrSingleplayer()) { ParentsFriendsLoomBehaviour component = ((Component)__instance).GetComponent<ParentsFriendsLoomBehaviour>(); if (!((Object)(object)component == (Object)null)) { __instance.enemy.NavMeshAgent.OverrideAgent(2.5f * component.MoveMult, 30f, 0.1f); } } } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyShadow), "StateFollow")] private static void EnemyShadowStateFollowSuppressIdleLeavePrefix(EnemyShadow __instance, bool ___closeEnoughToReachOut, bool ___closeEnoughToSlap) { if (IsHandAttackLocked(__instance) || ___closeEnoughToReachOut || ___closeEnoughToSlap) { SuppressIdleLeaveTimers(__instance); } } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyShadow), "StateFollow")] private static void EnemyShadowStateFollowPostfix(EnemyShadow __instance, bool ___closeEnoughToReachOut, bool ___closeEnoughToSlap) { if (IsHandAttackLocked(__instance) || ___closeEnoughToReachOut || ___closeEnoughToSlap) { HoldStillForHandAttack(__instance); } } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyShadow), "StateSlap")] private static void EnemyShadowStateSlapPostfix(EnemyShadow __instance) { HoldStillForHandAttack(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyShadow), "StateCoolDown")] private static void EnemyShadowStateCoolDownHoldStillPostfix(EnemyShadow __instance) { HoldStillForHandAttack(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyShadow), "StateChooseTarget")] private static void EnemyShadowStateChooseTargetHoldStillPostfix(EnemyShadow __instance) { if (IsHandAttackLocked(__instance)) { HoldStillForHandAttack(__instance); } } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyShadow), "StateStuckAttack")] private static void EnemyShadowStateStuckAttackHoldStillPostfix(EnemyShadow __instance) { if (IsHandAttackLocked(__instance)) { HoldStillForHandAttack(__instance); } } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyShadow), "StateLeave")] private static void EnemyShadowStateLeaveClearHandLockPrefix(EnemyShadow __instance) { ClearHandAttackLock(__instance); } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyShadow), "StateDespawn")] private static void EnemyShadowStateDespawnClearHandLockPrefix(EnemyShadow __instance) { ClearHandAttackLock(__instance); } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyShadow), "StateStun")] private static void EnemyShadowStateStunClearHandLockPrefix(EnemyShadow __instance) { ClearHandAttackLock(__instance); } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyShadow), "ReturnHandsToDefaultPosition")] private static void EnemyShadowReturnHandsPrefix(EnemyShadow __instance, ref float _speed) { ParentsFriendsLoomBehaviour component = ((Component)__instance).GetComponent<ParentsFriendsLoomBehaviour>(); if (!((Object)(object)component == (Object)null)) { _speed *= component.AttackMult; } } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyShadow), "ReachOutHandsToSlap")] private static void EnemyShadowReachOutHandsToSlapPostfix(EnemyShadow __instance) { BeginHandAttackLock(__instance); SetHandAnimatorSpeed(__instance, GetAttackMult(__instance)); } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyShadow), "ReachOutHandsToStuckTarget")] private static void EnemyShadowReachOutHandsToStuckTargetPostfix(EnemyShadow __instance) { BeginHandAttackLock(__instance); SetHandAnimatorSpeed(__instance, GetAttackMult(__instance)); } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyShadow), "ReturnHandsToDefaultPosition")] private static void EnemyShadowReturnHandsPostfix(EnemyShadow __instance) { ((Component)__instance).GetComponent<ParentsFriendsLoomBehaviour>()?.TryEndHandAttackLock(); } [HarmonyPrefix] [HarmonyPatch(typeof(EnemyShadow), "Slap")] private static void EnemyShadowSlapPrefix(EnemyShadow __instance) { SetHandAnimatorSpeed(__instance, 1f); } [HarmonyTranspiler] [HarmonyPatch(typeof(EnemyShadow), "UpdateHandPositionTo")] private static IEnumerable<CodeInstruction> UpdateHandPositionToTranspiler(IEnumerable<CodeInstruction> instructions) { return InjectHandMotionScalers(instructions, scaleSmoothDampPair: true); } [HarmonyTranspiler] [HarmonyPatch(typeof(EnemyShadow), "ReachOutHandsToSlap")] private static IEnumerable<CodeInstruction> ReachOutHandsToSlapTranspiler(IEnumerable<CodeInstruction> instructions) { return InjectHandMotionScalers(instructions, scaleSmoothDampPair: false); } [HarmonyTranspiler] [HarmonyPatch(typeof(EnemyShadow), "ReachOutHandsToStuckTarget")] private static IEnumerable<CodeInstruction> ReachOutHandsToStuckTargetTranspiler(IEnumerable<CodeInstruction> instructions) { return InjectHandMotionScalers(instructions, scaleSmoothDampPair: false); } internal static void AfterPatchAll() { EnemyShadow[] array = Object.FindObjectsByType<EnemyShadow>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (EnemyShadow shadow in array) { EnsureLoomBehaviour(shadow); } EnemyHunter[] array2 = Object.FindObjectsByType<EnemyHunter>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (EnemyHunter hunter in array2) { EnsureHunterBehaviour(hunter); } } internal static void AfterUnpatchAll() { ParentsFriendsLoomBehaviour[] array = Object.FindObjectsByType<ParentsFriendsLoomBehaviour>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (ParentsFriendsLoomBehaviour parentsFriendsLoomBehaviour in array) { parentsFriendsLoomBehaviour.Restore(); Object.Destroy((Object)(object)parentsFriendsLoomBehaviour); } ParentsFriendsHunterBehaviour[] array2 = Object.FindObjectsByType<ParentsFriendsHunterBehaviour>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (ParentsFriendsHunterBehaviour parentsFriendsHunterBehaviour in array2) { parentsFriendsHunterBehaviour.Restore(); Object.Destroy((Object)(object)parentsFriendsHunterBehaviour); } } private static IEnumerable<CodeInstruction> InjectHandMotionScalers(IEnumerable<CodeInstruction> instructions, bool scaleSmoothDampPair) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Expected O, but got Unknown List<CodeInstruction> list = instructions.ToList(); MethodInfo methodInfo = AccessTools.Method(typeof(ParentsFriendsPatch), "ScaleSmoothTime", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(ParentsFriendsPatch), "ScaleMaxSpeed", (Type[])null, (Type[])null); MethodInfo methodInfo3 = AccessTools.Method(typeof(ParentsFriendsPatch), "ScaleLerpRate", (Type[])null, (Type[])null); if (scaleSmoothDampPair) { for (int i = 0; i < list.Count - 1; i++) { if (IsLdcR4(list[i], 0.12f) && IsLdcR4(list[i + 1], 4f)) { list.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)methodInfo)); list.Insert(i + 3, new CodeInstruction(OpCodes.Call, (object)methodInfo2)); break; } } } for (int j = 0; j < list.Count - 2; j++) { if (IsDeltaTimeGetter(list[j]) && IsLdcR4(list[j + 1], 10f) && !(list[j + 2].opcode != OpCodes.Mul)) { list.Insert(j + 2, new CodeInstruction(OpCodes.Call, (object)methodInfo3)); j += 2; } } return list; } private static bool IsLdcR4(CodeInstruction instruction, float value) { if (instruction.opcode == OpCodes.Ldc_R4 && instruction.operand is float num) { return Mathf.Abs(num - value) < 0.0001f; } return false; } private static bool IsDeltaTimeGetter(CodeInstruction instruction) { if (instruction.opcode == OpCodes.Call && instruction.operand is MethodInfo methodInfo && methodInfo.DeclaringType == typeof(Time)) { return methodInfo.Name == "get_deltaTime"; } return false; } private static float ClampedAttackMult() { return Mathf.Clamp(ParentsFriendsMutator.Settings.LoomAttackSpeedMult, 0.05f, 2f); } private static float ScaleSmoothTime(float original) { return original / ClampedAttackMult(); } private static float ScaleMaxSpeed(float original) { return original * ClampedAttackMult(); } private static float ScaleLerpRate(float original) { return original * ClampedAttackMult(); } private static float GetAttackMult(EnemyShadow shadow) { ParentsFriendsLoomBehaviour component = ((Component)shadow).GetComponent<ParentsFriendsLoomBehaviour>(); if (!((Object)(object)component != (Object)null)) { return ClampedAttackMult(); } return component.AttackMult; } private static void SetHandAnimatorSpeed(EnemyShadow shadow, float speed) { if ((Object)(object)shadow.leftHandAnimator != (Object)null) { shadow.leftHandAnimator.speed = speed; } if ((Object)(object)shadow.rightHandAnimator != (Object)null) { shadow.rightHandAnimator.speed = speed; } } private static void EnsureAtLeastOne(EnemyDirector director, string enemyName, string setupName) { //IL_0058: 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) IList<EnemySetup> enemyList = director.enemyList; if (EnemyListContains(enemyList, enemyName)) { return; } EnemySetup val = ((IEnumerable<EnemySetup>)Enemies.AllEnemies).FirstOrDefault((Func<EnemySetup, bool>)((EnemySetup s) => ((Object)s).name == setupName)); if (!Object.op_Implicit((Object)(object)val) || !IsAllowedByLevelsCompleted(val) || !TryGetSetupDifficulty(val, out var difficulty) || !DifficultyQuotaAllows(director, difficulty)) { return; } IList<EnemySetup> list = enemyList.Where(delegate(EnemySetup candidate) { IEnumerable<EnemyParent> source = from so in candidate.spawnObjects select ((PrefabRef<GameObject>)(object)so).Prefab.GetComponent<EnemyParent>() into ep where (Object)(object)ep != (Object)null select ep; return source.Any() && source.All((EnemyParent ep) => ep.difficulty == difficulty) && source.All((EnemyParent ep) => !ProtectedEnemyNames.Contains(ep.enemyName)); }).ToList(); if (list.Count == 0) { MutatorsAddonPlugin.Logger.LogWarning((object)$"Parents Friends: no {difficulty} enemies to replace with {enemyName}"); return; } EnemySetup val2 = list[Random.Range(0, list.Count)]; if (enemyList.Remove(val2)) { enemyList.Add(val); MutatorsAddonPlugin.Logger.LogInfo((object)("Parents Friends: guaranteed " + enemyName + " (replaced " + ((Object)val2).name + ")")); } } private static bool TryGetSetupDifficulty(EnemySetup setup, out Difficulty difficulty) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected I4, but got Unknown EnemyParent val = setup.spawnObjects.Select((PrefabRef so) => ((PrefabRef<GameObject>)(object)so).Prefab.GetComponent<EnemyParent>()).FirstOrDefault((Func<EnemyParent, bool>)((EnemyParent ep) => (Object)(object)ep != (Object)null)); if ((Object)(object)val == (Object)null) { difficulty = (Difficulty)0; return false; } difficulty = (Difficulty)(int)val.difficulty; return true; } private static bool DifficultyQuotaAllows(EnemyDirector director, Difficulty difficulty) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected I4, but got Unknown return (int)difficulty switch { 0 => director.amountCurve1Value > 0, 1 => director.amountCurve2Value > 0, 2 => director.amountCurve3Value > 0, _ => false, }; } private static bool IsHandAttackLocked(EnemyShadow shadow) { ParentsFriendsLoomBehaviour component = ((Component)shadow).GetComponent<ParentsFriendsLoomBehaviour>(); if ((Object)(object)component != (Object)null) { return component.HandAttackLock; } return false; } private static void BeginHandAttackLock(EnemyShadow shadow) { ((Component)shadow).GetComponent<ParentsFriendsLoomBehaviour>()?.BeginHandAttackLock(); } private static void ClearHandAttackLock(EnemyShadow shadow) { ((Component)shadow).GetComponent<ParentsFriendsLoomBehaviour>()?.ClearHandAttackLock(); } private static void HoldStillForHandAttack(EnemyShadow shadow) { if (SemiFunc.IsMasterClientOrSingleplayer() && !((Object)(object)((Component)shadow).GetComponent<ParentsFriendsLoomBehaviour>() == (Object)null) && !((Object)(object)shadow.enemy == (Object)null) && !((Object)(object)shadow.enemy.NavMeshAgent == (Object)null)) { SuppressIdleLeaveTimers(shadow); EnemyNavMeshAgent navMeshAgent = shadow.enemy.NavMeshAgent; navMeshAgent.ResetPath(); navMeshAgent.Stop(0.1f); } } private static void SuppressIdleLeaveTimers(EnemyShadow shadow) { if (SemiFunc.IsMasterClientOrSingleplayer() && !((Object)(object)((Component)shadow).GetComponent<ParentsFriendsLoomBehaviour>() == (Object)null) && !((Object)(object)shadow.enemy == (Object)null) && !((Object)(object)shadow.enemy.Rigidbody == (Object)null)) { shadow.enemy.Rigidbody.notMovingTimer = 0f; } } private static bool EnemyListContains(IList<EnemySetup> enemyList, string enemyName) { return enemyList.Any((EnemySetup setup) => setup.spawnObjects.Select((PrefabRef so) => ((PrefabRef<GameObject>)(object)so).Prefab.GetComponent<EnemyParent>()).Any((EnemyParent ep) => (Object)(object)ep != (Object)null && ep.enemyName == enemyName)); } private static bool IsAllowedByLevelsCompleted(EnemySetup setup) { if (!setup.levelsCompletedCondition) { return true; } if ((Object)(object)RunManager.instance == (Object)null) { return false; } int levelsCompleted = RunManager.instance.levelsCompleted; if (levelsCompleted < setup.levelsCompletedMin) { return false; } if (setup.levelsCompletedMax != 0 && levelsCompleted > setup.levelsCompletedMax) { return false; } return true; } private static void EnsureLoomBehaviour(EnemyShadow shadow) { if (!((Object)(object)shadow == (Object)null) && !((Object)(object)shadow.enemy == (Object)null)) { ParentsFriendsLoomBehaviour parentsFriendsLoomBehaviour = ((Component)shadow).GetComponent<ParentsFriendsLoomBehaviour>() ?? ((Component)shadow).gameObject.AddComponent<ParentsFriendsLoomBehaviour>(); parentsFriendsLoomBehaviour.RequestApply(shadow, ParentsFriendsMutator.Settings.LoomMoveSpeedMult, ParentsFriendsMutator.Settings.LoomAttackSpeedMult); } } private static void EnsureHunterBehaviour(EnemyHunter hunter) { if (!((Object)(object)hunter == (Object)null) && !((Object)(object)hunter.enemy == (Object)null)) { ParentsFriendsHunterBehaviour parentsFriendsHunterBehaviour = ((Component)hunter).GetComponent<ParentsFriendsHunterBehaviour>() ?? ((Component)hunter).gameObject.AddComponent<ParentsFriendsHunterBehaviour>(); parentsFriendsHunterBehaviour.RequestApply(hunter, ParentsFriendsMutator.Settings.HuntsmanMoveSpeedMult, ParentsFriendsMutator.Settings.HuntsmanAimSpeedMult); } } private static void ClearHunterAimLock(EnemyHunter hunter) { ((Component)hunter).GetComponent<ParentsFriendsHunterBehaviour>()?.ClearAimLock(); } } internal class SilentStalkersPatch { private const string WesleysEnemiesPluginGuid = "WesleysEnemies"; private static readonly HashSet<Sound> EnemySounds = new HashSet<Sound>(); private static readonly Dictionary<int, HashSet<Sound>> SoundsByParentId = new Dictionary<int, HashSet<Sound>>(); private static readonly Dictionary<Type, FieldInfo[]> SoundFieldsByType = new Dictionary<Type, FieldInfo[]>(); private static readonly Dictionary<string, string[]> WesleyMutedAudioSourceFields = new Dictionary<string, string[]> { ["Shotgunner"] = new string[1] { "ambientAudio" } }; [HarmonyPostfix] [HarmonyPatch(typeof(EnemyParent), "SpawnRPC")] private static void EnemyParentSpawnPostfix(EnemyParent __instance) { RegisterEnemySounds(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyParent), "DespawnRPC")] private static void EnemyParentDespawnPostfix(EnemyParent __instance) { UnregisterEnemySounds(__instance); } [HarmonyPrefix] [HarmonyPatch(typeof(Sound), "Play", new Type[] { typeof(Vector3), typeof(float), typeof(float), typeof(float), typeof(float) })] private static bool SoundPlayVector3Prefix(Sound __instance) { return !ShouldMuteSound(__instance); } [HarmonyPrefix] [HarmonyPatch(typeof(Sound), "Play", new Type[] { typeof(Transform), typeof(float), typeof(float), typeof(float), typeof(float) })] private static bool SoundPlayTransformPrefix(Sound __instance, Transform followTarget) { return !ShouldMuteSound(__instance, followTarget); } [HarmonyPrefix] [HarmonyPatch(typeof(Sound), "Play", new Type[] { typeof(Transform), typeof(Vector3), typeof(float), typeof(float), typeof(float), typeof(float) })] private static bool SoundPlayTransformContactPrefix(Sound __instance, Transform followTarget) { return !ShouldMuteSound(__instance, followTarget); } [HarmonyPrefix] [HarmonyPatch(typeof(Sound), "PlayLoop")] private static bool SoundPlayLoopPrefix(Sound __instance, bool playing) { if (!playing) { return true; } return !ShouldMuteSound(__instance); } internal static void AfterPatchAll() { ClearRegistry(); EnemyParent[] array = Object.FindObjectsByType<EnemyParent>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (EnemyParent parent in array) { RegisterEnemySounds(parent); } } internal static void AfterUnpatchAll() { ClearRegistry(); } private static bool ShouldMuteSound(Sound sound, Transform? followTarget = null) { if (EnemySounds.Contains(sound)) { return true; } if ((Object)(object)followTarget != (Object)null && IsUnderEnemyHierarchy(followTarget)) { return true; } if ((Object)(object)sound.Source != (Object)null) { return IsUnderEnemyHierarchy(((Component)sound.Source).transform); } return false; } private static bool IsUnderEnemyHierarchy(Transform root) { if (!((Object)(object)((Component)root).GetComponentInParent<EnemyParent>(true) != (Object)null)) { return (Object)(object)((Component)root).GetComponentInParent<Enemy>(true) != (Object)null; } return true; } private static void RegisterEnemySounds(EnemyParent parent) { int instanceID = ((Object)parent).GetInstanceID(); if (SoundsByParentId.ContainsKey(instanceID)) { return; } HashSet<Sound> hashSet = new HashSet<Sound>(); MonoBehaviour[] componentsInChildren = ((Component)parent).GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } FieldInfo[] soundFields = GetSoundFields(((object)val).GetType()); foreach (FieldInfo fieldInfo in soundFields) { object? value = fieldInfo.GetValue(val); Sound val2 = (Sound)((value is Sound) ? value : null); if (val2 != null) { hashSet.Add(val2); } } } SoundsByParentId[instanceID] = hashSet; foreach (Sound item in hashSet) { EnemySounds.Add(item); } if (Chainloader.PluginInfos.ContainsKey("WesleysEnemies")) { MuteWesleyExtraAudio(parent); } } private static void MuteWesleyExtraAudio(EnemyParent parent) { bool flag = false; MonoBehaviour[] componentsInChildren = ((Component)parent).GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if ((Object)(object)val == (Object)null || ((object)val).GetType().Assembly.GetName().Name != "WesleysEnemies") { continue; } if (WesleyMutedAudioSourceFields.TryGetValue(((object)val).GetType().Name, out string[] value)) { string[] array = value; foreach (string fieldName in array) { TryMuteAudioSourceField(val, fieldName); } } if (((object)val).GetType().Name == "Gusher") { flag = true; } } if (flag) { MuteGusherAmbienceAudioSources(parent); } } private static void MuteGusherAmbienceAudioSources(EnemyParent parent) { Transform[] componentsInChildren = ((Component)parent).GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if (!(((Object)val).name != "Ambience")) { AudioSource[] components = ((Component)val).GetComponents<AudioSource>(); foreach (AudioSource val2 in components) { val2.mute = true; } } } } private static void TryMuteAudioSourceField(MonoBehaviour mb, string fieldName) { object? obj = ((object)mb).GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(mb); AudioSource val = (AudioSource)((obj is AudioSource) ? obj : null); if (val != null) { val.mute = true; } } private static void UnregisterEnemySounds(EnemyParent parent) { int instanceID = ((Object)parent).GetInstanceID(); if (!SoundsByParentId.Remove(instanceID, out HashSet<Sound> value)) { return; } foreach (Sound item in value) { EnemySounds.Remove(item); } } private static void ClearRegistry() { EnemySounds.Clear(); SoundsByParentId.Clear(); } private static FieldInfo[] GetSoundFields(Type type) { if (SoundFieldsByType.TryGetValue(type, out FieldInfo[] value)) { return value; } List<FieldInfo> list = new List<FieldInfo>(); Type type2 = type; while (type2 != null && type2 != typeof(MonoBehaviour)) { FieldInfo[] fields = type2.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType == typeof(Sound)) { list.Add(fieldInfo); } } type2 = type2.BaseType; } FieldInfo[] array = list.ToArray(); SoundFieldsByType[type] = array; return array; } } internal class WrongWayMapPatch { private static readonly int MainTexStId = Shader.PropertyToID("_MainTex_ST"); private static readonly Vector4 FlippedMainTexSt = new Vector4(-1f, -1f, 1f, 1f); private static readonly MaterialPropertyBlock FlipPropertyBlock = new MaterialPropertyBlock(); private static int _flippedDisplayMeshId; [HarmonyPostfix] [HarmonyPriority(0)] [HarmonyPatch(typeof(MapToolController), "Update")] private static void MapToolControllerUpdatePostfix(MapToolController __instance) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance.PlayerAvatar != (Object)(object)PlayerAvatar.instance) { return; } MeshRenderer displayMesh = __instance.DisplayMesh; if (!((Object)(object)displayMesh == (Object)null)) { int instanceID = ((Object)displayMesh).GetInstanceID(); if (ShouldFlipDisplay(__instance)) { ((Renderer)displayMesh).GetPropertyBlock(FlipPropertyBlock); FlipPropertyBlock.SetVector(MainTexStId, FlippedMainTexSt); ((Renderer)displayMesh).SetPropertyBlock(FlipPropertyBlock); _flippedDisplayMeshId = instanceID; } else if (_flippedDisplayMeshId == instanceID) { ((Renderer)displayMesh).SetPropertyBlock((MaterialPropertyBlock)null); _flippedDisplayMeshId = 0; } } } private static bool ShouldFlipDisplay(MapToolController controller) { if (((Component)controller.VisualTransform).gameObject.activeSelf) { return controller.HideLerp < 1f; } return false; } internal static void AfterUnpatchAll() { _flippedDisplayMeshId = 0; MapToolController[] array = Object.FindObjectsByType<MapToolController>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (MapToolController val in array) { if ((Object)(object)val.DisplayMesh != (Object)null) { ((Renderer)val.DisplayMesh).SetPropertyBlock((MaterialPropertyBlock)null); } } } } } namespace GastrodonGroup.MutatorsAddon.MutatorDefinitions.WrongWayMap { internal static class WrongWayMapMutator { internal const string Name = "MAP-side Down"; internal const string Description = "The minimap screen is rotated 180 degrees"; } } namespace GastrodonGroup.MutatorsAddon.MutatorDefinitions.SilentStalkers { internal static class SilentStalkersMutator { internal const string Name = "Silent Stalkers"; internal const string Description = "You cannot hear the enemy sounds"; } } namespace GastrodonGroup.MutatorsAddon.MutatorDefinitions.ParentsFriends { internal static class ParentsFriendsMutator { internal const string Name = "Parents Friends"; internal const string Description = "Loom and Huntman are eager to approach you,\nwith their kind hands and gun."; internal static ParentsFriendsMutatorSettings Settings { get; private set; } internal static void BindConfig(ConfigFile config) { Settings = new ParentsFriendsMutatorSettings("Parents Friends", "Loom and Huntman are eager to approach you,\nwith their kind hands and gun.", config); } } internal class ParentsFriendsMutatorSettings : GenericMutatorSettings { internal const string LoomMoveSpeedMultKey = "loom-move-speed-mult"; internal const string LoomAttackSpeedMultKey = "loom-attack-speed-mult"; internal const string HuntsmanMoveSpeedMultKey = "huntsman-move-speed-mult"; internal const string HuntsmanAimSpeedMultKey = "huntsman-aim-speed-mult"; internal const float MoveMultMin = 0.25f; internal const float MoveMultMax = 5f; internal const float AttackMultMin = 0.05f; internal const float AttackMultMax = 2f; internal const float AimMultMax = 1f; internal const float LoomMoveMultMin = 0.25f; internal const float LoomMoveMultMax = 5f; internal const float LoomAttackMultMin = 0.05f; internal const float LoomAttackMultMax = 2f; private readonly ConfigEntry<float> _loomMoveSpeedMult; private readonly ConfigEntry<float> _loomAttackSpeedMult; private readonly ConfigEntry<float> _huntsmanMoveSpeedMult; private readonly ConfigEntry<float> _huntsmanAimSpeedMult; internal float LoomMoveSpeedMult => ((GenericMutatorSettings)this).GetClampedRuntimeOverride<float>("loom-move-speed-mult", _loomMoveSpeedMult); internal float LoomAttackSpeedMult => ((GenericMutatorSettings)this).GetClampedRuntimeOverride<float>("loom-attack-speed-mult", _loomAttackSpeedMult); internal float HuntsmanMoveSpeedMult => ((GenericMutatorSettings)this).GetClampedRuntimeOverride<float>("huntsman-move-speed-mult", _huntsmanMoveSpeedMult); internal float HuntsmanAimSpeedMult => ((GenericMutatorSettings)this).GetClampedRuntimeOverride<float>("huntsman-aim-speed-mult", _huntsmanAimSpeedMult); internal ParentsFriendsMutatorSettings(string name, string description, ConfigFile config) : base("GastrodonGroup.MutatorsAddon", name, description, config) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown string section = GenericMutatorSettings.GetSection(name); _loomMoveSpeedMult = config.Bind<float>(section, "Loom move speed multiplier", 2f, new ConfigDescription("Follow and leave speed for Loom. <1 slower, >1 faster.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 5f), Array.Empty<object>())); _loomAttackSpeedMult = config.Bind<float>(section, "Loom attack speed multiplier", 0.2f, new ConfigDescription("Reach-out and hand-return speed. Slap clap stays normal. CoolDown length unchanged.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 2f), Array.Empty<object>())); _huntsmanMoveSpeedMult = config.Bind<float>(section, "Huntsman move speed multiplier", 3f, new ConfigDescription("Roam / investigate / leave move speed for Huntsman. <1 slower, >1 faster.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 5f), Array.Empty<object>())); _huntsmanAimSpeedMult = config.Bind<float>(section, "Huntsman aim speed multiplier", 0.5f, new ConfigDescription("Scales StateAim wait after the 'ha!' (lower = longer hold before shoot; max 1 = vanilla aim length). Aim point freezes on aim start. Shoot itself unchanged.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 1f), Array.Empty<object>())); } } } namespace GastrodonGroup.MutatorsAddon.MutatorDefinitions.BadDog { internal static class BadDogMutator { internal const string Name = "Watchdog Out!"; internal const string Description = "Elsa transforms on sight instead of waiting for pets"; internal static BadDogMutatorSettings Settings { get; private set; } internal static void BindConfig(ConfigFile config) { Settings = new BadDogMutatorSettings("Watchdog Out!", "Elsa transforms on sight instead of waiting for pets", config); } } internal class BadDogMutatorSettings : GenericMutatorSettings { internal const string TransformCooldownKey = "transform-cooldown"; private readonly ConfigEntry<float> _transformCooldown; internal float TransformCooldown => ((GenericMutatorSettings)this).GetClampedRuntimeOverride<float>("transform-cooldown", _transformCooldown); internal BadDogMutatorSettings(string name, string description, ConfigFile config) : base("GastrodonGroup.MutatorsAddon", name, description, config) { _transformCooldown = config.Bind<float>(GenericMutatorSettings.GetSection(name), "Transform cooldown", 50f, "Seconds before Elsa can instantly transform again after leaving."); } } } namespace GastrodonGroup.MutatorsAddon.Behaviours { internal class BadDogBehaviour : MonoBehaviour { public float NoticeCooldown { get; internal set; } internal bool PendingLeaveAfterShrink { get; set; } private void Update() { if (!(NoticeCooldown <= 0f) && SemiFunc.IsMasterClientOrSingleplayer()) { NoticeCooldown -= Time.deltaTime; } } internal bool CanNotice() { return NoticeCooldown <= 0f; } } internal class ParentsFriendsHunterBehaviour : MonoBehaviour { private EnemyHunter? _hunter; private float _originalDefaultSpeed; private float _originalDefaultAcceleration; private float _originalPositionSpeedIdle; private float _originalPositionSpeedChase; private bool _applied; private bool _pending; internal float MoveMult { get; private set; } = 1f; internal float AimMult { get; private set; } = 1f; internal bool AimLocked { get; set; } internal bool PendingAimTimerScale { get; set; } internal void RequestApply(EnemyHunter hunter, float moveMult, float aimMult) { _hunter = hunter; MoveMult = Mathf.Clamp(moveMult, 0.25f, 5f); AimMult = Mathf.Clamp(aimMult, 0.05f, 1f); _pending = true; TryApply(); } private void Update() { if (_pending && !_applied) { TryApply(); } } internal void ClearAimLock() { AimLocked = false; PendingAimTimerScale = false; } private void TryApply() { if (_applied || (Object)(object)_hunter == (Object)null) { return; } Enemy enemy = _hunter.enemy; if (!((Object)(object)enemy == (Object)null)) { EnemyNavMeshAgent navMeshAgent = enemy.NavMeshAgent; EnemyRigidbody rigidbody = enemy.Rigidbody; if (!((Object)(object)navMeshAgent == (Object)null) && !((Object)(object)rigidbody == (Object)null) && !((Object)(object)navMeshAgent.Agent == (Object)null)) { _originalDefaultSpeed = navMeshAgent.DefaultSpeed; _originalDefaultAcceleration = navMeshAgent.DefaultAcceleration; _originalPositionSpeedIdle = rigidbody.positionSpeedIdle; _originalPositionSpeedChase = rigidbody.positionSpeedChase; navMeshAgent.DefaultSpeed = _originalDefaultSpeed * MoveMult; navMeshAgent.Agent.speed = navMeshAgent.DefaultSpeed; rigidbody.positionSpeedIdle = _originalPositionSpeedIdle * MoveMult; rigidbody.positionSpeedChase = _originalPositionSpeedChase * MoveMult; _applied = true; _pending = false; } } } internal void Restore() { _pending = false; ClearAimLock(); if (!_applied || (Object)(object)_hunter == (Object)null) { return; } Enemy enemy = _hunter.enemy; if ((Object)(object)enemy == (Object)null) { _applied = false; return; } EnemyNavMeshAgent navMeshAgent = enemy.NavMeshAgent; EnemyRigidbody rigidbody = enemy.Rigidbody; if ((Object)(object)navMeshAgent != (Object)null) { navMeshAgent.DefaultSpeed = _originalDefaultSpeed; navMeshAgent.DefaultAcceleration = _originalDefaultAcceleration; if ((Object)(object)navMeshAgent.Agent != (Object)null) { navMeshAgent.Agent.speed = _originalDefaultSpeed; } } if ((Object)(object)rigidbody != (Object)null) { rigidbody.positionSpeedIdle = _originalPositionSpeedIdle; rigidbody.positionSpeedChase = _originalPositionSpeedChase; } _applied = false; } private void OnDestroy() { Restore(); } } internal class ParentsFriendsLoomBehaviour : MonoBehaviour { private const float HandsHomeDistance = 0.28f; private const float MaxHandAttackLockSeconds = 45f; private EnemyShadow? _shadow; private float _originalDefaultSpeed; private float _originalDefaultAcceleration; private float _originalPositionSpeedIdle; private float _originalPositionSpeedChase; private bool _applied; private bool _pending; private float _handAttackLockStartTime; internal float MoveMult { get; private set; } = 1f; internal float AttackMult { get; private set; } = 1f; internal bool HandAttackLock { get; private set; } internal void RequestApply(EnemyShadow shadow, float moveMult, float attackMult) { _shadow = shadow; MoveMult = Mathf.Clamp(moveMult, 0.25f, 5f); AttackMult = Mathf.Clamp(attackMult, 0.05f, 2f); _pending = true; TryApply(); } private void Update() { if (_pending && !_applied) { TryApply(); } if (HandAttackLock) { TryEndHandAttackLock(); } } internal void BeginHandAttackLock() { if (!HandAttackLock) { HandAttackLock = true; _handAttackLockStartTime = Time.time; } } internal void ClearHandAttackLock() { HandAttackLock = false; } internal void TryEndHandAttackLock() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Invalid comparison between Unknown and I4 //IL_0083: 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_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) if (!HandAttackLock || (Object)(object)_shadow == (Object)null) { return; } if (Time.time - _handAttackLockStartTime >= 45f) { HandAttackLock = false; } else { if ((int)_shadow.currentState == 5) { return; } Transform rightWristPivot = _shadow.rightWristPivot; Transform leftWristPivot = _shadow.leftWristPivot; if ((Object)(object)rightWristPivot == (Object)null || (Object)(object)leftWristPivot == (Object)null) { HandAttackLock = false; return; } GetHandRestLocalPositions(_shadow, out var rightRest, out var leftRest); float num = Vector3.Distance(rightWristPivot.localPosition, rightRest); float num2 = Vector3.Distance(leftWristPivot.localPosition, leftRest); if (num <= 0.28f && num2 <= 0.28f) { HandAttackLock = false; } } } private static void GetHandRestLocalPositions(EnemyShadow shadow, out Vector3 rightRest, out Vector3 leftRest) { //IL_0002: 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_000e: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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) rightRest = shadow.originalRightWristPosition; leftRest = shadow.originalLeftWristPosition; int bendState = shadow.bendState; if (bendState >= 0) { List<Vector3> rightBendHandPoses = shadow.rightBendHandPoses; List<Vector3> leftBendHandPoses = shadow.leftBendHandPoses; if (rightBendHandPoses != null && leftBendHandPoses != null && bendState < rightBendHandPoses.Count && bendState < leftBendHandPoses.Count) { rightRest = rightBendHandPoses[bendState]; leftRest = leftBendHandPoses[bendState]; } } } private void TryApply() { if (_applied || (Object)(object)_shadow == (Object)null) { return; } Enemy enemy = _shadow.enemy; if (!((Object)(object)enemy == (Object)null)) { EnemyNavMeshAgent navMeshAgent = enemy.NavMeshAgent; EnemyRigidbody rigidbody = enemy.Rigidbody; if (!((Object)(object)navMeshAgent == (Object)null) && !((Object)(object)rigidbody == (Object)null) && !((Object)(object)navMeshAgent.Agent == (Object)null)) { _originalDefaultSpeed = navMeshAgent.DefaultSpeed; _originalDefaultAcceleration = navMeshAgent.DefaultAcceleration; _originalPositionSpeedIdle = rigidbody.positionSpeedIdle; _originalPositionSpeedChase = rigidbody.positionSpeedChase; navMeshAgent.DefaultSpeed = _originalDefaultSpeed * MoveMult; navMeshAgent.Agent.speed = navMeshAgent.DefaultSpeed; rigidbody.positionSpeedIdle = _originalPositionSpeedIdle * MoveMult; rigidbody.positionSpeedChase = _originalPositionSpeedChase * MoveMult; _applied = true; _pending = false; } } } internal void Restore() { _pending = false; HandAttackLock = false; if (!_applied || (Object)(object)_shadow == (Object)null) { return; } Enemy enemy = _shadow.enemy; if ((Object)(object)enemy == (Object)null) { _applied = false; return; } EnemyNavMeshAgent navMeshAgent = enemy.NavMeshAgent; EnemyRigidbody rigidbody = enemy.Rigidbody; if ((Object)(object)navMeshAgent != (Object)null) { navMeshAgent.DefaultSpeed = _originalDefaultSpeed; navMeshAgent.DefaultAcceleration = _originalDefaultAcceleration; if ((Object)(object)navMeshAgent.Agent != (Object)null) { navMeshAgent.Agent.speed = _originalDefaultSpeed; } } if ((Object)(object)rigidbody != (Object)null) { rigidbody.positionSpeedIdle = _originalPositionSpeedIdle; rigidbody.positionSpeedChase = _originalPositionSpeedChase; } _applied = false; } private void OnDestroy() { Restore(); } } }