Decompiled source of gabdao dangerousenemies bigedition v1.0.0

plugins/DangerousEnemies.BIGEdition.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn;
using Jotunn.Utils;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("DangerousEnemies.BIGEdition")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DangerousEnemies.BIGEdition")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4a71157e-ac54-41a5-90d9-9b5755a21a84")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
[SynchronizationMode(/*Could not decode attribute arguments.*/)]
[BepInPlugin("gabdao.dangerousenemies.bigedition", "DangerousEnemies BIG Edition", "1.0.0")]
[BepInDependency("com.jotunn.jotunn", "2.26.1")]
public class DangerousEnemiesBIGPlugin : BaseUnityPlugin
{
	public static class TrollConstants
	{
		public const string TROLL_PREFIX = "Troll";

		public const string TROLL_PUNCH_ATTACK = "troll_punch";

		public const string TROLL_GROUNDSLAM_ATTACK = "troll_groundslam";

		public const string TROLL_THROW_ATTACK = "troll_throw";

		public const string TROLL_THROW_PROJECTILE = "troll_throw_projectile";

		public const float DEFAULT_CLEANUP_INTERVAL = 60f;

		public const float ANIM_CLEANUP_INTERVAL = 30f;
	}

	public static class BearConstants
	{
		public const string BEAR_PREFIX = "Bjorn";

		public const string BEAR_BITE_ATTACK = "bjorn_bite";

		public const string BEAR_SLAM_ATTACK = "bjorn_slam";

		public const string BEAR_CLAWS_ATTACK = "bjorn_claws";

		public const string BEAR_SWIPEL_ATTACK = "bjorn_swipe_l";

		public const string BEAR_SWIPER_ATTACK = "bjorn_swipe_r";

		public const string BEAR_SWIPECOMBO_ATTACK = "bjorn_swipe_combo";

		public const float DEFAULT_CLEANUP_INTERVAL = 60f;

		public const float ANIM_CLEANUP_INTERVAL = 30f;
	}

	public static class AbominationConstants
	{
		public const string ABOMINATION_PREFIX = "Abomination";

		public const string ATTACK1 = "Abomination_attack1";

		public const string ATTACK2 = "Abomination_attack2";

		public const string ATTACK3 = "Abomination_attack3";

		public const float DEFAULT_CLEANUP_INTERVAL = 60f;

		public const float ANIM_CLEANUP_INTERVAL = 30f;
	}

	public static class GolemConstants
	{
		public const string GOLEM_PREFIX = "StoneGolem";

		public const string GROUNDSLAM = "stonegolem_attack2_left_groundslam";

		public const string DOUBLESMASH = "stonegolem_attack_doublesmash";

		public const string SPIKE = "stonegolem_attack1_spike";

		public const string SPIKESWEEP = "stonegolem_attack3_spikesweep";

		public const float DEFAULT_CLEANUP_INTERVAL = 60f;

		public const float ANIM_CLEANUP_INTERVAL = 30f;
	}

	public static class CultistConstants
	{
		public const string PREFIX = "Cultist";

		public const float DEFAULT_CLEANUP_INTERVAL = 60f;

		public const float ANIM_CLEANUP_INTERVAL = 30f;

		public const string ATTACK_FIRECLAW = "Fenring_attack_fireclaw";

		public const string ATTACK_DOUBLE_FIRECLAW = "Fenring_attack_fireclaw_double";

		public const string ATTACK_AOE_FIRE = "Fenring_attack_flames";
	}

	public static class BruteConstants
	{
		public const string BRUTE_PREFIX = "GoblinBrute";

		public const string ATTACK = "GoblinBrute_Attack";

		public const string RAGE_ATTACK = "GoblinBrute_RageAttack";

		public const float DEFAULT_CLEANUP_INTERVAL = 60f;

		public const float ANIM_CLEANUP_INTERVAL = 30f;
	}

	public static class LoxConstants
	{
		public const string LOX_PREFIX = "Lox";

		public const string BITE = "lox_bite";

		public const string STOMP = "lox_stomp";

		public const float DEFAULT_CLEANUP_INTERVAL = 60f;

		public const float ANIM_CLEANUP_INTERVAL = 30f;
	}

	public static class SoldierConstants
	{
		public const string SOLDIER_PREFIX = "SeekerBrute";

		public const string SOLDIER_BITE_ATTACK = "SeekerBrute_bite";

		public const string SOLDIER_RAM_ATTACK = "SeekerBrute_ram";

		public const string SOLDIER_GROUNDSLAM_ATTACK = "SeekerBrute_groundslam";

		public const float ATTACK_CLEANUP_INTERVAL = 60f;

		public const float ANIMATOR_CLEANUP_INTERVAL = 30f;
	}

	public static class SerpentConstants
	{
		public const string SERPENT_PREFIX = "Serpent";

		public const string SERPENT_BITE_ATTACK = "Serpent_attack";

		public const float ATTACK_CLEANUP_INTERVAL = 60f;
	}

	public static class TrollAnimHashes
	{
		public const int GroundSlam = 1203776827;

		public const int Punch = 752971864;

		public const int TrunkSwingV = 22911243;

		public const int TrunkSwingH = -78470040;
	}

	public static class BearAnimHashes
	{
		public const int Slam = -153875945;

		public const int Bite = -2115618530;

		public const int SwipeL = -1030126497;

		public const int SwipeR = 949401916;

		public const int Claws = -1993876325;

		public const int SwipeCombo1 = 1437481170;

		public const int SwipeCombo2 = 581503044;
	}

	public static class AbominationAnimHashes
	{
		public const int VSlam = -1415997692;

		public const int HSweep = 1203776827;

		public const int AOECrush = -593582190;
	}

	public static class GolemAnimHashes
	{
		public const int Crush = -287095546;

		public const int GolemSlam = -1415997692;

		public const int Sweep = -593582190;

		public const int Poke = 1203776827;
	}

	public static class CultistAnimHashes
	{
		public const int Fireclaw = 210160161;

		public const int DoubleFireclaw = -37429503;

		public const int AOEFire = 638396485;
	}

	public static class BruteAnimHashes
	{
		public const int SlamCombo = -322548239;

		public const int Swing = 848348862;

		public const int Swing2 = 1167586856;
	}

	public static class LoxAnimHashes
	{
		public const int Bite = -2115618530;

		public const int Stomp = 1607512578;
	}

	public static class SoldierAnimHashes
	{
		public const int Ram = -636786879;

		public const int SoldierBite = 735162116;

		public const int SoldierGroundSlam = -53398733;
	}

	public static class ReflectionCache
	{
		private static FieldInfo _staggerDamageField;

		private static FieldRef<MonsterAI, Character> _characterRef;

		public static FieldInfo StaggerDamageField
		{
			get
			{
				if (_staggerDamageField == null)
				{
					_staggerDamageField = typeof(Character).GetField("m_staggerDamage", BindingFlags.Instance | BindingFlags.NonPublic);
					if (_staggerDamageField == null)
					{
						throw new InvalidOperationException("Failed to find m_staggerDamage field - game version may have changed");
					}
				}
				return _staggerDamageField;
			}
		}

		public static FieldRef<MonsterAI, Character> CharacterRef
		{
			get
			{
				if (_characterRef == null)
				{
					_characterRef = AccessTools.FieldRefAccess<MonsterAI, Character>("m_character");
				}
				return _characterRef;
			}
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "SelectBestAttack")]
	public static class TrollAttackIntervalPatch
	{
		private struct AttackData
		{
			public string LastAttack;

			public float LastModified;

			public AttackData(string attack)
			{
				LastAttack = attack;
				LastModified = Time.time;
			}
		}

		private static readonly Dictionary<MonsterAI, AttackData> s_attackData = new Dictionary<MonsterAI, AttackData>();

		private static float s_lastCleanupTime = 0f;

		private static void Postfix(MonsterAI __instance, ref ItemData __result)
		{
			if ((Object)(object)__result?.m_dropPrefab == (Object)null)
			{
				return;
			}
			Character val = ReflectionCache.CharacterRef.Invoke(__instance);
			if (!((Object)(object)((val != null) ? ((Component)val).gameObject : null) == (Object)null) && ((Object)((Component)val).gameObject).name.StartsWith("Troll"))
			{
				if (Time.time - s_lastCleanupTime > 60f)
				{
					CleanupDestroyedInstances();
					s_lastCleanupTime = Time.time;
				}
				string name = ((Object)__result.m_dropPrefab).name;
				if (!s_attackData.TryGetValue(__instance, out var value) || value.LastAttack != name)
				{
					s_attackData[__instance] = new AttackData(name);
					ModifyAttackInterval(__result, name);
				}
			}
		}

		private static void ModifyAttackInterval(ItemData result, string attackName)
		{
			switch (attackName)
			{
			case "troll_punch":
				result.m_shared.m_aiAttackInterval = Random.Range(PunchIntervalMin.Value, PunchIntervalMax.Value);
				DebugLog($"Modified {attackName} interval to {result.m_shared.m_aiAttackInterval:F2}s");
				break;
			case "troll_groundslam":
				result.m_shared.m_aiAttackInterval = Random.Range(GroundSlamIntervalMin.Value, GroundSlamIntervalMax.Value);
				DebugLog($"Modified {attackName} interval to {result.m_shared.m_aiAttackInterval:F2}s");
				break;
			case "troll_throw":
				result.m_shared.m_aiAttackInterval = Random.Range(ThrowIntervalMin.Value, ThrowIntervalMax.Value);
				result.m_shared.m_aiAttackRange = TrollThrowRange.Value;
				DebugLog($"Modified {attackName} interval to {result.m_shared.m_aiAttackInterval:F2}s, range to {result.m_shared.m_aiAttackRange:F1}");
				break;
			}
		}

		private static void CleanupDestroyedInstances()
		{
			List<MonsterAI> list = s_attackData.Keys.Where((MonsterAI key) => (Object)(object)key == (Object)null || (Object)(object)((Component)key).gameObject == (Object)null).ToList();
			foreach (MonsterAI item in list)
			{
				s_attackData.Remove(item);
			}
			if (list.Count > 0)
			{
				DebugLog($"Cleaned up {list.Count} destroyed attack interval references");
			}
		}

		public static void Cleanup()
		{
			s_attackData.Clear();
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "SelectBestAttack")]
	public static class BearAttackIntervalPatch
	{
		private struct AttackData
		{
			public string LastAttack;

			public float LastModified;

			public AttackData(string attack)
			{
				LastAttack = attack;
				LastModified = Time.time;
			}
		}

		private static readonly Dictionary<MonsterAI, AttackData> s_attackData = new Dictionary<MonsterAI, AttackData>();

		private static float s_lastCleanupTime = 0f;

		private static void Postfix(MonsterAI __instance, ref ItemData __result)
		{
			if ((Object)(object)__result?.m_dropPrefab == (Object)null)
			{
				return;
			}
			Character val = ReflectionCache.CharacterRef.Invoke(__instance);
			if (!((Object)(object)((val != null) ? ((Component)val).gameObject : null) == (Object)null) && ((Object)((Component)val).gameObject).name.StartsWith("Bjorn"))
			{
				if (Time.time - s_lastCleanupTime > 60f)
				{
					CleanupDestroyedInstances();
					s_lastCleanupTime = Time.time;
				}
				string name = ((Object)__result.m_dropPrefab).name;
				if (!s_attackData.TryGetValue(__instance, out var value) || value.LastAttack != name)
				{
					s_attackData[__instance] = new AttackData(name);
					ModifyAttackInterval(__result, name);
				}
			}
		}

		private static void ModifyAttackInterval(ItemData result, string attackName)
		{
			switch (attackName)
			{
			case "bjorn_bite":
				result.m_shared.m_aiAttackInterval = Random.Range(BiteIntervalMin.Value, BiteIntervalMax.Value);
				DebugLog($"Modified {attackName} interval to {result.m_shared.m_aiAttackInterval:F2}s");
				break;
			case "bjorn_slam":
				result.m_shared.m_aiAttackInterval = Random.Range(SlamIntervalMin.Value, SlamIntervalMax.Value);
				DebugLog($"Modified {attackName} interval to {result.m_shared.m_aiAttackInterval:F2}s");
				break;
			case "bjorn_claws":
				result.m_shared.m_aiAttackInterval = Random.Range(ClawsIntervalMin.Value, ClawsIntervalMax.Value);
				DebugLog($"Modified {attackName} interval to {result.m_shared.m_aiAttackInterval:F2}s");
				break;
			case "bjorn_swipe_l":
				result.m_shared.m_aiAttackInterval = Random.Range(SwipeLIntervalMin.Value, SwipeLIntervalMax.Value);
				DebugLog($"Modified {attackName} interval to {result.m_shared.m_aiAttackInterval:F2}s");
				break;
			case "bjorn_swipe_r":
				result.m_shared.m_aiAttackInterval = Random.Range(SwipeRIntervalMin.Value, SwipeRIntervalMax.Value);
				DebugLog($"Modified {attackName} interval to {result.m_shared.m_aiAttackInterval:F2}s");
				break;
			case "bjorn_swipe_combo":
				result.m_shared.m_aiAttackInterval = Random.Range(SwipeComboIntervalMin.Value, SwipeComboIntervalMax.Value);
				DebugLog($"Modified {attackName} interval to {result.m_shared.m_aiAttackInterval:F2}s");
				break;
			}
		}

		private static void CleanupDestroyedInstances()
		{
			List<MonsterAI> list = s_attackData.Keys.Where((MonsterAI key) => (Object)(object)key == (Object)null || (Object)(object)((Component)key).gameObject == (Object)null).ToList();
			foreach (MonsterAI item in list)
			{
				s_attackData.Remove(item);
			}
			if (list.Count > 0)
			{
				DebugLog($"Cleaned up {list.Count} destroyed attack interval references");
			}
		}

		public static void Cleanup()
		{
			s_attackData.Clear();
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "SelectBestAttack")]
	public static class AbominationAttackIntervalPatch
	{
		private struct AttackData
		{
			public string LastAttack;

			public float LastModified;

			public AttackData(string attack)
			{
				LastAttack = attack;
				LastModified = Time.time;
			}
		}

		private static readonly Dictionary<MonsterAI, AttackData> s_attackData = new Dictionary<MonsterAI, AttackData>();

		private static float s_lastCleanupTime = 0f;

		private static void Postfix(MonsterAI __instance, ref ItemData __result)
		{
			if ((Object)(object)__result?.m_dropPrefab == (Object)null)
			{
				return;
			}
			Character val = ReflectionCache.CharacterRef.Invoke(__instance);
			if (!((Object)(object)((val != null) ? ((Component)val).gameObject : null) == (Object)null) && ((Object)((Component)val).gameObject).name.StartsWith("Abomination"))
			{
				if (Time.time - s_lastCleanupTime > 60f)
				{
					CleanupDestroyedInstances();
					s_lastCleanupTime = Time.time;
				}
				string name = ((Object)__result.m_dropPrefab).name;
				if (!s_attackData.TryGetValue(__instance, out var value) || value.LastAttack != name)
				{
					s_attackData[__instance] = new AttackData(name);
					ModifyAttackInterval(__result, name);
				}
			}
		}

		private static void ModifyAttackInterval(ItemData result, string attackName)
		{
			switch (attackName)
			{
			case "Abomination_attack1":
				result.m_shared.m_aiAttackInterval = Random.Range(HSweepIntervalMin.Value, HSweepIntervalMax.Value);
				DebugLog($"Modified {attackName} interval to {result.m_shared.m_aiAttackInterval:F2}s");
				break;
			case "Abomination_attack2":
				result.m_shared.m_aiAttackInterval = Random.Range(VSlamIntervalMin.Value, VSlamIntervalMax.Value);
				DebugLog($"Modified {attackName} interval to {result.m_shared.m_aiAttackInterval:F2}s");
				break;
			case "Abomination_attack3":
				result.m_shared.m_aiAttackInterval = Random.Range(AOECrushIntervalMin.Value, AOECrushIntervalMax.Value);
				DebugLog($"Modified {attackName} interval to {result.m_shared.m_aiAttackInterval:F2}s");
				break;
			}
		}

		private static void CleanupDestroyedInstances()
		{
			List<MonsterAI> list = s_attackData.Keys.Where((MonsterAI key) => (Object)(object)key == (Object)null || (Object)(object)((Component)key).gameObject == (Object)null).ToList();
			foreach (MonsterAI item in list)
			{
				s_attackData.Remove(item);
			}
			if (list.Count > 0)
			{
				DebugLog($"Cleaned up {list.Count} destroyed attack interval references (Abomination)");
			}
		}

		public static void Cleanup()
		{
			s_attackData.Clear();
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "SelectBestAttack")]
	public static class GolemAttackIntervalPatch
	{
		private struct AttackData
		{
			public string LastAttack;

			public float LastModified;

			public AttackData(string attack)
			{
				LastAttack = attack;
				LastModified = Time.time;
			}
		}

		private static readonly Dictionary<MonsterAI, AttackData> s_attackData = new Dictionary<MonsterAI, AttackData>();

		private static float s_lastCleanupTime = 0f;

		private static void Postfix(MonsterAI __instance, ref ItemData __result)
		{
			if ((Object)(object)__result?.m_dropPrefab == (Object)null)
			{
				return;
			}
			Character val = ReflectionCache.CharacterRef.Invoke(__instance);
			if (!((Object)(object)((val != null) ? ((Component)val).gameObject : null) == (Object)null) && ((Object)((Component)val).gameObject).name.StartsWith("StoneGolem"))
			{
				if (Time.time - s_lastCleanupTime > 60f)
				{
					CleanupDestroyedInstances();
					s_lastCleanupTime = Time.time;
				}
				string name = ((Object)__result.m_dropPrefab).name;
				if (!s_attackData.TryGetValue(__instance, out var value) || value.LastAttack != name)
				{
					s_attackData[__instance] = new AttackData(name);
					ModifyAttackInterval(__result, name);
				}
			}
		}

		private static void ModifyAttackInterval(ItemData result, string attackName)
		{
			switch (attackName)
			{
			case "stonegolem_attack2_left_groundslam":
				result.m_shared.m_aiAttackInterval = Random.Range(GolemSlamIntervalMin.Value, GolemSlamIntervalMax.Value);
				DebugLog($"Modified {attackName} interval to {result.m_shared.m_aiAttackInterval:F2}s");
				break;
			case "stonegolem_attack_doublesmash":
				result.m_shared.m_aiAttackInterval = Random.Range(CrushIntervalMin.Value, CrushIntervalMax.Value);
				DebugLog($"Modified {attackName} interval to {result.m_shared.m_aiAttackInterval:F2}s");
				break;
			case "stonegolem_attack1_spike":
				result.m_shared.m_aiAttackInterval = Random.Range(CrushIntervalMin.Value, CrushIntervalMax.Value);
				DebugLog($"Modified {attackName} interval to {result.m_shared.m_aiAttackInterval:F2}s");
				break;
			case "stonegolem_attack3_spikesweep":
				result.m_shared.m_aiAttackInterval = Random.Range(CrushIntervalMin.Value, CrushIntervalMax.Value);
				DebugLog($"Modified {attackName} interval to {result.m_shared.m_aiAttackInterval:F2}s");
				break;
			}
		}

		private static void CleanupDestroyedInstances()
		{
			List<MonsterAI> list = s_attackData.Keys.Where((MonsterAI key) => (Object)(object)key == (Object)null || (Object)(object)((Component)key).gameObject == (Object)null).ToList();
			foreach (MonsterAI item in list)
			{
				s_attackData.Remove(item);
			}
			if (list.Count > 0)
			{
				DebugLog($"Cleaned up {list.Count} destroyed attack interval references");
			}
		}

		public static void Cleanup()
		{
			s_attackData.Clear();
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "SelectBestAttack")]
	public static class CultistAttackIntervalPatch
	{
		private static readonly Dictionary<MonsterAI, string> lastAttackByInstance = new Dictionary<MonsterAI, string>();

		private static float lastCleanupTime = 0f;

		private static void Postfix(MonsterAI __instance, ref ItemData __result)
		{
			if ((Object)(object)__result?.m_dropPrefab == (Object)null)
			{
				return;
			}
			Character val = ReflectionCache.CharacterRef.Invoke(__instance);
			if ((Object)(object)((val != null) ? ((Component)val).gameObject : null) == (Object)null || !((Object)((Component)val).gameObject).name.Contains("Cultist"))
			{
				return;
			}
			if (Time.time - lastCleanupTime > 60f)
			{
				CleanupDestroyedInstances();
				lastCleanupTime = Time.time;
			}
			string name = ((Object)__result.m_dropPrefab).name;
			if (!lastAttackByInstance.TryGetValue(__instance, out var value) || value != name)
			{
				lastAttackByInstance[__instance] = name;
				switch (name)
				{
				case "Fenring_attack_fireclaw":
					__result.m_shared.m_aiAttackInterval = Random.Range(FireclawIntervalMin.Value, FireclawIntervalMax.Value);
					break;
				case "Fenring_attack_fireclaw_double":
					__result.m_shared.m_aiAttackInterval = Random.Range(DoubleFireclawIntervalMin.Value, DoubleFireclawIntervalMax.Value);
					break;
				case "Fenring_attack_flames":
					__result.m_shared.m_aiAttackInterval = Random.Range(AOEFireIntervalMin.Value, AOEFireIntervalMax.Value);
					break;
				}
			}
		}

		private static void CleanupDestroyedInstances()
		{
			foreach (MonsterAI item in lastAttackByInstance.Keys.Where((MonsterAI k) => (Object)(object)k == (Object)null || (Object)(object)((Component)k).gameObject == (Object)null).ToList())
			{
				lastAttackByInstance.Remove(item);
			}
		}

		public static void Cleanup()
		{
			lastAttackByInstance.Clear();
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "SelectBestAttack")]
	public static class BruteAttackIntervalPatch
	{
		private static readonly Dictionary<MonsterAI, string> lastAttackByInstance = new Dictionary<MonsterAI, string>();

		private static float lastCleanupTime = 0f;

		private static void Postfix(MonsterAI __instance, ref ItemData __result)
		{
			if (__result == null || (Object)(object)__result.m_dropPrefab == (Object)null)
			{
				return;
			}
			Character val = ReflectionCache.CharacterRef.Invoke(__instance);
			if ((Object)(object)val == (Object)null || !((Object)((Component)val).gameObject).name.Contains("Brute"))
			{
				return;
			}
			if (Time.time - lastCleanupTime > 60f)
			{
				CleanupDestroyed();
				lastCleanupTime = Time.time;
			}
			string name = ((Object)__result.m_dropPrefab).name;
			if (!lastAttackByInstance.TryGetValue(__instance, out var value) || value != name)
			{
				lastAttackByInstance[__instance] = name;
				if (name == "GoblinBrute_Attack")
				{
					__result.m_shared.m_aiAttackInterval = Random.Range(SwingIntervalMin.Value, SwingIntervalMax.Value);
				}
				else if (name == "GoblinBrute_RageAttack")
				{
					__result.m_shared.m_aiAttackInterval = Random.Range(SlamComboIntervalMin.Value, SlamComboIntervalMax.Value);
				}
			}
		}

		private static void CleanupDestroyed()
		{
			foreach (MonsterAI item in lastAttackByInstance.Keys.Where((MonsterAI k) => (Object)(object)k == (Object)null || (Object)(object)((Component)k).gameObject == (Object)null).ToList())
			{
				lastAttackByInstance.Remove(item);
			}
		}

		public static void Cleanup()
		{
			lastAttackByInstance.Clear();
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "SelectBestAttack")]
	public static class LoxAttackIntervalPatch
	{
		private struct AttackData
		{
			public string LastAttack;

			public float LastModified;

			public AttackData(string attack)
			{
				LastAttack = attack;
				LastModified = Time.time;
			}
		}

		private static readonly Dictionary<MonsterAI, AttackData> s_attackData = new Dictionary<MonsterAI, AttackData>();

		private static float s_lastCleanupTime = 0f;

		private static void Postfix(MonsterAI __instance, ref ItemData __result)
		{
			if ((Object)(object)__result?.m_dropPrefab == (Object)null)
			{
				return;
			}
			Character val = ReflectionCache.CharacterRef.Invoke(__instance);
			if (!((Object)(object)((val != null) ? ((Component)val).gameObject : null) == (Object)null) && ((Object)((Component)val).gameObject).name.StartsWith("Lox"))
			{
				if (Time.time - s_lastCleanupTime > 60f)
				{
					CleanupDestroyedInstances();
					s_lastCleanupTime = Time.time;
				}
				string name = ((Object)__result.m_dropPrefab).name;
				if (!s_attackData.TryGetValue(__instance, out var value) || value.LastAttack != name)
				{
					s_attackData[__instance] = new AttackData(name);
					ModifyAttackInterval(__result, name);
				}
			}
		}

		private static void ModifyAttackInterval(ItemData result, string attackName)
		{
			if (!(attackName == "lox_bite"))
			{
				if (attackName == "lox_stomp")
				{
					result.m_shared.m_aiAttackInterval = Random.Range(StompIntervalMin.Value, StompIntervalMax.Value);
					DebugLog($"Modified {attackName} interval to {result.m_shared.m_aiAttackInterval:F2}s");
				}
			}
			else
			{
				result.m_shared.m_aiAttackInterval = Random.Range(LoxBiteIntervalMin.Value, LoxBiteIntervalMax.Value);
				DebugLog($"Modified {attackName} interval to {result.m_shared.m_aiAttackInterval:F2}s");
			}
		}

		private static void CleanupDestroyedInstances()
		{
			List<MonsterAI> list = s_attackData.Keys.Where((MonsterAI key) => (Object)(object)key == (Object)null || (Object)(object)((Component)key).gameObject == (Object)null).ToList();
			foreach (MonsterAI item in list)
			{
				s_attackData.Remove(item);
			}
			if (list.Count > 0)
			{
				DebugLog($"Cleaned up {list.Count} destroyed attack interval references (Lox)");
			}
		}

		public static void Cleanup()
		{
			s_attackData.Clear();
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "SelectBestAttack")]
	public static class SoldierAttackIntervalPatch
	{
		private struct AttackData
		{
			public string LastAttack;

			public float LastModified;

			public AttackData(string attack)
			{
				LastAttack = attack;
				LastModified = Time.time;
			}
		}

		private static readonly Dictionary<MonsterAI, AttackData> s_attackData = new Dictionary<MonsterAI, AttackData>();

		private static float s_lastCleanupTime = 0f;

		private static void Postfix(MonsterAI __instance, ref ItemData __result)
		{
			if ((Object)(object)__result?.m_dropPrefab == (Object)null)
			{
				return;
			}
			Character val = ReflectionCache.CharacterRef.Invoke(__instance);
			if ((Object)(object)((val != null) ? ((Component)val).gameObject : null) == (Object)null || !((Object)((Component)val).gameObject).name.StartsWith("SeekerBrute"))
			{
				return;
			}
			if (Time.time - s_lastCleanupTime > 60f)
			{
				CleanupDestroyedInstances();
				s_lastCleanupTime = Time.time;
			}
			string name = ((Object)__result.m_dropPrefab).name;
			if (!s_attackData.TryGetValue(__instance, out var value) || value.LastAttack != name)
			{
				s_attackData[__instance] = new AttackData(name);
				switch (name)
				{
				case "SeekerBrute_bite":
					__result.m_shared.m_aiAttackInterval = Random.Range(SoldierBiteIntervalMin.Value, SoldierBiteIntervalMax.Value);
					break;
				case "SeekerBrute_ram":
					__result.m_shared.m_aiAttackInterval = Random.Range(RamIntervalMin.Value, RamIntervalMax.Value);
					break;
				case "SeekerBrute_groundslam":
					__result.m_shared.m_aiAttackInterval = Random.Range(SoldierGroundSlamIntervalMin.Value, SoldierGroundSlamIntervalMax.Value);
					break;
				}
			}
		}

		private static void CleanupDestroyedInstances()
		{
			foreach (MonsterAI item in s_attackData.Keys.Where((MonsterAI k) => (Object)(object)k == (Object)null || (Object)(object)((Component)k).gameObject == (Object)null).ToList())
			{
				s_attackData.Remove(item);
			}
		}

		public static void Cleanup()
		{
			s_attackData.Clear();
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "SelectBestAttack")]
	public static class DangerousSerpentIntervalPatch
	{
		private static readonly FieldRef<MonsterAI, Character> m_characterRef = AccessTools.FieldRefAccess<MonsterAI, Character>("m_character");

		private static readonly Dictionary<MonsterAI, string> lastAttackByInstance = new Dictionary<MonsterAI, string>();

		private static float lastCleanupTime = 0f;

		private static void Postfix(MonsterAI __instance, ref ItemData __result)
		{
			if ((Object)(object)__result?.m_dropPrefab == (Object)null)
			{
				return;
			}
			Character val = m_characterRef.Invoke(__instance);
			if ((Object)(object)((val != null) ? ((Component)val).gameObject : null) == (Object)null || !((Object)((Component)val).gameObject).name.StartsWith("Serpent"))
			{
				return;
			}
			PeriodicCleanup();
			string name = ((Object)__result.m_dropPrefab).name;
			if (!lastAttackByInstance.TryGetValue(__instance, out var value) || value != name)
			{
				lastAttackByInstance[__instance] = name;
				if (name == "Serpent_attack")
				{
					__result.m_shared.m_aiAttackInterval = Random.Range(SerpentBiteIntervalMin.Value, SerpentBiteIntervalMax.Value);
				}
			}
		}

		private static void PeriodicCleanup()
		{
			if (Time.time - lastCleanupTime > 60f)
			{
				CleanupDestroyedInstances();
				lastCleanupTime = Time.time;
			}
		}

		private static void CleanupDestroyedInstances()
		{
			foreach (MonsterAI item in lastAttackByInstance.Keys.Where((MonsterAI k) => (Object)(object)k == (Object)null || (Object)(object)((Component)k).gameObject == (Object)null).ToList())
			{
				lastAttackByInstance.Remove(item);
			}
		}

		public static void Cleanup()
		{
			lastAttackByInstance.Clear();
		}
	}

	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	public static class TrollProjectilePatch
	{
		public static void Postfix(ZNetScene __instance)
		{
			GameObject prefab = __instance.GetPrefab("troll_throw_projectile");
			if ((Object)(object)prefab == (Object)null)
			{
				Logger.LogError((object)"[TrollProjectilePatch] Could not find 'troll_throw_projectile' prefab.");
				return;
			}
			Projectile component = prefab.GetComponent<Projectile>();
			if ((Object)(object)component == (Object)null)
			{
				Logger.LogError((object)"[TrollProjectilePatch] 'troll_throw_projectile' prefab has no Projectile component.");
				return;
			}
			component.m_rayRadius = TrollThrowRayRadius.Value;
			component.m_aoe = TrollThrowAOE.Value;
			component.m_attackForce = TrollThrowAttackForce.Value;
			component.m_drag = TrollThrowDrag.Value;
			component.m_gravity = TrollThrowGravity.Value;
			DebugLog($"Modified troll projectile: AOE={component.m_aoe}, Force={component.m_attackForce}, Gravity={component.m_gravity}");
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "SelectBestAttack")]
	public static class AbominationAOECrushRayWidthPatch
	{
		private static readonly HashSet<MonsterAI> modifiedInstances = new HashSet<MonsterAI>();

		private static float s_lastCleanupTime = 0f;

		private static void Postfix(MonsterAI __instance, ref ItemData __result)
		{
			if (__result == null || (Object)(object)__result.m_dropPrefab == (Object)null)
			{
				return;
			}
			Character val = ReflectionCache.CharacterRef.Invoke(__instance);
			if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null || !((Object)((Component)val).gameObject).name.StartsWith("Abomination"))
			{
				return;
			}
			if (Time.time - s_lastCleanupTime > 60f)
			{
				CleanupDestroyedInstances();
				s_lastCleanupTime = Time.time;
			}
			if (!(((Object)__result.m_dropPrefab).name == "Abomination_attack3") || modifiedInstances.Contains(__instance))
			{
				return;
			}
			try
			{
				if (__result.m_shared?.m_attack != null)
				{
					__result.m_shared.m_attack.m_attackRayWidth = AbominationAOECrushRayWidth.Value;
					modifiedInstances.Add(__instance);
					DebugLog($"Applied AOECrush ray width {AbominationAOECrushRayWidth.Value:F2} to {((Object)((Component)val).gameObject).name}");
				}
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("[AbominationAOECrushRayWidthPatch] Failed to apply AOECrush ray width: " + ex.Message));
			}
		}

		private static void CleanupDestroyedInstances()
		{
			List<MonsterAI> list = modifiedInstances.Where((MonsterAI k) => (Object)(object)k == (Object)null || (Object)(object)((Component)k).gameObject == (Object)null).ToList();
			foreach (MonsterAI item in list)
			{
				modifiedInstances.Remove(item);
			}
			if (list.Count > 0)
			{
				DebugLog($"Cleaned up {list.Count} destroyed ray width references (Abomination)");
			}
		}

		public static void Cleanup()
		{
			modifiedInstances.Clear();
		}
	}

	[HarmonyPatch(typeof(Character), "Awake")]
	public static class StaggerFactorPatch
	{
		private static void Postfix(Character __instance)
		{
			if (!((Object)(object)((__instance != null) ? ((Component)__instance).gameObject : null) == (Object)null))
			{
				if ((Object)(object)((__instance != null) ? ((Component)__instance).gameObject : null) != (Object)null && ((Object)((Component)__instance).gameObject).name.StartsWith("Troll"))
				{
					__instance.m_staggerDamageFactor = TrollStaggerDamageFactor.Value;
					DebugLog($"Applied stagger damage factor {TrollStaggerDamageFactor.Value:F2} to {((Object)((Component)__instance).gameObject).name}");
				}
				else if ((Object)(object)((__instance != null) ? ((Component)__instance).gameObject : null) != (Object)null && ((Object)((Component)__instance).gameObject).name.StartsWith("Abomination"))
				{
					__instance.m_staggerDamageFactor = AbominationStaggerDamageFactor.Value;
					DebugLog($"Applied stagger damage factor {AbominationStaggerDamageFactor.Value:F2} to {((Object)((Component)__instance).gameObject).name}");
				}
				else if ((Object)(object)((__instance != null) ? ((Component)__instance).gameObject : null) != (Object)null && ((Object)((Component)__instance).gameObject).name.StartsWith("Bjorn"))
				{
					__instance.m_staggerDamageFactor = BearStaggerDamageFactor.Value;
					DebugLog($"Applied stagger damage factor {BearStaggerDamageFactor.Value:F2} to {((Object)((Component)__instance).gameObject).name}");
				}
				else if ((Object)(object)((__instance != null) ? ((Component)__instance).gameObject : null) != (Object)null && ((Object)((Component)__instance).gameObject).name.StartsWith("StoneGolem"))
				{
					__instance.m_staggerDamageFactor = GolemStaggerDamageFactor.Value;
					DebugLog($"Applied stagger damage factor {GolemStaggerDamageFactor.Value:F2} to {((Object)((Component)__instance).gameObject).name}");
				}
				else if ((Object)(object)((__instance != null) ? ((Component)__instance).gameObject : null) != (Object)null && ((Object)((Component)__instance).gameObject).name.Contains("Cultist"))
				{
					__instance.m_staggerDamageFactor = CultistStaggerDamageFactor.Value;
					DebugLog($"Applied stagger damage factor {CultistStaggerDamageFactor.Value:F2} to {((Object)((Component)__instance).gameObject).name}");
				}
				else if ((Object)(object)__instance != (Object)null && ((Object)((Component)__instance).gameObject).name.Contains("GoblinBrute"))
				{
					__instance.m_staggerDamageFactor = BruteStaggerDamageFactor.Value;
					DebugLog($"Applied stagger damage factor {BruteStaggerDamageFactor.Value:F2} to {((Object)((Component)__instance).gameObject).name}");
				}
				else if ((Object)(object)__instance != (Object)null && ((Object)((Component)__instance).gameObject).name.Contains("SeekerBrute"))
				{
					__instance.m_staggerDamageFactor = SoldierStaggerDamageFactor.Value;
					DebugLog($"Applied stagger damage factor {SoldierStaggerDamageFactor.Value:F2} to {((Object)((Component)__instance).gameObject).name}");
				}
			}
		}
	}

	[HarmonyPatch(typeof(Character), "UpdateStagger")]
	public static class StaggerDrainPatch
	{
		private static bool Prefix(Character __instance, float dt)
		{
			if ((Object)(object)((__instance != null) ? ((Component)__instance).gameObject : null) == (Object)null || __instance.m_staggerDamageFactor <= 0f)
			{
				return true;
			}
			string name = ((Object)((Component)__instance).gameObject).name;
			try
			{
				float num = __instance.GetMaxHealth() * __instance.m_staggerDamageFactor;
				float num2 = (float)ReflectionCache.StaggerDamageField.GetValue(__instance);
				if (name.StartsWith("Troll"))
				{
					num2 -= num / 5f * TrollStaggerDrainMultiplier.Value * dt;
				}
				else if (name.StartsWith("Bjorn"))
				{
					num2 -= num / 5f * BearStaggerDrainMultiplier.Value * dt;
				}
				else if (name.StartsWith("Abomination"))
				{
					num2 -= num / 5f * AbominationStaggerDrainMultiplier.Value * dt;
				}
				else if (name.StartsWith("StoneGolem"))
				{
					num2 -= num / 5f * GolemStaggerDrainMultiplier.Value * dt;
				}
				else if (name.Contains("Cultist"))
				{
					num2 -= num / 5f * CultistStaggerDrainMultiplier.Value * dt;
				}
				else if (name.Contains("GoblinBrute"))
				{
					num2 -= num / 5f * BruteStaggerDrainMultiplier.Value * dt;
				}
				else
				{
					if (!name.Contains("SeekerBrute"))
					{
						return true;
					}
					num2 -= num / 5f * SoldierStaggerDrainMultiplier.Value * dt;
				}
				if (num2 < 0f)
				{
					num2 = 0f;
				}
				ReflectionCache.StaggerDamageField.SetValue(__instance, num2);
				return false;
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Error in stagger drain patch: " + ex.Message));
				return true;
			}
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	public static class TrollAnimationSpeedPatch
	{
		private class TrollAnimationState
		{
			public float LastMultiplier;

			public int LastStateHash;

			public float StateStartTime;

			public bool MultiplierActive;

			public void Reset()
			{
				LastMultiplier = 0f;
				LastStateHash = 0;
				StateStartTime = 0f;
				MultiplierActive = false;
			}
		}

		private static readonly Dictionary<Animator, TrollAnimationState> s_animStates = new Dictionary<Animator, TrollAnimationState>();

		private static float s_lastCleanupTime = 0f;

		private static void Postfix(MonsterAI __instance)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)((__instance != null) ? ((Component)__instance).gameObject : null) == (Object)null || !((Object)((Component)__instance).gameObject).name.StartsWith("Troll"))
				{
					return;
				}
				Animator componentInChildren = ((Component)__instance).gameObject.GetComponentInChildren<Animator>();
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					AnimatorStateInfo currentAnimatorStateInfo = componentInChildren.GetCurrentAnimatorStateInfo(0);
					int shortNameHash = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash;
					if (!s_animStates.TryGetValue(componentInChildren, out var value))
					{
						value = new TrollAnimationState();
						s_animStates[componentInChildren] = value;
					}
					if (Time.time - s_lastCleanupTime > 30f)
					{
						CleanupDestroyedAnimators();
						s_lastCleanupTime = Time.time;
					}
					bool stateChanged = value.LastStateHash != shortNameHash;
					switch (shortNameHash)
					{
					case 1203776827:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, GroundSlamAnimSpeedMin.Value, GroundSlamAnimSpeedMax.Value, -1f, "GroundSlam");
						break;
					case 752971864:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, PunchAnimSpeedMin.Value, PunchAnimSpeedMax.Value, -1f, "Punch");
						break;
					case 22911243:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, TrunkSwingVAnimSpeedMin.Value, TrunkSwingVAnimSpeedMax.Value, TrunkSwingVAnimSpeedDuration.Value, "TrunkSwingV");
						break;
					case -78470040:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, TrunkSwingHAnimSpeedMin.Value, TrunkSwingHAnimSpeedMax.Value, TrunkSwingHAnimSpeedDuration.Value, "TrunkSwingH");
						break;
					default:
						ClearMultiplier(componentInChildren, value);
						value.LastStateHash = shortNameHash;
						break;
					}
				}
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"[Troll Animation Speed] Exception: {arg}");
			}
		}

		private static void HandleAnimationSpeed(Animator animator, TrollAnimationState state, int currentHash, bool stateChanged, float minSpeed, float maxSpeed, float duration, string animName)
		{
			if (stateChanged)
			{
				ClearMultiplier(animator, state);
				float num = Mathf.Min(minSpeed, maxSpeed);
				float num2 = Mathf.Max(minSpeed, maxSpeed);
				float num3 = Random.Range(num, num2);
				animator.speed *= num3;
				state.LastMultiplier = num3;
				state.MultiplierActive = true;
				state.StateStartTime = Time.time;
				DebugLog($"Applied {num3:F2}x speed to {animName}");
			}
			else if (state.MultiplierActive && duration > 0f && Time.time - state.StateStartTime > duration)
			{
				ClearMultiplier(animator, state);
				DebugLog("Duration expired for " + animName + ", clearing multiplier");
			}
			state.LastStateHash = currentHash;
		}

		private static void ClearMultiplier(Animator animator, TrollAnimationState state)
		{
			if (!state.MultiplierActive || state.LastMultiplier == 0f)
			{
				return;
			}
			try
			{
				animator.speed /= state.LastMultiplier;
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("[Troll Anim Speed] Failed to clear multiplier: " + ex.Message));
			}
			finally
			{
				state.MultiplierActive = false;
				state.LastMultiplier = 0f;
			}
		}

		private static void CleanupDestroyedAnimators()
		{
			List<Animator> list = s_animStates.Keys.Where((Animator key) => (Object)(object)key == (Object)null || (Object)(object)((Component)key).gameObject == (Object)null).ToList();
			foreach (Animator item in list)
			{
				s_animStates.Remove(item);
			}
			if (list.Count > 0)
			{
				DebugLog($"Cleaned up {list.Count} destroyed animator references");
			}
		}

		public static void Cleanup()
		{
			foreach (KeyValuePair<Animator, TrollAnimationState> item in s_animStates.Where((KeyValuePair<Animator, TrollAnimationState> kvp) => (Object)(object)kvp.Key != (Object)null))
			{
				ClearMultiplier(item.Key, item.Value);
			}
			s_animStates.Clear();
			DebugLog("All animation states cleared");
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	public static class BearAnimationSpeedPatch
	{
		private class BearAnimationState
		{
			public float LastMultiplier;

			public int LastStateHash;

			public float StateStartTime;

			public bool MultiplierActive;

			public void Reset()
			{
				LastMultiplier = 0f;
				LastStateHash = 0;
				StateStartTime = 0f;
				MultiplierActive = false;
			}
		}

		private static readonly Dictionary<Animator, BearAnimationState> s_animStates = new Dictionary<Animator, BearAnimationState>();

		private static float s_lastCleanupTime = 0f;

		private static void Postfix(MonsterAI __instance)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)((__instance != null) ? ((Component)__instance).gameObject : null) == (Object)null || !((Object)((Component)__instance).gameObject).name.StartsWith("Bjorn"))
				{
					return;
				}
				Animator componentInChildren = ((Component)__instance).gameObject.GetComponentInChildren<Animator>();
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					AnimatorStateInfo currentAnimatorStateInfo = componentInChildren.GetCurrentAnimatorStateInfo(0);
					int shortNameHash = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash;
					if (!s_animStates.TryGetValue(componentInChildren, out var value))
					{
						value = new BearAnimationState();
						s_animStates[componentInChildren] = value;
					}
					if (Time.time - s_lastCleanupTime > 30f)
					{
						CleanupDestroyedAnimators();
						s_lastCleanupTime = Time.time;
					}
					bool stateChanged = value.LastStateHash != shortNameHash;
					switch (shortNameHash)
					{
					case -2115618530:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, BiteAnimSpeedMin.Value, BiteAnimSpeedMax.Value, BiteAnimSpeedDuration.Value, "Bite");
						break;
					case -1993876325:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, ClawsAnimSpeedMin.Value, ClawsAnimSpeedMax.Value, ClawsAnimSpeedDuration.Value, "Claws");
						break;
					case -153875945:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, SlamAnimSpeedMin.Value, SlamAnimSpeedMax.Value, SlamAnimSpeedDuration.Value, "Slam");
						break;
					case -1030126497:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, SwipeLAnimSpeedMin.Value, SwipeLAnimSpeedMax.Value, SwipeLAnimSpeedDuration.Value, "SwipeL");
						break;
					case 949401916:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, SwipeRAnimSpeedMin.Value, SwipeRAnimSpeedMax.Value, SwipeRAnimSpeedDuration.Value, "SwipeR");
						break;
					case 1437481170:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, SwipeComboAnimSpeedMin.Value, SwipeComboAnimSpeedMax.Value, SwipeComboAnimSpeedDuration.Value, "SwipeCombo");
						break;
					case 581503044:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, SwipeComboAnimSpeedMin.Value, SwipeComboAnimSpeedMax.Value, SwipeComboAnimSpeedDuration.Value, "SwipeCombo");
						break;
					default:
						ClearMultiplier(componentInChildren, value);
						value.LastStateHash = shortNameHash;
						break;
					}
				}
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"[Bears Animation Speed] Exception: {arg}");
			}
		}

		private static void HandleAnimationSpeed(Animator animator, BearAnimationState state, int currentHash, bool stateChanged, float minSpeed, float maxSpeed, float duration, string animName)
		{
			if (stateChanged)
			{
				ClearMultiplier(animator, state);
				float num = Mathf.Min(minSpeed, maxSpeed);
				float num2 = Mathf.Max(minSpeed, maxSpeed);
				float num3 = Random.Range(num, num2);
				animator.speed *= num3;
				state.LastMultiplier = num3;
				state.MultiplierActive = true;
				state.StateStartTime = Time.time;
				DebugLog($"Applied {num3:F2}x speed to {animName}");
			}
			else if (state.MultiplierActive && duration > 0f && Time.time - state.StateStartTime > duration)
			{
				ClearMultiplier(animator, state);
				DebugLog("Duration expired for " + animName + ", clearing multiplier");
			}
			state.LastStateHash = currentHash;
		}

		private static void ClearMultiplier(Animator animator, BearAnimationState state)
		{
			if (!state.MultiplierActive || state.LastMultiplier == 0f)
			{
				return;
			}
			try
			{
				animator.speed /= state.LastMultiplier;
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("[Bear Anim Speed] Failed to clear multiplier: " + ex.Message));
			}
			finally
			{
				state.MultiplierActive = false;
				state.LastMultiplier = 0f;
			}
		}

		private static void CleanupDestroyedAnimators()
		{
			List<Animator> list = s_animStates.Keys.Where((Animator key) => (Object)(object)key == (Object)null || (Object)(object)((Component)key).gameObject == (Object)null).ToList();
			foreach (Animator item in list)
			{
				s_animStates.Remove(item);
			}
			if (list.Count > 0)
			{
				DebugLog($"Cleaned up {list.Count} destroyed animator references");
			}
		}

		public static void Cleanup()
		{
			foreach (KeyValuePair<Animator, BearAnimationState> item in s_animStates.Where((KeyValuePair<Animator, BearAnimationState> kvp) => (Object)(object)kvp.Key != (Object)null))
			{
				ClearMultiplier(item.Key, item.Value);
			}
			s_animStates.Clear();
			DebugLog("All animation states cleared");
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	public static class AbominationAnimationSpeedPatch
	{
		private class AnimState
		{
			public float LastMultiplier;

			public int LastStateHash;

			public float StateStartTime;

			public bool MultiplierActive;

			public float EffectiveDuration = -1f;

			public void Reset()
			{
				LastMultiplier = 0f;
				LastStateHash = 0;
				StateStartTime = 0f;
				MultiplierActive = false;
				EffectiveDuration = -1f;
			}
		}

		private static readonly Dictionary<Animator, AnimState> s_animStates = new Dictionary<Animator, AnimState>();

		private static float s_lastCleanupTime = 0f;

		private static void Postfix(MonsterAI __instance)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)((__instance != null) ? ((Component)__instance).gameObject : null) == (Object)null || !((Object)((Component)__instance).gameObject).name.StartsWith("Abomination"))
				{
					return;
				}
				Animator componentInChildren = ((Component)__instance).gameObject.GetComponentInChildren<Animator>();
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					AnimatorStateInfo currentAnimatorStateInfo = componentInChildren.GetCurrentAnimatorStateInfo(0);
					int shortNameHash = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash;
					if (!s_animStates.TryGetValue(componentInChildren, out var value))
					{
						value = new AnimState();
						s_animStates[componentInChildren] = value;
					}
					if (Time.time - s_lastCleanupTime > 30f)
					{
						CleanupDestroyedAnimators();
						s_lastCleanupTime = Time.time;
					}
					bool stateChanged = value.LastStateHash != shortNameHash;
					switch (shortNameHash)
					{
					case -1415997692:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, VSlamAnimSpeedMin.Value, VSlamAnimSpeedMax.Value, VSlamAnimSpeedBaseDuration.Value, "VSlam");
						break;
					case 1203776827:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, HSweepAnimSpeedMin.Value, HSweepAnimSpeedMax.Value, HSweepAnimSpeedBaseDuration.Value, "HSweep");
						break;
					case -593582190:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, AOECrushAnimSpeedMin.Value, AOECrushAnimSpeedMax.Value, AOECrushAnimSpeedBaseDuration.Value, "AOECrush");
						break;
					default:
						ClearMultiplier(componentInChildren, value);
						value.LastStateHash = shortNameHash;
						break;
					}
				}
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"[Abomination Animation Speed] Exception: {arg}");
			}
		}

		private static void HandleAnimationSpeed(Animator animator, AnimState state, int currentHash, bool stateChanged, float minSpeed, float maxSpeed, float baseDuration, string animName)
		{
			if (stateChanged)
			{
				ClearMultiplier(animator, state);
				float num = Mathf.Min(minSpeed, maxSpeed);
				float num2 = Mathf.Max(minSpeed, maxSpeed);
				float num3 = Random.Range(num, num2);
				float num4 = ((baseDuration > 0f) ? (baseDuration / num3) : (-1f));
				animator.speed *= num3;
				state.LastMultiplier = num3;
				state.MultiplierActive = true;
				state.StateStartTime = Time.time;
				state.EffectiveDuration = num4;
				DebugLog($"Applied {num3:F2}x speed to {animName} (adjusted duration {num4:F2}s)");
			}
			else if (state.MultiplierActive && state.EffectiveDuration > 0f && Time.time - state.StateStartTime > state.EffectiveDuration)
			{
				ClearMultiplier(animator, state);
				DebugLog("Duration expired for " + animName + ", clearing multiplier");
			}
			state.LastStateHash = currentHash;
		}

		private static void ClearMultiplier(Animator animator, AnimState state)
		{
			if (!state.MultiplierActive || state.LastMultiplier == 0f)
			{
				return;
			}
			try
			{
				animator.speed /= state.LastMultiplier;
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("[Abomination Anim Speed] Failed to clear multiplier: " + ex.Message));
			}
			finally
			{
				state.MultiplierActive = false;
				state.LastMultiplier = 0f;
			}
		}

		private static void CleanupDestroyedAnimators()
		{
			List<Animator> list = s_animStates.Keys.Where((Animator k) => (Object)(object)k == (Object)null || (Object)(object)((Component)k).gameObject == (Object)null).ToList();
			foreach (Animator item in list)
			{
				s_animStates.Remove(item);
			}
			if (list.Count > 0)
			{
				DebugLog($"Cleaned up {list.Count} destroyed animator references (Abomination)");
			}
		}

		public static void Cleanup()
		{
			foreach (KeyValuePair<Animator, AnimState> item in s_animStates.Where((KeyValuePair<Animator, AnimState> kvp) => (Object)(object)kvp.Key != (Object)null))
			{
				ClearMultiplier(item.Key, item.Value);
			}
			s_animStates.Clear();
			DebugLog("All Abomination animation states cleared");
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	public static class GolemAnimationSpeedPatch
	{
		private class AnimState
		{
			public float LastMultiplier;

			public int LastStateHash;

			public float StateStartTime;

			public bool MultiplierActive;

			public float EffectiveDuration = -1f;

			public void Reset()
			{
				LastMultiplier = 0f;
				LastStateHash = 0;
				StateStartTime = 0f;
				MultiplierActive = false;
				EffectiveDuration = -1f;
			}
		}

		private static readonly Dictionary<Animator, AnimState> s_animStates = new Dictionary<Animator, AnimState>();

		private static float s_lastCleanupTime = 0f;

		private static void Postfix(MonsterAI __instance)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)((__instance != null) ? ((Component)__instance).gameObject : null) == (Object)null || !((Object)((Component)__instance).gameObject).name.StartsWith("StoneGolem"))
				{
					return;
				}
				Animator componentInChildren = ((Component)__instance).gameObject.GetComponentInChildren<Animator>();
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					AnimatorStateInfo currentAnimatorStateInfo = componentInChildren.GetCurrentAnimatorStateInfo(0);
					int shortNameHash = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash;
					if (!s_animStates.TryGetValue(componentInChildren, out var value))
					{
						value = new AnimState();
						s_animStates[componentInChildren] = value;
					}
					if (Time.time - s_lastCleanupTime > 30f)
					{
						CleanupDestroyedAnimators();
						s_lastCleanupTime = Time.time;
					}
					bool stateChanged = value.LastStateHash != shortNameHash;
					switch (shortNameHash)
					{
					case -287095546:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, CrushAnimSpeedMin.Value, CrushAnimSpeedMax.Value, CrushAnimSpeedBaseDuration.Value, "Crush");
						break;
					case -1415997692:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, GolemSlamAnimSpeedMin.Value, GolemSlamAnimSpeedMax.Value, GolemSlamAnimSpeedBaseDuration.Value, "GolemSlam");
						break;
					case 1203776827:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, PokeAnimSpeedMin.Value, PokeAnimSpeedMax.Value, PokeAnimSpeedBaseDuration.Value, "Poke");
						break;
					case -593582190:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, SweepAnimSpeedMin.Value, SweepAnimSpeedMax.Value, SweepAnimSpeedBaseDuration.Value, "Sweep");
						break;
					default:
						ClearMultiplier(componentInChildren, value);
						value.LastStateHash = shortNameHash;
						break;
					}
				}
			}
			catch (Exception arg)
			{
				Logger.LogError((object)$"[Golem Animation Speed] Exception: {arg}");
			}
		}

		private static void HandleAnimationSpeed(Animator animator, AnimState state, int currentHash, bool stateChanged, float minSpeed, float maxSpeed, float baseDuration, string animName)
		{
			if (stateChanged)
			{
				ClearMultiplier(animator, state);
				float num = Random.Range(Mathf.Min(minSpeed, maxSpeed), Mathf.Max(minSpeed, maxSpeed));
				float num2 = ((baseDuration > 0f) ? (baseDuration / num) : (-1f));
				animator.speed *= num;
				state.LastMultiplier = num;
				state.MultiplierActive = true;
				state.StateStartTime = Time.time;
				state.EffectiveDuration = num2;
				DebugLog($"Applied {num:F2}x speed to {animName}, adjusted duration {num2:F2}s");
			}
			else if (state.MultiplierActive && state.EffectiveDuration > 0f && Time.time - state.StateStartTime > state.EffectiveDuration)
			{
				ClearMultiplier(animator, state);
				DebugLog("Duration expired for " + animName + ", clearing multiplier");
			}
			state.LastStateHash = currentHash;
		}

		private static void ClearMultiplier(Animator animator, AnimState state)
		{
			if (!state.MultiplierActive || state.LastMultiplier == 0f)
			{
				return;
			}
			try
			{
				animator.speed /= state.LastMultiplier;
			}
			catch (Exception ex)
			{
				Logger.LogWarning((object)("[Golem Anim Speed] Failed to clear multiplier: " + ex.Message));
			}
			finally
			{
				state.MultiplierActive = false;
				state.LastMultiplier = 0f;
			}
		}

		private static void CleanupDestroyedAnimators()
		{
			List<Animator> list = s_animStates.Keys.Where((Animator a) => (Object)(object)a == (Object)null || (Object)(object)((Component)a).gameObject == (Object)null).ToList();
			foreach (Animator item in list)
			{
				s_animStates.Remove(item);
			}
			if (list.Count > 0)
			{
				DebugLog($"Cleaned up {list.Count} destroyed animator references (Golem)");
			}
		}

		public static void Cleanup()
		{
			foreach (KeyValuePair<Animator, AnimState> item in s_animStates.Where((KeyValuePair<Animator, AnimState> kvp) => (Object)(object)kvp.Key != (Object)null))
			{
				ClearMultiplier(item.Key, item.Value);
			}
			s_animStates.Clear();
			DebugLog("All Golem animation states cleared");
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	public static class CultistAnimationSpeedPatch
	{
		private class AnimState
		{
			public float LastMultiplier;

			public int LastStateHash;

			public float StateStartTime;

			public bool MultiplierActive;

			public float EffectiveDuration;

			public void Reset()
			{
				LastMultiplier = 0f;
				LastStateHash = 0;
				StateStartTime = 0f;
				MultiplierActive = false;
				EffectiveDuration = -1f;
			}
		}

		private static readonly Dictionary<Animator, AnimState> animStates = new Dictionary<Animator, AnimState>();

		private static float lastCleanupTime = 0f;

		private static void Postfix(MonsterAI __instance)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((__instance != null) ? ((Component)__instance).gameObject : null) == (Object)null || !((Object)((Component)__instance).gameObject).name.Contains("Cultist"))
			{
				return;
			}
			Animator componentInChildren = ((Component)__instance).gameObject.GetComponentInChildren<Animator>();
			if (!((Object)(object)componentInChildren == (Object)null))
			{
				AnimatorStateInfo currentAnimatorStateInfo = componentInChildren.GetCurrentAnimatorStateInfo(0);
				int shortNameHash = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash;
				if (!animStates.TryGetValue(componentInChildren, out var value))
				{
					value = (animStates[componentInChildren] = new AnimState());
				}
				if (Time.time - lastCleanupTime > 30f)
				{
					CleanupDestroyedAnimators();
					lastCleanupTime = Time.time;
				}
				bool changed = value.LastStateHash != shortNameHash;
				switch (shortNameHash)
				{
				case 210160161:
					Handle(componentInChildren, value, shortNameHash, changed, FireclawAnimSpeedMin.Value, FireclawAnimSpeedMax.Value, FireclawAnimSpeedBaseDuration.Value, "Fireclaw");
					break;
				case -37429503:
					Handle(componentInChildren, value, shortNameHash, changed, DoubleFireclawAnimSpeedMin.Value, DoubleFireclawAnimSpeedMax.Value, DoubleFireclawAnimSpeedBaseDuration.Value, "DoubleFireclaw");
					break;
				case 638396485:
					Handle(componentInChildren, value, shortNameHash, changed, AOEFireAnimSpeedMin.Value, AOEFireAnimSpeedMax.Value, AOEFireAnimSpeedBaseDuration.Value, "AOEFire");
					break;
				default:
					Clear(componentInChildren, value);
					value.LastStateHash = shortNameHash;
					break;
				}
			}
		}

		private static void Handle(Animator animator, AnimState state, int hash, bool changed, float min, float max, float baseDur, string name)
		{
			if (changed)
			{
				Clear(animator, state);
				float num = Random.Range(Mathf.Min(min, max), Mathf.Max(min, max));
				float num2 = ((baseDur > 0f) ? (baseDur / num) : (-1f));
				animator.speed *= num;
				state.LastMultiplier = num;
				state.MultiplierActive = true;
				state.StateStartTime = Time.time;
				state.EffectiveDuration = num2;
				ConfigEntry<bool> enableDebugLogging = EnableDebugLogging;
				if (enableDebugLogging != null && enableDebugLogging.Value)
				{
					Debug.Log((object)$"[Cultist] Applied {num:F2}x speed to {name} (duration {num2:F2}s)");
				}
			}
			else if (state.MultiplierActive && state.EffectiveDuration > 0f && Time.time - state.StateStartTime > state.EffectiveDuration)
			{
				Clear(animator, state);
				ConfigEntry<bool> enableDebugLogging2 = EnableDebugLogging;
				if (enableDebugLogging2 != null && enableDebugLogging2.Value)
				{
					Debug.Log((object)("[Cultist] Duration expired for " + name + ", cleared multiplier"));
				}
			}
			state.LastStateHash = hash;
		}

		private static void Clear(Animator animator, AnimState state)
		{
			if (!state.MultiplierActive || state.LastMultiplier == 0f)
			{
				return;
			}
			try
			{
				animator.speed /= state.LastMultiplier;
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[Cultist Anim] Failed to clear: " + ex.Message));
			}
			finally
			{
				state.MultiplierActive = false;
				state.LastMultiplier = 0f;
			}
		}

		private static void CleanupDestroyedAnimators()
		{
			foreach (Animator item in animStates.Keys.Where((Animator k) => (Object)(object)k == (Object)null || (Object)(object)((Component)k).gameObject == (Object)null).ToList())
			{
				animStates.Remove(item);
			}
		}

		public static void Cleanup()
		{
			foreach (KeyValuePair<Animator, AnimState> item in animStates.Where((KeyValuePair<Animator, AnimState> kvp) => (Object)(object)kvp.Key != (Object)null))
			{
				Clear(item.Key, item.Value);
			}
			animStates.Clear();
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	public static class BruteAnimationSpeedPatch
	{
		private class AnimState
		{
			public float LastMultiplier;

			public int LastStateHash;

			public float StateStartTime;

			public bool MultiplierActive;

			public float EffectiveDuration = -1f;

			public void Reset()
			{
				LastMultiplier = 0f;
				LastStateHash = 0;
				StateStartTime = 0f;
				MultiplierActive = false;
				EffectiveDuration = -1f;
			}
		}

		private static readonly Dictionary<Animator, AnimState> s_animStates = new Dictionary<Animator, AnimState>();

		private static float s_lastCleanupTime = 0f;

		private static void Postfix(MonsterAI __instance)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)((__instance != null) ? ((Component)__instance).gameObject : null) == (Object)null || !((Object)((Component)__instance).gameObject).name.Contains("Brute"))
				{
					return;
				}
				Animator componentInChildren = ((Component)__instance).gameObject.GetComponentInChildren<Animator>();
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					AnimatorStateInfo currentAnimatorStateInfo = componentInChildren.GetCurrentAnimatorStateInfo(0);
					int shortNameHash = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash;
					if (!s_animStates.TryGetValue(componentInChildren, out var value))
					{
						value = new AnimState();
						s_animStates[componentInChildren] = value;
					}
					if (Time.time - s_lastCleanupTime > 30f)
					{
						CleanupDestroyedAnimators();
						s_lastCleanupTime = Time.time;
					}
					bool stateChanged = value.LastStateHash != shortNameHash;
					switch (shortNameHash)
					{
					case -322548239:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, SlamComboAnimSpeedMin.Value, SlamComboAnimSpeedMax.Value, SlamComboAnimSpeedBaseDuration.Value, "SlamCombo");
						break;
					case 848348862:
					case 1167586856:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, SwingAnimSpeedMin.Value, SwingAnimSpeedMax.Value, SwingAnimSpeedBaseDuration.Value, "Swing");
						break;
					default:
						ClearMultiplier(componentInChildren, value);
						value.LastStateHash = shortNameHash;
						break;
					}
				}
			}
			catch (Exception arg)
			{
				Debug.LogError((object)$"[Brute Animation Speed] Exception: {arg}");
			}
		}

		private static void HandleAnimationSpeed(Animator animator, AnimState state, int currentHash, bool stateChanged, float minSpeed, float maxSpeed, float baseDuration, string animName)
		{
			if (stateChanged)
			{
				ClearMultiplier(animator, state);
				float num = Mathf.Min(minSpeed, maxSpeed);
				float num2 = Mathf.Max(minSpeed, maxSpeed);
				float num3 = Random.Range(num, num2);
				float num4 = ((baseDuration > 0f) ? (baseDuration / num3) : (-1f));
				animator.speed *= num3;
				state.LastMultiplier = num3;
				state.MultiplierActive = true;
				state.StateStartTime = Time.time;
				state.EffectiveDuration = num4;
				Debug.Log((object)$"[Brute] Applied {num3:F2}x speed to {animName}, adjusted duration {num4:F2}s");
			}
			else if (state.MultiplierActive && state.EffectiveDuration > 0f && Time.time - state.StateStartTime > state.EffectiveDuration)
			{
				ClearMultiplier(animator, state);
				Debug.Log((object)("[Brute] Duration expired for " + animName + ", clearing multiplier"));
			}
			state.LastStateHash = currentHash;
		}

		private static void ClearMultiplier(Animator animator, AnimState state)
		{
			if (!state.MultiplierActive || state.LastMultiplier == 0f)
			{
				return;
			}
			try
			{
				animator.speed /= state.LastMultiplier;
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[Brute Anim Speed] Failed to clear multiplier: " + ex.Message));
			}
			finally
			{
				state.MultiplierActive = false;
				state.LastMultiplier = 0f;
			}
		}

		private static void CleanupDestroyedAnimators()
		{
			List<Animator> list = s_animStates.Keys.Where((Animator k) => (Object)(object)k == (Object)null || (Object)(object)((Component)k).gameObject == (Object)null).ToList();
			foreach (Animator item in list)
			{
				s_animStates.Remove(item);
			}
			if (list.Count > 0)
			{
				Debug.Log((object)$"[Brute Anim Speed] Cleaned up {list.Count} destroyed animator references");
			}
		}

		public static void Cleanup()
		{
			foreach (KeyValuePair<Animator, AnimState> item in s_animStates.Where((KeyValuePair<Animator, AnimState> kvp) => (Object)(object)kvp.Key != (Object)null))
			{
				ClearMultiplier(item.Key, item.Value);
			}
			s_animStates.Clear();
			Debug.Log((object)"[Brute Anim Speed] All animation states cleared");
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	public static class LoxAnimationSpeedPatch
	{
		private class AnimState
		{
			public float LastMultiplier;

			public int LastStateHash;

			public float StateStartTime;

			public bool MultiplierActive;

			public float EffectiveDuration = -1f;

			public void Reset()
			{
				LastMultiplier = 0f;
				LastStateHash = 0;
				StateStartTime = 0f;
				MultiplierActive = false;
				EffectiveDuration = -1f;
			}
		}

		private static readonly Dictionary<Animator, AnimState> animStates = new Dictionary<Animator, AnimState>();

		private static float lastCleanupTime = 0f;

		private static void Postfix(MonsterAI __instance)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				GameObject gameObject = ((Component)__instance).gameObject;
				if ((Object)(object)gameObject == (Object)null || !((Object)gameObject).name.StartsWith("Lox"))
				{
					return;
				}
				Animator componentInChildren = gameObject.GetComponentInChildren<Animator>();
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					AnimatorStateInfo currentAnimatorStateInfo = componentInChildren.GetCurrentAnimatorStateInfo(0);
					int shortNameHash = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash;
					if (!animStates.TryGetValue(componentInChildren, out var value))
					{
						value = new AnimState();
						animStates[componentInChildren] = value;
					}
					PeriodicCleanup();
					bool stateChanged = value.LastStateHash != shortNameHash;
					switch (shortNameHash)
					{
					case -2115618530:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, LoxBiteAnimSpeedMin.Value, LoxBiteAnimSpeedMax.Value, LoxBiteAnimSpeedBaseDuration.Value, "Bite");
						break;
					case 1607512578:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, StompAnimSpeedMin.Value, StompAnimSpeedMax.Value, StompAnimSpeedBaseDuration.Value, "Stomp");
						break;
					default:
						ClearMultiplier(componentInChildren, value);
						value.LastStateHash = shortNameHash;
						break;
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[Lox Anim Speed] Exception: " + ex));
			}
		}

		private static void HandleAnimationSpeed(Animator animator, AnimState state, int currentHash, bool stateChanged, float minSpeed, float maxSpeed, float baseDuration, string animName)
		{
			if (stateChanged)
			{
				ClearMultiplier(animator, state);
				float num = Mathf.Min(minSpeed, maxSpeed);
				float num2 = Mathf.Max(minSpeed, maxSpeed);
				float num3 = Random.Range(num, num2);
				float num4 = ((baseDuration > 0f) ? (baseDuration / num3) : (-1f));
				animator.speed *= num3;
				state.LastMultiplier = num3;
				state.MultiplierActive = true;
				state.StateStartTime = Time.time;
				state.EffectiveDuration = num4;
				Debug.Log((object)$"[Lox] Applied {num3:F2}x speed to {animName}, adjusted duration: {num4:F2}s");
			}
			else if (state.MultiplierActive && state.EffectiveDuration > 0f && Time.time - state.StateStartTime > state.EffectiveDuration)
			{
				ClearMultiplier(animator, state);
				Debug.Log((object)("[Lox] Duration expired for " + animName + ", clearing multiplier"));
			}
			state.LastStateHash = currentHash;
		}

		private static void ClearMultiplier(Animator animator, AnimState state)
		{
			if (!state.MultiplierActive || state.LastMultiplier == 0f)
			{
				return;
			}
			try
			{
				animator.speed /= state.LastMultiplier;
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[Lox Anim Speed] Failed to clear multiplier: " + ex.Message));
			}
			finally
			{
				state.MultiplierActive = false;
				state.LastMultiplier = 0f;
			}
		}

		private static void PeriodicCleanup()
		{
			if (Time.time - lastCleanupTime > 30f)
			{
				CleanupDestroyedAnimators();
				lastCleanupTime = Time.time;
			}
		}

		private static void CleanupDestroyedAnimators()
		{
			List<Animator> list = animStates.Keys.Where((Animator key) => (Object)(object)key == (Object)null || (Object)(object)((Component)key).gameObject == (Object)null).ToList();
			foreach (Animator item in list)
			{
				animStates.Remove(item);
			}
			if (list.Count > 0)
			{
				Debug.Log((object)$"[Lox Anim Speed] Cleaned up {list.Count} destroyed animator refs");
			}
		}

		public static void Cleanup()
		{
			foreach (KeyValuePair<Animator, AnimState> item in animStates.Where((KeyValuePair<Animator, AnimState> kvp) => (Object)(object)kvp.Key != (Object)null))
			{
				ClearMultiplier(item.Key, item.Value);
			}
			animStates.Clear();
			Debug.Log((object)"[Lox Anim Speed] All animation states cleared");
		}
	}

	[HarmonyPatch(typeof(MonsterAI), "UpdateAI")]
	public static class SoldierAnimationSpeedPatch
	{
		private class AnimState
		{
			public float LastMultiplier;

			public int LastStateHash;

			public float StateStartTime;

			public bool MultiplierActive;

			public float EffectiveDuration = -1f;

			public void Reset()
			{
				LastMultiplier = 0f;
				LastStateHash = 0;
				StateStartTime = 0f;
				MultiplierActive = false;
				EffectiveDuration = -1f;
			}
		}

		private static readonly Dictionary<Animator, AnimState> animStates = new Dictionary<Animator, AnimState>();

		private static float lastCleanupTime = 0f;

		private static void Postfix(MonsterAI __instance)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				GameObject gameObject = ((Component)__instance).gameObject;
				if ((Object)(object)gameObject == (Object)null || !((Object)gameObject).name.StartsWith("SeekerBrute"))
				{
					return;
				}
				Animator componentInChildren = gameObject.GetComponentInChildren<Animator>();
				if (!((Object)(object)componentInChildren == (Object)null))
				{
					AnimatorStateInfo currentAnimatorStateInfo = componentInChildren.GetCurrentAnimatorStateInfo(0);
					int shortNameHash = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash;
					if (!animStates.TryGetValue(componentInChildren, out var value))
					{
						value = new AnimState();
						animStates[componentInChildren] = value;
					}
					PeriodicCleanup();
					bool stateChanged = value.LastStateHash != shortNameHash;
					switch (shortNameHash)
					{
					case 735162116:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, SoldierBiteAnimSpeedMin.Value, SoldierBiteAnimSpeedMax.Value, SoldierBiteAnimSpeedBaseDuration.Value, "SoldierBite");
						break;
					case -636786879:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, RamAnimSpeedMin.Value, RamAnimSpeedMax.Value, RamAnimSpeedBaseDuration.Value, "Ram");
						break;
					case -53398733:
						HandleAnimationSpeed(componentInChildren, value, shortNameHash, stateChanged, SoldierGroundSlamAnimSpeedMin.Value, SoldierGroundSlamAnimSpeedMax.Value, SoldierGroundSlamAnimSpeedBaseDuration.Value, "SoldierGroundSlam");
						break;
					default:
						ClearMultiplier(componentInChildren, value);
						value.LastStateHash = shortNameHash;
						break;
					}
				}
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[Soldier Anim Speed] Exception: " + ex));
			}
		}

		private static void HandleAnimationSpeed(Animator animator, AnimState state, int currentHash, bool stateChanged, float minSpeed, float maxSpeed, float baseDuration, string animName)
		{
			if (stateChanged)
			{
				ClearMultiplier(animator, state);
				float num = Mathf.Min(minSpeed, maxSpeed);
				float num2 = Mathf.Max(minSpeed, maxSpeed);
				float num3 = Random.Range(num, num2);
				float num4 = ((baseDuration > 0f) ? (baseDuration / num3) : (-1f));
				animator.speed *= num3;
				state.LastMultiplier = num3;
				state.MultiplierActive = true;
				state.StateStartTime = Time.time;
				state.EffectiveDuration = num4;
				Debug.Log((object)$"[Soldier] Applied {num3:F2}x speed to {animName}, adjusted duration: {num4:F2}s");
			}
			else if (state.MultiplierActive && state.EffectiveDuration > 0f && Time.time - state.StateStartTime > state.EffectiveDuration)
			{
				ClearMultiplier(animator, state);
				Debug.Log((object)("[Soldier] Duration expired for " + animName + ", clearing multiplier"));
			}
			state.LastStateHash = currentHash;
		}

		private static void ClearMultiplier(Animator animator, AnimState state)
		{
			if (!state.MultiplierActive || state.LastMultiplier == 0f)
			{
				return;
			}
			try
			{
				animator.speed /= state.LastMultiplier;
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("[Soldier Anim Speed] Failed to clear multiplier: " + ex.Message));
			}
			finally
			{
				state.MultiplierActive = false;
				state.LastMultiplier = 0f;
			}
		}

		private static void PeriodicCleanup()
		{
			if (Time.time - lastCleanupTime > 30f)
			{
				CleanupDestroyedAnimators();
				lastCleanupTime = Time.time;
			}
		}

		private static void CleanupDestroyedAnimators()
		{
			List<Animator> list = animStates.Keys.Where((Animator key) => (Object)(object)key == (Object)null || (Object)(object)((Component)key).gameObject == (Object)null).ToList();
			foreach (Animator item in list)
			{
				animStates.Remove(item);
			}
			if (list.Count > 0)
			{
				Debug.Log((object)$"[Soldier Anim Speed] Cleaned up {list.Count} destroyed animator refs");
			}
		}

		public static void Cleanup()
		{
			foreach (KeyValuePair<Animator, AnimState> item in animStates.Where((KeyValuePair<Animator, AnimState> kvp) => (Object)(object)kvp.Key != (Object)null))
			{
				ClearMultiplier(item.Key, item.Value);
			}
			animStates.Clear();
			Debug.Log((object)"[Soldier Anim Speed] All animation states cleared");
		}
	}

	public static ConfigEntry<bool> EnableTrollPatches;

	public static ConfigEntry<bool> EnableBearPatches;

	public static ConfigEntry<bool> EnableAbominationPatches;

	public static ConfigEntry<bool> EnableGolemPatches;

	public static ConfigEntry<bool> EnableCultistPatches;

	public static ConfigEntry<bool> EnableBrutePatches;

	public static ConfigEntry<bool> EnableLoxPatches;

	public static ConfigEntry<bool> EnableSoldierPatches;

	public static ConfigEntry<bool> EnableSerpentPatches;

	public static ConfigEntry<bool> EnableStaggerPatches;

	public static ConfigEntry<float> PunchIntervalMin;

	public static ConfigEntry<float> PunchIntervalMax;

	public static ConfigEntry<float> GroundSlamIntervalMin;

	public static ConfigEntry<float> GroundSlamIntervalMax;

	public static ConfigEntry<float> ThrowIntervalMin;

	public static ConfigEntry<float> ThrowIntervalMax;

	public static ConfigEntry<float> TrunkSwingHIntervalMin;

	public static ConfigEntry<float> TrunkSwingHIntervalMax;

	public static ConfigEntry<float> TrunkSwingVIntervalMin;

	public static ConfigEntry<float> TrunkSwingVIntervalMax;

	public static ConfigEntry<float> TrollThrowRayRadius;

	public static ConfigEntry<float> TrollThrowAOE;

	public static ConfigEntry<float> TrollThrowAttackForce;

	public static ConfigEntry<float> TrollThrowDrag;

	public static ConfigEntry<float> TrollThrowGravity;

	public static ConfigEntry<float> TrollThrowRange;

	public static ConfigEntry<float> BiteIntervalMin;

	public static ConfigEntry<float> BiteIntervalMax;

	public static ConfigEntry<float> SlamIntervalMin;

	public static ConfigEntry<float> SlamIntervalMax;

	public static ConfigEntry<float> ClawsIntervalMin;

	public static ConfigEntry<float> ClawsIntervalMax;

	public static ConfigEntry<float> SwipeLIntervalMin;

	public static ConfigEntry<float> SwipeLIntervalMax;

	public static ConfigEntry<float> SwipeRIntervalMin;

	public static ConfigEntry<float> SwipeRIntervalMax;

	public static ConfigEntry<float> SwipeComboIntervalMin;

	public static ConfigEntry<float> SwipeComboIntervalMax;

	public static ConfigEntry<float> HSweepIntervalMin;

	public static ConfigEntry<float> HSweepIntervalMax;

	public static ConfigEntry<float> VSlamIntervalMin;

	public static ConfigEntry<float> VSlamIntervalMax;

	public static ConfigEntry<float> AOECrushIntervalMin;

	public static ConfigEntry<float> AOECrushIntervalMax;

	public static ConfigEntry<float> GolemSlamIntervalMin;

	public static ConfigEntry<float> GolemSlamIntervalMax;

	public static ConfigEntry<float> CrushIntervalMin;

	public static ConfigEntry<float> CrushIntervalMax;

	public static ConfigEntry<float> PokeIntervalMin;

	public static ConfigEntry<float> PokeIntervalMax;

	public static ConfigEntry<float> SweepIntervalMin;

	public static ConfigEntry<float> SweepIntervalMax;

	public static ConfigEntry<float> FireclawIntervalMin;

	public static ConfigEntry<float> FireclawIntervalMax;

	public static ConfigEntry<float> DoubleFireclawIntervalMin;

	public static ConfigEntry<float> DoubleFireclawIntervalMax;

	public static ConfigEntry<float> AOEFireIntervalMin;

	public static ConfigEntry<float> AOEFireIntervalMax;

	public static ConfigEntry<float> SwingIntervalMin;

	public static ConfigEntry<float> SwingIntervalMax;

	public static ConfigEntry<float> SlamComboIntervalMin;

	public static ConfigEntry<float> SlamComboIntervalMax;

	public static ConfigEntry<float> LoxBiteIntervalMin;

	public static ConfigEntry<float> LoxBiteIntervalMax;

	public static ConfigEntry<float> StompIntervalMin;

	public static ConfigEntry<float> StompIntervalMax;

	public static ConfigEntry<float> SoldierBiteIntervalMin;

	public static ConfigEntry<float> SoldierBiteIntervalMax;

	public static ConfigEntry<float> RamIntervalMin;

	public static ConfigEntry<float> RamIntervalMax;

	public static ConfigEntry<float> SoldierGroundSlamIntervalMin;

	public static ConfigEntry<float> SoldierGroundSlamIntervalMax;

	public static ConfigEntry<float> SerpentBiteIntervalMin;

	public static ConfigEntry<float> SerpentBiteIntervalMax;

	public static ConfigEntry<float> TrollStaggerDamageFactor;

	public static ConfigEntry<float> TrollStaggerDrainMultiplier;

	public static ConfigEntry<float> AbominationStaggerDamageFactor;

	public static ConfigEntry<float> AbominationStaggerDrainMultiplier;

	public static ConfigEntry<float> BearStaggerDamageFactor;

	public static ConfigEntry<float> BearStaggerDrainMultiplier;

	public static ConfigEntry<float> GolemStaggerDamageFactor;

	public static ConfigEntry<float> GolemStaggerDrainMultiplier;

	public static ConfigEntry<float> CultistStaggerDamageFactor;

	public static ConfigEntry<float> CultistStaggerDrainMultiplier;

	public static ConfigEntry<float> BruteStaggerDamageFactor;

	public static ConfigEntry<float> BruteStaggerDrainMultiplier;

	public static ConfigEntry<float> LoxStaggerDamageFactor;

	public static ConfigEntry<float> LoxStaggerDrainMultiplier;

	public static ConfigEntry<float> SoldierStaggerDamageFactor;

	public static ConfigEntry<float> SoldierStaggerDrainMultiplier;

	public static ConfigEntry<bool> EnableDebugLogging;

	public static ConfigEntry<float> GroundSlamAnimSpeedMin;

	public static ConfigEntry<float> GroundSlamAnimSpeedMax;

	public static ConfigEntry<float> PunchAnimSpeedMin;

	public static ConfigEntry<float> PunchAnimSpeedMax;

	public static ConfigEntry<float> TrunkSwingVAnimSpeedMin;

	public static ConfigEntry<float> TrunkSwingVAnimSpeedMax;

	public static ConfigEntry<float> TrunkSwingHAnimSpeedMin;

	public static ConfigEntry<float> TrunkSwingHAnimSpeedMax;

	public static ConfigEntry<float> TrunkSwingVAnimSpeedDuration;

	public static ConfigEntry<float> TrunkSwingHAnimSpeedDuration;

	public static ConfigEntry<float> SlamAnimSpeedMin;

	public static ConfigEntry<float> SlamAnimSpeedMax;

	public static ConfigEntry<float> SlamAnimSpeedDuration;

	public static ConfigEntry<float> BiteAnimSpeedMin;

	public static ConfigEntry<float> BiteAnimSpeedMax;

	public static ConfigEntry<float> BiteAnimSpeedDuration;

	public static ConfigEntry<float> SwipeLAnimSpeedMin;

	public static ConfigEntry<float> SwipeLAnimSpeedMax;

	public static ConfigEntry<float> SwipeLAnimSpeedDuration;

	public static ConfigEntry<float> SwipeRAnimSpeedMin;

	public static ConfigEntry<float> SwipeRAnimSpeedMax;

	public static ConfigEntry<float> SwipeRAnimSpeedDuration;

	public static ConfigEntry<float> ClawsAnimSpeedMin;

	public static ConfigEntry<float> ClawsAnimSpeedMax;

	public static ConfigEntry<float> ClawsAnimSpeedDuration;

	public static ConfigEntry<float> SwipeComboAnimSpeedMin;

	public static ConfigEntry<float> SwipeComboAnimSpeedMax;

	public static ConfigEntry<float> SwipeComboAnimSpeedDuration;

	public static ConfigEntry<float> VSlamAnimSpeedMin;

	public static ConfigEntry<float> VSlamAnimSpeedMax;

	public static ConfigEntry<float> VSlamAnimSpeedBaseDuration;

	public static ConfigEntry<float> HSweepAnimSpeedMin;

	public static ConfigEntry<float> HSweepAnimSpeedMax;

	public static ConfigEntry<float> HSweepAnimSpeedBaseDuration;

	public static ConfigEntry<float> AOECrushAnimSpeedMin;

	public static ConfigEntry<float> AOECrushAnimSpeedMax;

	public static ConfigEntry<float> AOECrushAnimSpeedBaseDuration;

	public static ConfigEntry<float> AbominationAOECrushRayWidth;

	public static ConfigEntry<float> CrushAnimSpeedMin;

	public static ConfigEntry<float> CrushAnimSpeedMax;

	public static ConfigEntry<float> GolemSlamAnimSpeedMin;

	public static ConfigEntry<float> GolemSlamAnimSpeedMax;

	public static ConfigEntry<float> PokeAnimSpeedMin;

	public static ConfigEntry<float> PokeAnimSpeedMax;

	public static ConfigEntry<float> SweepAnimSpeedMin;

	public static ConfigEntry<float> SweepAnimSpeedMax;

	public static ConfigEntry<float> CrushAnimSpeedBaseDuration;

	public static ConfigEntry<float> GolemSlamAnimSpeedBaseDuration;

	public static ConfigEntry<float> PokeAnimSpeedBaseDuration;

	public static ConfigEntry<float> SweepAnimSpeedBaseDuration;

	public static ConfigEntry<float> FireclawAnimSpeedMin;

	public static ConfigEntry<float> FireclawAnimSpeedMax;

	public static ConfigEntry<float> FireclawAnimSpeedBaseDuration;

	public static ConfigEntry<float> DoubleFireclawAnimSpeedMin;

	public static ConfigEntry<float> DoubleFireclawAnimSpeedMax;

	public static ConfigEntry<float> DoubleFireclawAnimSpeedBaseDuration;

	public static ConfigEntry<float> AOEFireAnimSpeedMin;

	public static ConfigEntry<float> AOEFireAnimSpeedMax;

	public static ConfigEntry<float> AOEFireAnimSpeedBaseDuration;

	public static ConfigEntry<float> SlamComboAnimSpeedMin;

	public static ConfigEntry<float> SlamComboAnimSpeedMax;

	public static ConfigEntry<float> SlamComboAnimSpeedBaseDuration;

	public static ConfigEntry<float> SwingAnimSpeedMin;

	public static ConfigEntry<float> SwingAnimSpeedMax;

	public static ConfigEntry<float> SwingAnimSpeedBaseDuration;

	public static ConfigEntry<float> LoxBiteAnimSpeedMin;

	public static ConfigEntry<float> LoxBiteAnimSpeedMax;

	public static ConfigEntry<float> LoxBiteAnimSpeedBaseDuration;

	public static ConfigEntry<float> StompAnimSpeedMin;

	public static ConfigEntry<float> StompAnimSpeedMax;

	public static ConfigEntry<float> StompAnimSpeedBaseDuration;

	public static ConfigEntry<float> SoldierBiteAnimSpeedMin;

	public static ConfigEntry<float> SoldierBiteAnimSpeedMax;

	public static ConfigEntry<float> RamAnimSpeedMin;

	public static ConfigEntry<float> RamAnimSpeedMax;

	public static ConfigEntry<float> SoldierGroundSlamAnimSpeedMin;

	public static ConfigEntry<float> SoldierGroundSlamAnimSpeedMax;

	public static ConfigEntry<float> SoldierBiteAnimSpeedBaseDuration;

	public static ConfigEntry<float> RamAnimSpeedBaseDuration;

	public static ConfigEntry<float> SoldierGroundSlamAnimSpeedBaseDuration;

	private Harmony _harmony;

	private void Awake()
	{
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_0176: Unknown result type (might be due to invalid IL or missing references)
		//IL_017e: Expected O, but got Unknown
		//IL_017e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0188: Expected O, but got Unknown
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: 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_020b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: Unknown result type (might be due to invalid IL or missing references)
		//IL_0218: Expected O, but got Unknown
		//IL_0218: Unknown result type (might be due to invalid IL or missing references)
		//IL_0222: Expected O, but got Unknown
		//IL_0258: Unknown result type (might be due to invalid IL or missing references)
		//IL_025d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0265: Expected O, but got Unknown
		//IL_0265: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Expected O, but got Unknown
		//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b2: Expected O, but got Unknown
		//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bc: Expected O, but got Unknown
		//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ff: Expected O, but got Unknown
		//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0309: Expected O, but got Unknown
		//IL_033f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0344: Unknown result type (might be due to invalid IL or missing references)
		//IL_034c: Expected O, but got Unknown
		//IL_034c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0356: Expected O, but got Unknown
		//IL_038c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0391: Unknown result type (might be due to invalid IL or missing references)
		//IL_0399: Expected O, but got Unknown
		//IL_0399: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a3: Expected O, but got Unknown
		//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03de: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e6: Expected O, but got Unknown
		//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03f0: Expected O, but got Unknown
		//IL_0426: Unknown result type (might be due to invalid IL or missing references)
		//IL_042b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0433: Expected O, but got Unknown
		//IL_0433: Unknown result type (might be due to invalid IL or missing references)
		//IL_043d: Expected O, but got Unknown
		//IL_0473: Unknown result type (might be due to invalid IL or missing references)
		//IL_0478: Unknown result type (might be due to invalid IL or missing references)
		//IL_0480: Expected O, but got Unknown
		//IL_0480: Unknown result type (might be due to invalid IL or missing references)
		//IL_048a: Expected O, but got Unknown
		//IL_04c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_04cd: Expected O, but got Unknown
		//IL_04cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d7: Expected O, but got Unknown
		//IL_050d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0512: Unknown result type (might be due to invalid IL or missing references)
		//IL_051a: Expected O, but got Unknown
		//IL_051a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0524: Expected O, but got Unknown
		//IL_055a: Unknown result type (might be due to invalid IL or missing references)
		//IL_055f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0567: Expected O, but got Unknown
		//IL_0567: Unknown result type (might be due to invalid IL or missing references)
		//IL_0571: Expected O, but got Unknown
		//IL_05a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_05b4: Expected O, but got Unknown
		//IL_05b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_05be: Expected O, but got Unknown
		//IL_05f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_05f9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0601: Expected O, but got Unknown
		//IL_0601: Unknown result type (might be due to invalid IL or missing references)
		//IL_060b: Expected O, but got Unknown
		//IL_0641: Unknown result type (might be due to invalid IL or missing references)
		//IL_0646: Unknown result type (might be due to invalid IL or missing references)
		//IL_064e: Expected O, but got Unknown
		//IL_064e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0658: Expected O, but got Unknown
		//IL_068e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0693: Unknown result type (might be due to invalid IL or missing references)
		//IL_069b: Expected O, but got Unknown
		//IL_069b: Unknown result type (might be due to invalid IL or missing references)
		//IL_06a5: Expected O, but got Unknown
		//IL_06db: Unknown result type (might be due to invalid IL or missing references)
		//IL_06e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_06e8: Expected O, but got Unknown
		//IL_06e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_06f2: Expected O, but got Unknown
		//IL_0728: Unknown result type (might be due to invalid IL or missing references)
		//IL_072d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0735: Expected O, but got Unknown
		//IL_0735: Unknown result type (might be due to invalid IL or missing references)
		//IL_073f: Expected O, but got Unknown
		//IL_0775: Unknown result type (might be due to invalid IL or missing references)
		//IL_077a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0782: Expected O, but got Unknown
		//IL_0782: Unknown result type (might be due to invalid IL or missing references)
		//IL_078c: Expected O, but got Unknown
		//IL_07c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_07c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_07cf: Expected O, but got Unknown
		//IL_07cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_07d9: Expected O, but got Unknown
		//IL_080f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0814: Unknown result type (might be due to invalid IL or missing references)
		//IL_081c: Expected O, but got Unknown
		//IL_081c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0826: Expected O, but got Unknown
		//IL_085c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0861: Unknown result type (might be due to invalid IL or missing references)
		//IL_0869: Expected O, but got Unknown
		//IL_0869: Unknown result type (might be due to invalid IL or missing references)
		//IL_0873: Expected O, but got Unknown
		//IL_08a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_08ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_08b6: Expected O, but got Unknown
		//IL_08b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_08c0: Expected O, but got Unknown
		//IL_08f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_08fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0903: Expected O, but got Unknown
		//IL_0903: Unknown result type (might be due to invalid IL or missing references)
		//IL_090d: Expected O, but got Unknown
		//IL_0943: Unknown result type (might be due to invalid IL or missing references)
		//IL_0948: Unknown result type (might be due to invalid IL or missing references)
		//IL_0950: Expected O, but got Unknown
		//IL_0950: Unknown result type (might be due to invalid IL or missing references)
		//IL_095a: Expected O, but got Unknown
		//IL_0990: Unknown result type (might be due to invalid IL or missing references)
		//IL_0995: Unknown result type (might be due to invalid IL or missing references)
		//IL_099d: Expected O, but got Unknown
		//IL_099d: Unknown result type (might be due to invalid IL or missing references)
		//IL_09a7: Expected O, but got Unknown
		//IL_09dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_09e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_09ea: Expected O, but got Unknown
		//IL_09ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_09f4: Expected O, but got Unknown
		//IL_0a2a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a2f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a37: Expected O, but got Unknown
		//IL_0a37: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a41: Expected O, but got Unknown
		//IL_0a77: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a7c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a84: Expected O, but got Unknown
		//IL_0a84: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a8e: Expected O, but got Unknown
		//IL_0ac4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ac9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0ad1: Expected O, but got Unknown
		//IL_0ad1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0adb: Expected O, but got Unknown
		//IL_0b11: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b16: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b1e: Expected O, but got Unknown
		//IL_0b1e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b28: Expected O, but got Unknown
		//IL_0b5e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b63: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b6b: Expected O, but got Unknown
		//IL_0b6b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0b75: Expected O, but got Unknown
		//IL_0bab: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bb0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bb8: Expected O, but got Unknown
		//IL_0bb8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bc2: Expected O, but got Unknown
		//IL_0bf8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0bfd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c05: Expected O, but got Unknown
		//IL_0c05: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c0f: Expected O, but got Unknown
		//IL_0c42: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c4c: Expected O, but got Unknown
		//IL_0c7f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0c89: Expected O, but got Unknown
		//IL_0cbc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0cc6: Expected O, but got Unknown
		//IL_0cf9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d03: Expected O, but got Unknown
		//IL_0d36: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d40: Expected O, but got Unknown
		//IL_0d73: Unknown result type (might be due to invalid IL or missing references)
		//IL_0d7d: Expected O, but got Unknown
		//IL_0db0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0dba: Expected O, but got Unknown
		//IL_0ded: Unknown result type (might be due to invalid IL or missing references)
		//IL_0df7: Expected O, but got Unknown
		//IL_0e2a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e34: Expected O, but got Unknown
		//IL_0e67: Unknown result type (might be due to invalid IL or missing references)
		//IL_0e71: Expected O, but got Unknown
		//IL_0ea4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0eae: Expected O, but got Unknown
		//IL_0ee1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0eeb: Expected O, but got Unknown
		//IL_0f1e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0f28: Expected O, but got Unknown
		//IL_0f5b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0f65: Expected O, but got Unknown
		//IL_0f98: Unknown result type (might be due to invalid IL or missing references)
		//IL_0fa2: Expected O, but got Unknown
		//IL_0fd5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0fdf: Expected O, but got Unknown
		//IL_1012: Unknown result type (might be due to invalid IL or missing references)
		//IL_101c: Expected O, but got Unknown
		//IL_104f: Unknown result type (might be due to invalid IL or missing references)
		//IL_1059: Expected O, but got Unknown
		//IL_108c: Unknown result type (might be due to invalid IL or missing references)
		//IL_1096: Expected O, but got Unknown
		//IL_10c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_10d3: Expected O, but got Unknown
		//IL_1106: Unknown result type (might be due to invalid IL or missing references)
		//IL_1110: Expected O, but got Unknown
		//IL_1143: Unknown result type (might be due to invalid IL or missing references)
		//IL_114d: Expected O, but got Unknown
		//IL_1183: Unknown result type (might be due to invalid IL or missing references)
		//IL_1188: Unknown result type (might be due to invalid IL or missing references)
		//IL_1190: Expected O, but got Unknown
		//IL_1190: Unknown result type (might be due to invalid IL or missing references)
		//IL_119a: Expected O, but got Unknown
		//IL_11d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_11d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_11dd: Expected O, but got Unknown
		//IL_11dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_11e7: Expected O, but got Unknown
		//IL_121d: Unknown result type (might be due to invalid IL or missing references)
		//IL_1222: Unknown result type (might be due to invalid IL or missing references)
		//IL_122a: Expected O, but got Unknown
		//IL_122a: Unknown result type (might be due to invalid IL or missing references)
		//IL_1234: Expected O, but got Unknown
		//IL_126a: Unknown result type (might be due to invalid IL or missing references)
		//IL_126f: Unknown result type