Decompiled source of ExtraWeaponCustomization v2.8.0

ExtraWeaponCustomization.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using AIGraph;
using AK;
using Agents;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Hook;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using CharacterDestruction;
using CullingSystem;
using EWC.API;
using EWC.CustomWeapon;
using EWC.CustomWeapon.KillTracker;
using EWC.CustomWeapon.ObjectWrappers;
using EWC.CustomWeapon.Properties;
using EWC.CustomWeapon.Properties.Effects;
using EWC.CustomWeapon.Properties.Effects.Heal;
using EWC.CustomWeapon.Properties.Effects.Hit.DOT;
using EWC.CustomWeapon.Properties.Effects.Hit.Explosion;
using EWC.CustomWeapon.Properties.Effects.Hit.Explosion.EEC_ExplosionFX;
using EWC.CustomWeapon.Properties.Effects.Hit.Explosion.EEC_ExplosionFX.Handlers;
using EWC.CustomWeapon.Properties.Effects.Triggers;
using EWC.CustomWeapon.Properties.Traits;
using EWC.CustomWeapon.Properties.Traits.CustomProjectile;
using EWC.CustomWeapon.Properties.Traits.CustomProjectile.Components;
using EWC.CustomWeapon.Properties.Traits.CustomProjectile.Managers;
using EWC.CustomWeapon.WeaponContext;
using EWC.CustomWeapon.WeaponContext.Contexts;
using EWC.Dependencies;
using EWC.JSON;
using EWC.JSON.Converters;
using EWC.Networking;
using EWC.Networking.Structs;
using EWC.Patches;
using EWC.Patches.Melee;
using EWC.Patches.Native;
using EWC.Utils;
using EWC.Utils.Log;
using EndskApi.Api;
using EndskApi.Enums.EnemyKill;
using EndskApi.Information.EnemyKill;
using Enemies;
using ExtraRecoilData.API;
using ExtraRecoilData.CustomRecoil;
using FX_EffectSystem;
using FirstPersonItem;
using GTFO.API;
using GTFO.API.JSON.Converters;
using GTFO.API.Utilities;
using GTFuckingXP.Extensions;
using GTFuckingXP.Information.Level;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.Attributes;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppInterop.Runtime.Runtime;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using KillIndicatorFix;
using LevelGeneration;
using LevelGeneration.Core;
using MTFO.API;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("ExtraWeaponCustomization")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+0aaa3ef20b4270d512a4bfe2ed004cbf2fc655e0")]
[assembly: AssemblyProduct("ExtraWeaponCustomization")]
[assembly: AssemblyTitle("ExtraWeaponCustomization")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace EWC
{
	internal static class Configuration
	{
		private static readonly ConfigFile configFile;

		private static ConfigEntry<bool> ForceCreateTemplate { get; set; }

		public static bool ShowExplosionEffect { get; set; }

		public static bool PlayExplosionSFX { get; set; }

		public static float ExplosionSFXCooldown { get; set; }

		public static int ExplosionSFXShotOverride { get; set; }

		public static float AutoAimTickDelay { get; set; }

		public static float HomingTickDelay { get; set; }

		static Configuration()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			ShowExplosionEffect = true;
			PlayExplosionSFX = true;
			ExplosionSFXCooldown = 0.08f;
			ExplosionSFXShotOverride = 8;
			AutoAimTickDelay = 0.1f;
			HomingTickDelay = 0.1f;
			configFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "ExtraWeaponCustomization.cfg"), true);
			BindAll(configFile);
		}

		internal static void Init()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			LiveEdit.CreateListener(Paths.ConfigPath, "ExtraWeaponCustomization.cfg", false).FileChanged += new LiveEditEventHandler(OnFileChanged);
		}

		private static void OnFileChanged(LiveEditEventArgs _)
		{
			configFile.Reload();
			string text = "Auto Aim Settings";
			AutoAimTickDelay = (float)configFile[text, "Search Cooldown"].BoxedValue;
			text = "Explosion Settings";
			ShowExplosionEffect = (bool)configFile[text, "Show Effect"].BoxedValue;
			PlayExplosionSFX = (bool)configFile[text, "Play Sound"].BoxedValue;
			ExplosionSFXCooldown = (float)configFile[text, "SFX Cooldown"].BoxedValue;
			ExplosionSFXShotOverride = (int)configFile[text, "Shots to Override SFX Cooldown"].BoxedValue;
			text = "Projectile Settings";
			HomingTickDelay = (float)configFile[text, "Homing Search Cooldown"].BoxedValue;
			CheckAndRefreshTemplate();
		}

		[MemberNotNull("ForceCreateTemplate")]
		private static void BindAll(ConfigFile config)
		{
			string text = "Auto Aim Settings";
			AutoAimTickDelay = config.Bind<float>(text, "Search Cooldown", AutoAimTickDelay, "Time between attempted searches to acquire targets.").Value;
			text = "Explosion Settings";
			ShowExplosionEffect = config.Bind<bool>(text, "Show Effect", ShowExplosionEffect, "Enables explosion visual FX.").Value;
			PlayExplosionSFX = config.Bind<bool>(text, "Play Sound", PlayExplosionSFX, "Enables explosion sound FX.").Value;
			ExplosionSFXCooldown = config.Bind<float>(text, "SFX Cooldown", ExplosionSFXCooldown, "Minimum time between explosion sound effects, to prevent obnoxiously loud sounds.").Value;
			ExplosionSFXShotOverride = config.Bind<int>(text, "Shots to Override SFX Cooldown", ExplosionSFXShotOverride, "Amount of shots fired before another explosion sound effect is forced, regardless of cooldown.\nSmaller numbers let fast-firing weapons and shotguns make more sounds in a short span of time.").Value;
			text = "Projectile Settings";
			HomingTickDelay = config.Bind<float>(text, "Homing Search Cooldown", HomingTickDelay, "Minimum time between attempted searches to acquire a new target.").Value;
			text = "Tools";
			ForceCreateTemplate = config.Bind<bool>(text, "Force Create Template", false, "Creates the template file again.");
		}

		private static void CheckAndRefreshTemplate()
		{
			if (ForceCreateTemplate.Value)
			{
				ForceCreateTemplate.Value = false;
				CustomWeaponManager.Current.CreateTemplate();
				configFile.Save();
			}
		}
	}
	[BepInPlugin("Dinorush.ExtraWeaponCustomization", "ExtraWeaponCustomization", "2.8.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal sealed class EntryPoint : BasePlugin
	{
		public const string MODNAME = "ExtraWeaponCustomization";

		public override void Load()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			EWCLogger.Log("Loading ExtraWeaponCustomization");
			if (!MTFOAPIWrapper.HasCustomContent)
			{
				EWCLogger.Error("No MTFO datablocks detected. Not loading EWC...");
				return;
			}
			new Harmony("ExtraWeaponCustomization").PatchAll();
			EnemyDetectionPatches.ApplyNativePatch();
			Configuration.Init();
			LevelAPI.OnLevelCleanup += LevelAPI_OnLevelCleanup;
			LevelAPI.OnEnterLevel += LevelAPI_OnLevelEnter;
			AssetAPI.OnStartupAssetsLoaded += AssetAPI_OnStartupAssetsLoaded;
			EWCLogger.Log("Loaded ExtraWeaponCustomization");
		}

		private void LevelAPI_OnLevelCleanup()
		{
			CustomWeaponManager.Current.ResetCWCs(activate: false);
			EWCProjectileManager.Reset();
		}

		private void LevelAPI_OnLevelEnter()
		{
			CustomWeaponManager.Current.ActivateCWCs();
		}

		private void AssetAPI_OnStartupAssetsLoaded()
		{
			ClassInjector.RegisterTypeInIl2Cpp<ExplosionEffectHandler>();
			ClassInjector.RegisterTypeInIl2Cpp<CustomWeaponComponent>();
			ClassInjector.RegisterTypeInIl2Cpp<EWCProjectileComponentBase>();
			ClassInjector.RegisterTypeInIl2Cpp<EWCProjectileComponentShooter>();
			LayerUtil.Init();
			ExplosionManager.Init();
			DOTDamageManager.Init();
			HealManager.Init();
			TriggerManager.Init();
			KillAPIWrapper.Init();
			EWCProjectileManager.Init();
			CustomWeaponManager.Current.GetCustomGunData(0u);
		}
	}
}
namespace EWC.Utils
{
	internal static class DamageableUtil
	{
		public static IDamageable? GetDamageableFromRayHit(RaycastHit rayHit)
		{
			if (!((Object)(object)((RaycastHit)(ref rayHit)).collider == (Object)null))
			{
				return GetDamageableFromCollider(((RaycastHit)(ref rayHit)).collider);
			}
			return null;
		}

		public static IDamageable? GetDamageableFromCollider(Collider? collider)
		{
			if (!((Object)(object)collider == (Object)null))
			{
				return GetDamageableFromGO(((Component)collider).gameObject);
			}
			return null;
		}

		public static IDamageable? GetDamageableFromGO(GameObject? go)
		{
			if ((Object)(object)go == (Object)null)
			{
				return null;
			}
			ColliderMaterial component = go.GetComponent<ColliderMaterial>();
			IDamageable val = ((component != null) ? component.Damageable : null);
			if (val != null)
			{
				return val;
			}
			return go.GetComponent<IDamageable>();
		}
	}
	public sealed class DelayedCallback
	{
		private readonly Func<float> _endTime;

		private readonly Action? _onStart;

		private readonly Action? _onRefresh;

		private readonly Action? _onEnd;

		private Coroutine? _routine;

		public DelayedCallback(Func<float> endTime, Action? onStart, Action? onRefresh, Action? onEnd)
		{
			_endTime = endTime;
			_onStart = onStart;
			_onRefresh = onRefresh;
			_onEnd = onEnd;
		}

		public void Start()
		{
			_onRefresh?.Invoke();
			if (_routine == null)
			{
				_routine = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(Update()), (Action)null);
			}
		}

		public IEnumerator Update()
		{
			_onStart?.Invoke();
			for (float num = _endTime(); num > Clock.Time; num = _endTime())
			{
				yield return (object)new WaitForSeconds(num - Clock.Time);
			}
			_routine = null;
			_onEnd?.Invoke();
		}

		public void Stop()
		{
			if (_routine != null)
			{
				CoroutineManager.StopCoroutine(_routine);
				_routine = null;
				_onEnd?.Invoke();
			}
		}

		public void Cancel()
		{
			if (_routine != null)
			{
				CoroutineManager.StopCoroutine(_routine);
				_routine = null;
			}
		}
	}
	internal static class DictExtensions
	{
		public static bool TryGetValueAs<Key, Value, ValueAs>(this IDictionary<Key, Value> dict, Key key, [MaybeNullWhen(false)] out ValueAs valueAs) where Key : notnull where ValueAs : Value
		{
			if (dict.TryGetValue(key, out Value value))
			{
				valueAs = (ValueAs)(object)value;
				return true;
			}
			valueAs = default(ValueAs);
			return false;
		}
	}
	internal static class FloatExtensions
	{
		public static float Map(this float orig, float fromMin, float fromMax, float toMin, float toMax)
		{
			if (fromMin == fromMax)
			{
				if (!(orig < fromMin))
				{
					return toMax;
				}
				return toMin;
			}
			orig = Mathf.Clamp(orig, fromMin, fromMax);
			return (orig - fromMin) / (fromMax - fromMin) * (toMax - toMin) + toMin;
		}
	}
	public sealed class HitData
	{
		public float damage;

		public Vector2 damageFalloff;

		public float falloff;

		public float precisionMulti;

		public float staggerMulti;

		public float maxRayDist;

		public PlayerAgent owner;

		public Vector3 fireDir;

		public Vector3 hitPos;

		public IDamageable? damageable;

		private RaycastHit _rayHit;

		private WeaponHitData? _weaponHitData;

		private MeleeWeaponFirstPerson? _meleeWeapon;

		public RaycastHit RayHit
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return _rayHit;
			}
			set
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				_rayHit = value;
				hitPos = ((RaycastHit)(ref _rayHit)).point;
				damageable = DamageableUtil.GetDamageableFromRayHit(_rayHit);
			}
		}

		public HitData(WeaponHitData hitData, float additionalDist = 0f)
		{
			Setup(hitData, additionalDist);
		}

		public HitData(MeleeWeaponFirstPerson melee, MeleeWeaponDamageData hitData)
		{
			Setup(melee, hitData);
		}

		public HitData()
		{
		}

		public void Setup(WeaponHitData hitData, float additionalDist = 0f)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			_weaponHitData = hitData;
			_meleeWeapon = null;
			damage = hitData.damage;
			damageFalloff = hitData.damageFalloff;
			precisionMulti = hitData.precisionMulti;
			staggerMulti = hitData.staggerMulti;
			owner = hitData.owner;
			fireDir = hitData.fireDir;
			maxRayDist = hitData.maxRayDist;
			RayHit = hitData.rayHit;
			SetFalloff(additionalDist);
		}

		public void Setup(MeleeWeaponFirstPerson melee, MeleeWeaponDamageData hitData)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			_weaponHitData = null;
			_meleeWeapon = melee;
			damage = melee.m_damageToDeal;
			precisionMulti = melee.m_precisionMultiToDeal;
			staggerMulti = melee.m_staggerMultiToDeal;
			falloff = 1f;
			fireDir = hitData.hitPos - hitData.sourcePos;
			hitPos = hitData.hitPos;
			damageable = DamageableUtil.GetDamageableFromGO(hitData.damageGO);
		}

		public void Apply()
		{
			if (_weaponHitData != null)
			{
				Apply(_weaponHitData);
			}
			else if ((Object)(object)_meleeWeapon != (Object)null)
			{
				Apply(_meleeWeapon);
			}
		}

		public WeaponHitData Apply(WeaponHitData hitData)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			hitData.owner = owner;
			hitData.damage = damage;
			hitData.precisionMulti = precisionMulti;
			hitData.staggerMulti = staggerMulti;
			hitData.rayHit = RayHit;
			hitData.fireDir = fireDir;
			hitData.maxRayDist = maxRayDist;
			return hitData;
		}

		public MeleeWeaponFirstPerson Apply(MeleeWeaponFirstPerson melee)
		{
			melee.m_damageToDeal = damage;
			melee.m_precisionMultiToDeal = precisionMulti;
			melee.m_staggerMultiToDeal = staggerMulti;
			return melee;
		}

		public void SetFalloff(float additionalDist = 0f)
		{
			//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)
			RaycastHit rayHit = RayHit;
			falloff = (((RaycastHit)(ref rayHit)).distance + additionalDist).Map(damageFalloff.x, damageFalloff.y, 1f, BulletWeapon.s_falloffMin);
		}

		public WeaponHitData ToWeaponHitData()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			return new WeaponHitData
			{
				damage = damage,
				damageFalloff = damageFalloff,
				precisionMulti = precisionMulti,
				staggerMulti = staggerMulti,
				owner = owner,
				rayHit = RayHit,
				fireDir = fireDir,
				maxRayDist = maxRayDist
			};
		}
	}
	public static class LayerUtil
	{
		public static int MaskDynamic { get; private set; }

		public static int MaskEntityAndWorld { get; private set; }

		public static int MaskEntityAndWorld3P { get; private set; }

		public static int MaskWorld { get; private set; }

		public static int MaskWorldExcProj { get; private set; }

		public static int MaskDecalValid { get; private set; }

		public static int MaskEntityDynamic3P { get; private set; }

		public static int MaskEntity { get; private set; }

		public static int MaskEntity3P { get; private set; }

		public static int MaskOwner { get; private set; }

		public static int MaskFriendly { get; private set; }

		public static int MaskEnemy { get; private set; }

		public static int MaskEnemyDynamic { get; private set; }

		internal static void Init()
		{
			MaskOwner = LayerMask.GetMask(new string[1] { "PlayerMover" });
			MaskFriendly = LayerMask.GetMask(new string[1] { "PlayerSynced" });
			MaskEnemy = LayerMask.GetMask(new string[1] { "EnemyDamagable" });
			MaskDynamic = LayerMask.GetMask(new string[1] { "Dynamic" });
			MaskEnemyDynamic = MaskEnemy | MaskDynamic;
			MaskEntity3P = MaskFriendly | MaskEnemy;
			MaskEntity = MaskOwner | MaskEntity3P;
			MaskDecalValid = LayerMask.GetMask(new string[3] { "Default", "Default_NoGraph", "Default_BlockGraph" });
			MaskWorldExcProj = MaskDecalValid | MaskDynamic;
			MaskWorld = MaskWorldExcProj | LayerMask.GetMask(new string[1] { "ProjectileBlocker" });
			MaskEntityAndWorld = MaskEntity | MaskWorld;
			MaskEntityDynamic3P = MaskEntity3P | MaskDynamic;
			MaskEntityAndWorld3P = MaskEntity3P | MaskWorld;
		}
	}
	[Flags]
	internal enum SearchSetting
	{
		None = 0,
		Alloc = 1,
		CacheHit = 2,
		CheckLOS = 4,
		CheckDoors = 8,
		CheckOwner = 0x10,
		CheckFriendly = 0x20,
		IgnoreDupes = 0x40
	}
	internal static class SearchUtil
	{
		private static readonly List<EnemyAgent> s_enemyCache = new List<EnemyAgent>();

		private static readonly List<(EnemyAgent, RaycastHit)> s_combinedCache = new List<(EnemyAgent, RaycastHit)>();

		private static readonly List<(PlayerAgent, RaycastHit)> s_combinedCachePlayer = new List<(PlayerAgent, RaycastHit)>();

		private static readonly Queue<AIG_CourseNode> s_nodeQueue = new Queue<AIG_CourseNode>();

		private static readonly List<RaycastHit> s_lockCache = new List<RaycastHit>();

		public static HashSet<IntPtr>? DupeCheckSet;

		public static int SightBlockLayer = 0;

		public const float WeakspotBufferDist = 0.1f;

		private static Ray s_ray;

		private static RaycastHit s_rayHit;

		private const float Epsilon = 1E-05f;

		private static Vector3 ClosestPointOnBounds(Bounds bounds, Vector3 point)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(Mathf.Clamp(point.x, ((Bounds)(ref bounds)).min.x, ((Bounds)(ref bounds)).max.x), Mathf.Clamp(point.y, ((Bounds)(ref bounds)).min.y, ((Bounds)(ref bounds)).max.y), Mathf.Clamp(point.z, ((Bounds)(ref bounds)).min.z, ((Bounds)(ref bounds)).max.z));
		}

		private static bool PortalInRange(Ray ray, float range, float angle, AIG_CoursePortal portal)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: 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_00f2: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			Bounds portalBounds = portal.m_cullPortal.m_portalBounds;
			Vector3 val = ClosestPointOnBounds(portalBounds, ((Ray)(ref ray)).origin);
			Vector3 val2 = ((Ray)(ref ray)).origin - val;
			if (((Vector3)(ref val2)).sqrMagnitude > range * range)
			{
				return false;
			}
			if (angle >= 180f || ((Bounds)(ref portalBounds)).Contains(((Ray)(ref ray)).origin))
			{
				return true;
			}
			Vector3 val3 = portal.m_cullPortal.m_center - ((Ray)(ref ray)).origin;
			float num = Vector3.Dot(val3, ((Ray)(ref ray)).direction);
			if (angle == 90f)
			{
				return num >= 0f;
			}
			val = Vector3.Project(val3, ((Ray)(ref ray)).direction);
			Bounds portalBounds2 = portal.m_cullPortal.m_portalBounds;
			val2 = ((Bounds)(ref portalBounds2)).extents;
			float magnitude = ((Vector3)(ref val2)).magnitude;
			float num2 = ((Vector3)(ref val)).magnitude * Mathf.Tan(angle * (MathF.PI / 180f));
			if (num2 < 0f)
			{
				if (num >= 0f)
				{
					return true;
				}
				num2 = Mathf.Max(0f, num2 + magnitude);
				val2 = val3 - val;
				return ((Vector3)(ref val2)).sqrMagnitude >= num2 * num2;
			}
			if (num <= 0f)
			{
				return false;
			}
			num2 += magnitude;
			val2 = val3 - val;
			return ((Vector3)(ref val2)).sqrMagnitude <= num2 * num2;
		}

		private static bool RaycastEnsured(Collider collider, Vector3 backupOrigin, float range, out RaycastHit hit)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: 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)
			if (collider.Raycast(s_ray, ref hit, range))
			{
				return true;
			}
			Vector3 val = collider.ClosestPoint(backupOrigin);
			Bounds bounds = collider.bounds;
			Vector3 val2 = val - ((Bounds)(ref bounds)).center;
			Vector3 normalized = ((Vector3)(ref val2)).normalized;
			bounds = collider.bounds;
			((Ray)(ref s_ray)).origin = ((Bounds)(ref bounds)).center + val2 + normalized * Mathf.Min(0.1f, range / 2f);
			((Ray)(ref s_ray)).direction = -normalized;
			return collider.Raycast(s_ray, ref hit, range);
		}

		private static bool TryGetClosestHit(Ray ray, float range, float angle, Agent agent, out RaycastHit hit, SearchSetting settings)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Invalid comparison between Unknown and I4
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Invalid comparison between Unknown and I4
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: 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_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: 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_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			hit = default(RaycastHit);
			if ((Object)(object)agent == (Object)null || !agent.Alive)
			{
				return false;
			}
			if (settings.HasFlag(SearchSetting.IgnoreDupes))
			{
				if ((int)agent.Type == 1)
				{
					HashSet<IntPtr>? dupeCheckSet = DupeCheckSet;
					if (dupeCheckSet != null && dupeCheckSet.Contains(((Il2CppObjectBase)((Il2CppObjectBase)agent).Cast<EnemyAgent>().Damage).Pointer))
					{
						return false;
					}
				}
				if ((int)agent.Type == 0)
				{
					HashSet<IntPtr>? dupeCheckSet2 = DupeCheckSet;
					if (dupeCheckSet2 != null && dupeCheckSet2.Contains(((Il2CppObjectBase)((Il2CppObjectBase)agent).Cast<PlayerAgent>().Damage).Pointer))
					{
						return false;
					}
				}
			}
			((Ray)(ref s_ray)).origin = ((Ray)(ref ray)).origin;
			float num = range * range;
			float num2 = num;
			Collider val = null;
			bool flag = false;
			foreach (Collider componentsInChild in ((Component)agent).GetComponentsInChildren<Collider>())
			{
				Dam_EnemyDamageLimb val2 = null;
				if ((int)agent.Type == 1)
				{
					val2 = ((Component)componentsInChild).GetComponent<Dam_EnemyDamageLimb>();
					if ((Object)(object)val2 == (Object)null || val2.IsDestroyed)
					{
						continue;
					}
				}
				else if ((int)agent.Type == 0 && ((Component)componentsInChild).GetComponent<IDamageable>() == null)
				{
					continue;
				}
				Vector3 val3 = componentsInChild.ClosestPoint(((Ray)(ref ray)).origin);
				Vector3 direction = val3 - ((Ray)(ref ray)).origin;
				float num3 = ((Vector3)(ref direction)).sqrMagnitude;
				float num4 = num3;
				if (val2 != null && (int)val2.m_type == 1 && num3 < num)
				{
					float num5 = Math.Max(((Vector3)(ref direction)).magnitude - 0.1f, 0f);
					num3 = num5 * num5;
				}
				if (!(num3 < num2) || !(Vector3.Angle(((Ray)(ref ray)).direction, val3 - ((Ray)(ref ray)).origin) <= angle) || (settings.HasFlag(SearchSetting.CheckLOS) && Physics.Linecast(((Ray)(ref ray)).origin, val3, SightBlockLayer)))
				{
					continue;
				}
				num2 = num3;
				val = componentsInChild;
				if (!settings.HasFlag(SearchSetting.CacheHit))
				{
					break;
				}
				if (num2 < 1E-05f)
				{
					if (!(num4 > 1E-05f))
					{
						((Ray)(ref s_ray)).origin = ((Ray)(ref s_ray)).origin - ((Ray)(ref ray)).direction * Math.Min(0.1f, range / 2f);
						((Ray)(ref s_ray)).direction = val3 - ((Ray)(ref s_ray)).origin;
						if (RaycastEnsured(componentsInChild, ((Ray)(ref ray)).origin, range, out hit))
						{
							((RaycastHit)(ref hit)).point = val3;
							((RaycastHit)(ref hit)).distance = 0f;
							flag = true;
						}
						else
						{
							val = null;
						}
					}
					break;
				}
				((Ray)(ref s_ray)).direction = direction;
			}
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if (settings.HasFlag(SearchSetting.CacheHit) && !flag && !RaycastEnsured(val, ((Ray)(ref ray)).origin, range, out hit))
			{
				return false;
			}
			return true;
		}

		private static void CacheEnemiesInRange(Ray ray, float range, float angle, AIG_CourseNode origin, SearchSetting settings)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: 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_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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)
			AIG_SearchID.IncrementSearchID();
			ushort searchID = AIG_SearchID.SearchID;
			float num = range * range;
			s_nodeQueue.Enqueue(origin);
			((AIG_CourseGraphMember)origin).m_searchID = searchID;
			s_combinedCache.Clear();
			AIG_CourseNode result;
			while (s_nodeQueue.TryDequeue(out result))
			{
				Enumerator<AIG_CoursePortal> enumerator = result.m_portals.GetEnumerator();
				while (enumerator.MoveNext())
				{
					AIG_CoursePortal current = enumerator.Current;
					AIG_CourseNode oppositeNode = current.GetOppositeNode(result);
					if ((!settings.HasFlag(SearchSetting.CheckDoors) || current.IsTraversable) && ((AIG_CourseGraphMember)oppositeNode).m_searchID != searchID && PortalInRange(ray, range, angle, current))
					{
						((AIG_CourseGraphMember)oppositeNode).m_searchID = searchID;
						s_nodeQueue.Enqueue(oppositeNode);
					}
				}
				Enumerator<EnemyAgent> enumerator2 = result.m_enemiesInNode.GetEnumerator();
				while (enumerator2.MoveNext())
				{
					EnemyAgent current2 = enumerator2.Current;
					if (!((Object)(object)current2 == (Object)null) && ((Agent)current2).Alive)
					{
						Vector3 val = ClosestPointOnBounds(((C_Cullable)current2.MovingCuller.Culler).Bounds, ((Ray)(ref ray)).origin) - ((Ray)(ref ray)).origin;
						if (!(((Vector3)(ref val)).sqrMagnitude > num) && TryGetClosestHit(ray, range, angle, (Agent)(object)current2, out s_rayHit, settings))
						{
							s_combinedCache.Add((current2, s_rayHit));
						}
					}
				}
			}
		}

		public static List<EnemyAgent> GetEnemiesInRange(Ray ray, float range, float angle, AIG_CourseNode origin, SearchSetting settings = SearchSetting.None)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			s_enemyCache.Clear();
			if (range == 0f || angle == 0f)
			{
				if (!settings.HasFlag(SearchSetting.Alloc))
				{
					return s_enemyCache;
				}
				return new List<EnemyAgent>();
			}
			CacheEnemiesInRange(ray, range, angle, origin, settings);
			if (settings.HasFlag(SearchSetting.Alloc))
			{
				return s_combinedCache.ConvertAll(((EnemyAgent, RaycastHit) pair) => pair.Item1);
			}
			foreach (var item2 in s_combinedCache)
			{
				EnemyAgent item = item2.Item1;
				s_enemyCache.Add(item);
			}
			return s_enemyCache;
		}

		public static List<(EnemyAgent enemy, RaycastHit hit)> GetEnemyHitsInRange(Ray ray, float range, float angle, AIG_CourseNode origin, SearchSetting settings = SearchSetting.CacheHit)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (range == 0f || angle == 0f)
			{
				s_combinedCache.Clear();
				if (!settings.HasFlag(SearchSetting.Alloc))
				{
					return s_combinedCache;
				}
				return new List<(EnemyAgent, RaycastHit)>();
			}
			settings |= SearchSetting.CacheHit;
			CacheEnemiesInRange(ray, range, angle, origin, settings);
			if (settings.HasFlag(SearchSetting.Alloc))
			{
				return new List<(EnemyAgent, RaycastHit)>(s_combinedCache);
			}
			return s_combinedCache;
		}

		public static List<RaycastHit> GetLockHitsInRange(Ray ray, float range, float angle, SearchSetting settings = SearchSetting.None)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			s_lockCache.Clear();
			if (range == 0f || angle == 0f)
			{
				if (!settings.HasFlag(SearchSetting.Alloc))
				{
					return s_lockCache;
				}
				return new List<RaycastHit>();
			}
			Collider[] array = Il2CppArrayBase<Collider>.op_Implicit((Il2CppArrayBase<Collider>)(object)Physics.OverlapSphere(((Ray)(ref ray)).origin, range, LayerUtil.MaskDynamic));
			Vector3 direction = ((Ray)(ref ray)).direction;
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				IDamageable damageableFromCollider = DamageableUtil.GetDamageableFromCollider(val);
				if (damageableFromCollider == null)
				{
					continue;
				}
				if (settings.HasFlag(SearchSetting.IgnoreDupes))
				{
					HashSet<IntPtr>? dupeCheckSet = DupeCheckSet;
					if (dupeCheckSet != null && dupeCheckSet.Contains(((Il2CppObjectBase)damageableFromCollider.GetBaseDamagable()).Pointer))
					{
						continue;
					}
				}
				if (!settings.HasFlag(SearchSetting.CheckLOS) || !Physics.Linecast(((Ray)(ref ray)).origin, damageableFromCollider.DamageTargetPos, ref s_rayHit, SightBlockLayer) || !(((Il2CppObjectBase)((Component)((RaycastHit)(ref s_rayHit)).collider).gameObject).Pointer != ((Il2CppObjectBase)((Component)val).gameObject).Pointer))
				{
					((Ray)(ref ray)).direction = damageableFromCollider.DamageTargetPos - ((Ray)(ref ray)).origin;
					if (val.Raycast(ray, ref s_rayHit, range) && Vector3.Angle(((Ray)(ref ray)).direction, direction) < angle)
					{
						s_lockCache.Add(s_rayHit);
					}
				}
			}
			if (settings.HasFlag(SearchSetting.Alloc))
			{
				return new List<RaycastHit>(s_lockCache);
			}
			return s_lockCache;
		}

		public static List<(PlayerAgent, RaycastHit)> GetPlayerHitsInRange(Ray ray, float range, float angle, SearchSetting settings = SearchSetting.CheckOwner | SearchSetting.CheckFriendly)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			s_combinedCachePlayer.Clear();
			if (range == 0f || angle == 0f)
			{
				if (!settings.HasFlag(SearchSetting.Alloc))
				{
					return s_combinedCachePlayer;
				}
				return new List<(PlayerAgent, RaycastHit)>();
			}
			float num = range * range;
			Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
			while (enumerator.MoveNext())
			{
				PlayerAgent current = enumerator.Current;
				if ((Object)(object)current == (Object)null || !((Agent)current).Alive)
				{
					continue;
				}
				Vector3 val = ClosestPointOnBounds(((C_Cullable)current.m_movingCuller.Culler).Bounds, ((Ray)(ref ray)).origin) - ((Ray)(ref ray)).origin;
				if (((Vector3)(ref val)).sqrMagnitude > num)
				{
					continue;
				}
				if (((Agent)current).IsLocallyOwned)
				{
					if (!settings.HasFlag(SearchSetting.CheckOwner))
					{
						continue;
					}
					((Ray)(ref s_ray)).origin = ((Ray)(ref ray)).origin;
					((Ray)(ref s_ray)).direction = ((Dam_SyncedDamageBase)current.Damage).DamageTargetPos - ((Ray)(ref ray)).origin;
					if (!((Component)current).GetComponent<Collider>().Raycast(s_ray, ref s_rayHit, range) || (settings.HasFlag(SearchSetting.CheckLOS) && Physics.Linecast(((Ray)(ref ray)).origin, ((RaycastHit)(ref s_rayHit)).point, SightBlockLayer)))
					{
						continue;
					}
				}
				else if (!settings.HasFlag(SearchSetting.CheckFriendly) || !TryGetClosestHit(ray, range, angle, (Agent)(object)current, out s_rayHit, settings))
				{
					continue;
				}
				s_combinedCachePlayer.Add((current, s_rayHit));
			}
			if (settings.HasFlag(SearchSetting.Alloc))
			{
				return new List<(PlayerAgent, RaycastHit)>(s_combinedCachePlayer);
			}
			return s_combinedCachePlayer;
		}

		private static bool HasCluster(AIG_VoxelNodePillar pillar)
		{
			Enumerator<AIG_VoxelNode> enumerator = pillar.m_nodes.GetEnumerator();
			AIG_NodeCluster val = default(AIG_NodeCluster);
			while (enumerator.MoveNext())
			{
				AIG_VoxelNode current = enumerator.Current;
				if (current.ClusterID != 0 && AIG_NodeCluster.TryGetNodeCluster(current.ClusterID, ref val))
				{
					return true;
				}
			}
			return false;
		}

		public static AIG_CourseNode GetCourseNode(Vector3 position, Agent agent)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position2 = agent.Position;
			if (TryGetGeomorphVolumeSilent(Dimension.GetDimensionFromPos(position).DimensionIndex, position, out AIG_GeomorphNodeVolume resultingGeoVolume))
			{
				position.y = ((AIG_NodeVolume)resultingGeoVolume).Position.y;
				position2.y = position.y;
				Vector3 val = position2 - position;
				Vector3 normalized = ((Vector3)(ref val)).normalized;
				AIG_VoxelNodePillar val2 = null;
				for (int i = 0; i < 10; i++)
				{
					if (((AIG_NodeVolume)resultingGeoVolume).m_voxelNodeVolume.TryGetPillar(position, ref val2) && HasCluster(val2))
					{
						break;
					}
					position += normalized;
				}
				if (val2 == null)
				{
					return agent.CourseNode;
				}
				Enumerator<AIG_VoxelNode> enumerator = val2.m_nodes.GetEnumerator();
				AIG_NodeCluster val3 = default(AIG_NodeCluster);
				while (enumerator.MoveNext())
				{
					AIG_VoxelNode current = enumerator.Current;
					if (current.ClusterID != 0 && AIG_NodeCluster.TryGetNodeCluster(current.ClusterID, ref val3) && val3.CourseNode != null)
					{
						return val3.CourseNode;
					}
				}
			}
			return agent.CourseNode;
		}

		private static bool TryGetGeomorphVolumeSilent(eDimensionIndex dimensionIndex, Vector3 pos, [MaybeNullWhen(false)] out AIG_GeomorphNodeVolume resultingGeoVolume)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			resultingGeoVolume = null;
			LG_Floor currentFloor = Builder.Current.m_currentFloor;
			if ((Object)(object)currentFloor == (Object)null)
			{
				return false;
			}
			Dimension val = default(Dimension);
			if (!currentFloor.GetDimension(dimensionIndex, ref val))
			{
				return false;
			}
			if (val.Grid == null || !TryGetCell(val.Grid, pos, out LG_Cell cell))
			{
				return false;
			}
			if (((CellBase<LG_Tile, LG_Cell>)(object)cell).m_grouping == null || (Object)(object)((CellBase<LG_Tile, LG_Cell>)(object)cell).m_grouping.m_geoRoot == (Object)null)
			{
				return false;
			}
			resultingGeoVolume = ((Il2CppObjectBase)((CellBase<LG_Tile, LG_Cell>)(object)cell).m_grouping.m_geoRoot.m_nodeVolume).TryCast<AIG_GeomorphNodeVolume>();
			return (Object)(object)resultingGeoVolume != (Object)null;
		}

		private static bool TryGetCell(LG_Grid grid, Vector3 pos, [MaybeNullWhen(false)] out LG_Cell cell)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			pos -= ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_gridPosition;
			int num = Mathf.RoundToInt((pos.x - ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_cellDimHalf) / ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_cellDim);
			int num2 = Mathf.RoundToInt((pos.z - ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_cellDimHalf) / ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_cellDim);
			if (num < 0 || num2 < 0 || num >= ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_sizeX || num2 >= ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).m_sizeZ)
			{
				cell = null;
				return false;
			}
			cell = ((CellGridBase<LG_Grid, LG_Tile, LG_Cell>)(object)grid).GetCell(num, num2);
			return true;
		}
	}
	internal static class SortUtil
	{
		private static List<(RaycastHit hit, float distance)> s_limbCache = new List<(RaycastHit, float)>();

		private static List<(EnemyAgent enemy, float value)> s_enemyTupleCache = new List<(EnemyAgent, float)>();

		public static int Rayhit(RaycastHit x, RaycastHit y)
		{
			if (((RaycastHit)(ref x)).distance == ((RaycastHit)(ref y)).distance)
			{
				return 0;
			}
			if (!(((RaycastHit)(ref x)).distance < ((RaycastHit)(ref y)).distance))
			{
				return 1;
			}
			return -1;
		}

		public static int EnemyRayhit((EnemyAgent, RaycastHit hit) x, (EnemyAgent, RaycastHit hit) y)
		{
			if (((RaycastHit)(ref x.hit)).distance == ((RaycastHit)(ref y.hit)).distance)
			{
				return 0;
			}
			if (!(((RaycastHit)(ref x.hit)).distance < ((RaycastHit)(ref y.hit)).distance))
			{
				return 1;
			}
			return -1;
		}

		public static void SortWithWeakspotBuffer(IList<RaycastHit> list)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			foreach (RaycastHit item in list)
			{
				RaycastHit current = item;
				IDamageable? damageableFromRayHit = DamageableUtil.GetDamageableFromRayHit(current);
				int num;
				if (damageableFromRayHit == null)
				{
					num = 0;
				}
				else
				{
					Dam_EnemyDamageLimb obj = ((Il2CppObjectBase)damageableFromRayHit).TryCast<Dam_EnemyDamageLimb>();
					num = ((((obj != null) ? new eLimbDamageType?(obj.m_type) : null) == (eLimbDamageType?)1) ? 1 : 0);
				}
				bool flag = (byte)num != 0;
				s_limbCache.Add((current, flag ? Mathf.Max(((RaycastHit)(ref current)).distance - 0.1f, 0f) : ((RaycastHit)(ref current)).distance));
			}
			s_limbCache.Sort(FloatTuple);
			CopySortedList(s_limbCache, list);
			s_limbCache.Clear();
		}

		public static void CopySortedList<T>(IList<(T, float)> sortedList, IList<T> list)
		{
			for (int i = 0; i < list.Count; i++)
			{
				list[i] = sortedList[i].Item1;
			}
		}

		public static void CopySortedList<T>(IList<(T, float, float)> sortedList, IList<T> list)
		{
			for (int i = 0; i < list.Count; i++)
			{
				list[i] = sortedList[i].Item1;
			}
		}

		public static int FloatTuple<T>((T, float val) x, (T, float val) y)
		{
			if (x.val == y.val)
			{
				return 0;
			}
			if (!(x.val < y.val))
			{
				return 1;
			}
			return -1;
		}

		public static int FloatTuple<T>((T, float val1, float val2) x, (T, float val1, float val2) y)
		{
			if (x.val1 == y.val1)
			{
				if (x.val2 == y.val2)
				{
					return 0;
				}
				if (!(x.val2 < y.val2))
				{
					return 1;
				}
				return -1;
			}
			if (!(x.val1 < y.val1))
			{
				return 1;
			}
			return -1;
		}
	}
	internal static class StringExtensions
	{
		public static T ToEnum<T>(this string? value, T defaultValue) where T : struct
		{
			if (string.IsNullOrEmpty(value))
			{
				return defaultValue;
			}
			if (!Enum.TryParse<T>(value.Replace(" ", null), ignoreCase: true, out var result))
			{
				return defaultValue;
			}
			return result;
		}
	}
}
namespace EWC.Utils.Log
{
	internal static class EWCLogger
	{
		private static ManualLogSource logger = Logger.CreateLogSource("ExtraWeaponCustomization");

		public static void Log(string format, params object[] args)
		{
			Log(string.Format(format, args));
		}

		public static void Log(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)8, (object)str);
			}
		}

		public static void Warning(string format, params object[] args)
		{
			Warning(string.Format(format, args));
		}

		public static void Warning(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)4, (object)str);
			}
		}

		public static void Error(string format, params object[] args)
		{
			Error(string.Format(format, args));
		}

		public static void Error(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)2, (object)str);
			}
		}

		public static void Debug(string format, params object[] args)
		{
			Debug(string.Format(format, args));
		}

		public static void Debug(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)32, (object)str);
			}
		}
	}
}
namespace EWC.Patches
{
	[HarmonyPatch]
	internal static class EnemyLimbPatches
	{
		private static float _cachedArmor;

		[HarmonyPatch(typeof(Dam_EnemyDamageLimb), "BulletDamage")]
		[HarmonyPatch(typeof(Dam_EnemyDamageLimb), "MeleeDamage")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void Pre_Damage(Dam_EnemyDamageLimb __instance)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			ContextController cachedHitCC = WeaponPatches.CachedHitCC;
			if (cachedHitCC != null && (int)__instance.m_type == 2)
			{
				_cachedArmor = __instance.m_armorDamageMulti;
				__instance.m_armorDamageMulti = cachedHitCC.Invoke(new WeaponArmorContext(_cachedArmor)).ArmorMulti;
			}
		}

		[HarmonyPatch(typeof(Dam_EnemyDamageLimb), "BulletDamage")]
		[HarmonyPatch(typeof(Dam_EnemyDamageLimb), "MeleeDamage")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void Post_Damage(Dam_EnemyDamageLimb __instance)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			if (WeaponPatches.CachedHitCC != null && (int)__instance.m_type == 2)
			{
				__instance.m_armorDamageMulti = _cachedArmor;
			}
		}

		[HarmonyPatch(typeof(Dam_EnemyDamageLimb_Custom), "ApplyWeakspotAndArmorModifiers")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static bool Pre_WeakspotModifiers(Dam_EnemyDamageLimb_Custom __instance, float dam, float precisionMulti, ref float __result)
		{
			if (!WeaponPatches.CachedBypassTumorCap)
			{
				return true;
			}
			__result = dam * Mathf.Max(((Dam_EnemyDamageLimb)__instance).m_weakspotDamageMulti * precisionMulti, 1f) * ((Dam_EnemyDamageLimb)__instance).m_armorDamageMulti;
			return false;
		}
	}
	[HarmonyPatch]
	internal static class FPISPatches
	{
		private static CustomWeaponComponent? _cachedCWC;

		[HarmonyPatch(typeof(FPIS_Aim), "Enter")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void Post_AimEnter(FPIS_Aim __instance)
		{
			_cachedCWC = ((Component)((FPItemState)__instance).Holder.WieldedItem).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)_cachedCWC == (Object)null))
			{
				_cachedCWC.Invoke(StaticContext<WeaponAimContext>.Instance);
			}
		}

		[HarmonyPatch(typeof(FPIS_Aim), "Exit")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void Post_AimExit()
		{
			if (!((Object)(object)_cachedCWC == (Object)null))
			{
				_cachedCWC.Invoke(StaticContext<WeaponAimEndContext>.Instance);
			}
		}
	}
	[HarmonyPatch]
	internal static class PlayerInventoryPatches
	{
		private static bool _allowReload = true;

		[HarmonyPatch(typeof(PUI_Inventory), "SetSlotAmmo")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void SetAmmoUICallback(PUI_Inventory __instance, InventorySlot slot, ref int clipAbs, ref int inPackAbs, ref float inPackRel)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			if ((int)slot == 0)
			{
				return;
			}
			SNet_Player owner = __instance.m_owner;
			object obj;
			if (owner == null)
			{
				obj = null;
			}
			else
			{
				SNet_IPlayerAgent playerAgent = owner.PlayerAgent;
				if (playerAgent == null)
				{
					obj = null;
				}
				else
				{
					PlayerAgent obj2 = ((Il2CppObjectBase)playerAgent).TryCast<PlayerAgent>();
					if (obj2 == null)
					{
						obj = null;
					}
					else
					{
						FirstPersonItemHolder fPItemHolder = obj2.FPItemHolder;
						if (fPItemHolder == null)
						{
							obj = null;
						}
						else
						{
							ItemEquippable wieldedItem = fPItemHolder.WieldedItem;
							if (wieldedItem == null)
							{
								obj = null;
							}
							else
							{
								BulletWeapon obj3 = ((Il2CppObjectBase)wieldedItem).TryCast<BulletWeapon>();
								obj = ((obj3 != null) ? ((Component)obj3).GetComponent<CustomWeaponComponent>() : null);
							}
						}
					}
				}
			}
			CustomWeaponComponent customWeaponComponent = (CustomWeaponComponent)obj;
			if (!((Object)(object)customWeaponComponent == (Object)null))
			{
				PUI_InventoryItem val = __instance.m_inventorySlots[slot];
				WeaponPreAmmoUIContext weaponPreAmmoUIContext = new WeaponPreAmmoUIContext(clipAbs, inPackAbs, inPackRel, val.ShowAmmoClip, val.ShowAmmoPack, val.ShowAmmoTotalRel, val.ShowAmmoInfinite);
				customWeaponComponent.Invoke(weaponPreAmmoUIContext);
				clipAbs = weaponPreAmmoUIContext.Clip;
				inPackAbs = weaponPreAmmoUIContext.Reserve;
				inPackRel = weaponPreAmmoUIContext.TotalRel;
				val.ShowAmmoClip = weaponPreAmmoUIContext.ShowClip;
				val.ShowAmmoPack = weaponPreAmmoUIContext.ShowReserve;
				val.ShowAmmoTotalRel = weaponPreAmmoUIContext.ShowRel;
				val.ShowAmmoInfinite = weaponPreAmmoUIContext.ShowInfinite;
			}
		}

		private static InventorySlot AmmoToSlot(AmmoType ammo)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected I4, but got Unknown
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			return (InventorySlot)((int)ammo switch
			{
				0 => 1, 
				1 => 2, 
				2 => 3, 
				_ => 0, 
			});
		}

		[HarmonyPatch(typeof(PlayerAmmoStorage), "PickupAmmo")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void AmmoPackCallback(PlayerAmmoStorage __instance, AmmoType ammoType, ref float ammoAmount)
		{
			//IL_0006: 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)
			BackpackItem val = default(BackpackItem);
			if (__instance.m_playerBackpack.TryGetBackpackItem(AmmoToSlot(ammoType), ref val))
			{
				Item instance = val.Instance;
				CustomWeaponComponent customWeaponComponent = ((instance != null) ? ((Component)instance).GetComponent<CustomWeaponComponent>() : null);
				if ((Object)(object)customWeaponComponent != (Object)null)
				{
					ammoAmount = customWeaponComponent.Invoke(new WeaponPreAmmoPackContext(ammoAmount)).AmmoAmount;
				}
			}
		}

		[HarmonyPatch(typeof(PlayerAmmoStorage), "PickupAmmo")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PostAmmoPackCallback(PlayerAmmoStorage __instance, AmmoType ammoType)
		{
			//IL_0006: 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)
			BackpackItem val = default(BackpackItem);
			if (__instance.m_playerBackpack.TryGetBackpackItem(AmmoToSlot(ammoType), ref val))
			{
				Item instance = val.Instance;
				((instance != null) ? ((Component)instance).GetComponent<CustomWeaponComponent>() : null)?.Invoke(new WeaponPostAmmoPackContext(__instance));
			}
		}

		[HarmonyPatch(typeof(PlayerInventoryLocal), "DoReload")]
		[HarmonyPatch(typeof(PlayerInventoryBase), "DoReload")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void ReloadCallback(PlayerInventoryBase __instance)
		{
			ItemEquippable wieldedItem = __instance.m_wieldedItem;
			CustomWeaponComponent customWeaponComponent = ((wieldedItem != null) ? ((Component)wieldedItem).GetComponent<CustomWeaponComponent>() : null);
			if (!((Object)(object)customWeaponComponent == (Object)null))
			{
				customWeaponComponent.Invoke(StaticContext<WeaponPostReloadContext>.Instance);
			}
		}

		[HarmonyPatch(typeof(PlayerInventoryLocal), "TriggerReload")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static bool ReloadPreStartCallback(PlayerInventoryLocal __instance)
		{
			_allowReload = true;
			ItemEquippable wieldedItem = ((PlayerInventoryBase)__instance).m_wieldedItem;
			CustomWeaponComponent customWeaponComponent = ((wieldedItem != null) ? ((Component)wieldedItem).GetComponent<CustomWeaponComponent>() : null);
			if ((Object)(object)customWeaponComponent == (Object)null)
			{
				return true;
			}
			_allowReload = customWeaponComponent.Invoke(new WeaponPreReloadContext()).Allow;
			return _allowReload;
		}

		[HarmonyPatch(typeof(PlayerInventoryLocal), "TriggerReload")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void ReloadStartCallback(PlayerInventoryLocal __instance)
		{
			if (_allowReload)
			{
				ItemEquippable wieldedItem = ((PlayerInventoryBase)__instance).m_wieldedItem;
				CustomWeaponComponent customWeaponComponent = ((wieldedItem != null) ? ((Component)wieldedItem).GetComponent<CustomWeaponComponent>() : null);
				if (!((Object)(object)customWeaponComponent == (Object)null) && customWeaponComponent.Weapon.IsReloading)
				{
					customWeaponComponent.Invoke(StaticContext<WeaponReloadStartContext>.Instance);
				}
			}
		}

		[HarmonyPatch(typeof(PlayerAmmoStorage), "FillAllClips")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PostFillAllClipsCallback(PlayerAmmoStorage __instance)
		{
			BackpackItem val = default(BackpackItem);
			if (__instance.m_playerBackpack.TryGetBackpackItem((InventorySlot)1, ref val))
			{
				Item instance = val.Instance;
				((instance != null) ? ((Component)instance).GetComponent<CustomWeaponComponent>() : null)?.Invoke(new WeaponPostAmmoInitContext(__instance, __instance.StandardAmmo));
			}
			BackpackItem val2 = default(BackpackItem);
			if (__instance.m_playerBackpack.TryGetBackpackItem((InventorySlot)2, ref val2))
			{
				Item instance2 = val2.Instance;
				((instance2 != null) ? ((Component)instance2).GetComponent<CustomWeaponComponent>() : null)?.Invoke(new WeaponPostAmmoInitContext(__instance, __instance.SpecialAmmo));
			}
		}
	}
	[HarmonyPatch]
	internal static class ShotgunPatches
	{
		[HarmonyPatch(typeof(Shotgun), "Fire")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void Pre_Fire(Shotgun __instance)
		{
			WeaponRayPatches.CachedWeapon = (BulletWeapon?)(object)__instance;
		}

		[HarmonyPatch(typeof(Shotgun), "Fire")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void Post_Fire(Shotgun __instance)
		{
			WeaponRayPatches.CachedWeapon = null;
		}
	}
	[HarmonyPatch]
	internal static class WeaponArchetypePatches
	{
		[HarmonyPatch(typeof(BulletWeaponArchetype), "SetOwner")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void SetupCallback(BulletWeaponArchetype __instance, PlayerAgent owner)
		{
			if (!((Object)(object)owner == (Object)null))
			{
				CustomWeaponComponent component = ((Component)__instance.m_weapon).GetComponent<CustomWeaponComponent>();
				if (!((Object)(object)component == (Object)null))
				{
					component.OwnerInit();
				}
			}
		}

		[HarmonyPatch(typeof(BWA_Burst), "OnStartFiring")]
		[HarmonyPatch(typeof(BWA_Auto), "OnStartFiring")]
		[HarmonyPatch(typeof(BulletWeaponArchetype), "OnStartFiring")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static bool StartFireCallback(BulletWeaponArchetype __instance)
		{
			BulletWeapon weapon = __instance.m_weapon;
			CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null);
			if ((Object)(object)customWeaponComponent == (Object)null)
			{
				return true;
			}
			customWeaponComponent.CancelShot = false;
			WeaponPreStartFireContext weaponPreStartFireContext = new WeaponPreStartFireContext();
			customWeaponComponent.Invoke(weaponPreStartFireContext);
			customWeaponComponent.UpdateStoredFireRate();
			if (!weaponPreStartFireContext.Allow)
			{
				customWeaponComponent.StoreCancelShot();
			}
			return weaponPreStartFireContext.Allow;
		}

		[HarmonyPatch(typeof(BWA_Burst), "OnStartFiring")]
		[HarmonyPatch(typeof(BWA_Auto), "OnStartFiring")]
		[HarmonyPatch(typeof(BulletWeaponArchetype), "OnStartFiring")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PostStartFireCallback(BulletWeaponArchetype __instance)
		{
			BulletWeapon weapon = __instance.m_weapon;
			CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null);
			if (!((Object)(object)customWeaponComponent == (Object)null))
			{
				if (customWeaponComponent.ResetShotIfCancel(__instance))
				{
					customWeaponComponent.CancelShot = false;
					__instance.m_readyToFire = false;
				}
				else
				{
					customWeaponComponent.Invoke(StaticContext<WeaponPostStartFireContext>.Instance);
				}
			}
		}

		[HarmonyPatch(typeof(BWA_Auto), "OnFireShot")]
		[HarmonyPatch(typeof(BWA_Burst), "OnFireShot")]
		[HarmonyPatch(typeof(BWA_Semi), "OnFireShot")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static bool PreFireCallback(BulletWeaponArchetype __instance)
		{
			BulletWeapon weapon = __instance.m_weapon;
			CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null);
			if ((Object)(object)customWeaponComponent == (Object)null)
			{
				return true;
			}
			if (customWeaponComponent.CancelShot)
			{
				return false;
			}
			WeaponFireCancelContext weaponFireCancelContext = new WeaponFireCancelContext();
			customWeaponComponent.Invoke(weaponFireCancelContext);
			if (!weaponFireCancelContext.Allow)
			{
				customWeaponComponent.StoreCancelShot();
			}
			else
			{
				customWeaponComponent.Invoke(StaticContext<WeaponPreFireContext>.Instance);
			}
			return weaponFireCancelContext.Allow;
		}

		[HarmonyPatch(typeof(BWA_Auto), "OnFireShot")]
		[HarmonyPatch(typeof(BWA_Burst), "OnFireShot")]
		[HarmonyPatch(typeof(BWA_Semi), "OnFireShot")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PostFireCallback(BulletWeaponArchetype __instance)
		{
			BulletWeapon weapon = __instance.m_weapon;
			CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null);
			if (!((Object)(object)customWeaponComponent == (Object)null) && !customWeaponComponent.CancelShot)
			{
				customWeaponComponent.Invoke(StaticContext<WeaponPostFireContext>.Instance);
			}
		}

		[HarmonyPatch(typeof(BulletWeaponArchetype), "PostFireCheck")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void PrePostFireCallback(BulletWeaponArchetype __instance)
		{
			BulletWeapon weapon = __instance.m_weapon;
			CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null);
			if (!((Object)(object)customWeaponComponent == (Object)null))
			{
				customWeaponComponent.ResetShotIfCancel(__instance);
			}
		}

		[HarmonyPatch(typeof(BulletWeaponArchetype), "PostFireCheck")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PostPostFireCallback(BulletWeaponArchetype __instance)
		{
			BulletWeapon weapon = __instance.m_weapon;
			CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null);
			if (!((Object)(object)customWeaponComponent == (Object)null))
			{
				if (customWeaponComponent.CancelShot)
				{
					customWeaponComponent.CancelShot = false;
					return;
				}
				customWeaponComponent.UpdateStoredFireRate();
				customWeaponComponent.ModifyFireRate();
			}
		}

		[HarmonyPatch(typeof(BWA_Burst), "OnStopFiring")]
		[HarmonyPatch(typeof(BWA_Auto), "OnStopFiring")]
		[HarmonyPatch(typeof(BulletWeaponArchetype), "OnStopFiring")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void StopFiringCallback(BulletWeaponArchetype __instance)
		{
			BulletWeapon weapon = __instance.m_weapon;
			CustomWeaponComponent customWeaponComponent = ((weapon != null) ? ((Component)weapon).GetComponent<CustomWeaponComponent>() : null);
			if (!((Object)(object)customWeaponComponent == (Object)null))
			{
				customWeaponComponent.Invoke(StaticContext<WeaponPostStopFiringContext>.Instance);
			}
		}
	}
	[HarmonyPatch]
	internal static class WeaponPatches
	{
		private static uint s_lastSearchID = 0u;

		private static float s_origHitDamage = 0f;

		private static float s_origHitPrecision = 0f;

		private static readonly HitData s_hitData = new HitData();

		private static ContextController? _cachedHitCC = null;

		public static ContextController? CachedHitCC
		{
			get
			{
				return _cachedHitCC;
			}
			set
			{
				_cachedHitCC = value;
				CachedBypassTumorCap = false;
			}
		}

		public static bool CachedBypassTumorCap { get; private set; } = false;


		[HarmonyPatch(typeof(BulletWeapon), "OnGearSpawnComplete")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void SetupCallback(BulletWeapon __instance)
		{
			CustomWeaponManager.Current.AddWeaponListener((ItemEquippable)(object)__instance);
			CustomWeaponData customGunData = CustomWeaponManager.Current.GetCustomGunData(((GameDataBlockBase<ArchetypeDataBlock>)(object)((ItemEquippable)__instance).ArchetypeData).persistentID);
			if (customGunData != null && !((Object)(object)((Component)__instance).gameObject.GetComponent<CustomWeaponComponent>() != (Object)null))
			{
				((Component)__instance).gameObject.AddComponent<CustomWeaponComponent>().Register(customGunData);
			}
		}

		[HarmonyPatch(typeof(BulletWeapon), "OnWield")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void UpdateCurrentWeapon(BulletWeapon __instance)
		{
			CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				component.Invoke(StaticContext<WeaponWieldContext>.Instance);
				component.RefreshSoundDelay();
				s_lastSearchID = 0u;
			}
		}

		[HarmonyPatch(typeof(BulletWeapon), "OnUnWield")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void UpdateWeaponUnwielded(BulletWeapon __instance)
		{
			CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				component.Invoke(StaticContext<WeaponUnWieldContext>.Instance);
			}
		}

		[HarmonyPatch(typeof(BulletWeapon), "BulletHit")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void HitCallback(ref WeaponHitData weaponRayData, bool doDamage, float additionalDis, uint damageSearchID, ref bool allowDirectionalBonus)
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Invalid comparison between Unknown and I4
			CachedHitCC = null;
			if (!allowDirectionalBonus || weaponRayData.vfxBulletHit != null || !doDamage || (!((Agent)weaponRayData.owner).IsLocallyOwned && (!SNet.IsMaster || !weaponRayData.owner.Owner.IsBot)))
			{
				return;
			}
			s_hitData.Setup(weaponRayData, additionalDis);
			IDamageable damageable = s_hitData.damageable;
			IDamageable val = ((((damageable != null) ? damageable.GetBaseDamagable() : null) != null) ? damageable.GetBaseDamagable() : damageable);
			if (damageSearchID != 0 && val != null && val.TempSearchID == damageSearchID)
			{
				return;
			}
			ItemEquippable wieldedItem = s_hitData.owner.Inventory.WieldedItem;
			CustomWeaponComponent customWeaponComponent = ((wieldedItem != null) ? ((Component)wieldedItem).GetComponent<CustomWeaponComponent>() : null);
			if ((Object)(object)customWeaponComponent == (Object)null)
			{
				Agent val2 = ((damageable != null) ? damageable.GetBaseAgent() : null);
				if ((Object)(object)val2 != (Object)null && (int)val2.Type == 1 && val2.Alive)
				{
					KillTrackerManager.ClearHit(((Il2CppObjectBase)val2).TryCast<EnemyAgent>());
				}
				return;
			}
			if (damageable != null && damageSearchID != 0)
			{
				if (s_lastSearchID != damageSearchID)
				{
					s_lastSearchID = damageSearchID;
					s_origHitDamage = s_hitData.damage;
					s_origHitPrecision = s_hitData.precisionMulti;
				}
				s_hitData.damage = s_origHitDamage;
				s_hitData.precisionMulti = s_origHitPrecision;
			}
			ApplyEWCHit(customWeaponComponent, damageable, s_hitData, damageSearchID != 0, ref s_origHitDamage, ref allowDirectionalBonus);
		}

		public static void ApplyEWCHit(CustomWeaponComponent cwc, IDamageable? damageable, HitData hitData, bool pierce, ref float pierceDamage, ref bool doBackstab)
		{
			ApplyEWCHit(cwc.GetContextController(), cwc.Weapon, damageable, hitData, pierce, ref pierceDamage, ref doBackstab);
		}

		public static void ApplyEWCHit(ContextController cc, ItemEquippable weapon, IDamageable? damageable, HitData hitData, bool pierce, ref float pierceDamage, ref bool doBackstab)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Invalid comparison between Unknown and I4
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			CachedHitCC = cc;
			if (damageable != null)
			{
				WeaponDamageContext weaponDamageContext = new WeaponDamageContext(hitData.damage, hitData.precisionMulti, damageable);
				cc.Invoke(weaponDamageContext);
				hitData.damage = weaponDamageContext.Damage.Value;
				hitData.precisionMulti = weaponDamageContext.Precision.Value;
				CachedBypassTumorCap = weaponDamageContext.BypassTumorCap;
				if (pierce)
				{
					WeaponPierceContext weaponPierceContext = new WeaponPierceContext(pierceDamage, damageable);
					cc.Invoke(weaponPierceContext);
					pierceDamage = weaponPierceContext.Value;
				}
			}
			Agent val = ((damageable != null) ? damageable.GetBaseAgent() : null);
			if ((Object)(object)val != (Object)null && (int)val.Type == 1 && val.Alive)
			{
				Dam_EnemyDamageLimb val2 = ((Il2CppObjectBase)damageable).TryCast<Dam_EnemyDamageLimb>();
				float num = val2.ApplyDamageFromBehindBonus(1f, hitData.hitPos, ((Vector3)(ref hitData.fireDir)).normalized, 1f);
				WeaponBackstabContext weaponBackstabContext = new WeaponBackstabContext();
				cc.Invoke(weaponBackstabContext);
				WeaponPreHitEnemyContext weaponPreHitEnemyContext = new WeaponPreHitEnemyContext(hitData, CachedBypassTumorCap, num.Map(1f, 2f, 1f, weaponBackstabContext.Value), val2, DamageType.Bullet);
				cc.Invoke(weaponPreHitEnemyContext);
				KillTrackerManager.RegisterHit(weapon, weaponPreHitEnemyContext);
				if (weaponBackstabContext.Value > 1f)
				{
					hitData.damage *= weaponPreHitEnemyContext.Backstab / num;
				}
				else
				{
					doBackstab = false;
				}
			}
			else
			{
				cc.Invoke(new WeaponPreHitContext(hitData));
			}
			hitData.Apply();
		}
	}
	[HarmonyPatch]
	internal static class WeaponRayPatches
	{
		public static BulletWeapon? CachedWeapon = null;

		private static HitData s_hitData = new HitData();

		private static CustomWeaponComponent? _cachedCWC = null;

		[HarmonyTargetMethod]
		private static MethodBase FindWeaponRayFunc(Harmony harmony)
		{
			return AccessTools.Method(typeof(Weapon), "CastWeaponRay", new Type[4]
			{
				typeof(Transform),
				typeof(WeaponHitData).MakeByRefType(),
				typeof(Vector3),
				typeof(int)
			}, (Type[])null);
		}

		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void PreRayCallback(ref WeaponHitData weaponRayData, Vector3 originPos, int altRayCastMask)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			if (altRayCastMask != -1)
			{
				return;
			}
			if ((Object)(object)CachedWeapon != (Object)null)
			{
				_cachedCWC = ((Component)CachedWeapon).GetComponent<CustomWeaponComponent>();
			}
			else
			{
				PlayerAgent owner = weaponRayData.owner;
				object cachedCWC;
				if (owner == null)
				{
					cachedCWC = null;
				}
				else
				{
					ItemEquippable wieldedItem = owner.Inventory.WieldedItem;
					cachedCWC = ((wieldedItem != null) ? ((Component)wieldedItem).GetComponent<CustomWeaponComponent>() : null);
				}
				_cachedCWC = (CustomWeaponComponent?)cachedCWC;
			}
			if (!((Object)(object)_cachedCWC == (Object)null))
			{
				s_hitData.Setup(weaponRayData);
				_cachedCWC.Invoke(new WeaponPreRayContext(s_hitData, originPos));
				s_hitData.Apply();
			}
		}

		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PostRayCallback(ref WeaponHitData weaponRayData, Vector3 originPos, int altRayCastMask, ref bool __result)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			if (altRayCastMask == -1 && !((Object)(object)_cachedCWC == (Object)null))
			{
				s_hitData.Setup(weaponRayData);
				if (!_cachedCWC.Invoke(new WeaponCancelRayContext(s_hitData, originPos)).Result)
				{
					__result = false;
					return;
				}
				__result = _cachedCWC.Invoke(new WeaponPostRayContext(s_hitData, originPos, __result)).Result;
				s_hitData.Apply();
			}
		}
	}
	[HarmonyPatch]
	internal static class WeaponRecoilPatches
	{
		private static BulletWeapon? _cachedWeapon;

		private static CustomWeaponComponent? _cachedComponent;

		[HarmonyPatch(typeof(BulletWeapon), "OnWield")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void UpdateCurrentWeapon(BulletWeapon __instance)
		{
			PlayerAgent owner = ((Item)__instance).Owner;
			if (owner != null && ((Agent)owner).IsLocallyOwned)
			{
				_cachedWeapon = __instance;
				_cachedComponent = ((Component)__instance).GetComponent<CustomWeaponComponent>();
			}
		}

		[HarmonyAfter(new string[] { "Dinorush.ExtraRecoilData" })]
		[HarmonyPatch(typeof(FPS_RecoilSystem), "ApplyRecoil")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PostApplyRecoilCallback(FPS_RecoilSystem __instance, bool resetSimilarity, RecoilDataBlock recoilData)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_cachedComponent == (Object)null))
			{
				WeaponRecoilContext weaponRecoilContext = new WeaponRecoilContext();
				_cachedComponent.Invoke(weaponRecoilContext);
				if (weaponRecoilContext.Value != 1f)
				{
					Vector2 val = default(Vector2);
					((Vector2)(ref val))..ctor(__instance.recoilDir.x * (weaponRecoilContext.Value - 1f), __instance.recoilDir.y * (weaponRecoilContext.Value - 1f));
					Vector2 currentRecoilForce = __instance.currentRecoilForce;
					currentRecoilForce.x -= val.x * (1f - recoilData.worldToViewSpaceBlendVertical);
					currentRecoilForce.y -= val.y * (1f - recoilData.worldToViewSpaceBlendHorizontal);
					Vector2 currentRecoilForceVP = __instance.currentRecoilForceVP;
					currentRecoilForceVP.x -= val.x * recoilData.worldToViewSpaceBlendVertical;
					currentRecoilForceVP.y -= val.y * recoilData.worldToViewSpaceBlendHorizontal;
					Vector2 recoilDir = __instance.recoilDir;
					((Vector2)(ref recoilDir)).Set(__instance.recoilDir.x * weaponRecoilContext.Value, __instance.recoilDir.y * weaponRecoilContext.Value);
					__instance.currentRecoilForce = currentRecoilForce;
					__instance.currentRecoilForceVP = currentRecoilForceVP;
				}
			}
		}
	}
	[HarmonyPatch]
	internal static class WeaponSyncPatches
	{
		[HarmonyPatch(typeof(BulletWeaponSynced), "OnGearSpawnComplete")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void Post_SetupSynced(BulletWeaponSynced __instance)
		{
			CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				component.SetToSync();
			}
		}

		[HarmonyPatch(typeof(ShotgunSynced), "Fire")]
		[HarmonyPatch(typeof(BulletWeaponSynced), "Fire")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void Pre_FireSynced(BulletWeaponSynced __instance)
		{
			CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				component.Invoke(StaticContext<WeaponPreFireContextSync>.Instance);
			}
		}

		[HarmonyPatch(typeof(ShotgunSynced), "Fire")]
		[HarmonyPatch(typeof(BulletWeaponSynced), "Fire")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void Post_FireSynced(BulletWeaponSynced __instance)
		{
			CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				component.UpdateStoredFireRate();
				component.ModifyFireRate();
				component.Invoke(StaticContext<WeaponPostFireContextSync>.Instance);
			}
		}
	}
	[HarmonyPatch]
	internal static class PlayerLocalPatches
	{
		[HarmonyPatch(typeof(PUI_LocalPlayerStatus), "UpdateHealth")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void UpdateHealth(PUI_LocalPlayerStatus __instance, float health, bool meleeBuffActive)
		{
			if (__instance.m_lastHealthVal <= 0.14f && health > 0.14f && __instance.m_warningRoutine != null)
			{
				__instance.m_healthWarningLooping = true;
			}
		}
	}
}
namespace EWC.Patches.Native
{
	internal static class EnemyDetectionPatches
	{
		private unsafe delegate void d_DetectOnNoise(IntPtr _this, IntPtr agentTarget, float movementDetectionDistance, float shootDetectionDistance, float delta, out float output, Il2CppMethodInfo* methodInfo);

		private struct CWCHolder
		{
			public CustomWeaponComponent? primary;

			public bool hasPrimary;

			public CustomWeaponComponent? special;

			public bool hasSpecial;

			public readonly bool IsValid
			{
				get
				{
					if ((Object)(object)primary != (Object)null == hasPrimary)
					{
						return (Object)(object)special != (Object)null == hasSpecial;
					}
					return false;
				}
			}
		}

		private static INativeDetour? DetectOnNoiseDetour;

		private static d_DetectOnNoise? orig_DetectOnNoise;

		private static readonly Dictionary<int, CWCHolder> s_cachedCWCs = new Dictionary<int, CWCHolder>();

		internal unsafe static void ApplyNativePatch()
		{
			DetectOnNoiseDetour = INativeDetour.CreateAndApply<d_DetectOnNoise>((IntPtr)(nint)Il2CppAPI.GetIl2CppMethod<EnemyDetection>("DetectOnNoiseDistance_Conditional_AnimatedWindow", typeof(void).Name, false, new string[5]
			{
				"AgentTarget",
				typeof(float).Name,
				typeof(float).Name,
				typeof(float).Name,
				typeof(float).MakeByRefType().Name
			}), (d_DetectOnNoise)DetectOnNoisePatch, ref orig_DetectOnNoise);
			NativePatchAPI.AddDetectPostfix(Post_DetectAgentNoise);
		}

		private unsafe static void DetectOnNoisePatch(IntPtr _this, IntPtr agentTarget, float movementDetectionDistance, float shootDetectionDistance, float delta, out float output, Il2CppMethodInfo* methodInfo)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0044: Expected O, but got Unknown
			output = 0f;
			EnemyDetection val = new EnemyDetection(_this);
			AgentTarget agentTarget2 = new AgentTarget(agentTarget);
			if (NativePatchAPI.RunDetectPrefix(val, agentTarget2, movementDetectionDistance, shootDetectionDistance, delta, ref output))
			{
				orig_DetectOnNoise(_this, agentTarget, movementDetectionDistance, shootDetectionDistance, delta, out output, methodInfo);
			}
			NativePatchAPI.RunDetectPostfix(val, agentTarget2, movementDetectionDistance, shootDetectionDistance, delta, ref output);
		}

		private static void UpdateCache()
		{
			if (s_cachedCWCs.Count == PlayerManager.PlayerAgentsInLevel.Count && !s_cachedCWCs.Values.Any((CWCHolder holder) => !holder.IsValid))
			{
				return;
			}
			s_cachedCWCs.Clear();
			Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator();
			PlayerBackpack val = default(PlayerBackpack);
			BackpackItem val2 = default(BackpackItem);
			BackpackItem val3 = default(BackpackItem);
			while (enumerator.MoveNext())
			{
				PlayerAgent current = enumerator.Current;
				if (PlayerBackpackManager.TryGetBackpack(current.Owner, ref val) && val.TryGetBackpackItem((InventorySlot)1, ref val2) && val.TryGetBackpackItem((InventorySlot)2, ref val3))
				{
					Item instance = val2.Instance;
					CustomWeaponComponent customWeaponComponent = ((instance != null) ? ((Component)instance).GetComponent<CustomWeaponComponent>() : null);
					Item instance2 = val3.Instance;
					CustomWeaponComponent customWeaponComponent2 = ((instance2 != null) ? ((Component)instance2).GetComponent<CustomWeaponComponent>() : null);
					s_cachedCWCs.Add(((Agent)current).GlobalID, new CWCHolder
					{
						primary = customWeaponComponent,
						hasPrimary = ((Object)(object)customWeaponComponent != (Object)null),
						special = customWeaponComponent2,
						hasSpecial = ((Object)(object)customWeaponComponent2 != (Object)null)
					});
				}
			}
		}

		private static void Post_DetectAgentNoise(EnemyDetection __instance, AgentTarget agentTarget, float _mv, float _wp, float _delta, ref float output)
		{
			UpdateCache();
			if (s_cachedCWCs.TryGetValue(agentTarget.m_globalID, out var value) && (value.hasPrimary || value.hasSpecial))
			{
				WeaponStealthUpdateContext weaponStealthUpdateContext = new WeaponStealthUpdateContext(__instance.m_ai.m_enemyAgent, __instance.m_noiseDetectionOn, output);
				value.primary?.Invoke(weaponStealthUpdateContext);
				value.special?.Invoke(weaponStealthUpdateContext);
				output = weaponStealthUpdateContext.Output;
			}
		}
	}
}
namespace EWC.Patches.Melee
{
	[HarmonyPatch]
	internal static class MeleePatches
	{
		private static readonly HitData s_hitData = new HitData();

		private static float s_origHitDamage = 0f;

		private static float s_origHitPrecision = 0f;

		public static float CachedCharge { get; private set; } = 0f;


		[HarmonyPatch(typeof(MeleeWeaponFirstPerson), "SetupMeleeAnimations")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void SetupCallback(MeleeWeaponFirstPerson __instance)
		{
			CachedCharge = 0f;
			CustomWeaponManager.Current.AddWeaponListener((ItemEquippable)(object)__instance);
			CustomWeaponData customMeleeData = CustomWeaponManager.Current.GetCustomMeleeData(((GameDataBlockBase<MeleeArchetypeDataBlock>)(object)((ItemEquippable)__instance).MeleeArchetypeData).persistentID);
			if (customMeleeData != null && !((Object)(object)((Component)__instance).gameObject.GetComponent<CustomWeaponComponent>() != (Object)null))
			{
				((Component)__instance).gameObject.AddComponent<CustomWeaponComponent>().Register(customMeleeData);
			}
		}

		[HarmonyPatch(typeof(MeleeWeaponFirstPerson), "OnWield")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void UpdateCurrentWeapon(MeleeWeaponFirstPerson __instance)
		{
			CachedCharge = 0f;
			CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				component.Invoke(StaticContext<WeaponWieldContext>.Instance);
			}
		}

		[HarmonyPatch(typeof(MeleeWeaponFirstPerson), "OnUnWield")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void ClearCharge(MeleeWeaponFirstPerson __instance)
		{
			CachedCharge = 0f;
			CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				component.Invoke(StaticContext<WeaponUnWieldContext>.Instance);
			}
		}

		[HarmonyPatch(typeof(MeleeWeaponFirstPerson), "SetNextDamageToDeal")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void SetDamageCallback(MeleeWeaponFirstPerson __instance, eMeleeWeaponDamage dam, float scale)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			s_origHitDamage = __instance.m_damageToDeal;
			s_origHitPrecision = __instance.m_precisionMultiToDeal;
			CachedCharge = (((int)dam == 2) ? scale : 0f);
		}

		[HarmonyPatch(typeof(MeleeWeaponFirstPerson), "DoAttackDamage")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void HitCallback(MeleeWeaponFirstPerson __instance, MeleeWeaponDamageData data, bool isPush)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Invalid comparison between Unknown and I4
			if (isPush)
			{
				return;
			}
			s_hitData.Setup(__instance, data);
			IDamageable damageable = s_hitData.damageable;
			CustomWeaponComponent component = ((Component)__instance).GetComponent<CustomWeaponComponent>();
			if ((Object)(object)component == (Object)null)
			{
				Agent val = ((damageable != null) ? damageable.GetBaseAgent() : null);
				if ((Object)(object)val != (Object)null && (int)val.Type == 1 && val.Alive)
				{
					KillTrackerManager.ClearHit(((Il2CppObjectBase)val).TryCast<EnemyAgent>());
				}
				WeaponPatches.CachedHitCC = null;
			}
			else
			{
				s_hitData.damage = s_origHitDamage;
				s_hitData.precisionMulti = s_origHitPrecision;
				bool doBackstab = true;
				WeaponPatches.ApplyEWCHit(component, damageable, s_hitData, pierce: false, ref s_origHitDamage, ref doBackstab);
			}
		}
	}
	[HarmonyPatch]
	internal static class MWSPatches
	{
		[HarmonyPatch(typeof(MWS_ChargeUp), "Enter")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void ChargeCallback(MWS_ChargeUp __instance)
		{
			CustomWeaponComponent component = ((Component)((MWS_Base)__instance).m_weapon).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				WeaponFireRateContext weaponFireRateContext = new WeaponFireRateContext(1f);
				component.Invoke(weaponFireRateContext);
				__instance.m_maxDamageTime /= weaponFireRateContext.Value;
			}
		}

		[HarmonyPatch(typeof(MWS_Push), "Enter")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PushCallback(MWS_Push __instance)
		{
			CustomWeaponComponent component = ((Component)((MWS_Base)__instance).m_weapon).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				WeaponFireRateContext weaponFireRateContext = new WeaponFireRateContext(1f);
				component.Invoke(weaponFireRateContext);
				Animator weaponAnimator = ((MWS_Base)__instance).m_weapon.WeaponAnimator;
				weaponAnimator.speed *= weaponFireRateContext.Value;
			}
		}

		[HarmonyPatch(typeof(MWS_AttackSwingBase), "Enter")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PreSwingCallback(MWS_AttackSwingBase __instance)
		{
			CustomWeaponComponent component = ((Component)((MWS_Base)__instance).m_weapon).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				component.Invoke(StaticContext<WeaponPreFireContext>.Instance);
			}
		}

		[HarmonyPatch(typeof(MWS_AttackSwingBase), "Exit")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void PostSwingCallback(MWS_AttackSwingBase __instance)
		{
			CustomWeaponComponent component = ((Component)((MWS_Base)__instance).m_weapon).GetComponent<CustomWeaponComponent>();
			if (!((Object)(object)component == (Object)null))
			{
				component.Invoke(StaticContext<WeaponPostFireContext>.Instance);
			}
		}
	}
}
namespace EWC.Networking
{
	public abstract class SyncedEvent<T> where T : struct
	{
		public delegate void ReceiveHandler(T packet);

		private bool _isSetup;

		public abstract string GUID { get; }

		public bool IsSetup => _isSetup;

		public string EventName { get; private set; } = string.Empty;


		public event ReceiveHandler? OnReceive;

		public event ReceiveHandler? OnReceiveLocal;

		public void Setup()
		{
			if (!_isSetup)
			{
				EventName = "EWC" + GUID;
				NetworkAPI.RegisterEvent<T>(EventName, (Action<ulong, T>)ReceiveClient_Callback);
				_isSetup = true;
			}
		}

		public void Send(T packetData, SNet_Player? target = null, SNet_ChannelType priority = 4)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target != (Object)null)
			{
				NetworkAPI.InvokeEvent<T>(EventName, packetData, target, priority);
			}
			else
			{
				NetworkAPI.InvokeEvent<T>(EventName, packetData, priority);
			}
			ReceiveLocal_Callback(packetData);
		}

		private void ReceiveLocal_Callback(T packet)
		{
			ReceiveLocal(packet);
			this.OnReceiveLocal?.Invoke(packet);
		}

		private void ReceiveClient_Callback(ulong sender, T packet)
		{
			Receive(packet);
			this.OnReceive?.Invoke(packet);
		}

		protected virtual void ReceiveLocal(T packet)
		{
		}

		protected virtual void Receive(T packet)
		{
		}
	}
	public abstract class SyncedEventMasterOnly<T> : SyncedEvent<T> where T : struct
	{
		public void Send(T packet, SNet_ChannelType priority = 4)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (!SNet.IsMaster)
			{
				Send(packet, SNet.Master, priority);
			}
			else
			{
				Receive(packet);
			}
		}
	}
}
namespace EWC.Networking.Structs
{
	public struct LowResColor
	{
		public byte r;

		public byte g;

		public byte b;

		public byte a;

		private static Color s_color = Color.black;

		public static implicit operator Color(LowResColor lowResColor)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			s_color.r = (float)(int)lowResColor.r / 255f;
			s_color.g = (float)(int)lowResColor.g / 255f;
			s_color.b = (float)(int)lowResColor.b / 255f;
			s_color.a = (float)(int)lowResColor.a / 255f;
			return s_color;
		}

		public static implicit operator LowResColor(Color color)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			LowResColor result = default(LowResColor);
			result.r = (byte)(color.r * 255f);
			result.g = (byte)(color.g * 255f);
			result.b = (byte)(color.b * 255f);
			result.a = (byte)(color.a * 255f);
			return result;
		}
	}
}
namespace EWC.JSON
{
	internal static class CustomWeaponTemplate
	{
		internal static CustomWeaponData CreateTemplate()
		{
			return new CustomWeaponData
			{
				ArchetypeID = 0u,
				Name = "Example",
				Properties = new PropertyList(new List<WeaponPropertyBase>
				{
					new AmmoMod(),
					new AmmoRegen(),
					new DamageMod(),
					new DamageModPerTarget(),
					new DamageOverTime(),
					new Explosive(),
					new FireRateMod(),
					new HealthMod(),
					new RecoilMod(),
					new TempProperties(),
					new Accelerate(),
					new AmmoCap(),
					new ArmorPierce(),
					new AutoAim(),
					new AutoTrigger(),
					new BackstabMulti(),
					new BioPing(),
					new DataSwap(),
					new EnforceFireRate(),
					new HoldBurst(),
					new MultiShot(),
					new PierceMulti(),
					new Projectile(),
					new ReserveClip(),
					new Silence(),
					new ThickBullet(),
					new TumorMulti(),
					new WallPierce()
				})
			};
		}
	}
	public static class EWCJson
	{
		private static readonly JsonSerializerOptions _setting;

		static EWCJson()
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			_setting = new JsonSerializerOptions
			{
				ReadCommentHandling = JsonCommentHandling.Skip,
				IncludeFields = true,
				PropertyNameCaseInsensitive = true,
				WriteIndented = true,
				IgnoreReadOnlyProperties = true
			};
			_setting.Converters.Add(new JsonStringEnumConverter());
			_setting.Converters.Add(new TriggerConverter());
			_setting.Converters.Add(new TriggerCoordinatorConverter());
			_setting.Converters.Add(new WeaponPropertyConverter());
			_setting.Converters.Add(new PropertyListConverter());
			_setting.Converters.Add((JsonConverter)new ColorConverter());
			if (PDAPIWrapper.HasPData)
			{
				_setting.Converters.Add(PDAPIWrapper.PersistentIDConverter);
			}
		}

		public static T? Deserialize<T>(string json)
		{
			return JsonSerializer.Deserialize<T>(json, _setting);
		}

		public static T? Deserialize<T>(ref Utf8JsonReader reader)
		{
			return JsonSerializer.Deserialize<T>(ref reader, _setting);
		}

		public static object? Deserialize(Type type, string json)
		{
			return JsonSerializer.Deserialize(json, type, _setting);
		}

		public static string Serialize<T>(T value)
		{
			return JsonSerializer.Serialize(value, _setting);
		}

		public static void Serialize<T>(Utf8JsonWriter writer, T value)
		{
			JsonSerializer.Serialize(writer, value, _setting);
		}
	}
}
namespace EWC.JSON.Converters
{
	public sealed class PropertyListConverter : JsonConverter<PropertyList>
	{
		public override PropertyList Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{
			return new PropertyList(EWCJson.Deserialize<List<WeaponPropertyBase>>(ref reader) ?? throw new JsonException("Unable to deserialize property list"));
		}

		public override void Write(Utf8JsonWriter writer, PropertyList value, JsonSerializerOptions options)
		{
			EWCJson.Serialize(writer, value.Properties);
		}
	}
	public sealed class TriggerConverter : JsonConverter<ITrigger>
	{
		public override ITrigger? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
		{