Decompiled source of Hunter Enhancements v1.2.3

BepInEx/plugins/HunterMod.dll

Decompiled 2 weeks 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 BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Photon.Pun;
using UnityEngine;
using UnityEngine.AI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[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: AssemblyVersion("1.0.0.0")]
namespace HunterMod;

public enum AimMode
{
	Default,
	MinigunAccuracy,
	SniperAccuracy
}
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("Hunter " + GetHunterName() + " damage interrupt delay finished.");
			}
		}
		if (isReloading)
		{
			currentReloadTimer -= Time.deltaTime;
			if (currentReloadTimer <= 0f)
			{
				isReloading = false;
				currentReloadTimer = 0f;
				Plugin.LogInfoF($"Hunter {GetHunterName()} finished reloading (Skill: {currentSkill}).");
			}
		}
	}

	public bool TryDecrementTotalAmmo()
	{
		if (!ConfigEnableTotalAmmoLimit)
		{
			return true;
		}
		if (currentTotalAmmo > 0)
		{
			currentTotalAmmo--;
			Plugin.LogInfoF($"Hunter {GetHunterName()} ammo decremented. Remaining: {currentTotalAmmo}");
			if (currentTotalAmmo <= 0)
			{
				if (!Plugin.IsRepoLastStandActive())
				{
					isOutOfAmmoPermanently = true;
					Plugin.LogErrorF("Hunter " + GetHunterName() + " HAS RUN OUT OF TOTAL AMMO! (Last Stand NOT Active). Perm Leave.");
					CancelActions();
					return false;
				}
				Plugin.LogWarningF("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("Hunter " + GetHunterName() + " WAS ALREADY OOA & Last Stand inactive! Force Perm Leave state.");
		}
		else if (!isOutOfAmmoPermanently && flag)
		{
			Plugin.LogWarningF("Hunter " + GetHunterName() + " ammo already at 0, Last Stand active. Not setting OOA flag.");
		}
		return false;
	}

	public void StartReload()
	{
		if (isOutOfAmmoPermanently)
		{
			Plugin.LogDebugF("StartReload blocked: Hunter " + GetHunterName() + " permanently OOA.");
		}
		else if (damageInterruptDelayTimer > 0f)
		{
			Plugin.LogDebugF($"StartReload blocked: Hunter {GetHunterName()} Interrupt Delay ({damageInterruptDelayTimer:F1}s).");
		}
		else if (isMinigunBurstActive)
		{
			Plugin.LogWarningF("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($"Hunter {GetHunterName()} unknown skill '{currentSkill}', defaulting Medium.");
				break;
			}
			currentReloadTimer = num;
			Plugin.LogInfoF($"Hunter {GetHunterName()} started reload (Skill: {currentSkill}, Time: {num:F1}s).");
		}
		else
		{
			Plugin.LogWarningF("Hunter " + GetHunterName() + " tried StartReload but was already reloading.");
		}
	}

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

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

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

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

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

	private string GetHunterName()
	{
		GameObject gameObject = ((Component)this).gameObject;
		return ((gameObject != null) ? ((Object)gameObject).name : null) ?? "Unknown Hunter";
	}
}
[HarmonyPatch(typeof(EnemyHunter))]
internal static class HunterPatches
{
	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)
	{
		if ((Object)(object)instance?.enemy == (Object)null)
		{
			Plugin.LogErrorF("GetEnemyNavMeshAgent: Instance or instance.enemy is null!");
			return null;
		}
		try
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(Enemy), "NavMeshAgent");
			if (fieldInfo != null)
			{
				object value = fieldInfo.GetValue(instance.enemy);
				return (EnemyNavMeshAgent)((value is EnemyNavMeshAgent) ? value : null);
			}
			Plugin.LogErrorF("GetEnemyNavMeshAgent: Could not find Field 'NavMeshAgent' on type 'Enemy' for " + ((Object)((Component)instance).gameObject).name + "!");
			return null;
		}
		catch (Exception ex)
		{
			Plugin.LogErrorF("GetEnemyNavMeshAgent: Error accessing 'NavMeshAgent' field on " + ((Object)((Component)instance).gameObject).name + ": " + ex.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>();
			Plugin.LogInfoF("Added HunterAmmoTracker to " + ((Object)((Component)instance).gameObject).name + ". 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;
				}
			}
			Plugin.LogInfoF($"Hunter {((Object)((Component)__instance).gameObject).name} spawned with Skill: {orAddTracker.currentSkill}");
			orAddTracker.isOutOfAmmoPermanently = false;
			if (orAddTracker.ConfigEnableTotalAmmoLimit)
			{
				orAddTracker.currentTotalAmmo = orAddTracker.ConfigTotalAmmoCount;
			}
			else
			{
				orAddTracker.currentTotalAmmo = 9999;
			}
			Plugin.LogInfoF($"Hunter {((Object)((Component)__instance).gameObject).name} initialized ammo: {orAddTracker.currentTotalAmmo}");
			orAddTracker.EndMinigunBurst();
			stateLeaveFailCounters.Remove(((Object)__instance).GetInstanceID());
		}
		else
		{
			object obj;
			if (__instance == null)
			{
				obj = null;
			}
			else
			{
				GameObject gameObject = ((Component)__instance).gameObject;
				obj = ((gameObject != null) ? ((Object)gameObject).name : null);
			}
			Plugin.LogErrorF("Failed GetOrAddTracker for " + (string?)obj + " in OnSpawnPostfix.");
		}
	}

	[HarmonyPatch("StateIdle")]
	[HarmonyPrefix]
	private static bool StateIdlePrefix(EnemyHunter __instance, ref bool ___stateImpulse)
	{
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: 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.LogDebugF("StateIdlePrefix: Hunter " + ((Object)((Component)__instance).gameObject).name + " OOA. Forcing Leave.");
			Plugin.CallUpdateState(__instance, (State)9);
			stateLeaveFailCounters.Remove(((Object)__instance).GetInstanceID());
			return false;
		}
		if (Plugin.ShouldRunAwayWhileReloading() && orAddTracker.IsReloading)
		{
			Plugin.LogDebugF("StateIdlePrefix: Hunter " + ((Object)((Component)__instance).gameObject).name + " reloading. Moving away.");
			enemyNavMeshAgent.Warp(((Component)__instance).transform.position);
			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_00a5: 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)9);
			stateLeaveFailCounters.Remove(((Object)__instance).GetInstanceID());
			return false;
		}
		if (Plugin.ShouldRunAwayWhileReloading() && orAddTracker.IsReloading)
		{
			Plugin.LogDebugF("StateRoamPrefix: Hunter " + ((Object)((Component)__instance).gameObject).name + " 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_0177: 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)
		{
			Plugin.LogDebugF("StateAimPrefix: Hunter " + ((Object)((Component)__instance).gameObject).name + " OOA. Forcing Leave.");
			Plugin.CallUpdateState(__instance, (State)9);
			stateLeaveFailCounters.Remove(((Object)__instance).GetInstanceID());
			return false;
		}
		if (orAddTracker.IsReloading || orAddTracker.IsInterrupted || !orAddTracker.HasTotalAmmo)
		{
			string text = ((!orAddTracker.HasTotalAmmo) ? "OOA" : (orAddTracker.IsReloading ? $"reload({orAddTracker.GetRemainingReloadTime():F1}s)" : $"interrupt({orAddTracker.ConfigDamageInterruptDelay:F1}s)"));
			Plugin.LogDebugF("StateAimPrefix BLOCKED: " + ((Object)((Component)__instance).gameObject).name + " is " + text + ".");
			if (Plugin.ShouldRunAwayWhileReloading() && orAddTracker.IsReloading)
			{
				Plugin.LogDebugF("StateAimPrefix: " + ((Object)((Component)__instance).gameObject).name + " 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)
		{
			Plugin.LogErrorF("StateShootPrefix: " + ((Object)((Component)__instance).gameObject).name + " OOA! Forcing Leave.");
			orAddTracker.isOutOfAmmoPermanently = true;
			Plugin.CallUpdateState(__instance, (State)9);
			stateLeaveFailCounters.Remove(((Object)__instance).GetInstanceID());
			return false;
		}
		if (!Plugin.IsMinigunModeEnabled())
		{
			if (!orAddTracker.TryDecrementTotalAmmo())
			{
				Plugin.LogInfoF("StateShootPrefix(N): " + ((Object)((Component)__instance).gameObject).name + " OOA this shot. Forcing Leave.");
				Plugin.CallUpdateState(__instance, (State)9);
				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)
			{
				Plugin.LogErrorF("StateShootPrefix(M-Init): " + ((Object)((Component)__instance).gameObject).name + " OOA! Forcing Leave.");
				orAddTracker.isOutOfAmmoPermanently = true;
				Plugin.CallUpdateState(__instance, (State)9);
				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())
			{
				Plugin.LogInfoF("StateShootPrefix(M): " + ((Object)((Component)__instance).gameObject).name + " OOA mid-burst. End & Leave.");
				orAddTracker.EndMinigunBurst();
				Plugin.CallUpdateState(__instance, (State)9);
				stateLeaveFailCounters.Remove(((Object)__instance).GetInstanceID());
				return false;
			}
			Plugin.LogDebugF($"StateShootPrefix: Fire minigun {orAddTracker.ConfigMinigunShots - orAddTracker.minigunShotsRemaining + 1}/{orAddTracker.ConfigMinigunShots}. Ammo: {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)8);
			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)9);
			stateLeaveFailCounters.Remove(((Object)__instance).GetInstanceID());
			return false;
		}
		if (___stateTimer <= Time.deltaTime)
		{
			Plugin.LogInfoF($"StateShootEndPrefix(N): Shot {___shotsFired} done. LeaveStart & Reload.");
			Plugin.CallUpdateState(__instance, (State)8);
			orAddTracker.StartReload();
			return false;
		}
		return true;
	}

	private static bool PreventReEngagePrefix(EnemyHunter __instance)
	{
		HunterAmmoTracker hunterAmmoTracker = ((__instance != null) ? ((Component)__instance).GetComponent<HunterAmmoTracker>() : null);
		if ((Object)(object)hunterAmmoTracker != (Object)null && hunterAmmoTracker.isOutOfAmmoPermanently)
		{
			Plugin.LogDebugF("PreventReEngagePrefix: " + ((Object)((Component)__instance).gameObject).name + " 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_0151: 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)
		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)
			{
				Plugin.LogInfoF("StateLeavePrefix: Hunter " + ((Object)((Component)__instance).gameObject).name + " OOA and reached Leave destination/timer. Forcing Despawn.");
				Plugin.CallUpdateState(__instance, (State)10);
				stateLeaveFailCounters.Remove(instanceID);
				return false;
			}
			Plugin.LogDebugF("StateLeavePrefix: " + ((Object)((Component)__instance).gameObject).name + " reloading & reached dest/timer. Finding new retreat point.");
			if (Plugin.FindRetreatPoint(__instance, out var retreatPoint))
			{
				stateLeaveFailCounters.Remove(instanceID);
				FieldInfo fieldInfo = AccessTools.Field(typeof(EnemyHunter), "leavePosition");
				if (fieldInfo != null)
				{
					fieldInfo.SetValue(__instance, 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;
				Plugin.LogWarningF($"StateLeavePrefix: No new retreat point for {((Object)((Component)__instance).gameObject).name} while reloading. Failure {num}/{5}");
				___stateTimer = 1f;
				if (num >= 5)
				{
					Plugin.LogErrorF($"StateLeavePrefix: Hunter {((Object)((Component)__instance).gameObject).name} failed find retreat point {5} times WHILE RELOADING. Forcing Despawn.");
					Plugin.CallUpdateState(__instance, (State)10);
					stateLeaveFailCounters.Remove(instanceID);
				}
			}
			return false;
		}
		Plugin.LogDebugF($"StateLeavePrefix: Timer > deltaT ({___stateTimer:F3}), allow original method.");
		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;

	public static Plugin Instance { get; private set; }

	internal static ManualLogSource Log { get; private set; }

	public static ConfigEntry<bool> EnableMinigunMode { get; private set; }

	public static ConfigEntry<int> MinigunShots { get; private set; }

	public static ConfigEntry<float> MinigunShotDelay { get; private set; }

	public static ConfigEntry<float> FastReloadTimeConfig { get; private set; }

	public static ConfigEntry<float> MediumReloadTimeConfig { get; private set; }

	public static ConfigEntry<float> SlowReloadTimeConfig { get; private set; }

	public static ConfigEntry<int> FastSkillWeight { get; private set; }

	public static ConfigEntry<int> MediumSkillWeight { get; private set; }

	public static ConfigEntry<int> SlowSkillWeight { get; private set; }

	public static ConfigEntry<bool> EnableDamageInterruptConfig { get; private set; }

	public static ConfigEntry<float> DamageInterruptDelayConfig { get; private set; }

	public static ConfigEntry<bool> EnableTotalAmmoLimitConfig { get; private set; }

	public static ConfigEntry<int> TotalAmmoCountConfig { get; private set; }

	public static ConfigEntry<bool> RunAwayWhileReloadingConfig { get; private set; }

	public static ConfigEntry<bool> EnableInfoLogs { get; private set; }

	public static ConfigEntry<bool> EnableDebugLogs { get; private set; }

	public static ConfigEntry<bool> EnableWarningLogs { get; private set; }

	public static ConfigEntry<bool> EnableErrorLogs { get; private set; }

	private void Awake()
	{
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0093: Expected O, but got Unknown
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Expected O, but got Unknown
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Expected O, but got Unknown
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Expected O, but got Unknown
		//IL_0181: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Expected O, but got Unknown
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Expected O, but got Unknown
		//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f1: Expected O, but got Unknown
		//IL_021a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0224: Expected O, but got Unknown
		//IL_0279: Unknown result type (might be due to invalid IL or missing references)
		//IL_0283: Expected O, but got Unknown
		//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fc: 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()
	{
		isRepoLastStandModPresent = Chainloader.PluginInfos.ContainsKey("umbreon222.repo.laststand");
		if (isRepoLastStandModPresent)
		{
			LogInfoF("RepoLastStandMod detected. Enabling compatibility logic.");
			try
			{
				string text = "RepoLastStandMod";
				repoStateManagerType = Type.GetType("RepoLastStandMod.StateManager, " + text, throwOnError: false);
				if (repoStateManagerType == null && Chainloader.PluginInfos.TryGetValue("umbreon222.repo.laststand", out var value) && (Object)(object)value.Instance != (Object)null)
				{
					text = ((object)value.Instance).GetType().Assembly.FullName;
					repoStateManagerType = Type.GetType("RepoLastStandMod.StateManager, " + text, throwOnError: false);
					LogDebugF("Attempting to load StateManager from assembly: " + text);
				}
				if (repoStateManagerType != null)
				{
					repoStateManagerInstanceProperty = AccessTools.Property(repoStateManagerType, "Instance");
					repoLastStandActiveField = AccessTools.Field(repoStateManagerType, "LastStandActive");
					if (repoStateManagerInstanceProperty == null)
					{
						LogErrorF("Could not find 'Instance' property on StateManager.");
					}
					if (repoLastStandActiveField == null)
					{
						LogErrorF("Could not find 'LastStandActive' field on StateManager.");
					}
					if (repoStateManagerInstanceProperty == null || repoLastStandActiveField == 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 arg)
			{
				LogErrorF($"Error during reflection for RepoLastStandMod compatibility: {arg}");
				isRepoLastStandModPresent = false;
				return;
			}
		}
		LogInfoF("RepoLastStandMod not detected.");
	}

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

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

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

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

	public static bool IsMinigunModeEnabled()
	{
		return EnableMinigunMode.Value;
	}

	public static bool ShouldRunAwayWhileReloading()
	{
		return RunAwayWhileReloadingConfig.Value;
	}

	public static void CallUpdateState(EnemyHunter instance, State newState)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		MethodInfo methodInfo = AccessTools.Method(typeof(EnemyHunter), "UpdateState", (Type[])null, (Type[])null);
		if (methodInfo != null)
		{
			methodInfo.Invoke(instance, new object[1] { newState });
			return;
		}
		object obj;
		if (instance == null)
		{
			obj = null;
		}
		else
		{
			GameObject gameObject = ((Component)instance).gameObject;
			obj = ((gameObject != null) ? ((Object)gameObject).name : null);
		}
		LogErrorF("Could not find method 'UpdateState' on " + (string?)obj + "!");
	}

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

	private static PhotonView GetPhotonView(EnemyHunter instance)
	{
		if ((Object)(object)instance == (Object)null)
		{
			return null;
		}
		try
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(EnemyHunter), "photonView");
			if (fieldInfo != null)
			{
				object? value = fieldInfo.GetValue(instance);
				return (PhotonView)((value is PhotonView) ? value : null);
			}
			LogErrorF("GetPhotonView: Could not find field 'photonView' on " + ((Object)((Component)instance).gameObject).name + "!");
			return null;
		}
		catch (Exception ex)
		{
			LogErrorF("GetPhotonView: Error accessing 'photonView' field on " + ((Object)((Component)instance).gameObject).name + ": " + ex.Message);
			return null;
		}
	}

	public static void CallShootRPC(EnemyHunter instance)
	{
		//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0173: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: 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_018d: 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)
		//IL_0221: Unknown result type (might be due to invalid IL or missing references)
		//IL_022c: 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_01b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01be: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0252: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d6: 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_0211: Unknown result type (might be due to invalid IL or missing references)
		//IL_0216: 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);
			}
			LogDebugF("CallShootRPC skipped on non-MasterClient for " + (string?)obj);
			return;
		}
		PhotonView photonView = GetPhotonView(instance);
		if ((Object)(object)photonView == (Object)null)
		{
			LogErrorF("CallShootRPC: PhotonView is null for " + ((Object)((Component)instance).gameObject).name + "! 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 fieldInfo = AccessTools.Field(typeof(EnemyHunter), "investigatePoint");
			if (fieldInfo != null)
			{
				Vector3 val2 = (Vector3)fieldInfo.GetValue(instance);
				float num = ((Vector3.Distance(((Component)instance).transform.position, val2) > 10f) ? 0.5f : 1f);
				LayerMask val3 = LayerMask.op_Implicit(LayerMask.GetMask(new string[4] { "Player", "Default", "PhysGrabObject", "Enemy" }));
				LayerMask val4 = LayerMask.op_Implicit(LayerMask.GetMask(new string[1] { "Default" }));
				RaycastHit val5 = default(RaycastHit);
				if (Physics.SphereCast(instance.gunAimTransform.position, num, instance.gunAimTransform.forward, ref val5, 50f, LayerMask.op_Implicit(val3)))
				{
					if (!Physics.Linecast(instance.gunAimTransform.position, ((RaycastHit)(ref val5)).point, LayerMask.op_Implicit(val4)))
					{
						val = ((RaycastHit)(ref val5)).point;
					}
					else if (Physics.Raycast(instance.gunAimTransform.position, instance.gunAimTransform.forward, ref val5, 50f, LayerMask.op_Implicit(val3)))
					{
						val = ((RaycastHit)(ref val5)).point;
					}
				}
				else if (Physics.Raycast(instance.gunAimTransform.position, instance.gunAimTransform.forward, ref val5, 50f, LayerMask.op_Implicit(val3)))
				{
					val = ((RaycastHit)(ref val5)).point;
				}
			}
			else
			{
				LogWarningF("Could not access investigatePoint field for " + ((Object)((Component)instance).gameObject).name + "!");
			}
		}
		catch (Exception ex)
		{
			LogErrorF("Error calculating target position: " + ex.Message);
		}
		try
		{
			LogDebugF($"Sending ShootRPC for {((Object)((Component)instance).gameObject).name} targeting {val}");
			photonView.RPC("ShootRPC", (RpcTarget)0, new object[1] { val });
		}
		catch (Exception arg)
		{
			LogErrorF($"Failed to send ShootRPC for {((Object)((Component)instance).gameObject).name}: {arg}");
		}
	}

	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_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: 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_0142: Unknown result type (might be due to invalid IL or missing references)
		//IL_0147: Unknown result type (might be due to invalid IL or missing references)
		//IL_0154: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0190: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0202: Unknown result type (might be due to invalid IL or missing references)
		//IL_0207: Unknown result type (might be due to invalid IL or missing references)
		//IL_020c: 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_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b2: 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_0224: Unknown result type (might be due to invalid IL or missing references)
		//IL_0229: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: 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 = float.MaxValue;
		if (GameDirector.instance.PlayerList == null || GameDirector.instance.PlayerList.Count == 0)
		{
			LogWarningF("FindRetreatPoint: GameDirector.PlayerList is null or empty.");
			return false;
		}
		foreach (PlayerAvatar player in GameDirector.instance.PlayerList)
		{
			if (!((Object)(object)player == (Object)null) && ((Component)player).gameObject.activeSelf)
			{
				float num2 = Vector3.Distance(((Component)instance).transform.position, ((Component)player).transform.position);
				if (num2 < num)
				{
					num = num2;
					val = player;
				}
			}
		}
		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;
		Vector3 val3 = ((Vector3)(ref val2)).normalized;
		val3.y = 0f;
		if (val3 == Vector3.zero)
		{
			val3 = ((Component)instance).transform.forward;
		}
		float num3 = 20f;
		float num4 = 15f;
		Vector3 val4 = ((Component)instance).transform.position + val3 * num3;
		NavMeshHit val5 = default(NavMeshHit);
		if (NavMesh.SamplePosition(val4, ref val5, num4, -1))
		{
			retreatPoint = ((NavMeshHit)(ref val5)).position;
			LogDebugF($"Found retreat point for {((Object)((Component)instance).gameObject).name} at {retreatPoint} (away from player {((Object)val).GetInstanceID()})");
			return true;
		}
		val4 = ((Component)instance).transform.position + val3 * 8f;
		if (NavMesh.SamplePosition(val4, ref val5, num4, -1))
		{
			retreatPoint = ((NavMeshHit)(ref val5)).position;
			LogDebugF($"Found fallback retreat point (closer) for {((Object)((Component)instance).gameObject).name} at {retreatPoint}");
			return true;
		}
		LogWarningF("Could not find NavMesh retreat point for " + ((Object)((Component)instance).gameObject).name + " after searching.");
		return false;
	}

	public static bool IsRepoLastStandActive()
	{
		if (!isRepoLastStandModPresent || repoStateManagerType == null || repoStateManagerInstanceProperty == null || repoLastStandActiveField == null)
		{
			return false;
		}
		try
		{
			object value = repoStateManagerInstanceProperty.GetValue(null);
			if (value == null)
			{
				LogWarningF("RepoLastStandMod StateManager.Instance returned null.");
				return false;
			}
			object value2 = repoLastStandActiveField.GetValue(value);
			return (bool)value2;
		}
		catch (Exception arg)
		{
			LogErrorF($"Error getting RepoLastStandMod state via reflection: {arg}");
			return false;
		}
	}
}
public static class PluginInfo
{
	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
{
	Fast,
	Medium,
	Slow
}