Decompiled source of EnemySpeedUp v4.0.0

EnemySpeedUp.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("REPOJP")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("zabuMod")]
[assembly: AssemblyTitle("zabuMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace EnemySpeedUp
{
	[BepInPlugin("REPOJP.EnemySpeedUp", "EnemySpeedUp", "4.0.0")]
	public sealed class EnemySpeedUpV2_AllVisuals : BaseUnityPlugin
	{
		[CompilerGenerated]
		private sealed class <CoLateSpawnSupport>d__15 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public EnemySpeedUpV2_AllVisuals <>4__this;

			private float <interval>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <CoLateSpawnSupport>d__15(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Expected O, but got Unknown
				//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Expected O, but got Unknown
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(2f);
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					break;
				case 2:
					<>1__state = -1;
					break;
				}
				if (EnemySpeedUpConfig.Enable != null && EnemySpeedUpConfig.Enable.Value)
				{
					LateSpawnSupport.Apply();
				}
				<interval>5__1 = 1f;
				if (EnemySpeedUpConfig.LateSpawnSupportIntervalSeconds != null)
				{
					<interval>5__1 = Mathf.Clamp(EnemySpeedUpConfig.LateSpawnSupportIntervalSeconds.Value, 0.25f, 5f);
				}
				<>2__current = (object)new WaitForSeconds(<interval>5__1);
				<>1__state = 2;
				return true;
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public const string PluginGuid = "REPOJP.EnemySpeedUp";

		public const string PluginName = "EnemySpeedUp";

		public const string PluginVersion = "4.0.0";

		private Harmony _harmony;

		private Coroutine _lateSpawnSupportCoroutine;

		private float _reloadAt;

		private bool _reloadQueued;

		internal static EnemySpeedUpV2_AllVisuals Instance { get; private set; }

		internal static ManualLogSource Log => ((BaseUnityPlugin)Instance).Logger;

		private void Awake()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			Instance = this;
			((Component)this).transform.parent = null;
			((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			EnemySpeedUpConfig.Bind(((BaseUnityPlugin)this).Config);
			((BaseUnityPlugin)this).Config.SettingChanged += OnSettingChanged;
			_harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
			_harmony.PatchAll();
			DynamicEnemyAnimPatcher.PatchAll(_harmony);
			DynamicEnemyTimerPatcher.PatchAll(_harmony);
			RuntimeCache.Rebuild();
			_lateSpawnSupportCoroutine = ((MonoBehaviour)this).StartCoroutine(CoLateSpawnSupport());
			Log.LogInfo((object)$"{((BaseUnityPlugin)this).Info.Metadata.GUID} v{((BaseUnityPlugin)this).Info.Metadata.Version} loaded");
		}

		private void OnDestroy()
		{
			try
			{
				if (((BaseUnityPlugin)this).Config != null)
				{
					((BaseUnityPlugin)this).Config.SettingChanged -= OnSettingChanged;
				}
			}
			catch
			{
			}
			try
			{
				if (_lateSpawnSupportCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(_lateSpawnSupportCoroutine);
					_lateSpawnSupportCoroutine = null;
				}
			}
			catch
			{
			}
			try
			{
				Harmony harmony = _harmony;
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}
			catch
			{
			}
		}

		[IteratorStateMachine(typeof(<CoLateSpawnSupport>d__15))]
		private IEnumerator CoLateSpawnSupport()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <CoLateSpawnSupport>d__15(0)
			{
				<>4__this = this
			};
		}

		private void Update()
		{
			if (_reloadQueued && !(Time.unscaledTime - _reloadAt < 0.25f))
			{
				_reloadQueued = false;
				RuntimeCache.Rebuild();
				ApplyUtil.ReapplyAll();
				if (EnemySpeedUpConfig.LogLevel.Value >= EnemySpeedUpLogLevel.Info)
				{
					RateLog.Info("ConfigReload", "Config reloaded. 設定再読み込み完了");
				}
			}
		}

		private void OnSettingChanged(object sender, SettingChangedEventArgs e)
		{
			_reloadAt = Time.unscaledTime;
			_reloadQueued = true;
		}
	}
	internal enum EnemySpeedUpLogLevel
	{
		Off,
		Error,
		Warn,
		Info,
		Debug
	}
	[Flags]
	internal enum EnemySpeedUpDamageRageAffects
	{
		None = 0,
		MoveNav = 1,
		MoveRb = 2,
		Anim = 4
	}
	internal enum EnemySpeedUpDamageRageMode
	{
		MissingHpRatio,
		CurrentHpRatio
	}
	internal static class EnemySpeedUpConfig
	{
		internal static ConfigEntry<bool> Enable;

		internal static ConfigEntry<float> NavMoveMultiplier;

		internal static ConfigEntry<float> NavAttackMoveMultiplier;

		internal static ConfigEntry<float> RbMoveMultiplier;

		internal static ConfigEntry<float> RbAttackMoveMultiplier;

		internal static ConfigEntry<float> AnimationSpeedMultiplier;

		internal static ConfigEntry<bool> EnableEnemyTimerAcceleration;

		internal static ConfigEntry<float> EnemyTimerMultiplier;

		internal static ConfigEntry<bool> EnableLateSpawnSupport;

		internal static ConfigEntry<float> LateSpawnSupportIntervalSeconds;

		internal static ConfigEntry<string> ExcludedEnemies;

		internal static ConfigEntry<EnemySpeedUpDamageRageMode> DamageRageMode;

		internal static ConfigEntry<float> DamageRageMaxMultiplier;

		internal static ConfigEntry<EnemySpeedUpDamageRageAffects> DamageRageAffects;

		internal static ConfigEntry<EnemySpeedUpLogLevel> LogLevel;

		internal static ConfigEntry<bool> LogAppliedMultipliers;

		internal static void Bind(ConfigFile config)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Expected O, but got Unknown
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Expected O, but got Unknown
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Expected O, but got Unknown
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Expected O, but got Unknown
			Enable = config.Bind<bool>("General", "Enable", true, "Enable or disable the mod. MOD有効/無効");
			NavMoveMultiplier = config.Bind<float>("Move", "NavMoveMultiplier", 2f, new ConfigDescription("NavMesh normal movement multiplier. NavMesh通常移動倍率", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 100f), Array.Empty<object>()));
			NavAttackMoveMultiplier = config.Bind<float>("Move", "NavAttackMoveMultiplier", 2f, new ConfigDescription("NavMesh attack movement multiplier. NavMesh攻撃中移動倍率", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 100f), Array.Empty<object>()));
			RbMoveMultiplier = config.Bind<float>("Move", "RbMoveMultiplier", 2f, new ConfigDescription("Rigidbody normal movement multiplier. Rigidbody通常移動倍率", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 100f), Array.Empty<object>()));
			RbAttackMoveMultiplier = config.Bind<float>("Move", "RbAttackMoveMultiplier", 2f, new ConfigDescription("Rigidbody attack movement multiplier. Rigidbody攻撃中移動倍率", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 100f), Array.Empty<object>()));
			AnimationSpeedMultiplier = config.Bind<float>("Anim", "AnimationSpeedMultiplier", 1f, new ConfigDescription("Global animation and visual speed multiplier for all enemy states. 敵の全状態の見た目速度倍率", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()));
			EnableEnemyTimerAcceleration = config.Bind<bool>("State", "EnableAttackIntervalAcceleration", false, "Enable enemy internal timer acceleration for attack interval, wait, cooldown, delay fields.スタン系を除いた攻撃間隔、待機、クールダウン、ディレイ系内部タイマー加速の有効化");
			EnemyTimerMultiplier = config.Bind<float>("State", "EnemyTimerMultiplier", 2f, new ConfigDescription("Enemy internal attack interval and wait timer multiplier. スタン系を除いた敵内部の攻撃間隔、待機タイマー倍率", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 100f), Array.Empty<object>()));
			EnableLateSpawnSupport = config.Bind<bool>("Runtime", "EnableLateSpawnSupport", true, "Apply speed setup and player awareness support to enemies spawned after level generation.レベル生成後に追加された敵へ速度設定とプレイヤー認識補助を適用");
			LateSpawnSupportIntervalSeconds = config.Bind<float>("Runtime", "LateSpawnSupportIntervalSeconds", 1f, new ConfigDescription("Late-spawn support interval seconds.途中生成敵サポートの実行間隔秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 5f), Array.Empty<object>()));
			ExcludedEnemies = config.Bind<string>("Exclude", "ExcludedEnemies", "EnemyCeilingEye", "Excluded enemy names in CSV. 除外敵名CSV");
			DamageRageMode = config.Bind<EnemySpeedUpDamageRageMode>("DamageRage", "DamageRageMode", EnemySpeedUpDamageRageMode.MissingHpRatio, "Damage rage calculation mode. 被ダメ加速計算方式");
			DamageRageMaxMultiplier = config.Bind<float>("DamageRage", "DamageRageMaxMultiplier", 2f, new ConfigDescription("Maximum rage multiplier. 被ダメ加速最大倍率", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			DamageRageAffects = config.Bind<EnemySpeedUpDamageRageAffects>("DamageRage", "DamageRageAffects", EnemySpeedUpDamageRageAffects.Anim, "Where damage rage applies. MoveNav/MoveRb/Anim. 被ダメ加速適用先");
			LogLevel = config.Bind<EnemySpeedUpLogLevel>("Logging", "LogLevel", EnemySpeedUpLogLevel.Info, "Log level. ログレベル");
			LogAppliedMultipliers = config.Bind<bool>("Logging", "LogAppliedMultipliers", false, "Log applied multipliers. 倍率適用ログ");
		}
	}
	internal static class FixedSpec
	{
		internal const bool MasterClientOnly = true;

		internal const bool ApplyClientVisuals = true;

		internal const float MinNavSpeed = 0.1f;

		internal const float MinRbSpeed = 0.1f;

		internal const float MinAnimSpeed = 0.01f;

		internal const float MaxVfxMultiplier = 3f;

		internal const float LogRateLimitSeconds = 10f;

		internal const float MinTimerMultiplier = 0.1f;

		internal const float MaxTimerMultiplier = 100f;
	}
	internal static class RuntimeCache
	{
		internal struct VfxSnapshot
		{
			internal Dictionary<int, float> ParticleSimulationSpeed;

			internal Dictionary<int, float> TrailTime;

			internal Dictionary<int, Vector2> LineTextureScale;

			internal static VfxSnapshot Capture(GameObject root)
			{
				//IL_0045: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0112: Unknown result type (might be due to invalid IL or missing references)
				VfxSnapshot vfxSnapshot = default(VfxSnapshot);
				vfxSnapshot.ParticleSimulationSpeed = new Dictionary<int, float>();
				vfxSnapshot.TrailTime = new Dictionary<int, float>();
				vfxSnapshot.LineTextureScale = new Dictionary<int, Vector2>();
				VfxSnapshot result = vfxSnapshot;
				ParticleSystem[] componentsInChildren = root.GetComponentsInChildren<ParticleSystem>(true);
				foreach (ParticleSystem val in componentsInChildren)
				{
					try
					{
						MainModule main = val.main;
						result.ParticleSimulationSpeed[((Object)val).GetInstanceID()] = ((MainModule)(ref main)).simulationSpeed;
					}
					catch
					{
					}
				}
				TrailRenderer[] componentsInChildren2 = root.GetComponentsInChildren<TrailRenderer>(true);
				foreach (TrailRenderer val2 in componentsInChildren2)
				{
					try
					{
						result.TrailTime[((Object)val2).GetInstanceID()] = val2.time;
					}
					catch
					{
					}
				}
				LineRenderer[] componentsInChildren3 = root.GetComponentsInChildren<LineRenderer>(true);
				foreach (LineRenderer val3 in componentsInChildren3)
				{
					try
					{
						Material sharedMaterial = ((Renderer)val3).sharedMaterial;
						if ((Object)(object)sharedMaterial != (Object)null && sharedMaterial.HasProperty("_MainTex"))
						{
							result.LineTextureScale[((Object)val3).GetInstanceID()] = sharedMaterial.mainTextureScale;
						}
					}
					catch
					{
					}
				}
				return result;
			}
		}

		internal static HashSet<string> ExcludedNames = new HashSet<string>(StringComparer.Ordinal);

		private static readonly Dictionary<Type, Func<object, Animator>> AnimatorGetterCache = new Dictionary<Type, Func<object, Animator>>();

		private static readonly Dictionary<int, float> LastAppliedAnimatorMultiplier = new Dictionary<int, float>();

		private static readonly Dictionary<int, VfxSnapshot> VfxSnapshots = new Dictionary<int, VfxSnapshot>();

		internal static void Rebuild()
		{
			ExcludedNames.Clear();
			if (string.IsNullOrWhiteSpace(EnemySpeedUpConfig.ExcludedEnemies.Value))
			{
				return;
			}
			string[] array = EnemySpeedUpConfig.ExcludedEnemies.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
			string[] array2 = array;
			foreach (string text in array2)
			{
				string text2 = text.Trim();
				if (text2.Length > 0)
				{
					ExcludedNames.Add(text2);
				}
			}
		}

		internal static bool IsExcluded(Component component)
		{
			if ((Object)(object)component == (Object)null)
			{
				return false;
			}
			if (ExcludedNames.Contains(((object)component).GetType().Name))
			{
				return true;
			}
			if ((Object)(object)component.gameObject != (Object)null && ExcludedNames.Contains(((Object)component.gameObject).name))
			{
				return true;
			}
			return false;
		}

		internal static bool TryGetAnimator(object instance, out Animator animator)
		{
			animator = null;
			if (instance == null)
			{
				return false;
			}
			Type type = instance.GetType();
			if (!AnimatorGetterCache.TryGetValue(type, out var value))
			{
				value = BuildAnimatorGetter(type);
				AnimatorGetterCache[type] = value;
			}
			if (value == null)
			{
				return false;
			}
			try
			{
				animator = value(instance);
				return (Object)(object)animator != (Object)null;
			}
			catch
			{
				animator = null;
				return false;
			}
		}

		private static Func<object, Animator> BuildAnimatorGetter(Type type)
		{
			string[] array = new string[4] { "animator", "Animator", "anim", "_animator" };
			string[] array2 = array;
			foreach (string text in array2)
			{
				FieldInfo field = AccessTools.Field(type, text);
				if (field != null && typeof(Animator).IsAssignableFrom(field.FieldType))
				{
					return delegate(object obj)
					{
						object? value2 = field.GetValue(obj);
						return (Animator)((value2 is Animator) ? value2 : null);
					};
				}
			}
			string[] array3 = array;
			foreach (string text2 in array3)
			{
				PropertyInfo property = AccessTools.Property(type, text2);
				if (property != null && typeof(Animator).IsAssignableFrom(property.PropertyType) && property.GetIndexParameters().Length == 0)
				{
					return delegate(object obj)
					{
						object? value = property.GetValue(obj, null);
						return (Animator)((value is Animator) ? value : null);
					};
				}
			}
			return null;
		}

		internal static float GetLastAnimatorMultiplier(Animator animator)
		{
			if ((Object)(object)animator == (Object)null)
			{
				return 1f;
			}
			if (LastAppliedAnimatorMultiplier.TryGetValue(((Object)animator).GetInstanceID(), out var value))
			{
				return value;
			}
			return 1f;
		}

		internal static void SetLastAnimatorMultiplier(Animator animator, float multiplier)
		{
			if (!((Object)(object)animator == (Object)null))
			{
				LastAppliedAnimatorMultiplier[((Object)animator).GetInstanceID()] = multiplier;
			}
		}

		internal static VfxSnapshot GetOrCreateVfxSnapshot(GameObject root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return default(VfxSnapshot);
			}
			int instanceID = ((Object)root).GetInstanceID();
			if (VfxSnapshots.TryGetValue(instanceID, out var value))
			{
				return value;
			}
			value = VfxSnapshot.Capture(root);
			VfxSnapshots[instanceID] = value;
			return value;
		}
	}
	internal static class RateLog
	{
		private static readonly Dictionary<string, float> LastAt = new Dictionary<string, float>(StringComparer.Ordinal);

		internal static void Info(string key, string message)
		{
			if (EnemySpeedUpConfig.LogLevel.Value >= EnemySpeedUpLogLevel.Info && Pass(key))
			{
				EnemySpeedUpV2_AllVisuals.Log.LogInfo((object)message);
			}
		}

		internal static void Warn(string key, string message)
		{
			if (EnemySpeedUpConfig.LogLevel.Value >= EnemySpeedUpLogLevel.Warn && Pass(key))
			{
				EnemySpeedUpV2_AllVisuals.Log.LogWarning((object)message);
			}
		}

		internal static void Debug(string key, string message)
		{
			if (EnemySpeedUpConfig.LogLevel.Value >= EnemySpeedUpLogLevel.Debug && Pass(key))
			{
				EnemySpeedUpV2_AllVisuals.Log.LogInfo((object)message);
			}
		}

		private static bool Pass(string key)
		{
			float unscaledTime = Time.unscaledTime;
			if (LastAt.TryGetValue(key, out var value) && unscaledTime - value < 10f)
			{
				return false;
			}
			LastAt[key] = unscaledTime;
			return true;
		}
	}
	internal static class ApplyUtil
	{
		private struct NavOriginal
		{
			internal float DefaultSpeed;

			internal float DefaultAcceleration;
		}

		private struct RbOriginal
		{
			internal float PositionSpeedIdle;

			internal float PositionSpeedChase;

			internal float RotationSpeedIdle;

			internal float RotationSpeedChase;
		}

		private static readonly Dictionary<int, NavOriginal> NavOriginals = new Dictionary<int, NavOriginal>();

		private static readonly Dictionary<int, RbOriginal> RbOriginals = new Dictionary<int, RbOriginal>();

		internal static void ReapplyAll()
		{
			EnemyNavMeshAgent[] array = Object.FindObjectsOfType<EnemyNavMeshAgent>(true);
			foreach (EnemyNavMeshAgent instance in array)
			{
				try
				{
					ApplyNav(instance);
				}
				catch
				{
				}
			}
			EnemyRigidbody[] array2 = Object.FindObjectsOfType<EnemyRigidbody>(true);
			foreach (EnemyRigidbody instance2 in array2)
			{
				try
				{
					ApplyRb(instance2);
				}
				catch
				{
				}
			}
		}

		internal static void ApplyNewOnly()
		{
			EnemyNavMeshAgent[] array = Object.FindObjectsOfType<EnemyNavMeshAgent>(true);
			foreach (EnemyNavMeshAgent val in array)
			{
				try
				{
					if (!((Object)(object)val == (Object)null) && !NavOriginals.ContainsKey(((Object)val).GetInstanceID()))
					{
						ApplyNav(val);
					}
				}
				catch
				{
				}
			}
			EnemyRigidbody[] array2 = Object.FindObjectsOfType<EnemyRigidbody>(true);
			foreach (EnemyRigidbody val2 in array2)
			{
				try
				{
					if (!((Object)(object)val2 == (Object)null) && !RbOriginals.ContainsKey(((Object)val2).GetInstanceID()))
					{
						ApplyRb(val2);
					}
				}
				catch
				{
				}
			}
		}

		internal static bool ShouldApplyGameplay(Component component)
		{
			if ((Object)(object)component == (Object)null)
			{
				return false;
			}
			if (!EnemySpeedUpConfig.Enable.Value)
			{
				return false;
			}
			if ((Object)(object)GameManager.instance == (Object)null)
			{
				return false;
			}
			if (RuntimeCache.IsExcluded(component))
			{
				return false;
			}
			if (GameManager.Multiplayer() && !PhotonNetwork.IsMasterClient)
			{
				return false;
			}
			return true;
		}

		internal static bool ShouldApplyVisual(Component component)
		{
			if ((Object)(object)component == (Object)null)
			{
				return false;
			}
			if (!EnemySpeedUpConfig.Enable.Value)
			{
				return false;
			}
			if ((Object)(object)GameManager.instance == (Object)null)
			{
				return false;
			}
			if (RuntimeCache.IsExcluded(component))
			{
				return false;
			}
			return true;
		}

		internal static void ApplyNav(EnemyNavMeshAgent instance)
		{
			if (!((Object)(object)instance == (Object)null) && ShouldApplyGameplay((Component)(object)instance))
			{
				int instanceID = ((Object)instance).GetInstanceID();
				if (!NavOriginals.TryGetValue(instanceID, out var value))
				{
					NavOriginal navOriginal = default(NavOriginal);
					navOriginal.DefaultSpeed = instance.DefaultSpeed;
					navOriginal.DefaultAcceleration = instance.DefaultAcceleration;
					value = navOriginal;
					NavOriginals[instanceID] = value;
				}
				float damageRageMultiplier = GetDamageRageMultiplier(((Component)instance).gameObject, EnemySpeedUpDamageRageAffects.MoveNav);
				float num = EnemySpeedUpConfig.NavMoveMultiplier.Value * damageRageMultiplier;
				instance.DefaultSpeed = Mathf.Max(0.1f, value.DefaultSpeed * num);
				instance.DefaultAcceleration = Mathf.Max(0f, value.DefaultAcceleration * num);
			}
		}

		internal static void ApplyRb(EnemyRigidbody instance)
		{
			if (!((Object)(object)instance == (Object)null) && ShouldApplyGameplay((Component)(object)instance))
			{
				int instanceID = ((Object)instance).GetInstanceID();
				if (!RbOriginals.TryGetValue(instanceID, out var value))
				{
					RbOriginal rbOriginal = default(RbOriginal);
					rbOriginal.PositionSpeedIdle = instance.positionSpeedIdle;
					rbOriginal.PositionSpeedChase = instance.positionSpeedChase;
					rbOriginal.RotationSpeedIdle = instance.rotationSpeedIdle;
					rbOriginal.RotationSpeedChase = instance.rotationSpeedChase;
					value = rbOriginal;
					RbOriginals[instanceID] = value;
				}
				float damageRageMultiplier = GetDamageRageMultiplier(((Component)instance).gameObject, EnemySpeedUpDamageRageAffects.MoveRb);
				float num = EnemySpeedUpConfig.RbMoveMultiplier.Value * damageRageMultiplier;
				instance.positionSpeedIdle = Mathf.Max(0.1f, value.PositionSpeedIdle * num);
				instance.positionSpeedChase = Mathf.Max(0.1f, value.PositionSpeedChase * num);
				instance.rotationSpeedIdle = Mathf.Max(0.1f, value.RotationSpeedIdle * num);
				instance.rotationSpeedChase = Mathf.Max(0.1f, value.RotationSpeedChase * num);
			}
		}

		internal static float GetVisualMultiplier(Component component)
		{
			if ((Object)(object)component == (Object)null)
			{
				return 1f;
			}
			float value = EnemySpeedUpConfig.AnimationSpeedMultiplier.Value;
			value *= GetDamageRageMultiplier(component.gameObject, EnemySpeedUpDamageRageAffects.Anim);
			return Mathf.Max(0.01f, value);
		}

		internal static float GetDamageRageMultiplier(GameObject owner, EnemySpeedUpDamageRageAffects target)
		{
			if ((Object)(object)owner == (Object)null)
			{
				return 1f;
			}
			if ((EnemySpeedUpConfig.DamageRageAffects.Value & target) == 0)
			{
				return 1f;
			}
			EnemyHealth val = owner.GetComponentInParent<EnemyHealth>();
			if ((Object)(object)val == (Object)null)
			{
				val = owner.GetComponent<EnemyHealth>();
			}
			if ((Object)(object)val == (Object)null)
			{
				return 1f;
			}
			if (val.dead)
			{
				return 1f;
			}
			float num = Mathf.Max(1f, (float)val.health);
			float num2 = Mathf.Clamp((float)val.healthCurrent, 0f, num);
			float num3 = num2 / num;
			EnemySpeedUpDamageRageMode value = EnemySpeedUpConfig.DamageRageMode.Value;
			EnemySpeedUpDamageRageMode enemySpeedUpDamageRageMode = value;
			float num4 = ((enemySpeedUpDamageRageMode == EnemySpeedUpDamageRageMode.MissingHpRatio || enemySpeedUpDamageRageMode != EnemySpeedUpDamageRageMode.CurrentHpRatio) ? (1f - num3) : (1f - num3));
			float num5 = Mathf.Max(1f, EnemySpeedUpConfig.DamageRageMaxMultiplier.Value);
			return 1f + num4 * (num5 - 1f);
		}

		internal static void ApplyAnimatorSpeed(Animator animator, float multiplier)
		{
			if (!((Object)(object)animator == (Object)null) && !(animator.speed <= 0f))
			{
				float lastAnimatorMultiplier = RuntimeCache.GetLastAnimatorMultiplier(animator);
				float num = animator.speed;
				if (lastAnimatorMultiplier > 0f)
				{
					num = animator.speed / lastAnimatorMultiplier;
				}
				float speed = Mathf.Max(0.01f, num * multiplier);
				animator.speed = speed;
				RuntimeCache.SetLastAnimatorMultiplier(animator, multiplier);
			}
		}

		internal static void ApplyVfx(GameObject root, float multiplier)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			float num = Mathf.Clamp(multiplier, 0f, 3f);
			RuntimeCache.VfxSnapshot orCreateVfxSnapshot = RuntimeCache.GetOrCreateVfxSnapshot(root);
			ParticleSystem[] componentsInChildren = root.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val in componentsInChildren)
			{
				try
				{
					if (orCreateVfxSnapshot.ParticleSimulationSpeed.TryGetValue(((Object)val).GetInstanceID(), out var value))
					{
						MainModule main = val.main;
						((MainModule)(ref main)).simulationSpeed = value * num;
					}
				}
				catch
				{
				}
			}
			TrailRenderer[] componentsInChildren2 = root.GetComponentsInChildren<TrailRenderer>(true);
			foreach (TrailRenderer val2 in componentsInChildren2)
			{
				try
				{
					if (orCreateVfxSnapshot.TrailTime.TryGetValue(((Object)val2).GetInstanceID(), out var value2))
					{
						val2.time = value2 / Mathf.Max(0.001f, num);
					}
				}
				catch
				{
				}
			}
			LineRenderer[] componentsInChildren3 = root.GetComponentsInChildren<LineRenderer>(true);
			foreach (LineRenderer val3 in componentsInChildren3)
			{
				try
				{
					if (orCreateVfxSnapshot.LineTextureScale.TryGetValue(((Object)val3).GetInstanceID(), out var value3))
					{
						Material material = ((Renderer)val3).material;
						if (!((Object)(object)material == (Object)null) && material.HasProperty("_MainTex"))
						{
							material.mainTextureScale = new Vector2(value3.x * num, value3.y);
						}
					}
				}
				catch
				{
				}
			}
		}
	}
	internal static class VisualContext
	{
		[ThreadStatic]
		private static int _depth;

		[ThreadStatic]
		private static float _multiplier;

		internal static bool Active => _depth > 0;

		internal static float Multiplier => (_multiplier > 0f) ? _multiplier : 1f;

		internal static void Enter(Component component)
		{
			_depth++;
			_multiplier = (((Object)(object)component != (Object)null) ? ApplyUtil.GetVisualMultiplier(component) : 1f);
		}

		internal static void Exit()
		{
			_depth--;
			if (_depth <= 0)
			{
				_depth = 0;
				_multiplier = 1f;
			}
		}

		internal static float GetScaledDeltaTime(float original)
		{
			if (!Active)
			{
				return original;
			}
			return original * Multiplier;
		}
	}
	internal static class OverrideGuard
	{
		private static readonly Dictionary<long, int> LastFrameByKey = new Dictionary<long, int>();

		internal static bool TryEnter(Component owner, int methodKind)
		{
			if ((Object)(object)owner == (Object)null)
			{
				return true;
			}
			int frameCount = Time.frameCount;
			long key = ((long)((Object)owner).GetInstanceID() << 8) ^ (uint)methodKind;
			if (LastFrameByKey.TryGetValue(key, out var value) && value == frameCount)
			{
				return false;
			}
			LastFrameByKey[key] = frameCount;
			return true;
		}
	}
	internal static class DynamicEnemyAnimPatcher
	{
		[CompilerGenerated]
		private sealed class <DeltaTimeTranspiler>d__5 : IEnumerable<CodeInstruction>, IEnumerable, IEnumerator<CodeInstruction>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private CodeInstruction <>2__current;

			private int <>l__initialThreadId;

			private IEnumerable<CodeInstruction> instructions;

			public IEnumerable<CodeInstruction> <>3__instructions;

			private MethodInfo <getter>5__1;

			private MethodInfo <scaled>5__2;

			private IEnumerator<CodeInstruction> <>s__3;

			private CodeInstruction <instruction>5__4;

			CodeInstruction IEnumerator<CodeInstruction>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DeltaTimeTranspiler>d__5(int <>1__state)
			{
				this.<>1__state = <>1__state;
				<>l__initialThreadId = Environment.CurrentManagedThreadId;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				int num = <>1__state;
				if (num == -3 || (uint)(num - 1) <= 1u)
				{
					try
					{
					}
					finally
					{
						<>m__Finally1();
					}
				}
				<getter>5__1 = null;
				<scaled>5__2 = null;
				<>s__3 = null;
				<instruction>5__4 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_00db: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e5: Expected O, but got Unknown
				try
				{
					switch (<>1__state)
					{
					default:
						return false;
					case 0:
						<>1__state = -1;
						<getter>5__1 = AccessTools.PropertyGetter(typeof(Time), "deltaTime");
						<scaled>5__2 = AccessTools.Method(typeof(VisualContext), "GetScaledDeltaTime", (Type[])null, (Type[])null);
						<>s__3 = instructions.GetEnumerator();
						<>1__state = -3;
						break;
					case 1:
						<>1__state = -3;
						if (CodeInstructionExtensions.Calls(<instruction>5__4, <getter>5__1))
						{
							<>2__current = new CodeInstruction(OpCodes.Call, (object)<scaled>5__2);
							<>1__state = 2;
							return true;
						}
						goto IL_00f9;
					case 2:
						{
							<>1__state = -3;
							goto IL_00f9;
						}
						IL_00f9:
						<instruction>5__4 = null;
						break;
					}
					if (<>s__3.MoveNext())
					{
						<instruction>5__4 = <>s__3.Current;
						<>2__current = <instruction>5__4;
						<>1__state = 1;
						return true;
					}
					<>m__Finally1();
					<>s__3 = null;
					return false;
				}
				catch
				{
					//try-fault
					((IDisposable)this).Dispose();
					throw;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			private void <>m__Finally1()
			{
				<>1__state = -1;
				if (<>s__3 != null)
				{
					<>s__3.Dispose();
				}
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}

			[DebuggerHidden]
			IEnumerator<CodeInstruction> IEnumerable<CodeInstruction>.GetEnumerator()
			{
				<DeltaTimeTranspiler>d__5 <DeltaTimeTranspiler>d__;
				if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
				{
					<>1__state = 0;
					<DeltaTimeTranspiler>d__ = this;
				}
				else
				{
					<DeltaTimeTranspiler>d__ = new <DeltaTimeTranspiler>d__5(0);
				}
				<DeltaTimeTranspiler>d__.instructions = <>3__instructions;
				return <DeltaTimeTranspiler>d__;
			}

			[DebuggerHidden]
			IEnumerator IEnumerable.GetEnumerator()
			{
				return ((IEnumerable<CodeInstruction>)this).GetEnumerator();
			}
		}

		private static bool _patched;

		private static readonly string[] TargetTypes = new string[32]
		{
			"EnemyAnimalAnim", "EnemyBangAnim", "EnemyBeamerAnim", "EnemyBirthdayBoy", "EnemyBombThrowerAnim", "EnemyBowtieAnim", "EnemyCeilingEyeAnim", "EnemyDuckAnim", "EnemyElsaAnim", "EnemyFloaterAnim",
			"EnemyGnomeAnim", "EnemyHeadAnimationSystem", "EnemyHeadVisual", "EnemyHeadEye", "EnemyHeadGrabberAnim", "EnemyHeartHugger", "EnemyHiddenAnim", "EnemyHunterAnim", "EnemyOogly", "EnemyRobeAnim",
			"EnemyRunnerAnim", "EnemyShadowAnim", "EnemySlowMouthAnim", "EnemySlowWalkerAnim", "EnemySpinnyAnim", "EnemyThinManAnim", "EnemyTickAnim", "EnemyTricycle", "EnemyTricycleVisuals", "EnemyTumblerAnim",
			"EnemyUpscreamAnim", "EnemyValuableThrowerAnim"
		};

		internal static void PatchAll(Harmony harmony)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			if (_patched || harmony == null)
			{
				return;
			}
			Assembly assembly = typeof(Enemy).Assembly;
			HarmonyMethod val = new HarmonyMethod(typeof(DynamicEnemyAnimPatcher).GetMethod("VisualMethodPrefix", BindingFlags.Static | BindingFlags.NonPublic));
			HarmonyMethod val2 = new HarmonyMethod(typeof(DynamicEnemyAnimPatcher).GetMethod("VisualMethodPostfix", BindingFlags.Static | BindingFlags.NonPublic));
			HarmonyMethod val3 = new HarmonyMethod(typeof(DynamicEnemyAnimPatcher).GetMethod("DeltaTimeTranspiler", BindingFlags.Static | BindingFlags.NonPublic));
			int num = 0;
			string[] targetTypes = TargetTypes;
			foreach (string name in targetTypes)
			{
				Type type = assembly.GetType(name);
				if (type == null)
				{
					continue;
				}
				MethodInfo[] methods = type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				MethodInfo[] array = methods;
				foreach (MethodInfo methodInfo in array)
				{
					if (!methodInfo.IsAbstract && !methodInfo.IsGenericMethod && !methodInfo.ContainsGenericParameters && methodInfo.GetMethodBody() != null && !methodInfo.IsSpecialName)
					{
						try
						{
							harmony.Patch((MethodBase)methodInfo, val, val2, val3, (HarmonyMethod)null, (HarmonyMethod)null);
							num++;
						}
						catch
						{
						}
					}
				}
			}
			if (EnemySpeedUpConfig.LogLevel.Value >= EnemySpeedUpLogLevel.Info)
			{
				RateLog.Info("DynamicPatch", $"Dynamic enemy visual patches applied: {num}");
			}
			_patched = true;
		}

		private static void VisualMethodPrefix(object __instance)
		{
			Component val = (Component)((__instance is Component) ? __instance : null);
			if (val != null && ApplyUtil.ShouldApplyVisual(val))
			{
				VisualContext.Enter(val);
			}
			else
			{
				VisualContext.Enter(null);
			}
		}

		private static void VisualMethodPostfix(object __instance)
		{
			try
			{
				Component val = (Component)((__instance is Component) ? __instance : null);
				if (val != null && ApplyUtil.ShouldApplyVisual(val))
				{
					if (RuntimeCache.TryGetAnimator(__instance, out var animator) && (Object)(object)animator != (Object)null)
					{
						ApplyUtil.ApplyAnimatorSpeed(animator, ApplyUtil.GetVisualMultiplier(val));
					}
					ApplyUtil.ApplyVfx(val.gameObject, ApplyUtil.GetVisualMultiplier(val));
				}
			}
			catch
			{
			}
			finally
			{
				VisualContext.Exit();
			}
		}

		[IteratorStateMachine(typeof(<DeltaTimeTranspiler>d__5))]
		private static IEnumerable<CodeInstruction> DeltaTimeTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DeltaTimeTranspiler>d__5(-2)
			{
				<>3__instructions = instructions
			};
		}
	}
	[HarmonyPatch(typeof(SemiFunc), "SpringFloatGet")]
	internal static class Patch_SemiFunc_SpringFloatGet
	{
		private static void Prefix(SpringFloat _attributes, ref float _deltaTime, out float __state)
		{
			__state = 0f;
			if (VisualContext.Active && _attributes != null)
			{
				float multiplier = VisualContext.Multiplier;
				__state = _attributes.speed;
				_attributes.speed *= multiplier;
				if (_deltaTime == -1f)
				{
					_deltaTime = Time.deltaTime * multiplier;
				}
				else
				{
					_deltaTime *= multiplier;
				}
			}
		}

		private static void Postfix(SpringFloat _attributes, float __state)
		{
			if (VisualContext.Active && _attributes != null && __state > 0f)
			{
				_attributes.speed = __state;
			}
		}
	}
	[HarmonyPatch(typeof(SemiFunc), "SpringQuaternionGet")]
	internal static class Patch_SemiFunc_SpringQuaternionGet
	{
		private static void Prefix(SpringQuaternion _attributes, ref float _deltaTime, out float __state)
		{
			__state = 0f;
			if (VisualContext.Active && _attributes != null)
			{
				float multiplier = VisualContext.Multiplier;
				__state = _attributes.speed;
				_attributes.speed *= multiplier;
				if (_deltaTime == -1f)
				{
					_deltaTime = Time.deltaTime * multiplier;
				}
				else
				{
					_deltaTime *= multiplier;
				}
			}
		}

		private static void Postfix(SpringQuaternion _attributes, float __state)
		{
			if (VisualContext.Active && _attributes != null && __state > 0f)
			{
				_attributes.speed = __state;
			}
		}
	}
	[HarmonyPatch(typeof(SemiFunc), "SpringVector3Get")]
	internal static class Patch_SemiFunc_SpringVector3Get
	{
		private static void Prefix(SpringVector3 _attributes, ref float _deltaTime, out float __state)
		{
			__state = 0f;
			if (VisualContext.Active && _attributes != null)
			{
				float multiplier = VisualContext.Multiplier;
				__state = _attributes.speed;
				_attributes.speed *= multiplier;
				if (_deltaTime == -1f)
				{
					_deltaTime = Time.deltaTime * multiplier;
				}
				else
				{
					_deltaTime *= multiplier;
				}
			}
		}

		private static void Postfix(SpringVector3 _attributes, float __state)
		{
			if (VisualContext.Active && _attributes != null && __state > 0f)
			{
				_attributes.speed = __state;
			}
		}
	}
	internal static class LateSpawnSupport
	{
		private static readonly Dictionary<int, float> LastPlayerAwarenessAt = new Dictionary<int, float>();

		private static readonly FieldInfo EnemyParentSetupDoneField = AccessTools.Field(typeof(EnemyParent), "SetupDone");

		internal static void Apply()
		{
			if (EnemySpeedUpConfig.EnableLateSpawnSupport != null && EnemySpeedUpConfig.EnableLateSpawnSupport.Value && !((Object)(object)GameManager.instance == (Object)null) && (!GameManager.Multiplayer() || PhotonNetwork.IsMasterClient))
			{
				ReleaseLateSpawnedEnemyParents();
				ApplyUtil.ApplyNewOnly();
				SyncPlayersToEnemies();
			}
		}

		private static void ReleaseLateSpawnedEnemyParents()
		{
			if ((Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated || EnemyParentSetupDoneField == null)
			{
				return;
			}
			EnemyParent[] array = Object.FindObjectsOfType<EnemyParent>(true);
			foreach (EnemyParent val in array)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null || !((Component)val).gameObject.activeInHierarchy)
				{
					continue;
				}
				try
				{
					if (!(EnemyParentSetupDoneField.GetValue(val) is int num) || num == 0)
					{
						Enemy componentInChildren = ((Component)val).GetComponentInChildren<Enemy>(true);
						if (!((Object)(object)componentInChildren == (Object)null))
						{
							EnemyParentSetupDoneField.SetValue(val, true);
						}
					}
				}
				catch
				{
				}
			}
		}

		private static void SyncPlayersToEnemies()
		{
			if ((Object)(object)GameDirector.instance == (Object)null || GameDirector.instance.PlayerList == null)
			{
				return;
			}
			PlayerAvatar[] array = GameDirector.instance.PlayerList.ToArray();
			if (array.Length == 0)
			{
				return;
			}
			Enemy[] array2 = Object.FindObjectsOfType<Enemy>(true);
			foreach (Enemy val in array2)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null || !((Component)val).gameObject.activeInHierarchy)
				{
					continue;
				}
				int instanceID = ((Object)val).GetInstanceID();
				if (LastPlayerAwarenessAt.TryGetValue(instanceID, out var value) && Time.time - value < 3f)
				{
					continue;
				}
				LastPlayerAwarenessAt[instanceID] = Time.time;
				foreach (PlayerAvatar val2 in array)
				{
					if (!((Object)(object)val2 == (Object)null) && !val2.isDisabled && !((Object)(object)val2.photonView == (Object)null))
					{
						try
						{
							val.PlayerAdded(val2.photonView.ViewID);
						}
						catch
						{
						}
					}
				}
			}
		}
	}
	internal static class EnemyTimerAcceleration
	{
		private static readonly Dictionary<Type, List<FieldInfo>> TimerFieldsByType = new Dictionary<Type, List<FieldInfo>>();

		internal static void Apply(Component component, float deltaTime)
		{
			if ((Object)(object)component == (Object)null || !EnemySpeedUpConfig.Enable.Value || !EnemySpeedUpConfig.EnableEnemyTimerAcceleration.Value || RuntimeCache.IsExcluded(component) || (GameManager.Multiplayer() && !PhotonNetwork.IsMasterClient))
			{
				return;
			}
			float num = Mathf.Clamp(EnemySpeedUpConfig.EnemyTimerMultiplier.Value, 0.1f, 100f);
			if (num <= 1.001f)
			{
				return;
			}
			float num2 = deltaTime * (num - 1f);
			if (num2 <= 0f)
			{
				return;
			}
			List<FieldInfo> timerFields = GetTimerFields(((object)component).GetType());
			for (int i = 0; i < timerFields.Count; i++)
			{
				FieldInfo fieldInfo = timerFields[i];
				try
				{
					object value = fieldInfo.GetValue(component);
					if (value is float)
					{
						float num3 = (float)value;
						if (!(num3 <= 0f))
						{
							fieldInfo.SetValue(component, Mathf.Max(0f, num3 - num2));
						}
					}
				}
				catch
				{
				}
			}
		}

		private static List<FieldInfo> GetTimerFields(Type type)
		{
			if (type == null)
			{
				return new List<FieldInfo>();
			}
			if (TimerFieldsByType.TryGetValue(type, out var value))
			{
				return value;
			}
			List<FieldInfo> list = new List<FieldInfo>();
			FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (!(fieldInfo.FieldType != typeof(float)) && LooksLikeAttackIntervalTimerField(fieldInfo.Name))
				{
					list.Add(fieldInfo);
				}
			}
			TimerFieldsByType[type] = list;
			return list;
		}

		private static bool LooksLikeAttackIntervalTimerField(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return false;
			}
			string text = name.ToLowerInvariant();
			if (text.Contains("stun") || text.Contains("freeze") || text.Contains("frozen") || text.Contains("invincible") || text.Contains("invulnerable") || text.Contains("indestructible") || text.Contains("tumble") || text.Contains("hurt") || text.Contains("damage") || text.Contains("death") || text.Contains("dead") || text.Contains("disable") || text.Contains("disabled") || text.Contains("spawn") || text.Contains("despawn"))
			{
				return false;
			}
			return text.Contains("timer") || text.Contains("cooldown") || text.Contains("delay") || text.Contains("pause") || text.Contains("wait") || text.Contains("interval");
		}
	}
	internal static class DynamicEnemyTimerPatcher
	{
		private static bool _patched;

		internal static void PatchAll(Harmony harmony)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			if (_patched || harmony == null)
			{
				return;
			}
			Assembly assembly = typeof(Enemy).Assembly;
			HarmonyMethod val = new HarmonyMethod(typeof(DynamicEnemyTimerPatcher).GetMethod("UpdatePostfix", BindingFlags.Static | BindingFlags.NonPublic));
			HarmonyMethod val2 = new HarmonyMethod(typeof(DynamicEnemyTimerPatcher).GetMethod("FixedUpdatePostfix", BindingFlags.Static | BindingFlags.NonPublic));
			int num = 0;
			Type[] types = assembly.GetTypes();
			foreach (Type type in types)
			{
				if (type == null || !typeof(Component).IsAssignableFrom(type) || !type.Name.StartsWith("Enemy", StringComparison.Ordinal))
				{
					continue;
				}
				MethodInfo declaredInstanceMethodNoWarn = GetDeclaredInstanceMethodNoWarn(type, "Update");
				if (declaredInstanceMethodNoWarn != null && !declaredInstanceMethodNoWarn.IsStatic && declaredInstanceMethodNoWarn.GetMethodBody() != null)
				{
					try
					{
						harmony.Patch((MethodBase)declaredInstanceMethodNoWarn, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						num++;
					}
					catch
					{
					}
				}
				MethodInfo declaredInstanceMethodNoWarn2 = GetDeclaredInstanceMethodNoWarn(type, "FixedUpdate");
				if (declaredInstanceMethodNoWarn2 != null && !declaredInstanceMethodNoWarn2.IsStatic && declaredInstanceMethodNoWarn2.GetMethodBody() != null)
				{
					try
					{
						harmony.Patch((MethodBase)declaredInstanceMethodNoWarn2, (HarmonyMethod)null, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
						num++;
					}
					catch
					{
					}
				}
			}
			if (EnemySpeedUpConfig.LogLevel.Value >= EnemySpeedUpLogLevel.Info)
			{
				RateLog.Info("DynamicTimerPatch", "Dynamic enemy attack interval timer patches applied: " + num);
			}
			_patched = true;
		}

		private static MethodInfo GetDeclaredInstanceMethodNoWarn(Type type, string methodName)
		{
			if (type == null || string.IsNullOrEmpty(methodName))
			{
				return null;
			}
			try
			{
				return type.GetMethod(methodName, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
			}
			catch
			{
				return null;
			}
		}

		private static void UpdatePostfix(object __instance)
		{
			Component component = (Component)((__instance is Component) ? __instance : null);
			EnemyTimerAcceleration.Apply(component, Time.deltaTime);
		}

		private static void FixedUpdatePostfix(object __instance)
		{
			Component component = (Component)((__instance is Component) ? __instance : null);
			EnemyTimerAcceleration.Apply(component, Time.fixedDeltaTime);
		}
	}
	[HarmonyPatch(typeof(EnemyNavMeshAgent), "Awake")]
	internal static class Patch_EnemyNavMeshAgent_Awake
	{
		private static void Postfix(EnemyNavMeshAgent __instance)
		{
			ApplyUtil.ApplyNav(__instance);
		}
	}
	[HarmonyPatch(typeof(EnemyNavMeshAgent), "OnEnable")]
	internal static class Patch_EnemyNavMeshAgent_OnEnable
	{
		private static void Postfix(EnemyNavMeshAgent __instance)
		{
			ApplyUtil.ApplyNav(__instance);
		}
	}
	[HarmonyPatch(typeof(EnemyNavMeshAgent), "OverrideAgent")]
	internal static class Patch_EnemyNavMeshAgent_OverrideAgent
	{
		private static void Prefix(EnemyNavMeshAgent __instance, ref float speed, ref float acceleration, float time)
		{
			if (!((Object)(object)__instance == (Object)null) && ApplyUtil.ShouldApplyGameplay((Component)(object)__instance) && OverrideGuard.TryEnter((Component)(object)__instance, 1))
			{
				float damageRageMultiplier = ApplyUtil.GetDamageRageMultiplier(((Component)__instance).gameObject, EnemySpeedUpDamageRageAffects.MoveNav);
				float num = EnemySpeedUpConfig.NavAttackMoveMultiplier.Value * damageRageMultiplier;
				speed = Mathf.Max(0.1f, speed * num);
				acceleration = Mathf.Max(0f, acceleration * num);
			}
		}
	}
	[HarmonyPatch(typeof(EnemyRigidbody), "Awake")]
	internal static class Patch_EnemyRigidbody_Awake
	{
		private static void Postfix(EnemyRigidbody __instance)
		{
			ApplyUtil.ApplyRb(__instance);
		}
	}
	[HarmonyPatch(typeof(EnemyRigidbody), "OverrideFollowPosition")]
	internal static class Patch_EnemyRigidbody_OverrideFollowPosition
	{
		private static void Prefix(EnemyRigidbody __instance, ref float speed)
		{
			if (!((Object)(object)__instance == (Object)null) && ApplyUtil.ShouldApplyGameplay((Component)(object)__instance) && OverrideGuard.TryEnter((Component)(object)__instance, 2))
			{
				float damageRageMultiplier = ApplyUtil.GetDamageRageMultiplier(((Component)__instance).gameObject, EnemySpeedUpDamageRageAffects.MoveRb);
				float num = EnemySpeedUpConfig.RbAttackMoveMultiplier.Value * damageRageMultiplier;
				speed = Mathf.Max(0.1f, speed * num);
			}
		}
	}
	[HarmonyPatch(typeof(EnemyRigidbody), "OverrideFollowRotation")]
	internal static class Patch_EnemyRigidbody_OverrideFollowRotation
	{
		private static void Prefix(EnemyRigidbody __instance, ref float speed)
		{
			if (!((Object)(object)__instance == (Object)null) && ApplyUtil.ShouldApplyGameplay((Component)(object)__instance) && OverrideGuard.TryEnter((Component)(object)__instance, 3))
			{
				float damageRageMultiplier = ApplyUtil.GetDamageRageMultiplier(((Component)__instance).gameObject, EnemySpeedUpDamageRageAffects.MoveRb);
				float num = EnemySpeedUpConfig.RbAttackMoveMultiplier.Value * damageRageMultiplier;
				speed = Mathf.Max(0.1f, speed * num);
			}
		}
	}
	[HarmonyPatch(typeof(EnemyParent), "SpawnRPC")]
	internal static class Patch_EnemyParent_SpawnRPC
	{
		private static void Postfix()
		{
			LateSpawnSupport.Apply();
		}
	}
	[HarmonyPatch(typeof(Enemy), "Start")]
	internal static class Patch_Enemy_Start
	{
		private static void Postfix(Enemy __instance)
		{
			if (!((Object)(object)__instance == (Object)null))
			{
				LateSpawnSupport.Apply();
			}
		}
	}
}