Decompiled source of Hunter Enhancements v1.2.6

BepInEx/plugins/HunterModFork.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;
using UnityEngine.AI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(/*Could not decode attribute arguments.*/)]
[assembly: AssemblyTitle("MakeHunterGreatAgain")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MakeHunterGreatAgain")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e4e08037-2bc1-4999-9007-48f22736ae36")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(8, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(/*Could not decode attribute arguments.*/)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = (byte[])(object)new Byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(/*Could not decode attribute arguments.*/)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(/*Could not decode attribute arguments.*/)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace HunterMod
{
	public enum AimMode : Enum
	{
		Default,
		MinigunAccuracy,
		SniperAccuracy
	}
	public enum State : Enum
	{
		None = 0,
		LeaveStart = 8,
		Leave = 9,
		Despawn = 10
	}
	public class HunterAmmoTracker : MonoBehaviour
	{
		public ReloadSkill currentSkill = ReloadSkill.Medium;

		public float ConfiguredFastReloadTime = 2f;

		public float ConfiguredMediumReloadTime = 5f;

		public float ConfiguredSlowReloadTime = 7f;

		public bool ConfigEnableDamageInterrupt = true;

		public float ConfigDamageInterruptDelay = 5f;

		public int ConfigMinigunShots = 10;

		public float ConfigMinigunShotDelay = 0.1f;

		public bool ConfigEnableTotalAmmoLimit = false;

		public int ConfigTotalAmmoCount = 30;

		public bool ConfigRunAwayWhileReloading = true;

		private float currentReloadTimer = 0f;

		private float damageInterruptDelayTimer = 0f;

		private bool isReloading = false;

		public int currentTotalAmmo = 30;

		public bool isOutOfAmmoPermanently = false;

		public bool isMinigunBurstActive = false;

		public int minigunShotsRemaining = 0;

		public float minigunShotTimer = 0f;

		public bool IsReloading => isReloading;

		public bool IsInterrupted => damageInterruptDelayTimer > 0f;

		public bool HasTotalAmmo => !ConfigEnableTotalAmmoLimit || currentTotalAmmo > 0;

		private void Update()
		{
			if (damageInterruptDelayTimer > 0f)
			{
				damageInterruptDelayTimer -= Time.deltaTime;
				if (damageInterruptDelayTimer <= 0f)
				{
					damageInterruptDelayTimer = 0f;
					Plugin.LogInfoF(String.Concat("Hunter ", GetHunterName(), " damage interrupt delay finished."));
				}
			}
			if (isReloading)
			{
				currentReloadTimer -= Time.deltaTime;
				if (currentReloadTimer <= 0f)
				{
					isReloading = false;
					currentReloadTimer = 0f;
					Plugin.LogInfoF(String.Format("Hunter {0} finished reloading (Skill: {1}).", (object)GetHunterName(), (object)currentSkill));
				}
			}
		}

		public bool TryDecrementTotalAmmo()
		{
			if (!ConfigEnableTotalAmmoLimit)
			{
				return true;
			}
			if (currentTotalAmmo > 0)
			{
				currentTotalAmmo--;
				Plugin.LogInfoF(String.Format("Hunter {0} ammo decremented. Remaining: {1}", (object)GetHunterName(), (object)currentTotalAmmo));
				if (currentTotalAmmo <= 0)
				{
					if (!Plugin.IsRepoLastStandActive())
					{
						isOutOfAmmoPermanently = true;
						Plugin.LogErrorF(String.Concat("Hunter ", GetHunterName(), " HAS RUN OUT OF TOTAL AMMO! (Last Stand NOT Active). Perm Leave."));
						CancelActions();
						return false;
					}
					Plugin.LogWarningF(String.Concat("Hunter ", GetHunterName(), " ammo reached 0, but Last Stand IS Active. Not setting perm OOA flag."));
					CancelActions();
				}
				return true;
			}
			bool flag = Plugin.IsRepoLastStandActive();
			if (!isOutOfAmmoPermanently && !flag)
			{
				isOutOfAmmoPermanently = true;
				Plugin.LogErrorF(String.Concat("Hunter ", GetHunterName(), " WAS ALREADY OOA & Last Stand inactive! Force Perm Leave state."));
			}
			else if (!isOutOfAmmoPermanently && flag)
			{
				Plugin.LogWarningF(String.Concat("Hunter ", GetHunterName(), " ammo already at 0, Last Stand active. Not setting OOA flag."));
			}
			return false;
		}

		public void StartReload()
		{
			if (isOutOfAmmoPermanently)
			{
				Plugin.LogDebugF(String.Concat("StartReload blocked: Hunter ", GetHunterName(), " permanently OOA."));
			}
			else if (damageInterruptDelayTimer > 0f)
			{
				Plugin.LogDebugF(String.Format("StartReload blocked: Hunter {0} Interrupt Delay ({1:F1}s).", (object)GetHunterName(), (object)damageInterruptDelayTimer));
			}
			else if (isMinigunBurstActive)
			{
				Plugin.LogWarningF(String.Concat("StartReload blocked: Hunter ", GetHunterName(), " Minigun Active."));
			}
			else if (!isReloading)
			{
				isReloading = true;
				float num;
				switch (currentSkill)
				{
				case ReloadSkill.Fast:
					num = ConfiguredFastReloadTime;
					break;
				case ReloadSkill.Medium:
					num = ConfiguredMediumReloadTime;
					break;
				case ReloadSkill.Slow:
					num = ConfiguredSlowReloadTime;
					break;
				default:
					num = ConfiguredMediumReloadTime;
					Plugin.LogWarningF(String.Format("Hunter {0} unknown skill '{1}', defaulting Medium.", (object)GetHunterName(), (object)currentSkill));
					break;
				}
				currentReloadTimer = num;
				Plugin.LogInfoF(String.Format("Hunter {0} started reload (Skill: {1}, Time: {2:F1}s).", (object)GetHunterName(), (object)currentSkill, (object)num));
			}
			else
			{
				Plugin.LogWarningF(String.Concat("Hunter ", GetHunterName(), " tried StartReload but was already reloading."));
			}
		}

		public void ApplyDamageInterrupt()
		{
			if (!isOutOfAmmoPermanently && ConfigEnableDamageInterrupt && isReloading)
			{
				isReloading = false;
				currentReloadTimer = 0f;
				damageInterruptDelayTimer = ConfigDamageInterruptDelay;
				Plugin.LogInfoF(String.Format("Hunter {0} hurt during reload! Reload cancelled, starting {1:F1}s interrupt delay.", (object)GetHunterName(), (object)ConfigDamageInterruptDelay));
			}
		}

		public float GetRemainingReloadTime()
		{
			return (!isReloading) ? 0f : currentReloadTimer;
		}

		public void InitializeMinigunBurst()
		{
			if (!isMinigunBurstActive)
			{
				isMinigunBurstActive = true;
				minigunShotsRemaining = ConfigMinigunShots;
				minigunShotTimer = 0f;
				Plugin.LogInfoF(String.Format("Hunter {0} initializing minigun burst ({1} shots).", (object)GetHunterName(), (object)minigunShotsRemaining));
			}
		}

		public void EndMinigunBurst()
		{
			if (isMinigunBurstActive)
			{
				isMinigunBurstActive = false;
				minigunShotsRemaining = 0;
				minigunShotTimer = 0f;
				Plugin.LogInfoF(String.Concat("Hunter ", GetHunterName(), " minigun burst ended/cancelled."));
			}
		}

		private void CancelActions()
		{
			isReloading = false;
			currentReloadTimer = 0f;
			EndMinigunBurst();
		}

		private string GetHunterName()
		{
			GameObject gameObject = ((Component)this).gameObject;
			return ((Object)(object)gameObject != (Object)null) ? ((Object)gameObject).name : "Unknown Hunter";
		}
	}
	[HarmonyPatch(/*Could not decode attribute arguments.*/)]
	internal static class HunterPatches : Object
	{
		private static Dictionary<int, int> stateLeaveFailCounters = new Dictionary<int, int>();

		private const int MAX_LEAVE_FAILURES_WHILE_RELOADING = 5;

		private static EnemyNavMeshAgent GetEnemyNavMeshAgent(EnemyHunter instance)
		{
			//IL_00ab: Expected O, but got Unknown
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.enemy == (Object)null)
			{
				Plugin.LogErrorF("GetEnemyNavMeshAgent: Instance or instance.enemy is null!");
				return null;
			}
			try
			{
				FieldInfo val = AccessTools.Field(typeof(Enemy), "NavMeshAgent");
				if (val != (FieldInfo)null)
				{
					object value = val.GetValue((object)instance.enemy);
					return (EnemyNavMeshAgent)((value is EnemyNavMeshAgent) ? value : null);
				}
				object obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					GameObject gameObject = ((Component)instance).gameObject;
					obj = ((gameObject != null) ? ((Object)gameObject).name : null);
				}
				if (obj == null)
				{
					obj = "Unknown";
				}
				Plugin.LogErrorF(String.Concat("GetEnemyNavMeshAgent: Could not find Field 'NavMeshAgent' on type 'Enemy' for ", (string)obj, "!"));
				return null;
			}
			catch (Exception val2)
			{
				Exception val3 = val2;
				object obj2;
				if (instance == null)
				{
					obj2 = null;
				}
				else
				{
					GameObject gameObject2 = ((Component)instance).gameObject;
					obj2 = ((gameObject2 != null) ? ((Object)gameObject2).name : null);
				}
				if (obj2 == null)
				{
					obj2 = "Unknown";
				}
				Plugin.LogErrorF(String.Concat("GetEnemyNavMeshAgent: Error accessing 'NavMeshAgent' field on ", (string)obj2, ": ", val3.Message));
				return null;
			}
		}

		private static HunterAmmoTracker GetOrAddTracker(EnemyHunter instance)
		{
			if ((Object)(object)instance == (Object)null)
			{
				return null;
			}
			HunterAmmoTracker hunterAmmoTracker = ((Component)instance).GetComponent<HunterAmmoTracker>();
			if ((Object)(object)hunterAmmoTracker == (Object)null)
			{
				hunterAmmoTracker = ((Component)instance).gameObject.AddComponent<HunterAmmoTracker>();
				object obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					GameObject gameObject = ((Component)instance).gameObject;
					obj = ((gameObject != null) ? ((Object)gameObject).name : null);
				}
				if (obj == null)
				{
					obj = "Unknown";
				}
				Plugin.LogInfoF(String.Concat("Added HunterAmmoTracker to ", (string)obj, ". Initializing..."));
				hunterAmmoTracker.ConfiguredFastReloadTime = Plugin.FastReloadTimeConfig.Value;
				hunterAmmoTracker.ConfiguredMediumReloadTime = Plugin.MediumReloadTimeConfig.Value;
				hunterAmmoTracker.ConfiguredSlowReloadTime = Plugin.SlowReloadTimeConfig.Value;
				hunterAmmoTracker.ConfigEnableDamageInterrupt = Plugin.EnableDamageInterruptConfig.Value;
				hunterAmmoTracker.ConfigDamageInterruptDelay = Plugin.DamageInterruptDelayConfig.Value;
				hunterAmmoTracker.ConfigMinigunShots = Plugin.MinigunShots.Value;
				hunterAmmoTracker.ConfigMinigunShotDelay = Plugin.MinigunShotDelay.Value;
				hunterAmmoTracker.ConfigEnableTotalAmmoLimit = Plugin.EnableTotalAmmoLimitConfig.Value;
				hunterAmmoTracker.ConfigTotalAmmoCount = Plugin.TotalAmmoCountConfig.Value;
				hunterAmmoTracker.ConfigRunAwayWhileReloading = Plugin.RunAwayWhileReloadingConfig.Value;
			}
			return hunterAmmoTracker;
		}

		[HarmonyPatch("OnSpawn")]
		[HarmonyPostfix]
		private static void OnSpawnPostfix(EnemyHunter __instance)
		{
			HunterAmmoTracker orAddTracker = GetOrAddTracker(__instance);
			if ((Object)(object)orAddTracker != (Object)null)
			{
				int value = Plugin.FastSkillWeight.Value;
				int value2 = Plugin.MediumSkillWeight.Value;
				int value3 = Plugin.SlowSkillWeight.Value;
				int num = value + value2 + value3;
				if (num <= 0)
				{
					orAddTracker.currentSkill = ReloadSkill.Medium;
				}
				else
				{
					int num2 = Random.Range(0, num);
					if (num2 < value)
					{
						orAddTracker.currentSkill = ReloadSkill.Fast;
					}
					else if (num2 < value + value2)
					{
						orAddTracker.currentSkill = ReloadSkill.Medium;
					}
					else
					{
						orAddTracker.currentSkill = ReloadSkill.Slow;
					}
				}
				object obj;
				if (__instance == null)
				{
					obj = null;
				}
				else
				{
					GameObject gameObject = ((Component)__instance).gameObject;
					obj = ((gameObject != null) ? ((Object)gameObject).name : null);
				}
				if (obj == null)
				{
					obj = "Unknown";
				}
				Plugin.LogInfoF(String.Format("Hunter {0} spawned with Skill: {1}", obj, (object)orAddTracker.currentSkill));
				orAddTracker.isOutOfAmmoPermanently = false;
				orAddTracker.currentTotalAmmo = (orAddTracker.ConfigEnableTotalAmmoLimit ? orAddTracker.ConfigTotalAmmoCount : 9999);
				object obj2;
				if (__instance == null)
				{
					obj2 = null;
				}
				else
				{
					GameObject gameObject2 = ((Component)__instance).gameObject;
					obj2 = ((gameObject2 != null) ? ((Object)gameObject2).name : null);
				}
				if (obj2 == null)
				{
					obj2 = "Unknown";
				}
				Plugin.LogInfoF(String.Format("Hunter {0} initialized ammo: {1}", obj2, (object)orAddTracker.currentTotalAmmo));
				orAddTracker.EndMinigunBurst();
				stateLeaveFailCounters.Remove(((Object)__instance).GetInstanceID());
			}
			else
			{
				object obj3;
				if (__instance == null)
				{
					obj3 = null;
				}
				else
				{
					GameObject gameObject3 = ((Component)__instance).gameObject;
					obj3 = ((gameObject3 != null) ? ((Object)gameObject3).name : null);
				}
				if (obj3 == null)
				{
					obj3 = "Unknown";
				}
				string text = (string)obj3;
				Plugin.LogErrorF(String.Concat("Failed GetOrAddTracker for ", text, " in OnSpawnPostfix."));
			}
		}

		[HarmonyPatch("StateIdle")]
		[HarmonyPrefix]
		private static bool StateIdlePrefix(EnemyHunter __instance, ref bool ___stateImpulse)
		{
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			HunterAmmoTracker orAddTracker = GetOrAddTracker(__instance);
			EnemyNavMeshAgent enemyNavMeshAgent = GetEnemyNavMeshAgent(__instance);
			if ((Object)(object)orAddTracker == (Object)null || (Object)(object)enemyNavMeshAgent == (Object)null)
			{
				return true;
			}
			if (orAddTracker.isOutOfAmmoPermanently)
			{
				object obj;
				if (__instance == null)
				{
					obj = null;
				}
				else
				{
					GameObject gameObject = ((Component)__instance).gameObject;
					obj = ((gameObject != null) ? ((Object)gameObject).name : null);
				}
				if (obj == null)
				{
					obj = "Unknown";
				}
				Plugin.LogDebugF(String.Concat("StateIdlePrefix: Hunter ", (string)obj, " OOA. Forcing Leave."));
				Plugin.CallUpdateState(__instance, State.Leave);
				stateLeaveFailCounters.Remove(((Object)__instance).GetInstanceID());
				return false;
			}
			if (Plugin.ShouldRunAwayWhileReloading() && orAddTracker.IsReloading)
			{
				object obj2;
				if (__instance == null)
				{
					obj2 = null;
				}
				else
				{
					GameObject gameObject2 = ((Component)__instance).gameObject;
					obj2 = ((gameObject2 != null) ? ((Object)gameObject2).name : null);
				}
				if (obj2 == null)
				{
					obj2 = "Unknown";
				}
				Plugin.LogDebugF(String.Concat("StateIdlePrefix: Hunter ", (string)obj2, " reloading. Moving away."));
				enemyNavMeshAgent.Warp(((Component)__instance).transform.position, false);
				enemyNavMeshAgent.ResetPath();
				if (Plugin.FindRetreatPoint(__instance, out var retreatPoint))
				{
					enemyNavMeshAgent.SetDestination(retreatPoint);
				}
				___stateImpulse = false;
				return false;
			}
			return true;
		}

		[HarmonyPatch("StateRoam")]
		[HarmonyPrefix]
		private static bool StateRoamPrefix(EnemyHunter __instance, ref bool ___stateImpulse)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			HunterAmmoTracker orAddTracker = GetOrAddTracker(__instance);
			EnemyNavMeshAgent enemyNavMeshAgent = GetEnemyNavMeshAgent(__instance);
			if ((Object)(object)orAddTracker == (Object)null || (Object)(object)enemyNavMeshAgent == (Object)null)
			{
				return true;
			}
			if (orAddTracker.isOutOfAmmoPermanently)
			{
				Plugin.CallUpdateState(__instance, State.Leave);
				stateLeaveFailCounters.Remove(((Object)__instance).GetInstanceID());
				return false;
			}
			if (Plugin.ShouldRunAwayWhileReloading() && orAddTracker.IsReloading)
			{
				object obj;
				if (__instance == null)
				{
					obj = null;
				}
				else
				{
					GameObject gameObject = ((Component)__instance).gameObject;
					obj = ((gameObject != null) ? ((Object)gameObject).name : null);
				}
				if (obj == null)
				{
					obj = "Unknown";
				}
				Plugin.LogDebugF(String.Concat("StateRoamPrefix: Hunter ", (string)obj, " reloading. Moving away."));
				enemyNavMeshAgent.ResetPath();
				if (Plugin.FindRetreatPoint(__instance, out var retreatPoint))
				{
					enemyNavMeshAgent.SetDestination(retreatPoint);
				}
				___stateImpulse = false;
				return false;
			}
			return true;
		}

		[HarmonyPatch("StateAim")]
		[HarmonyPrefix]
		private static bool StateAimPrefix(EnemyHunter __instance, ref float ___stateTimer)
		{
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			HunterAmmoTracker orAddTracker = GetOrAddTracker(__instance);
			if ((Object)(object)orAddTracker == (Object)null)
			{
				return true;
			}
			if (orAddTracker.isOutOfAmmoPermanently)
			{
				object obj;
				if (__instance == null)
				{
					obj = null;
				}
				else
				{
					GameObject gameObject = ((Component)__instance).gameObject;
					obj = ((gameObject != null) ? ((Object)gameObject).name : null);
				}
				if (obj == null)
				{
					obj = "Unknown";
				}
				Plugin.LogDebugF(String.Concat("StateAimPrefix: Hunter ", (string)obj, " OOA. Forcing Leave."));
				Plugin.CallUpdateState(__instance, State.Leave);
				stateLeaveFailCounters.Remove(((Object)__instance).GetInstanceID());
				return false;
			}
			if (orAddTracker.IsReloading || orAddTracker.IsInterrupted || !orAddTracker.HasTotalAmmo)
			{
				string text = ((!orAddTracker.HasTotalAmmo) ? "OOA" : (orAddTracker.IsReloading ? String.Format("reload({0:F1}s)", (object)orAddTracker.GetRemainingReloadTime()) : String.Format("interrupt({0:F1}s)", (object)orAddTracker.ConfigDamageInterruptDelay)));
				String[] obj2 = new String[5]
				{
					"StateAimPrefix BLOCKED: ",
					default(String),
					default(String),
					default(String),
					default(String)
				};
				object obj3;
				if (__instance == null)
				{
					obj3 = null;
				}
				else
				{
					GameObject gameObject2 = ((Component)__instance).gameObject;
					obj3 = ((gameObject2 != null) ? ((Object)gameObject2).name : null);
				}
				if (obj3 == null)
				{
					obj3 = "Unknown";
				}
				obj2[1] = (String)obj3;
				obj2[2] = " is ";
				obj2[3] = text;
				obj2[4] = ".";
				Plugin.LogDebugF(String.Concat((string[])(object)obj2));
				if (Plugin.ShouldRunAwayWhileReloading() && orAddTracker.IsReloading)
				{
					object obj4;
					if (__instance == null)
					{
						obj4 = null;
					}
					else
					{
						GameObject gameObject3 = ((Component)__instance).gameObject;
						obj4 = ((gameObject3 != null) ? ((Object)gameObject3).name : null);
					}
					if (obj4 == null)
					{
						obj4 = "Unknown";
					}
					Plugin.LogDebugF(String.Concat("StateAimPrefix: ", (string)obj4, " running away."));
					EnemyNavMeshAgent enemyNavMeshAgent = GetEnemyNavMeshAgent(__instance);
					if ((Object)(object)enemyNavMeshAgent != (Object)null)
					{
						enemyNavMeshAgent.ResetPath();
						if (Plugin.FindRetreatPoint(__instance, out var retreatPoint))
						{
							enemyNavMeshAgent.SetDestination(retreatPoint);
						}
					}
					else
					{
						Plugin.LogErrorF("StateAimPrefix: EnemyNavMeshAgent missing via reflection!");
					}
				}
				else
				{
					Plugin.CallAimLogic(__instance);
				}
				if (___stateTimer <= Time.deltaTime)
				{
					___stateTimer = 0.1f;
				}
				return false;
			}
			return true;
		}

		[HarmonyPatch("StateShoot")]
		[HarmonyPrefix]
		private static bool StateShootPrefix(EnemyHunter __instance, ref float ___stateTimer)
		{
			HunterAmmoTracker orAddTracker = GetOrAddTracker(__instance);
			if ((Object)(object)orAddTracker == (Object)null)
			{
				return true;
			}
			if (!orAddTracker.HasTotalAmmo)
			{
				object obj;
				if (__instance == null)
				{
					obj = null;
				}
				else
				{
					GameObject gameObject = ((Component)__instance).gameObject;
					obj = ((gameObject != null) ? ((Object)gameObject).name : null);
				}
				if (obj == null)
				{
					obj = "Unknown";
				}
				Plugin.LogErrorF(String.Concat("StateShootPrefix: ", (string)obj, " OOA! Forcing Leave."));
				orAddTracker.isOutOfAmmoPermanently = true;
				Plugin.CallUpdateState(__instance, State.Leave);
				stateLeaveFailCounters.Remove(((Object)__instance).GetInstanceID());
				return false;
			}
			if (!Plugin.IsMinigunModeEnabled())
			{
				if (!orAddTracker.TryDecrementTotalAmmo())
				{
					object obj2;
					if (__instance == null)
					{
						obj2 = null;
					}
					else
					{
						GameObject gameObject2 = ((Component)__instance).gameObject;
						obj2 = ((gameObject2 != null) ? ((Object)gameObject2).name : null);
					}
					if (obj2 == null)
					{
						obj2 = "Unknown";
					}
					Plugin.LogInfoF(String.Concat("StateShootPrefix(N): ", (string)obj2, " OOA this shot. Forcing Leave."));
					Plugin.CallUpdateState(__instance, State.Leave);
					stateLeaveFailCounters.Remove(((Object)__instance).GetInstanceID());
					return false;
				}
				Plugin.LogDebugF("StateShootPrefix: Minigun OFF. Allow original.");
				return true;
			}
			if (orAddTracker.IsReloading || orAddTracker.IsInterrupted)
			{
				return false;
			}
			if (!orAddTracker.isMinigunBurstActive)
			{
				if (!orAddTracker.HasTotalAmmo)
				{
					object obj3;
					if (__instance == null)
					{
						obj3 = null;
					}
					else
					{
						GameObject gameObject3 = ((Component)__instance).gameObject;
						obj3 = ((gameObject3 != null) ? ((Object)gameObject3).name : null);
					}
					if (obj3 == null)
					{
						obj3 = "Unknown";
					}
					Plugin.LogErrorF(String.Concat("StateShootPrefix(M-Init): ", (string)obj3, " OOA! Forcing Leave."));
					orAddTracker.isOutOfAmmoPermanently = true;
					Plugin.CallUpdateState(__instance, State.Leave);
					stateLeaveFailCounters.Remove(((Object)__instance).GetInstanceID());
					return false;
				}
				orAddTracker.InitializeMinigunBurst();
				___stateTimer = (float)orAddTracker.ConfigMinigunShots * orAddTracker.ConfigMinigunShotDelay + 1f;
			}
			orAddTracker.minigunShotTimer -= Time.deltaTime;
			if (orAddTracker.minigunShotTimer <= 0f && orAddTracker.minigunShotsRemaining > 0)
			{
				if (!orAddTracker.TryDecrementTotalAmmo())
				{
					object obj4;
					if (__instance == null)
					{
						obj4 = null;
					}
					else
					{
						GameObject gameObject4 = ((Component)__instance).gameObject;
						obj4 = ((gameObject4 != null) ? ((Object)gameObject4).name : null);
					}
					if (obj4 == null)
					{
						obj4 = "Unknown";
					}
					Plugin.LogInfoF(String.Concat("StateShootPrefix(M): ", (string)obj4, " OOA mid-burst. End & Leave."));
					orAddTracker.EndMinigunBurst();
					Plugin.CallUpdateState(__instance, State.Leave);
					stateLeaveFailCounters.Remove(((Object)__instance).GetInstanceID());
					return false;
				}
				Plugin.LogDebugF(String.Format("StateShootPrefix: Fire minigun {0}/{1}. Ammo: {2}", (object)(orAddTracker.ConfigMinigunShots - orAddTracker.minigunShotsRemaining + 1), (object)orAddTracker.ConfigMinigunShots, (object)orAddTracker.currentTotalAmmo));
				Plugin.CallShootRPC(__instance);
				orAddTracker.minigunShotsRemaining--;
				orAddTracker.minigunShotTimer = orAddTracker.ConfigMinigunShotDelay;
			}
			if (orAddTracker.minigunShotsRemaining <= 0 && orAddTracker.isMinigunBurstActive)
			{
				Plugin.LogInfoF("StateShootPrefix: Minigun burst done. LeaveStart & Reload.");
				orAddTracker.EndMinigunBurst();
				Plugin.CallUpdateState(__instance, State.LeaveStart);
				orAddTracker.StartReload();
				return false;
			}
			Plugin.CallAimLogic(__instance);
			return false;
		}

		[HarmonyPatch("OnHurt")]
		[HarmonyPostfix]
		private static void OnHurtPostfix(EnemyHunter __instance)
		{
			HunterAmmoTracker orAddTracker = GetOrAddTracker(__instance);
			if ((Object)(object)orAddTracker != (Object)null)
			{
				orAddTracker.ApplyDamageInterrupt();
			}
			else
			{
				Plugin.LogErrorF("Failed GetOrAddTracker in OnHurtPostfix.");
			}
		}

		[HarmonyPatch("StateShootEnd")]
		[HarmonyPrefix]
		private static bool StateShootEndPrefix(EnemyHunter __instance, ref float ___stateTimer, ref int ___shotsFired, int ___shotsFiredMax)
		{
			if (Plugin.IsMinigunModeEnabled())
			{
				return true;
			}
			HunterAmmoTracker orAddTracker = GetOrAddTracker(__instance);
			if ((Object)(object)orAddTracker == (Object)null)
			{
				return true;
			}
			if (orAddTracker.isOutOfAmmoPermanently)
			{
				Plugin.CallUpdateState(__instance, State.Leave);
				stateLeaveFailCounters.Remove(((Object)__instance).GetInstanceID());
				return false;
			}
			if (___stateTimer <= Time.deltaTime)
			{
				Plugin.LogInfoF(String.Format("StateShootEndPrefix(N): Shot {0} done. LeaveStart & Reload.", (object)___shotsFired));
				Plugin.CallUpdateState(__instance, State.LeaveStart);
				orAddTracker.StartReload();
				return false;
			}
			return true;
		}

		private static bool PreventReEngagePrefix(EnemyHunter __instance)
		{
			HunterAmmoTracker hunterAmmoTracker = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponent<HunterAmmoTracker>() : null);
			if ((Object)(object)hunterAmmoTracker != (Object)null && hunterAmmoTracker.isOutOfAmmoPermanently)
			{
				object obj;
				if (__instance == null)
				{
					obj = null;
				}
				else
				{
					GameObject gameObject = ((Component)__instance).gameObject;
					obj = ((gameObject != null) ? ((Object)gameObject).name : null);
				}
				if (obj == null)
				{
					obj = "Unknown";
				}
				Plugin.LogDebugF(String.Concat("PreventReEngagePrefix: ", (string)obj, " OOA. Prevent engage."));
				return false;
			}
			return true;
		}

		[HarmonyPatch("OnInvestigate")]
		[HarmonyPrefix]
		private static bool OnInvestigatePrefix(EnemyHunter __instance)
		{
			return PreventReEngagePrefix(__instance);
		}

		[HarmonyPatch("OnTouchPlayer")]
		[HarmonyPrefix]
		private static bool OnTouchPlayerPrefix(EnemyHunter __instance)
		{
			return PreventReEngagePrefix(__instance);
		}

		[HarmonyPatch("OnTouchPlayerGrabbedObject")]
		[HarmonyPrefix]
		private static bool OnTouchPlayerGrabbedObjectPrefix(EnemyHunter __instance)
		{
			return PreventReEngagePrefix(__instance);
		}

		[HarmonyPatch("OnGrabbed")]
		[HarmonyPrefix]
		private static bool OnGrabbedPrefix(EnemyHunter __instance)
		{
			return PreventReEngagePrefix(__instance);
		}

		[HarmonyPatch("StateLeave")]
		[HarmonyPrefix]
		private static bool StateLeavePrefix(EnemyHunter __instance, ref float ___stateTimer, Vector3 ___leavePosition, ref bool ___stateImpulse)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			HunterAmmoTracker orAddTracker = GetOrAddTracker(__instance);
			EnemyNavMeshAgent enemyNavMeshAgent = GetEnemyNavMeshAgent(__instance);
			if ((Object)(object)orAddTracker == (Object)null || (Object)(object)enemyNavMeshAgent == (Object)null)
			{
				return true;
			}
			int instanceID = ((Object)__instance).GetInstanceID();
			bool flag = Plugin.ShouldRunAwayWhileReloading() && orAddTracker.IsReloading;
			bool isOutOfAmmoPermanently = orAddTracker.isOutOfAmmoPermanently;
			if (!flag && !isOutOfAmmoPermanently)
			{
				stateLeaveFailCounters.Remove(instanceID);
				return true;
			}
			if (___stateTimer <= Time.deltaTime || Vector3.Distance(((Component)__instance).transform.position, ___leavePosition) < 1f)
			{
				if (isOutOfAmmoPermanently)
				{
					object obj;
					if (__instance == null)
					{
						obj = null;
					}
					else
					{
						GameObject gameObject = ((Component)__instance).gameObject;
						obj = ((gameObject != null) ? ((Object)gameObject).name : null);
					}
					if (obj == null)
					{
						obj = "Unknown";
					}
					Plugin.LogInfoF(String.Concat("StateLeavePrefix: Hunter ", (string)obj, " OOA and reached Leave destination/timer. Forcing Despawn."));
					Plugin.CallUpdateState(__instance, State.Despawn);
					stateLeaveFailCounters.Remove(instanceID);
					return false;
				}
				object obj2;
				if (__instance == null)
				{
					obj2 = null;
				}
				else
				{
					GameObject gameObject2 = ((Component)__instance).gameObject;
					obj2 = ((gameObject2 != null) ? ((Object)gameObject2).name : null);
				}
				if (obj2 == null)
				{
					obj2 = "Unknown";
				}
				Plugin.LogDebugF(String.Concat("StateLeavePrefix: ", (string)obj2, " reloading & reached dest/timer. Finding new retreat point."));
				if (Plugin.FindRetreatPoint(__instance, out var retreatPoint))
				{
					stateLeaveFailCounters.Remove(instanceID);
					FieldInfo val = AccessTools.Field(typeof(EnemyHunter), "leavePosition");
					if (val != (FieldInfo)null)
					{
						val.SetValue((object)__instance, (object)retreatPoint);
					}
					else
					{
						Plugin.LogErrorF("No leavePosition field!");
					}
					enemyNavMeshAgent.SetDestination(retreatPoint);
					___stateTimer = 5f;
					___stateImpulse = false;
				}
				else
				{
					int num = (stateLeaveFailCounters.ContainsKey(instanceID) ? stateLeaveFailCounters[instanceID] : 0);
					num++;
					stateLeaveFailCounters[instanceID] = num;
					object obj3;
					if (__instance == null)
					{
						obj3 = null;
					}
					else
					{
						GameObject gameObject3 = ((Component)__instance).gameObject;
						obj3 = ((gameObject3 != null) ? ((Object)gameObject3).name : null);
					}
					if (obj3 == null)
					{
						obj3 = "Unknown";
					}
					Plugin.LogWarningF(String.Format("StateLeavePrefix: No new retreat point for {0} while reloading. Failure {1}/{2}", obj3, (object)num, (object)5));
					___stateTimer = 1f;
					if (num >= 5)
					{
						object obj4;
						if (__instance == null)
						{
							obj4 = null;
						}
						else
						{
							GameObject gameObject4 = ((Component)__instance).gameObject;
							obj4 = ((gameObject4 != null) ? ((Object)gameObject4).name : null);
						}
						if (obj4 == null)
						{
							obj4 = "Unknown";
						}
						Plugin.LogErrorF(String.Format("StateLeavePrefix: Hunter {0} failed find retreat point {1} times WHILE RELOADING. Forcing Despawn.", obj4, (object)5));
						Plugin.CallUpdateState(__instance, State.Despawn);
						stateLeaveFailCounters.Remove(instanceID);
					}
				}
				return false;
			}
			Plugin.LogDebugF(String.Format("StateLeavePrefix: Timer > deltaT ({0:F3}), allow original method.", (object)___stateTimer));
			return true;
		}
	}
	[BepInPlugin("com.plusblankplus.huntermod", "Hunter Enhancements", "1.6.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private readonly Harmony harmony = new Harmony("com.plusblankplus.huntermod");

		private static bool isRepoLastStandModPresent;

		private const string RepoLastStandGuid = "umbreon222.repo.laststand";

		private static Type repoStateManagerType;

		private static PropertyInfo repoStateManagerInstanceProperty;

		private static FieldInfo repoLastStandActiveField;

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static Plugin Instance
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		internal static ManualLogSource Log
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static ConfigEntry<bool> EnableMinigunMode
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static ConfigEntry<int> MinigunShots
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static ConfigEntry<float> MinigunShotDelay
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static ConfigEntry<float> FastReloadTimeConfig
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static ConfigEntry<float> MediumReloadTimeConfig
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static ConfigEntry<float> SlowReloadTimeConfig
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static ConfigEntry<int> FastSkillWeight
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static ConfigEntry<int> MediumSkillWeight
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static ConfigEntry<int> SlowSkillWeight
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static ConfigEntry<bool> EnableDamageInterruptConfig
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static ConfigEntry<float> DamageInterruptDelayConfig
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static ConfigEntry<bool> EnableTotalAmmoLimitConfig
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static ConfigEntry<int> TotalAmmoCountConfig
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static ConfigEntry<bool> RunAwayWhileReloadingConfig
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static ConfigEntry<bool> EnableInfoLogs
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static ConfigEntry<bool> EnableDebugLogs
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static ConfigEntry<bool> EnableWarningLogs
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		[field: CompilerGenerated]
		[field: DebuggerBrowsable(/*Could not decode attribute arguments.*/)]
		public static ConfigEntry<bool> EnableErrorLogs
		{
			[CompilerGenerated]
			get;
			[CompilerGenerated]
			private set;
		}

		private void Awake()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Expected O, but got Unknown
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Expected O, but got Unknown
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Expected O, but got Unknown
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Expected O, but got Unknown
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Expected O, but got Unknown
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Expected O, but got Unknown
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
				Log = ((BaseUnityPlugin)this).Logger;
				Log.LogInfo((object)"Loading configuration...");
				EnableMinigunMode = ((BaseUnityPlugin)this).Config.Bind<bool>("A. General", "EnableMinigunMode", false, "Enable the Hunter's rapid-fire 'Minigun' mode.");
				MinigunShots = ((BaseUnityPlugin)this).Config.Bind<int>("A. General", "MinigunShots", 10, new ConfigDescription("Number of shots fired in one burst when Minigun Mode is enabled.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), Array.Empty<object>()));
				MinigunShotDelay = ((BaseUnityPlugin)this).Config.Bind<float>("A. General", "MinigunShotDelay", 0.1f, new ConfigDescription("Delay in seconds between each shot during a Minigun burst.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.02f, 0.5f), Array.Empty<object>()));
				FastReloadTimeConfig = ((BaseUnityPlugin)this).Config.Bind<float>("B. ReloadTimes", "FastReloadTime", 2f, new ConfigDescription("Reload time (s) for Hunters with 'Fast' skill.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 120f), Array.Empty<object>()));
				MediumReloadTimeConfig = ((BaseUnityPlugin)this).Config.Bind<float>("B. ReloadTimes", "MediumReloadTime", 5f, new ConfigDescription("Reload time (s) for Hunters with 'Medium' skill.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 180f), Array.Empty<object>()));
				SlowReloadTimeConfig = ((BaseUnityPlugin)this).Config.Bind<float>("B. ReloadTimes", "SlowReloadTime", 7f, new ConfigDescription("Reload time (s) for Hunters with 'Slow' skill.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1.5f, 300f), Array.Empty<object>()));
				FastSkillWeight = ((BaseUnityPlugin)this).Config.Bind<int>("C. SkillWeights", "FastSkillWeight", 5, new ConfigDescription("Probability weight for spawning with Fast reload skill.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
				MediumSkillWeight = ((BaseUnityPlugin)this).Config.Bind<int>("C. SkillWeights", "MediumSkillWeight", 3, new ConfigDescription("Probability weight for spawning with Medium reload skill.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
				SlowSkillWeight = ((BaseUnityPlugin)this).Config.Bind<int>("C. SkillWeights", "SlowSkillWeight", 1, new ConfigDescription("Probability weight for spawning with Slow reload skill.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
				EnableDamageInterruptConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("D. DamageBehavior", "EnableDamageInterrupt", true, "If enabled, getting hurt while reloading cancels it and imposes a delay before reloading can start.");
				DamageInterruptDelayConfig = ((BaseUnityPlugin)this).Config.Bind<float>("D. DamageBehavior", "DamageInterruptDelay", 5f, new ConfigDescription("Delay (s) imposed after a reload is interrupted by damage.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 15f), Array.Empty<object>()));
				RunAwayWhileReloadingConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("D. DamageBehavior", "RunAwayWhileReloading", true, "If enabled, the Hunter will actively move away from players while reloading (enters Leave state).");
				EnableTotalAmmoLimitConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("E. TotalAmmo", "EnableTotalAmmoLimit", false, "If enabled, the Hunter has a limited total number of shots before it runs away permanently.");
				TotalAmmoCountConfig = ((BaseUnityPlugin)this).Config.Bind<int>("E. TotalAmmo", "TotalAmmoCount", 30, new ConfigDescription("Total number of shots the Hunter has if the limit is enabled.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 200), Array.Empty<object>()));
				EnableInfoLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("Z. Logging", "EnableInfoLogs", true, "Enable standard informational logs.");
				EnableDebugLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("Z. Logging", "EnableDebugLogs", false, "Enable detailed debug logs (can be spammy).");
				EnableWarningLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("Z. Logging", "EnableWarningLogs", true, "Enable warning logs for potential issues.");
				EnableErrorLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("Z. Logging", "EnableErrorLogs", true, "Enable error logs for critical failures.");
				LogInfoF("Configuration loaded.");
				DetectRepoLastStandMod();
				LogInfoF("Applying Harmony patches for Hunter Enhancements...");
				harmony.PatchAll(typeof(HunterPatches));
				LogInfoF("Harmony patches applied successfully!");
				LogInfoF("Plugin com.plusblankplus.huntermod v1.6.1 is loaded!");
			}
			else
			{
				Object.Destroy((Object)(object)this);
			}
		}

		private static void DetectRepoLastStandMod()
		{
			//IL_017f: Expected O, but got Unknown
			isRepoLastStandModPresent = Chainloader.PluginInfos.ContainsKey("umbreon222.repo.laststand");
			if (isRepoLastStandModPresent)
			{
				LogInfoF("RepoLastStandMod detected. Enabling compatibility logic.");
				try
				{
					string text = "RepoLastStandMod";
					repoStateManagerType = Type.GetType(String.Concat("RepoLastStandMod.StateManager, ", text), false);
					PluginInfo val = default(PluginInfo);
					if (repoStateManagerType == (Type)null && Chainloader.PluginInfos.TryGetValue("umbreon222.repo.laststand", ref val) && (Object)(object)val.Instance != (Object)null)
					{
						text = ((Object)val.Instance).GetType().Assembly.FullName;
						repoStateManagerType = Type.GetType(String.Concat("RepoLastStandMod.StateManager, ", text), false);
						LogDebugF(String.Concat("Attempting to load StateManager from assembly: ", text));
					}
					if (repoStateManagerType != (Type)null)
					{
						repoStateManagerInstanceProperty = AccessTools.Property(repoStateManagerType, "Instance");
						repoLastStandActiveField = AccessTools.Field(repoStateManagerType, "LastStandActive");
						if (repoStateManagerInstanceProperty == (PropertyInfo)null)
						{
							LogErrorF("Could not find 'Instance' property on StateManager.");
						}
						if (repoLastStandActiveField == (FieldInfo)null)
						{
							LogErrorF("Could not find 'LastStandActive' field on StateManager.");
						}
						if (repoStateManagerInstanceProperty == (PropertyInfo)null || repoLastStandActiveField == (FieldInfo)null)
						{
							LogErrorF("Failed reflection for RepoLastStandMod. Compatibility disabled.");
							isRepoLastStandModPresent = false;
						}
					}
					else
					{
						LogErrorF("Could not find type 'RepoLastStandMod.StateManager'. Compatibility disabled.");
						isRepoLastStandModPresent = false;
					}
					return;
				}
				catch (Exception val2)
				{
					Exception val3 = val2;
					LogErrorF(String.Format("Error during reflection for RepoLastStandMod compatibility: {0}", (object)val3));
					isRepoLastStandModPresent = false;
					return;
				}
			}
			LogInfoF("RepoLastStandMod not detected.");
		}

		public static void LogInfoF(string message)
		{
			if (Log != null && EnableInfoLogs != null && EnableInfoLogs.Value)
			{
				Log.LogInfo((object)message);
			}
		}

		public static void LogDebugF(string message)
		{
			if (Log != null && EnableDebugLogs != null && EnableDebugLogs.Value)
			{
				Log.LogDebug((object)message);
			}
		}

		public static void LogWarningF(string message)
		{
			if (Log != null && EnableWarningLogs != null && EnableWarningLogs.Value)
			{
				Log.LogWarning((object)message);
			}
		}

		public static void LogErrorF(string message)
		{
			if (Log != null && EnableErrorLogs != null && EnableErrorLogs.Value)
			{
				Log.LogError((object)message);
			}
		}

		public static bool IsMinigunModeEnabled()
		{
			return EnableMinigunMode != null && EnableMinigunMode.Value;
		}

		public static bool ShouldRunAwayWhileReloading()
		{
			return RunAwayWhileReloadingConfig != null && RunAwayWhileReloadingConfig.Value;
		}

		public static void CallUpdateState(EnemyHunter instance, State newState)
		{
			MethodInfo val = AccessTools.Method(typeof(EnemyHunter), "UpdateState", (Type[])null, (Type[])null);
			if (val != (MethodInfo)null)
			{
				ParameterInfo[] parameters = ((MethodBase)val).GetParameters();
				object obj = null;
				if (parameters.Length == 1)
				{
					Type parameterType = parameters[0].ParameterType;
					obj = ((!parameterType.IsEnum) ? Convert.ChangeType((object)newState, parameterType) : Enum.ToObject(parameterType, Convert.ToInt32((object)newState)));
					((MethodBase)val).Invoke((object)instance, (object[])(object)new Object[1] { obj });
				}
				else
				{
					((MethodBase)val).Invoke((object)instance, (object[])(object)new Object[1] { (object)newState });
				}
			}
			else
			{
				object obj2;
				if (instance == null)
				{
					obj2 = null;
				}
				else
				{
					GameObject gameObject = ((Component)instance).gameObject;
					obj2 = ((gameObject != null) ? ((Object)gameObject).name : null);
				}
				if (obj2 == null)
				{
					obj2 = "Unknown";
				}
				string text = (string)obj2;
				LogErrorF(String.Concat("Could not find method 'UpdateState' on ", text, "!"));
			}
		}

		public static void CallAimLogic(EnemyHunter instance)
		{
			MethodInfo val = AccessTools.Method(typeof(EnemyHunter), "AimLogic", (Type[])null, (Type[])null);
			if (val != (MethodInfo)null)
			{
				((MethodBase)val).Invoke((object)instance, (object[])null);
				return;
			}
			object obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				GameObject gameObject = ((Component)instance).gameObject;
				obj = ((gameObject != null) ? ((Object)gameObject).name : null);
			}
			if (obj == null)
			{
				obj = "Unknown";
			}
			string text = (string)obj;
			LogErrorF(String.Concat("Could not find method 'AimLogic' on ", text, "!"));
		}

		private static PhotonView GetPhotonView(EnemyHunter instance)
		{
			//IL_0089: Expected O, but got Unknown
			if ((Object)(object)instance == (Object)null)
			{
				return null;
			}
			try
			{
				FieldInfo val = AccessTools.Field(typeof(EnemyHunter), "photonView");
				if (val != (FieldInfo)null)
				{
					object value = val.GetValue((object)instance);
					return (PhotonView)((value is PhotonView) ? value : null);
				}
				object obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					GameObject gameObject = ((Component)instance).gameObject;
					obj = ((gameObject != null) ? ((Object)gameObject).name : null);
				}
				if (obj == null)
				{
					obj = "Unknown";
				}
				LogErrorF(String.Concat("GetPhotonView: Could not find field 'photonView' on ", (string)obj, "!"));
				return null;
			}
			catch (Exception val2)
			{
				Exception val3 = val2;
				object obj2;
				if (instance == null)
				{
					obj2 = null;
				}
				else
				{
					GameObject gameObject2 = ((Component)instance).gameObject;
					obj2 = ((gameObject2 != null) ? ((Object)gameObject2).name : null);
				}
				if (obj2 == null)
				{
					obj2 = "Unknown";
				}
				LogErrorF(String.Concat("GetPhotonView: Error accessing 'photonView' field on ", (string)obj2, ": ", val3.Message));
				return null;
			}
		}

		public static void CallShootRPC(EnemyHunter instance)
		{
			//IL_029c: Expected O, but got Unknown
			//IL_0312: Expected O, but got Unknown
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.IsMasterClient && GameManager.Multiplayer())
			{
				object obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					GameObject gameObject = ((Component)instance).gameObject;
					obj = ((gameObject != null) ? ((Object)gameObject).name : null);
				}
				if (obj == null)
				{
					obj = "Unknown";
				}
				string text = (string)obj;
				LogDebugF(String.Concat("CallShootRPC skipped on non-MasterClient for ", text));
				return;
			}
			PhotonView photonView = GetPhotonView(instance);
			if ((Object)(object)photonView == (Object)null)
			{
				object obj2;
				if (instance == null)
				{
					obj2 = null;
				}
				else
				{
					GameObject gameObject2 = ((Component)instance).gameObject;
					obj2 = ((gameObject2 != null) ? ((Object)gameObject2).name : null);
				}
				if (obj2 == null)
				{
					obj2 = "Unknown";
				}
				LogErrorF(String.Concat("CallShootRPC: PhotonView is null for ", (string)obj2, "! Cannot send RPC."));
				return;
			}
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.gunAimTransform == (Object)null)
			{
				LogErrorF("CallShootRPC: instance or gunAimTransform is null!");
				return;
			}
			Vector3 val = instance.gunAimTransform.position + instance.gunAimTransform.forward * 50f;
			try
			{
				FieldInfo val2 = AccessTools.Field(typeof(EnemyHunter), "investigatePoint");
				if (val2 != (FieldInfo)null)
				{
					Vector3 val3 = (Vector3)val2.GetValue((object)instance);
					float num = ((Vector3.Distance(((Component)instance).transform.position, val3) > 10f) ? 0.5f : 1f);
					int mask = LayerMask.GetMask((string[])(object)new String[4] { "Player", "Default", "PhysGrabObject", "Enemy" });
					int mask2 = LayerMask.GetMask((string[])(object)new String[1] { "Default" });
					RaycastHit val4 = default(RaycastHit);
					RaycastHit val5 = default(RaycastHit);
					if (Physics.SphereCast(instance.gunAimTransform.position, num, instance.gunAimTransform.forward, ref val4, 50f, mask))
					{
						if (!Physics.Linecast(instance.gunAimTransform.position, ((RaycastHit)(ref val4)).point, mask2))
						{
							val = ((RaycastHit)(ref val4)).point;
						}
						else if (Physics.Raycast(instance.gunAimTransform.position, instance.gunAimTransform.forward, ref val4, 50f, mask))
						{
							val = ((RaycastHit)(ref val4)).point;
						}
					}
					else if (Physics.Raycast(instance.gunAimTransform.position, instance.gunAimTransform.forward, ref val5, 50f, mask))
					{
						val = ((RaycastHit)(ref val5)).point;
					}
				}
				else
				{
					object obj3;
					if (instance == null)
					{
						obj3 = null;
					}
					else
					{
						GameObject gameObject3 = ((Component)instance).gameObject;
						obj3 = ((gameObject3 != null) ? ((Object)gameObject3).name : null);
					}
					if (obj3 == null)
					{
						obj3 = "Unknown";
					}
					LogWarningF(String.Concat("Could not access investigatePoint field for ", (string)obj3, "!"));
				}
			}
			catch (Exception val6)
			{
				Exception val7 = val6;
				LogErrorF(String.Concat("Error calculating target position: ", val7.Message));
			}
			try
			{
				object obj4;
				if (instance == null)
				{
					obj4 = null;
				}
				else
				{
					GameObject gameObject4 = ((Component)instance).gameObject;
					obj4 = ((gameObject4 != null) ? ((Object)gameObject4).name : null);
				}
				if (obj4 == null)
				{
					obj4 = "Unknown";
				}
				LogDebugF(String.Format("Sending ShootRPC for {0} targeting {1}", obj4, (object)val));
				photonView.RPC("ShootRPC", (RpcTarget)0, (object[])(object)new Object[1] { (object)val });
			}
			catch (Exception val8)
			{
				Exception val9 = val8;
				object obj5;
				if (instance == null)
				{
					obj5 = null;
				}
				else
				{
					GameObject gameObject5 = ((Component)instance).gameObject;
					obj5 = ((gameObject5 != null) ? ((Object)gameObject5).name : null);
				}
				if (obj5 == null)
				{
					obj5 = "Unknown";
				}
				LogErrorF(String.Format("Failed to send ShootRPC for {0}: {1}", obj5, (object)val9));
			}
		}

		public static bool FindRetreatPoint(EnemyHunter instance, out Vector3 retreatPoint)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			retreatPoint = Vector3.zero;
			if ((Object)(object)instance == (Object)null || (Object)(object)GameDirector.instance == (Object)null)
			{
				return false;
			}
			PlayerAvatar val = null;
			float num = 3.4028235E+38f;
			if (GameDirector.instance.PlayerList == null || GameDirector.instance.PlayerList.Count == 0)
			{
				LogWarningF("FindRetreatPoint: GameDirector.PlayerList is null or empty.");
				return false;
			}
			Enumerator<PlayerAvatar> enumerator = GameDirector.instance.PlayerList.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					PlayerAvatar current = enumerator.Current;
					if ((Object)(object)current != (Object)null && ((Component)current).gameObject.activeSelf)
					{
						float num2 = Vector3.Distance(((Component)instance).transform.position, ((Component)current).transform.position);
						if (num2 < num)
						{
							num = num2;
							val = current;
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator).Dispose();
			}
			if ((Object)(object)val == (Object)null)
			{
				LogWarningF("FindRetreatPoint: Could not find an active player to run from.");
				return false;
			}
			Vector3 val2 = ((Component)instance).transform.position - ((Component)val).transform.position;
			val2 = ((Vector3)(ref val2)).normalized;
			val2.y = 0f;
			if (val2 == Vector3.zero)
			{
				val2 = ((Component)instance).transform.forward;
			}
			float num3 = 20f;
			float num4 = 15f;
			Vector3 val3 = ((Component)instance).transform.position + val2 * num3;
			NavMeshHit val4 = default(NavMeshHit);
			if (NavMesh.SamplePosition(val3, ref val4, num4, -1))
			{
				retreatPoint = ((NavMeshHit)(ref val4)).position;
				object obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					GameObject gameObject = ((Component)instance).gameObject;
					obj = ((gameObject != null) ? ((Object)gameObject).name : null);
				}
				if (obj == null)
				{
					obj = "Unknown";
				}
				LogDebugF(String.Format("Found retreat point for {0} at {1} (away from player {2})", obj, (object)retreatPoint, (object)((Object)val).GetInstanceID()));
				return true;
			}
			val3 = ((Component)instance).transform.position + val2 * 8f;
			if (NavMesh.SamplePosition(val3, ref val4, num4, -1))
			{
				retreatPoint = ((NavMeshHit)(ref val4)).position;
				object obj2;
				if (instance == null)
				{
					obj2 = null;
				}
				else
				{
					GameObject gameObject2 = ((Component)instance).gameObject;
					obj2 = ((gameObject2 != null) ? ((Object)gameObject2).name : null);
				}
				if (obj2 == null)
				{
					obj2 = "Unknown";
				}
				LogDebugF(String.Format("Found fallback retreat point (closer) for {0} at {1}", obj2, (object)retreatPoint));
				return true;
			}
			object obj3;
			if (instance == null)
			{
				obj3 = null;
			}
			else
			{
				GameObject gameObject3 = ((Component)instance).gameObject;
				obj3 = ((gameObject3 != null) ? ((Object)gameObject3).name : null);
			}
			if (obj3 == null)
			{
				obj3 = "Unknown";
			}
			LogWarningF(String.Concat("Could not find NavMesh retreat point for ", (string)obj3, " after searching."));
			return false;
		}

		public static bool IsRepoLastStandActive()
		{
			//IL_0077: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected I4, but got Unknown
			if (!isRepoLastStandModPresent || repoStateManagerType == (Type)null || repoStateManagerInstanceProperty == (PropertyInfo)null || repoLastStandActiveField == (FieldInfo)null)
			{
				return false;
			}
			try
			{
				object value = repoStateManagerInstanceProperty.GetValue((object)null);
				if (value == null)
				{
					LogWarningF("RepoLastStandMod StateManager.Instance returned null.");
					return false;
				}
				object value2 = repoLastStandActiveField.GetValue(value);
				return (byte)(int)(Boolean)value2 != 0;
			}
			catch (Exception val)
			{
				Exception val2 = val;
				LogErrorF(String.Format("Error getting RepoLastStandMod state via reflection: {0}", (object)val2));
				return false;
			}
		}
	}
	public static class PluginInfo : Object
	{
		public const string PLUGIN_GUID = "com.plusblankplus.huntermod";

		public const string PLUGIN_NAME = "Hunter Enhancements";

		public const string PLUGIN_VERSION = "1.6.1";
	}
	public enum ReloadSkill : Enum
	{
		Fast,
		Medium,
		Slow
	}
}