Decompiled source of Mutators Addon v0.3.0

BepInEx/plugins/GastrodonGroup-Mutators_Addon/MutatorsAddon.dll

Decompiled 3 weeks ago
using 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();
		}
	}
}