Decompiled source of SBG Arsenal v1.0.2

BepInEx/plugins/SBG_Arsenal/SBGArsenal.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FMODUnity;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using SBGArsenal.Core;
using SBGArsenal.Items;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Localization;
using UnityEngine.Localization.Components;
using UnityEngine.Localization.Settings;
using UnityEngine.Localization.Tables;
using UnityEngine.SceneManagement;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SBGArsenal
{
	[BepInPlugin("SBGArsenal", "SBGArsenal", "1.0.2")]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		public static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ArsenalConfig.Attach(((BaseUnityPlugin)this).Config);
			Registry.Add(new SuicideVestItem());
			Registry.Add(new GravityClubItem());
			Registry.Add(new SliceDriverItem());
			Registry.Add(new EagleEyeItem());
			Registry.Add(new ShadowCloneItem());
			Registry.Add(new MulliganItem());
			_harmony = new Harmony("SBGArsenal");
			ApplyPatches();
			Log.LogInfo((object)"SBGArsenal 1.0.2 loaded.");
		}

		private void ApplyPatches()
		{
			int num = 0;
			int num2 = 0;
			Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(Plugin).Assembly);
			foreach (Type type in typesFromAssembly)
			{
				if (type.GetCustomAttributes(typeof(HarmonyAttribute), inherit: true).Length != 0)
				{
					num++;
					try
					{
						_harmony.CreateClassProcessor(type).Patch();
						num2++;
					}
					catch (Exception arg)
					{
						Log.LogWarning((object)("Patch class " + type.FullName + " did not apply, the features " + $"it backs are disabled: {arg}"));
					}
				}
			}
			Log.LogInfo((object)$"Applied {num2} of {num} patch classes.");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "SBGArsenal";

		public const string PLUGIN_NAME = "SBGArsenal";

		public const string PLUGIN_VERSION = "1.0.2";
	}
}
namespace SBGArsenal.Patches
{
	public static class HitPatches
	{
		[HarmonyPatch(typeof(PlayerMovement), "OnLocalPlayerWillApplyItemHitPhysics")]
		public static class PlayerHitPatch
		{
			[HarmonyPrefix]
			private static bool Prefix(PlayerMovement __instance, PlayerInventory itemUser, ItemType itemType, ItemUseId itemUseId, Vector3 localOrigin, float distance, Vector3 incomingVelocityChange, bool isReflected, bool isInSpecialState, ProtectiveState protectiveState)
			{
				//IL_0000: 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_0020: 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_002c: 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_0049: 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_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_008a: Unknown result type (might be due to invalid IL or missing references)
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0091: Unknown result type (might be due to invalid IL or missing references)
				//IL_0099: Unknown result type (might be due to invalid IL or missing references)
				//IL_009b: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Unknown result type (might be due to invalid IL or missing references)
				ArsenalItem arsenalItem = Registry.Get(itemType);
				if (arsenalItem == null || !arsenalItem.DealsHits)
				{
					return true;
				}
				Vector3 val = arsenalItem.Knockback.VelocityFor(-localOrigin, distance);
				PlayerInfo val2 = (((Object)(object)itemUser != (Object)null) ? itemUser.PlayerInfo : null);
				bool flag = default(bool);
				bool flag2 = default(bool);
				__instance.TryKnockOut(val2, arsenalItem.KnockoutType, false, localOrigin, distance, val, (ElectromagnetShieldHitBlockType)0, itemUseId, isInSpecialState, true, ref flag, ref flag2);
				if (!flag && __instance.PlayerInfo.IsElectromagnetShieldActive)
				{
					Vector3 position = ((Component)__instance.PlayerInfo.ElectromagnetShieldCollider).transform.position;
					Vector3 val3 = ((Component)__instance).transform.TransformPoint(localOrigin);
					__instance.PlayerInfo.PlayElectromagnetShieldHitForAllClients(val3 - position, false);
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Hittable), "HitWithItemInternal")]
		public static class HittablePatch
		{
			[HarmonyPostfix]
			private static void Postfix(Hittable __instance, ItemType itemType, Vector3 hitLocalPosition, Vector3 direction, float distance, PlayerInventory itemUser, bool canHitWithNoUser)
			{
				//IL_0000: 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)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: 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_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: 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)
				ArsenalItem arsenalItem = Registry.Get(itemType);
				if (arsenalItem != null && arsenalItem.DealsHits && (canHitWithNoUser || !((Object)(object)itemUser == (Object)null)) && __instance.CanApplyPhysics())
				{
					Vector3 val = arsenalItem.Knockback.VelocityFor(direction, distance);
					Vector3 val2 = ((Component)__instance).transform.TransformPoint(hitLocalPosition);
					__instance.AsEntity.Rigidbody.AddForceAtPosition(val, val2, (ForceMode)2);
				}
			}
		}
	}
	[HarmonyPatch(typeof(PlayerMovement), "TryKnockOut")]
	public static class TryKnockOutPatch
	{
		[HarmonyPostfix]
		private static void Postfix(PlayerMovement __instance, bool __result, ref bool isNewKnockout)
		{
			if (__result && isNewKnockout && ((NetworkBehaviour)__instance).isLocalPlayer)
			{
				VestFuse.OnWearerKnockedOut();
			}
		}
	}
	public static class MatchSetupRulesPatches
	{
		[HarmonyPatch(typeof(MatchSetupRules), "Initialize")]
		public static class Initialize_Patch
		{
			[HarmonyPostfix]
			private static void Postfix(MatchSetupRules __instance)
			{
				//IL_002f: 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_00c8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ce: Expected I4, but got Unknown
				//IL_0119: 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_0172: Unknown result type (might be due to invalid IL or missing references)
				//IL_020a: 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_021c: Unknown result type (might be due to invalid IL or missing references)
				//IL_022b: Unknown result type (might be due to invalid IL or missing references)
				ArsenalItem[] activeArray = Registry.ActiveArray;
				if (activeArray.Length == 0)
				{
					return;
				}
				ItemSpawnerSettings itemSpawnerSettings = __instance.itemSpawnerSettings;
				InjectIntoPool(itemSpawnerSettings.aheadOfBallItemPool, activeArray);
				foreach (ItemPoolData itemPool in itemSpawnerSettings.itemPools)
				{
					InjectIntoPool(itemPool.pool, activeArray);
				}
				InjectIntoPool(itemSpawnerSettings.AheadOfBallItemPool, activeArray);
				foreach (ItemPoolData itemPool2 in itemSpawnerSettings.ItemPools)
				{
					InjectIntoPool(itemPool2.pool, activeArray);
				}
				ItemType[] itemOrder = __instance.itemOrder;
				int num = itemOrder.Length;
				ItemType[] array = (ItemType[])(object)new ItemType[num + activeArray.Length];
				Array.Copy(itemOrder, array, num);
				for (int i = 0; i < activeArray.Length; i++)
				{
					array[num + i] = (ItemType)(int)activeArray[i].ItemType;
				}
				__instance.itemOrder = array;
				int[] itemOrderLookup = __instance.itemOrderLookup;
				int[] array2 = new int[Math.Max(itemOrderLookup.Length, Registry.MaxItemId + 1)];
				Array.Copy(itemOrderLookup, array2, itemOrderLookup.Length);
				for (int j = 0; j < activeArray.Length; j++)
				{
					array2[activeArray[j].ItemType - 1] = num + j;
				}
				__instance.itemOrderLookup = array2;
				ArsenalItem[] array3 = activeArray;
				foreach (ArsenalItem arsenalItem in array3)
				{
					GameObject val = Object.Instantiate<GameObject>(__instance.itemPrefab);
					val.transform.SetParent((Transform)(object)__instance.itemsParent);
					val.transform.localScale = Vector3.one;
					__instance.spawnChanceSliders.Add(val.GetComponentInChildren<SliderOption>());
					LocalizeStringEvent componentInChildren = val.GetComponentInChildren<LocalizeStringEvent>();
					if ((Object)(object)componentInChildren != (Object)null)
					{
						((Behaviour)componentInChildren).enabled = false;
					}
					TMP_Text componentInChildren2 = val.GetComponentInChildren<TMP_Text>();
					if ((Object)(object)componentInChildren2 != (Object)null)
					{
						componentInChildren2.text = arsenalItem.DisplayName;
					}
				}
				if (((NetworkBehaviour)__instance).isServer)
				{
					int num2 = 1 + itemSpawnerSettings.ItemPools.Count;
					for (int l = 0; l < num2; l++)
					{
						array3 = activeArray;
						foreach (ArsenalItem arsenalItem2 in array3)
						{
							ItemPoolId val2 = ItemPoolId.Get(l, arsenalItem2.ItemType);
							if (!((SyncIDictionary<ItemPoolId, float>)(object)__instance.spawnChanceWeights).ContainsKey(val2))
							{
								((SyncIDictionary<ItemPoolId, float>)(object)__instance.spawnChanceWeights)[val2] = arsenalItem2.SpawnWeight;
							}
						}
					}
				}
				InitializeSliders(__instance, activeArray);
				if (!_watchingConfig)
				{
					_watchingConfig = true;
					ArsenalConfig.SpawnWeightChanged += ApplyConfiguredSpawnWeight;
				}
			}
		}

		[HarmonyPatch(typeof(MatchSetupRules), "ServerUpdateSpawnChanceValue")]
		public static class ServerUpdateSpawnChanceValue_Patch
		{
			[HarmonyPostfix]
			private static void Postfix(MatchSetupRules __instance, ItemPoolId itemPoolRef)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				if (((NetworkBehaviour)__instance).isServer && itemPoolRef.itemPoolIndex == 0)
				{
					__instance.itemSpawnerSettings.AheadOfBallItemPool.UpdateTotalWeight();
				}
			}
		}

		private static bool _watchingConfig;

		private static void InjectIntoPool(ItemPool pool, ArsenalItem[] items)
		{
			//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_0026: 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)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)pool == (Object)null)
			{
				return;
			}
			ItemSpawnChance[] spawnChances = pool.SpawnChances;
			ItemSpawnChance[] array = spawnChances;
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i].item == items[0].ItemType)
				{
					return;
				}
			}
			ItemSpawnChance[] array2 = (ItemSpawnChance[])(object)new ItemSpawnChance[spawnChances.Length + items.Length];
			Array.Copy(spawnChances, array2, spawnChances.Length);
			for (int j = 0; j < items.Length; j++)
			{
				array2[spawnChances.Length + j] = new ItemSpawnChance
				{
					item = items[j].ItemType,
					spawnChanceWeight = items[j].SpawnWeight
				};
			}
			pool.spawnChances = array2;
			pool.UpdateTotalWeight();
		}

		private static void ApplyConfiguredSpawnWeight(string section)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			ArsenalItem[] activeArray = Registry.ActiveArray;
			if (activeArray.Length == 0)
			{
				return;
			}
			MatchSetupRules instance = SingletonNetworkBehaviour<MatchSetupRules>.Instance;
			if (!((Object)(object)instance != (Object)null) || instance.itemOrderLookup == null || instance.itemOrderLookup.Length <= Registry.MaxItemId)
			{
				Plugin.Log.LogInfo((object)(section + " spawn weight changed; it will be used from the next match setup."));
				return;
			}
			ItemSpawnerSettings itemSpawnerSettings = instance.itemSpawnerSettings;
			ArsenalItem[] array = activeArray;
			foreach (ArsenalItem item in array)
			{
				SetPoolWeight(itemSpawnerSettings.aheadOfBallItemPool, item);
				foreach (ItemPoolData itemPool in itemSpawnerSettings.itemPools)
				{
					SetPoolWeight(itemPool.pool, item);
				}
			}
			if (!((NetworkBehaviour)instance).isServer)
			{
				Plugin.Log.LogInfo((object)(section + " spawn weight changed; the host decides spawn weights, so it only applies to lobbies you host."));
				return;
			}
			int num = 1 + itemSpawnerSettings.ItemPools.Count;
			for (int j = 0; j < num; j++)
			{
				array = activeArray;
				foreach (ArsenalItem arsenalItem in array)
				{
					((SyncIDictionary<ItemPoolId, float>)(object)instance.spawnChanceWeights)[ItemPoolId.Get(j, arsenalItem.ItemType)] = arsenalItem.SpawnWeight;
				}
			}
			Plugin.Log.LogInfo((object)(section + " spawn weight changed; applied to the current match setup."));
		}

		private static void SetPoolWeight(ItemPool pool, ArsenalItem item)
		{
			//IL_001c: 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)
			if ((Object)(object)pool == (Object)null)
			{
				return;
			}
			ItemSpawnChance[] spawnChances = pool.SpawnChances;
			for (int i = 0; i < spawnChances.Length; i++)
			{
				if (spawnChances[i].item == item.ItemType)
				{
					spawnChances[i].spawnChanceWeight = item.SpawnWeight;
					pool.UpdateTotalWeight();
					break;
				}
			}
		}

		private static void InitializeSliders(MatchSetupRules rules, ArsenalItem[] items)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_00d4: 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)
			SyncDictionary<ItemPoolId, float> weights = rules.spawnChanceWeights;
			int currentItemPoolIndex = rules.currentItemPoolIndex;
			rules.isPresetSuppressed = true;
			try
			{
				foreach (ArsenalItem arsenalItem in items)
				{
					ItemType itemType = arsenalItem.ItemType;
					int index = rules.itemOrderLookup[itemType - 1];
					SliderOption slider = rules.spawnChanceSliders[index];
					ItemPoolId val = ItemPoolId.Get(currentItemPoolIndex, itemType);
					float num = (((SyncIDictionary<ItemPoolId, float>)(object)weights).ContainsKey(val) ? (((SyncIDictionary<ItemPoolId, float>)(object)weights)[val] / 100f) : 0f);
					slider.Initialize((Action)delegate
					{
						//IL_0067: 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)
						slider.valueWithoutNotify = Mathf.Round(slider.value / 0.025f) * 0.025f;
						float num2 = slider.value * 100f;
						if (((NetworkBehaviour)rules).isServer)
						{
							((SyncIDictionary<ItemPoolId, float>)(object)weights)[ItemPoolId.Get(rules.currentItemPoolIndex, itemType)] = num2;
							rules.SetPreset((Preset)2);
						}
					}, num);
					if (((NetworkBehaviour)rules).isServer)
					{
						rules.ServerUpdateSpawnChanceValue(ItemPoolId.Get(currentItemPoolIndex, itemType));
					}
				}
			}
			finally
			{
				rules.isPresetSuppressed = false;
				rules.currentItemPoolDirty = true;
			}
		}
	}
	public static class NetworkPatches
	{
		[HarmonyPatch(typeof(BNetworkManager), "OnStartServer")]
		public static class OnStartServer_Patch
		{
			[HarmonyPostfix]
			private static void Postfix()
			{
				Net.RegisterServerHandlers();
			}
		}

		[HarmonyPatch(typeof(BNetworkManager), "OnStartClient")]
		public static class OnStartClient_Patch
		{
			[HarmonyPostfix]
			private static void Postfix()
			{
				Net.RegisterClientHandlers();
			}
		}

		[HarmonyPatch(typeof(BNetworkManager), "OnStopServer")]
		public static class OnStopServer_Patch
		{
			[HarmonyPostfix]
			private static void Postfix()
			{
				ShadowClone.ClearAll();
			}
		}

		[HarmonyPatch(typeof(BNetworkManager), "OnStopClient")]
		public static class OnStopClient_Patch
		{
			[HarmonyPostfix]
			private static void Postfix()
			{
				ShadowClone.ClearAll();
			}
		}
	}
	[HarmonyPatch]
	public static class PlayerInputPatches
	{
		private static readonly MethodInfo EquippedItemGetter = AccessTools.Method(typeof(PlayerInventory), "GetEffectivelyEquippedItem", (Type[])null, (Type[])null);

		private static readonly MethodInfo SensitivityFactorGetter = typeof(ItemSettings).GetProperty("RailgunZoomCameraSensitivityFactor")?.GetGetMethod();

		private static EagleEyeItem _scopedRifle;

		private static MethodBase TargetMethod()
		{
			return typeof(PlayerInput).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic).FirstOrDefault((MethodInfo method) => method.Name.Contains("UpdateCameraInput"));
		}

		private static bool Prepare(MethodBase original)
		{
			if (EquippedItemGetter != null && SensitivityFactorGetter != null && (original != null || TargetMethod() != null))
			{
				return true;
			}
			Plugin.Log.LogWarning((object)"Could not find the camera input method; scoped aim will keep hip-fire sensitivity.");
			return false;
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			int num = -1;
			int num2 = -1;
			for (int i = 0; i < list.Count; i++)
			{
				if (num < 0 && Calls(list[i], EquippedItemGetter) && i + 1 < list.Count && LoadsItemType(list[i + 1], (ItemType)16))
				{
					num = i;
				}
				if (num2 < 0 && Calls(list[i], SensitivityFactorGetter))
				{
					num2 = i;
				}
			}
			if (num < 0 || num2 <= num)
			{
				Plugin.Log.LogWarning((object)"PlayerInput's railgun zoom check did not match; scoped aim will keep hip-fire sensitivity.");
				return list;
			}
			list.Insert(num2 + 1, new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PlayerInputPatches), "ScaleForMagnification", (Type[])null, (Type[])null)));
			list.Insert(num + 1, new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PlayerInputPatches), "MapToRailgun", (Type[])null, (Type[])null)));
			return list;
		}

		private static bool Calls(CodeInstruction instruction, MethodInfo method)
		{
			if (instruction.opcode != OpCodes.Call && instruction.opcode != OpCodes.Callvirt)
			{
				return false;
			}
			return instruction.operand as MethodInfo == method;
		}

		private static bool LoadsItemType(CodeInstruction instruction, ItemType itemType)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Invalid comparison between I4 and Unknown
			if (instruction.opcode != OpCodes.Ldc_I4_S && instruction.opcode != OpCodes.Ldc_I4)
			{
				return false;
			}
			if (instruction.operand is IConvertible convertible)
			{
				return convertible.ToInt32(CultureInfo.InvariantCulture) == (int)itemType;
			}
			return false;
		}

		public static ItemType MapToRailgun(ItemType equipped)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			_scopedRifle = Registry.Get(equipped) as EagleEyeItem;
			if (_scopedRifle == null)
			{
				return equipped;
			}
			return (ItemType)16;
		}

		public static float ScaleForMagnification(float railgunFactor)
		{
			float magnification = ScopeZoom.Magnification;
			if (_scopedRifle == null || magnification <= 0f)
			{
				return railgunFactor;
			}
			return _scopedRifle.ScopeSensitivity / magnification;
		}
	}
	[HarmonyPatch(typeof(PlayerInventory))]
	public static class PlayerInventoryPatches
	{
		[HarmonyPatch]
		public static class FirstPersonAimPatch
		{
			private static MethodBase TargetMethod()
			{
				return typeof(PlayerInventory).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic).FirstOrDefault((MethodInfo method) => method.Name.Contains("ShouldBeInFirstPersonAim"));
			}

			private static bool Prepare(MethodBase original)
			{
				if (original != null || TargetMethod() != null)
				{
					return true;
				}
				Plugin.Log.LogWarning((object)"Could not find the first-person aim check; the rifle will aim without a scope.");
				return false;
			}

			[HarmonyPostfix]
			private static void Postfix(PlayerInventory __instance, ref bool __result)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: 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_0041: Invalid comparison between Unknown and I4
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0045: Invalid comparison between Unknown and I4
				if (!__result && Registry.Get(__instance.GetEffectivelyEquippedItem(true)) is EagleEyeItem && __instance.IsAimingItem && __instance.PlayerInfo.Input.IsHoldingAimSwing)
				{
					ItemUseType currentItemUse = __instance.CurrentItemUse;
					if ((int)currentItemUse == 0 || (int)currentItemUse == 3 || (int)currentItemUse == 4)
					{
						__result = true;
					}
				}
			}
		}

		private static double _dropRefusedTimestamp = double.MinValue;

		private const float DropRefusalCooldown = 3f;

		[HarmonyPatch("TryUseItem")]
		[HarmonyPrefix]
		private static bool TryUseItem_Prefix(PlayerInventory __instance, bool isAirhornReaction, ref bool shouldEatInput, ref bool __result)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!((NetworkBehaviour)__instance).isLocalPlayer)
			{
				return true;
			}
			ArsenalItem arsenalItem = Registry.Get(__instance.GetEffectiveSlot(__instance.EquippedItemIndex).itemType);
			if (arsenalItem == null)
			{
				return true;
			}
			InventorySlot val = default(InventorySlot);
			ItemData val2 = default(ItemData);
			bool flag = default(bool);
			if (!__instance.CanUseEquippedItem(false, isAirhornReaction, ref val, ref val2, ref shouldEatInput, ref flag))
			{
				__result = false;
				return false;
			}
			if (arsenalItem.DealsHits)
			{
				__instance.PlayerInfo.LocalPlayerCancelSmokeBombInvisibility();
			}
			__instance.ItemUseTimestamp = Time.timeAsDouble;
			__instance.CancelItemUse();
			__instance.itemUseRoutine = ((MonoBehaviour)__instance).StartCoroutine(arsenalItem.Use(__instance));
			__instance.PlayerInfo.CancelEmote(false);
			__instance.CancelItemFlourish();
			shouldEatInput = false;
			__result = true;
			return false;
		}

		[HarmonyPatch("DropItem")]
		[HarmonyPrefix]
		private static bool DropItem_Prefix(PlayerInventory __instance)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!((NetworkBehaviour)__instance).isLocalPlayer)
			{
				return true;
			}
			ArsenalItem arsenalItem = Registry.Get(__instance.GetEffectiveSlot(__instance.EquippedItemIndex).itemType);
			if (arsenalItem == null)
			{
				return true;
			}
			if (Time.timeAsDouble - _dropRefusedTimestamp >= 3.0)
			{
				_dropRefusedTimestamp = Time.timeAsDouble;
				string text = arsenalItem.DisplayName + " cannot be dropped: use it or lose it.";
				UiSettings uiSettings = GameManager.UiSettings;
				TextChatUi.ShowMessage(((Object)(object)uiSettings != (Object)null) ? uiSettings.ApplyColorTag(text, (TextHighlight)1) : text);
			}
			return false;
		}

		[HarmonyPatch("UpdateIsUpdateLoopRunning")]
		[HarmonyPrefix]
		private static bool UpdateIsUpdateLoopRunning_Prefix(PlayerInventory __instance)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			if (!((NetworkBehaviour)__instance).isLocalPlayer)
			{
				return true;
			}
			ArsenalItem arsenalItem = Registry.Get(__instance.GetEffectivelyEquippedItem(true));
			if (arsenalItem == null || !arsenalItem.IsAimed)
			{
				return true;
			}
			bool isUpdateLoopRunning = __instance.isUpdateLoopRunning;
			bool flag = (__instance.isUpdateLoopRunning = __instance.IsAimingItem);
			if (flag != isUpdateLoopRunning)
			{
				LockOnTargetUiManager.ClearTargets();
				__instance.ClearItemTargets();
				__instance.LocalPlayerSetLockOnTarget((LockOnTarget)null);
				if (flag)
				{
					BUpdate.RegisterCallback((IAnyBUpdateCallback)(object)__instance, (BUpdateLoopType)1);
				}
				else
				{
					BUpdate.DeregisterCallback((IAnyBUpdateCallback)(object)__instance, (BUpdateLoopType)1);
				}
			}
			return false;
		}

		[HarmonyPatch("LocalPlayerUpdateEquipmentSwitchers")]
		[HarmonyPostfix]
		private static void LocalPlayerUpdateEquipmentSwitchers_Postfix(PlayerInventory __instance)
		{
			//IL_0002: 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)
			ArsenalItem arsenalItem = Registry.Get(__instance.GetEffectivelyEquippedItem(false));
			if (arsenalItem != null)
			{
				__instance.PlayerInfo.RightHandEquipmentSwitcher.SetEquipment(arsenalItem.EquipmentType);
				__instance.PlayerInfo.LeftHandEquipmentSwitcher.SetEquipment((EquipmentType)0);
				if (((NetworkBehaviour)__instance).isLocalPlayer && arsenalItem is EagleEyeItem rifle)
				{
					ScopeZoom.EnsureOn(__instance, rifle);
				}
			}
		}
	}
	[HarmonyPatch(typeof(ItemCollection))]
	public static class ItemCollectionPatches
	{
		[HarmonyPatch("TryGetItemData")]
		[HarmonyPostfix]
		private static void TryGetItemData_Postfix(ItemType itemType, ref ItemData itemData, ref bool __result)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (!__result)
			{
				ArsenalItem arsenalItem = Registry.Get(itemType);
				if (arsenalItem != null)
				{
					itemData = arsenalItem.ItemData;
					__result = true;
				}
			}
		}

		[HarmonyPatch("GetItemIcon")]
		[HarmonyPrefix]
		private static bool GetItemIcon_Prefix(ItemType itemType, ref Sprite __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			ArsenalItem arsenalItem = Registry.Get(itemType);
			if (arsenalItem == null)
			{
				return true;
			}
			__result = arsenalItem.Icon;
			return false;
		}
	}
	[HarmonyPatch(typeof(EquipmentCollection))]
	public static class EquipmentCollectionPatches
	{
		[HarmonyPatch("TryGetEquipmentSettings")]
		[HarmonyPostfix]
		private static void TryGetEquipmentSettings_Postfix(EquipmentType type, ref EquipmentSettings equipmentSettings, ref bool __result)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (!__result)
			{
				ArsenalItem arsenalItem = Registry.Get(type);
				if (arsenalItem != null)
				{
					equipmentSettings = arsenalItem.EquipmentSettings;
					__result = true;
				}
			}
		}
	}
	[HarmonyPatch(typeof(EquipmentManager))]
	public static class EquipmentManagerPatches
	{
		[HarmonyPatch("GetUnusedEquipmentInternal")]
		[HarmonyPrefix]
		private static bool GetUnusedEquipmentInternal_Prefix(EquipmentType type, ref Equipment __result)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			ArsenalItem arsenalItem = Registry.Get(type);
			if (arsenalItem == null)
			{
				return true;
			}
			__result = arsenalItem.CloneEquipment();
			return false;
		}
	}
	[HarmonyPatch(typeof(ItemTypeExtensions))]
	public static class ItemTypeExtensionsPatches
	{
		[HarmonyPatch("TryGetEliminationReason")]
		[HarmonyPostfix]
		private static void TryGetEliminationReason_Postfix(ItemType itemType, float distance, bool isReflected, ref EliminationReason eliminationReason, ref bool __result)
		{
			//IL_0006: 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: Expected I4, but got Unknown
			if (!__result)
			{
				ArsenalItem arsenalItem = Registry.Get(itemType);
				if (arsenalItem != null)
				{
					eliminationReason = (EliminationReason)(int)arsenalItem.EliminationReason;
					__result = true;
				}
			}
		}
	}
}
namespace SBGArsenal.Items
{
	public class EagleEyeItem : ArsenalItem
	{
		private readonly ConfigEntry<bool> _enabled;

		private readonly ConfigEntry<float> _spawnWeight;

		private readonly ConfigEntry<int> _maxUses;

		private readonly ConfigEntry<float> _range;

		private readonly ConfigEntry<float> _chamberTime;

		private readonly ConfigEntry<float> _knockbackSpeed;

		private readonly ConfigEntry<float> _minFov;

		private readonly ConfigEntry<float> _maxFov;

		private readonly ConfigEntry<float> _zoomStep;

		private readonly ConfigEntry<float> _zoomInTime;

		private readonly ConfigEntry<bool> _rememberZoom;

		private readonly ConfigEntry<bool> _scopedOnly;

		private readonly ConfigEntry<float> _hipFireInaccuracy;

		private readonly ConfigEntry<float> _scopeSensitivity;

		public override ItemType ItemType => ArsenalIds.Sniper;

		public override EquipmentType EquipmentType => ArsenalIds.SniperEquip;

		public override string DisplayName => "Eagle Eye";

		public override Color Tint => new Color(0.25f, 0.27f, 0.3f);

		public override bool Enabled => _enabled.Value;

		public override float SpawnWeight => _spawnWeight.Value;

		public override int MaxUses => _maxUses.Value;

		public override bool DealsHits => true;

		public override bool IsAimed => true;

		public override ItemNonAimingUse NonAimUse
		{
			get
			{
				if (_scopedOnly.Value)
				{
					return (ItemNonAimingUse)0;
				}
				return (ItemNonAimingUse)2;
			}
		}

		public float MinFov => _minFov.Value;

		public float MaxFov => _maxFov.Value;

		public float ZoomStep => _zoomStep.Value;

		public float ZoomInTime => _zoomInTime.Value;

		public bool RememberZoom => _rememberZoom.Value;

		public float ScopeSensitivity => _scopeSensitivity.Value;

		public override float BallSwingPower => 1f;

		public override KnockoutType KnockoutType => (KnockoutType)26;

		public override EliminationReason EliminationReason => (EliminationReason)34;

		public override Knockback Knockback => new Knockback
		{
			MinDistance = 0f,
			MaxDistance = _range.Value,
			MinSpeed = _knockbackSpeed.Value,
			MaxSpeed = _knockbackSpeed.Value,
			MinUpwardSpeed = 6f
		};

		public override EquipmentType BorrowModelFrom => (EquipmentType)5;

		public override float BorrowedModelScale => 1f;

		public EagleEyeItem()
		{
			_enabled = ArsenalConfig.Bind("Eagle Eye", "Enabled", defaultValue: true, "Add the Eagle Eye rifle to the game.");
			_spawnWeight = ArsenalConfig.Bind("Eagle Eye", "SpawnWeight", 4f, "Default item-box weight, before the host's slider.");
			_maxUses = ArsenalConfig.Bind("Eagle Eye", "MaxUses", 2, "Rounds per pickup.");
			_range = ArsenalConfig.Bind("Eagle Eye", "Range", 400f, "Maximum shot distance in metres.");
			_chamberTime = ArsenalConfig.Bind("Eagle Eye", "ChamberTime", 1.6f, "Seconds of re-chamber after each shot.");
			_knockbackSpeed = ArsenalConfig.Bind("Eagle Eye", "KnockbackSpeed", 34f, "How hard a hit player is thrown.");
			_minFov = ArsenalConfig.Bind("Eagle Eye", "MinFov", 4f, "Field of view at maximum magnification. Smaller is more zoomed in.");
			_maxFov = ArsenalConfig.Bind("Eagle Eye", "MaxFov", 38f, "Field of view when the rifle is first shouldered.");
			_zoomStep = ArsenalConfig.Bind("Eagle Eye", "ZoomStep", 4f, "Degrees of field of view per scroll-wheel notch.");
			_zoomInTime = ArsenalConfig.Bind("Eagle Eye", "ZoomInTime", 0.1f, "Seconds the scope takes to reach its magnification when the rifle is shouldered, and to follow the scroll wheel afterwards. Zero snaps the sight picture in. The shot is aimed from the scope's own view either way, so quick-scoping is accurate whatever this is set to.");
			_rememberZoom = ArsenalConfig.Bind("Eagle Eye", "RememberZoom", defaultValue: true, "Come back up at the magnification the scope was last wound to, instead of starting wide every time. Quick-scoping wants this on; off is the slower, more deliberate rifle.");
			_scopedOnly = ArsenalConfig.Bind("Eagle Eye", "ScopedOnly", defaultValue: true, "Only fire with the scope up. A click that beats the scope by a frame is held by the game's input buffer and goes off as soon as the rifle is shouldered, so quick-scoping costs nothing; turn this off to allow hip fire as well. Read once, when the item is registered, so it applies from the next launch.");
			_hipFireInaccuracy = ArsenalConfig.Bind("Eagle Eye", "HipFireInaccuracy", 7f, "Maximum degrees a shot can wander when it is fired from the hip, which only happens with ScopedOnly off. Shots taken through the scope never wander, however early they are.");
			_scopeSensitivity = ArsenalConfig.Bind("Eagle Eye", "ScopeSensitivity", 1f, "Aim sensitivity while scoped, at 1x magnification and as a fraction of the normal rate. The scope divides this by the current magnification, so winding the zoom in slows the aim with it.");
		}

		public override IEnumerator Use(PlayerInventory inventory)
		{
			PlayerInfo playerInfo = inventory.PlayerInfo;
			bool num = inventory.IsInFirstPersonAim || inventory.IsAimingItem;
			Vector3 muzzlePosition = GetMuzzlePosition(inventory);
			Ray viewRay;
			Vector3 val = ResolveAimPoint(inventory, muzzlePosition, out viewRay);
			Vector3 val2 = ((Component)inventory).transform.position + ((Component)inventory).transform.up * 1.5f;
			if (BMath.Abs(FloatExtensions.WrapAngleDeg(VectorExtensions.GetYawDeg(val - val2) - VectorExtensions.GetYawDeg(((Component)inventory).transform.forward))) > 45f)
			{
				playerInfo.Movement.AlignWithCameraImmediately();
				muzzlePosition = GetMuzzlePosition(inventory);
			}
			Vector3 val3 = val - muzzlePosition;
			Vector3 val4 = ((((Vector3)(ref val3)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref val3)).normalized : ((Ray)(ref viewRay)).direction);
			if (!num && _hipFireInaccuracy.Value > 0f)
			{
				val4 = VectorExtensions.RandomlyRotatedDeg(val4, _hipFireInaccuracy.Value);
			}
			inventory.SetCurrentItemUse((ItemUseType)1);
			ItemUseId itemUseId = inventory.IncrementAndGetCurrentItemUseId(ItemType);
			int num2 = Physics.RaycastNonAlloc(muzzlePosition, val4, PlayerGolfer.raycastHitBuffer, _range.Value, LayerMask.op_Implicit(GameManager.LayerSettings.GunHittablesMask), (QueryTriggerInteraction)1);
			RaycastHit val5 = default(RaycastHit);
			Hittable val6 = default(Hittable);
			bool num3 = inventory.TryParseFirearmRaycastResults(PlayerGolfer.raycastHitBuffer, num2, (PlayerInfo)null, ref val5, ref val6);
			playerInfo.PlayerAudio.PlayElephantGunShotForAllClients();
			if (!num3)
			{
				Vector3 val7 = muzzlePosition + val4 * _range.Value;
				VfxManager.PlayElephantGunMissForAllClients(inventory, val4);
				playerInfo.PlayerAudio.PlayRegularBulletWhizzForAllClients((ItemType)3, (Hittable)null, Vector3.zero, val7);
			}
			else
			{
				bool flag = (Object)(object)val6 != (Object)null && inventory.CanHitWithGunshot(val6, (PlayerInfo)null);
				Vector3 val8 = (flag ? ((Component)val6).transform.InverseTransformPoint(((RaycastHit)(ref val5)).point) : Vector3.zero);
				VfxManager.PlayElephantGunHitForAllClients(inventory, new GunShotHitVfxData(flag ? val6 : null, false, val8, ((RaycastHit)(ref val5)).point));
				playerInfo.PlayerAudio.PlayRegularBulletWhizzForAllClients((ItemType)3, flag ? val6 : null, val8, ((RaycastHit)(ref val5)).point);
				if (flag)
				{
					Blast.Hit(this, inventory, val6, muzzlePosition, itemUseId);
				}
			}
			inventory.DecrementUseFromSlotAt(inventory.EquippedItemIndex);
			yield return (object)new WaitForSeconds(_chamberTime.Value);
			inventory.SetCurrentItemUse((ItemUseType)0);
			inventory.RemoveIfOutOfUses(inventory.EquippedItemIndex, true);
		}

		private static Vector3 GetMuzzlePosition(PlayerInventory inventory)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0030: 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)
			EquipmentSwitcher rightHandEquipmentSwitcher = inventory.PlayerInfo.RightHandEquipmentSwitcher;
			if ((Object)(object)rightHandEquipmentSwitcher == (Object)null)
			{
				return ((Component)inventory).transform.position + ((Component)inventory).transform.up * 1.5f;
			}
			return ((Component)rightHandEquipmentSwitcher).transform.TransformPoint(GameManager.ItemSettings.ElephantGunLocalBarrelEnd);
		}

		private Vector3 ResolveAimPoint(PlayerInventory inventory, Vector3 muzzle, out Ray viewRay)
		{
			//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_000c: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_005a: 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_006f: 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_00d2: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			viewRay = GetViewRay();
			int num = Physics.RaycastNonAlloc(((Ray)(ref viewRay)).origin, ((Ray)(ref viewRay)).direction, PlayerGolfer.raycastHitBuffer, _range.Value, LayerMask.op_Implicit(GameManager.LayerSettings.GunHittablesMask), (QueryTriggerInteraction)1);
			float num2 = float.MaxValue;
			Vector3 result = ((Ray)(ref viewRay)).origin + ((Ray)(ref viewRay)).direction * _range.Value;
			PlayerInventory val2 = default(PlayerInventory);
			for (int i = 0; i < num; i++)
			{
				RaycastHit val = PlayerGolfer.raycastHitBuffer[i];
				if (!(((RaycastHit)(ref val)).distance >= num2) && !(Vector3.Dot(((RaycastHit)(ref val)).point - muzzle, ((Ray)(ref viewRay)).direction) <= 0f) && (!ComponentExtensions.TryGetComponentInParent<PlayerInventory>((Component)(object)((RaycastHit)(ref val)).collider, ref val2, true) || !((Object)(object)val2 == (Object)(object)inventory)))
				{
					num2 = ((RaycastHit)(ref val)).distance;
					result = ((RaycastHit)(ref val)).point;
				}
			}
			return result;
		}

		private static Ray GetViewRay()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_0043: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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)
			FirstPersonCameraModule val = default(FirstPersonCameraModule);
			if ((int)CameraModuleController.CurrentModuleType == 2 && CameraModuleController.TryGetFirstPersonModule(ref val) && (Object)(object)val.Viewer != (Object)null)
			{
				((CameraModule)val).UpdateModule();
				return new Ray(((CameraModule)val).position, ((CameraModule)val).GetCurrentForward());
			}
			Transform transform = ((Component)GameManager.Camera).transform;
			return new Ray(transform.position, transform.forward);
		}

		public override GameObject BuildHeldModel()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3);
			obj.transform.localScale = new Vector3(0.06f, 0.08f, 0.55f);
			PrefabBuilder.AddPart(obj, (PrimitiveType)2, new Vector3(0f, 0.1f, 0.9f), new Vector3(0.45f, 0.5f, 0.06f), Quaternion.Euler(90f, 0f, 0f));
			PrefabBuilder.AddPart(obj, (PrimitiveType)2, new Vector3(0f, 0.9f, 0.1f), new Vector3(0.4f, 0.25f, 0.06f), Quaternion.Euler(90f, 0f, 0f));
			PrefabBuilder.AddPart(obj, (PrimitiveType)3, new Vector3(0f, -0.9f, -0.45f), new Vector3(0.8f, 1.1f, 0.25f));
			return obj;
		}

		public override Color IconPixel(float x, float y)
		{
			//IL_002c: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			if (IconFactory.InRect(x, y, 0.08f, 0.46f, 0.92f, 0.56f))
			{
				return new Color(0.3f, 0.32f, 0.35f);
			}
			if (IconFactory.InRect(x, y, 0.3f, 0.56f, 0.56f, 0.64f))
			{
				return new Color(0.5f, 0.53f, 0.56f);
			}
			if (IconFactory.InRect(x, y, 0.1f, 0.3f, 0.3f, 0.46f))
			{
				return new Color(0.35f, 0.26f, 0.18f);
			}
			if (IconFactory.InRect(x, y, 0.58f, 0.34f, 0.66f, 0.46f))
			{
				return new Color(0.35f, 0.26f, 0.18f);
			}
			return Color.clear;
		}
	}
	public class GravityClubItem : ArsenalItem
	{
		private readonly ConfigEntry<bool> _enabled;

		private readonly ConfigEntry<float> _spawnWeight;

		private readonly ConfigEntry<int> _maxUses;

		private readonly ConfigEntry<float> _radius;

		private readonly ConfigEntry<float> _windUp;

		private readonly ConfigEntry<float> _launchSpeed;

		private readonly ConfigEntry<float> _upwardSpeed;

		private const float ContactDelay = 0.18f;

		private const float ElectromagnetShieldRadius = 3f;

		public override ItemType ItemType => ArsenalIds.Hammer;

		public override EquipmentType EquipmentType => ArsenalIds.HammerEquip;

		public override string DisplayName => "Gravity Club";

		public override Color Tint => new Color(0.16f, 0.16f, 0.19f);

		public override bool Enabled => _enabled.Value;

		public override float SpawnWeight => _spawnWeight.Value;

		public override int MaxUses => _maxUses.Value;

		public override bool DealsHits => true;

		public override bool IsExplosive => true;

		public override KnockoutType KnockoutType => (KnockoutType)19;

		public override EliminationReason EliminationReason => (EliminationReason)28;

		public override float BallSwingPower => 1f;

		public override Knockback Knockback => new Knockback
		{
			MinDistance = 1f,
			MaxDistance = _radius.Value,
			MinSpeed = _launchSpeed.Value,
			MaxSpeed = _launchSpeed.Value * 0.35f,
			MinUpwardSpeed = _upwardSpeed.Value
		};

		public override EquipmentType BorrowModelFrom => (EquipmentType)15;

		public override float BorrowedModelScale => 2f;

		public GravityClubItem()
		{
			_enabled = ArsenalConfig.Bind("Gravity Club", "Enabled", defaultValue: true, "Add the gravity club to the game.");
			_spawnWeight = ArsenalConfig.Bind("Gravity Club", "SpawnWeight", 5f, "Default item-box weight, before the host's slider.");
			_maxUses = ArsenalConfig.Bind("Gravity Club", "MaxUses", 2, "Slams per pickup.");
			_radius = ArsenalConfig.Bind("Gravity Club", "Radius", 7f, "Blast radius of the slam.");
			_windUp = ArsenalConfig.Bind("Gravity Club", "WindUp", 0.55f, "Seconds of wind-up before the club comes down.");
			_launchSpeed = ArsenalConfig.Bind("Gravity Club", "LaunchSpeed", 32f, "Outward speed at the centre of the slam.");
			_upwardSpeed = ArsenalConfig.Bind("Gravity Club", "UpwardSpeed", 14f, "Minimum upward speed given to anything hit.");
		}

		public override IEnumerator Use(PlayerInventory inventory)
		{
			PlayerInfo playerInfo = inventory.PlayerInfo;
			PlayerAnimatorIo animator = playerInfo.AnimatorIo;
			inventory.SetCurrentItemUse((ItemUseType)3);
			if (BMath.Abs(FloatExtensions.WrapAngleDeg(VectorExtensions.GetYawDeg(((Component)GameManager.Camera).transform.forward) - playerInfo.Movement.Yaw)) > 45f)
			{
				playerInfo.Movement.AlignWithCameraImmediately();
			}
			animator.SetIsChargingSwing(true);
			for (float elapsed = 0f; elapsed < _windUp.Value; elapsed += Time.deltaTime)
			{
				animator.SetSwingCharge(Mathf.Clamp01(elapsed / _windUp.Value));
				yield return null;
			}
			animator.SetSwingCharge(1f);
			animator.SetIsChargingSwing(false);
			inventory.SetCurrentItemUse((ItemUseType)2);
			animator.SetIsSwinging(true);
			yield return (object)new WaitForSeconds(0.18f);
			Vector3 val = VectorExtensions.Horizontalized(((Component)inventory).transform.forward);
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			Vector3 val2 = ((Component)inventory).transform.position + normalized * 1.6f + Vector3.up * 0.2f;
			ItemUseId itemUseId = inventory.IncrementAndGetCurrentItemUseId(ItemType);
			Blast.Apply(this, inventory, val2, _radius.Value, itemUseId, new HashSet<Hittable>());
			PlayShockwave(val2);
			inventory.DecrementUseFromSlotAt(inventory.EquippedItemIndex);
			yield return (object)new WaitForSeconds(0.35f);
			animator.SetIsSwinging(false);
			inventory.SetCurrentItemUse((ItemUseType)0);
			inventory.RemoveIfOutOfUses(inventory.EquippedItemIndex, true);
		}

		private void PlayShockwave(Vector3 impact)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_003d: 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_004c: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_00d5: Unknown result type (might be due to invalid IL or missing references)
			float num = _radius.Value / 3f;
			Effects.PlayForAllClients((VfxType)40, impact, Quaternion.identity, Vector3.one * num);
			Effects.PlayForAllClients((VfxType)25, impact);
			Effects.PlayForAllClients((VfxType)98, impact);
			Effects.PlayForAllClients((VfxType)72, impact);
			Effects.PlayForAllClients((VfxType)42, impact);
			CameraGameplaySettings cameraGameplaySettings = GameManager.CameraGameplaySettings;
			if ((Object)(object)cameraGameplaySettings != (Object)null)
			{
				CameraModuleController.Shake(cameraGameplaySettings.LandmineExplosionScreenshakeSettings, impact, 1f, 1f);
			}
			AudioSettings audioSettings = GameManager.AudioSettings;
			if ((Object)(object)audioSettings != (Object)null)
			{
				RuntimeManager.PlayOneShot(audioSettings.LandmineExplosionEvent, impact);
			}
		}

		public override GameObject BuildHeldModel()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.CreatePrimitive((PrimitiveType)2);
			obj.transform.localScale = new Vector3(0.035f, 0.3f, 0.035f);
			PrefabBuilder.AddPart(obj, (PrimitiveType)3, new Vector3(0f, 1.05f, 0f), new Vector3(5.5f, 0.45f, 3.5f));
			PrefabBuilder.AddPart(obj, (PrimitiveType)3, new Vector3(0f, 1.05f, 0.9f), new Vector3(3.5f, 0.35f, 1.2f));
			return obj;
		}

		public override Color IconPixel(float x, float y)
		{
			//IL_002c: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			if (IconFactory.InRect(x, y, 0.16f, 0.62f, 0.84f, 0.88f))
			{
				return new Color(0.5f, 0.5f, 0.56f);
			}
			if (IconFactory.InRect(x, y, 0.16f, 0.62f, 0.84f, 0.66f))
			{
				return new Color(0.3f, 0.3f, 0.34f);
			}
			if (IconFactory.InRect(x, y, 0.46f, 0.1f, 0.54f, 0.64f))
			{
				return new Color(0.34f, 0.34f, 0.38f);
			}
			return Color.clear;
		}
	}
	public class MulliganItem : ArsenalItem
	{
		private readonly ConfigEntry<bool> _enabled;

		private readonly ConfigEntry<float> _spawnWeight;

		private readonly ConfigEntry<int> _maxUses;

		private readonly ConfigEntry<float> _maxRange;

		private readonly ConfigEntry<float> _cooldown;

		private const float HoleClearance = 1.5f;

		private static readonly Dictionary<uint, double> ServerReadyTimes = new Dictionary<uint, double>();

		private static readonly List<uint> ExpiredReadyTimes = new List<uint>();

		private double _localReadyTime;

		public override ItemType ItemType => ArsenalIds.BallSwap;

		public override EquipmentType EquipmentType => ArsenalIds.BallSwapEquip;

		public override string DisplayName => "Mulligan";

		public override Color Tint => new Color(0.2f, 0.8f, 0.45f);

		public override bool Enabled => _enabled.Value;

		public override float SpawnWeight => _spawnWeight.Value;

		public override int MaxUses => _maxUses.Value;

		public override bool IsAimed => true;

		public override EquipmentType BorrowModelFrom => (EquipmentType)11;

		public float Cooldown => _cooldown.Value;

		public MulliganItem()
		{
			_enabled = ArsenalConfig.Bind("Mulligan", "Enabled", defaultValue: true, "Add the mulligan to the game.");
			_spawnWeight = ArsenalConfig.Bind("Mulligan", "SpawnWeight", 4f, "Default item-box weight, before the host's slider.");
			_maxUses = ArsenalConfig.Bind("Mulligan", "MaxUses", 1, "Swaps per pickup.");
			_maxRange = ArsenalConfig.Bind("Mulligan", "MaxTargetRange", 250f, "How far away a target golfer can be.");
			_cooldown = ArsenalConfig.Bind("Mulligan", "CooldownSeconds", 20f, "Seconds a golfer must wait between swaps. The host's value is the one enforced.");
		}

		public override IEnumerator Use(PlayerInventory inventory)
		{
			inventory.SetCurrentItemUse((ItemUseType)1);
			PlayerInfo playerInfo = inventory.PlayerInfo;
			PlayerInfo target;
			string text = Validate(playerInfo, out target);
			if (text != null)
			{
				Refuse(text);
				inventory.SetCurrentItemUse((ItemUseType)0);
				yield break;
			}
			_localReadyTime = Time.timeAsDouble + (double)_cooldown.Value;
			Net.RequestBallSwap(((NetworkBehaviour)playerInfo).netId, ((NetworkBehaviour)target).netId);
			inventory.DecrementUseFromSlotAt(inventory.EquippedItemIndex);
			yield return (object)new WaitForSeconds(0.4f);
			inventory.SetCurrentItemUse((ItemUseType)0);
			inventory.RemoveIfOutOfUses(inventory.EquippedItemIndex, true);
		}

		private string Validate(PlayerInfo self, out PlayerInfo target)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			target = null;
			if (Time.timeAsDouble < _localReadyTime)
			{
				return "Ball swap is recharging";
			}
			GolfBall val = (((Object)(object)self.AsGolfer != (Object)null) ? self.AsGolfer.OwnBall : null);
			if (!IsInPlay(val))
			{
				return "Your ball is not in play";
			}
			if (!MatchSetupRules.GetValueAsBool((Rule)10))
			{
				return "Hitting other players' balls is off";
			}
			target = FindTarget(self);
			if ((Object)(object)target == (Object)null)
			{
				return "No golfer to swap with";
			}
			if (!AreClearOfHoles(val.Rigidbody.position, target.AsGolfer.OwnBall.Rigidbody.position))
			{
				return "Too close to the hole";
			}
			return null;
		}

		private PlayerInfo FindTarget(PlayerInfo self)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			Camera camera = GameManager.Camera;
			if ((Object)(object)camera == (Object)null)
			{
				return null;
			}
			HashSet<LockOnTarget> targets = LockOnTargetManager.Targets;
			if (targets == null)
			{
				return null;
			}
			bool valueAsBool = MatchSetupRules.GetValueAsBool((Rule)21);
			Vector3 position = ((Component)camera).transform.position;
			Vector3 forward = ((Component)camera).transform.forward;
			float num = _maxRange.Value * _maxRange.Value;
			PlayerInfo result = null;
			float num2 = float.MaxValue;
			foreach (LockOnTarget item in targets)
			{
				if ((Object)(object)item == (Object)null || (Object)(object)item.AsEntity == (Object)null || !item.AsEntity.IsPlayer)
				{
					continue;
				}
				PlayerInfo playerInfo = item.AsEntity.PlayerInfo;
				if ((Object)(object)playerInfo == (Object)null || (Object)(object)playerInfo == (Object)(object)self || (valueAsBool && self.IsTeammateOf(playerInfo, true)) || !IsInPlay(((Object)(object)playerInfo.AsGolfer != (Object)null) ? playerInfo.AsGolfer.OwnBall : null))
				{
					continue;
				}
				Vector3 val = item.GetLockOnPosition() - position;
				if (!(((Vector3)(ref val)).sqrMagnitude > num))
				{
					float num3 = Vector3.Angle(forward, val);
					if (!(num3 > 45f) && !(num3 >= num2))
					{
						result = playerInfo;
						num2 = num3;
					}
				}
			}
			return result;
		}

		public static void ServerSwap(uint requesterNetId, uint targetNetId)
		{
			//IL_0008: 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_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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_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)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || !(Registry.Get(ArsenalIds.BallSwap) is MulliganItem mulliganItem))
			{
				return;
			}
			PlayerInfo val = Net.FindPlayerOnServer(requesterNetId);
			PlayerInfo val2 = Net.FindPlayerOnServer(targetNetId);
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val == (Object)(object)val2 || !MatchSetupRules.GetValueAsBool((Rule)10) || (MatchSetupRules.GetValueAsBool((Rule)21) && val.IsTeammateOf(val2, true)))
			{
				return;
			}
			double timeAsDouble = Time.timeAsDouble;
			if (!ServerIsOffCooldown(requesterNetId, timeAsDouble))
			{
				return;
			}
			GolfBall val3 = (((Object)(object)val.AsGolfer != (Object)null) ? val.AsGolfer.OwnBall : null);
			GolfBall val4 = (((Object)(object)val2.AsGolfer != (Object)null) ? val2.AsGolfer.OwnBall : null);
			if (ServerIsInPlay(val3) && ServerIsInPlay(val4))
			{
				Vector3 position = val3.Rigidbody.position;
				Quaternion rotation = val3.Rigidbody.rotation;
				Vector3 position2 = val4.Rigidbody.position;
				Quaternion rotation2 = val4.Rigidbody.rotation;
				if (AreClearOfHoles(position, position2))
				{
					ServerReadyTimes[requesterNetId] = timeAsDouble + (double)mulliganItem.Cooldown;
					Teleport(val3, position2, rotation2);
					Teleport(val4, position, rotation);
					Net.BroadcastBallSwapCompleted(position2, position);
				}
			}
		}

		private static bool ServerIsOffCooldown(uint requesterNetId, double now)
		{
			ExpiredReadyTimes.Clear();
			foreach (KeyValuePair<uint, double> serverReadyTime in ServerReadyTimes)
			{
				if (serverReadyTime.Value <= now)
				{
					ExpiredReadyTimes.Add(serverReadyTime.Key);
				}
			}
			foreach (uint expiredReadyTime in ExpiredReadyTimes)
			{
				ServerReadyTimes.Remove(expiredReadyTime);
			}
			return !ServerReadyTimes.ContainsKey(requesterNetId);
		}

		private static bool IsInPlay(GolfBall ball)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ball == (Object)null || ball.IsHidden)
			{
				return false;
			}
			if ((int)ball.OutOfBoundsReturnState != 0)
			{
				return false;
			}
			if ((Object)(object)ball.Rigidbody == (Object)null)
			{
				return false;
			}
			Entity asEntity = ball.AsEntity;
			if ((Object)(object)asEntity == (Object)null || (Object)(object)asEntity.LevelBoundsTracker == (Object)null)
			{
				return false;
			}
			BoundsState authoritativeBoundsState = asEntity.LevelBoundsTracker.AuthoritativeBoundsState;
			if (!BoundsStateExtensions.IsInOutOfBoundsHazard(authoritativeBoundsState))
			{
				return !BoundsStateExtensions.HasState(authoritativeBoundsState, (BoundsState)8);
			}
			return false;
		}

		private static bool ServerIsInPlay(GolfBall ball)
		{
			if (IsInPlay(ball))
			{
				return !ball.isInHole;
			}
			return false;
		}

		private static bool AreClearOfHoles(Vector3 first, Vector3 second)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			GolfHoleTrigger[] array = Object.FindObjectsByType<GolfHoleTrigger>((FindObjectsInactive)1, (FindObjectsSortMode)0);
			for (int i = 0; i < array.Length; i++)
			{
				Collider ballTrigger = array[i].ballTrigger;
				if (!((Object)(object)ballTrigger == (Object)null))
				{
					Bounds bounds = ballTrigger.bounds;
					if (((Bounds)(ref bounds)).SqrDistance(first) < 2.25f)
					{
						return false;
					}
					if (((Bounds)(ref bounds)).SqrDistance(second) < 2.25f)
					{
						return false;
					}
				}
			}
			return true;
		}

		private static void Teleport(GolfBall ball, Vector3 position, Quaternion rotation)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0043: 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)
			ball.AsEntity.InformWillTeleport();
			ball.AsEntity.LevelBoundsTracker.ServerReturnToBounds(position, rotation);
			ball.AsEntity.InformTeleported();
			ball.OnRespawned();
			ball.ServerLastStrokePosition = position;
			Effects.PlayForAllClients((VfxType)84, position);
		}

		public static void PlayArrivalSound(Vector3 position)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			AudioSettings audioSettings = GameManager.AudioSettings;
			if ((Object)(object)audioSettings != (Object)null)
			{
				RuntimeManager.PlayOneShot(audioSettings.BallRespawnEvent, position);
			}
		}

		private static void Refuse(string message)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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)
			AudioSettings audioSettings = GameManager.AudioSettings;
			if ((Object)(object)audioSettings != (Object)null)
			{
				RuntimeManager.PlayOneShot(audioSettings.CosmeticsButtonSelectDisabled, default(Vector3));
			}
			if (SingletonBehaviour<TextPopupManager>.HasInstance)
			{
				PlayerInfo.PopupPenalty(message);
			}
		}

		public override Color IconPixel(float x, float y)
		{
			//IL_0002: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_004a: 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_006e: Unknown result type (might be due to invalid IL or missing references)
			if (Vector2.Distance(new Vector2(x, y), new Vector2(0.26f, 0.3f)) < 0.14f)
			{
				return Color.white;
			}
			if (Vector2.Distance(new Vector2(x, y), new Vector2(0.74f, 0.7f)) < 0.14f)
			{
				return Color.white;
			}
			if (IconFactory.InRect(x, y, 0.24f, 0.46f, 0.76f, 0.54f))
			{
				return Tint;
			}
			return Color.clear;
		}
	}
	public class ScopeOverlay : MonoBehaviour
	{
		private const int VignetteResolution = 128;

		private const float ClearRadius = 0.72f;

		private static Texture2D _vignette;

		private GUIStyle _readoutStyle;

		public float Magnification;

		public static ScopeOverlay EnsureOn(GameObject host)
		{
			ScopeOverlay component = host.GetComponent<ScopeOverlay>();
			if ((Object)(object)component != (Object)null)
			{
				return component;
			}
			component = host.AddComponent<ScopeOverlay>();
			((Behaviour)component).enabled = false;
			return component;
		}

		private void OnGUI()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: 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_00e9: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			if ((int)Event.current.type == 7)
			{
				float num = Screen.width;
				float num2 = Screen.height;
				float num3 = Mathf.Min(num, num2);
				Rect val = default(Rect);
				((Rect)(ref val))..ctor((num - num3) * 0.5f, (num2 - num3) * 0.5f, num3, num3);
				Color color = GUI.color;
				GUI.color = Color.black;
				Fill(new Rect(0f, 0f, ((Rect)(ref val)).xMin, num2));
				Fill(new Rect(((Rect)(ref val)).xMax, 0f, num - ((Rect)(ref val)).xMax, num2));
				Fill(new Rect(((Rect)(ref val)).xMin, 0f, num3, ((Rect)(ref val)).yMin));
				Fill(new Rect(((Rect)(ref val)).xMin, ((Rect)(ref val)).yMax, num3, num2 - ((Rect)(ref val)).yMax));
				GUI.DrawTexture(val, (Texture)(object)Vignette());
				GUI.color = new Color(0.86f, 0.89f, 0.92f, 0.8f);
				DrawCrosshair(val);
				GUI.color = color;
				GUI.Label(new Rect(((Rect)(ref val)).xMin, ((Rect)(ref val)).center.y + num3 * 0.3f, num3, num3 * 0.06f), Magnification.ToString("0.0") + "x", ReadoutStyle(num3));
			}
		}

		private static void Fill(Rect rect)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (!(((Rect)(ref rect)).width <= 0f) && !(((Rect)(ref rect)).height <= 0f))
			{
				GUI.DrawTexture(rect, (Texture)(object)Texture2D.whiteTexture);
			}
		}

		private static void DrawCrosshair(Rect tube)
		{
			//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_0068: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			float x = ((Rect)(ref tube)).center.x;
			float y = ((Rect)(ref tube)).center.y;
			float num = ((Rect)(ref tube)).width * 0.5f * 0.72f;
			float num2 = ((Rect)(ref tube)).width * 0.022f;
			float num3 = Mathf.Max(1f, Mathf.Round(((Rect)(ref tube)).width * 0.0015f));
			Fill(new Rect(x - num, y - num3 * 0.5f, num - num2, num3));
			Fill(new Rect(x + num2, y - num3 * 0.5f, num - num2, num3));
			Fill(new Rect(x - num3 * 0.5f, y - num, num3, num - num2));
			Fill(new Rect(x - num3 * 0.5f, y + num2, num3, num - num2));
			Fill(new Rect(x - num3, y - num3, num3 * 2f, num3 * 2f));
		}

		private GUIStyle ReadoutStyle(float diameter)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (_readoutStyle == null)
			{
				_readoutStyle = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)1
				};
				_readoutStyle.normal.textColor = new Color(0.86f, 0.89f, 0.92f, 0.85f);
			}
			_readoutStyle.fontSize = Mathf.Max(10, Mathf.RoundToInt(diameter * 0.028f));
			return _readoutStyle;
		}

		private static Texture2D Vignette()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_vignette != (Object)null)
			{
				return _vignette;
			}
			_vignette = new Texture2D(128, 128, (TextureFormat)5, false)
			{
				name = "Arsenal_ScopeVignette",
				wrapMode = (TextureWrapMode)1,
				filterMode = (FilterMode)1,
				hideFlags = (HideFlags)61
			};
			Color[] array = (Color[])(object)new Color[16384];
			for (int i = 0; i < 128; i++)
			{
				for (int j = 0; j < 128; j++)
				{
					float num = ((float)j + 0.5f) / 128f * 2f - 1f;
					float num2 = ((float)i + 0.5f) / 128f * 2f - 1f;
					float num3 = Mathf.Sqrt(num * num + num2 * num2);
					float num4 = Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.72f, 1f, num3));
					array[i * 128 + j] = new Color(0f, 0f, 0f, num4);
				}
			}
			_vignette.SetPixels(array);
			_vignette.Apply(false);
			return _vignette;
		}
	}
	public class ScopeZoom : MonoBehaviour
	{
		private PlayerInventory _inventory;

		private EagleEyeItem _rifle;

		private ScopeOverlay _overlay;

		private float _fov;

		private float _targetFov;

		private float _zoomSpeed;

		private bool _wasScoped;

		public static float Magnification { get; private set; }

		private static float DefaultFov
		{
			get
			{
				AllSettings all = GameSettings.All;
				GraphicsSettings val = ((all != null) ? all.Graphics : null);
				float num = ((val != null) ? ((float)val.FieldOfView) : 0f);
				if (!(num > 1f))
				{
					return 60f;
				}
				return num;
			}
		}

		public static void EnsureOn(PlayerInventory inventory, EagleEyeItem rifle)
		{
			if (!((Object)(object)inventory == (Object)null) && !((Object)(object)((Component)inventory).GetComponent<ScopeZoom>() != (Object)null))
			{
				ScopeZoom scopeZoom = ((Component)inventory).gameObject.AddComponent<ScopeZoom>();
				scopeZoom._inventory = inventory;
				scopeZoom._rifle = rifle;
				scopeZoom._overlay = ScopeOverlay.EnsureOn(((Component)inventory).gameObject);
			}
		}

		private void Update()
		{
			if ((Object)(object)_inventory == (Object)null || !((NetworkBehaviour)_inventory).isLocalPlayer)
			{
				return;
			}
			FirstPersonCameraModule val = default(FirstPersonCameraModule);
			if (!IsScoped())
			{
				if (_wasScoped)
				{
					LeaveScope();
				}
			}
			else if (CameraModuleController.TryGetFirstPersonModule(ref val))
			{
				if (!_wasScoped)
				{
					ShoulderUp();
				}
				else
				{
					WindZoom();
				}
				_fov = ((_zoomSpeed > 0f) ? Mathf.MoveTowards(_fov, _targetFov, _zoomSpeed * Time.deltaTime) : _targetFov);
				val.OverrideFovInstantly(_fov);
				Magnification = DefaultFov / Mathf.Max(_fov, 0.01f);
				ReticleManager.SetReticle((ReticleType)9);
				ReticleManager.SetRailgunNormalizedCharge(1f);
				ReticleManager.SetRailgunYaw(_inventory.PlayerInfo.Movement.Yaw);
				_overlay.Magnification = Magnification;
			}
		}

		private void OnDisable()
		{
			if (_wasScoped)
			{
				LeaveScope();
			}
		}

		private void ShoulderUp()
		{
			_wasScoped = true;
			if ((Object)(object)_overlay != (Object)null)
			{
				((Behaviour)_overlay).enabled = true;
			}
			if (!_rifle.RememberZoom || _targetFov <= 0f)
			{
				_targetFov = _rifle.MaxFov;
			}
			_targetFov = Mathf.Clamp(_targetFov, _rifle.MinFov, _rifle.MaxFov);
			float zoomInTime = _rifle.ZoomInTime;
			if (zoomInTime <= 0f)
			{
				_fov = _targetFov;
				_zoomSpeed = 0f;
			}
			else
			{
				_fov = DefaultFov;
				_zoomSpeed = Mathf.Abs(_fov - _targetFov) / zoomInTime;
			}
		}

		private void WindZoom()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			float num = ((Mouse.current != null) ? ((InputControl<Vector2>)(object)Mouse.current.scroll).ReadValue().y : 0f);
			if (!(Mathf.Abs(num) < 0.01f))
			{
				_targetFov = Mathf.Clamp(_targetFov - Mathf.Sign(num) * _rifle.ZoomStep, _rifle.MinFov, _rifle.MaxFov);
			}
		}

		private bool IsScoped()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			//IL_0020: 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)
			if (!_inventory.IsInFirstPersonAim)
			{
				return false;
			}
			if ((int)CameraModuleController.CurrentModuleType != 2)
			{
				return false;
			}
			return _inventory.GetEffectivelyEquippedItem(true) == _rifle.ItemType;
		}

		private void LeaveScope()
		{
			_wasScoped = false;
			Magnification = 0f;
			_zoomSpeed = 0f;
			if ((Object)(object)_overlay != (Object)null)
			{
				((Behaviour)_overlay).enabled = false;
			}
			FirstPersonCameraModule val = default(FirstPersonCameraModule);
			if (CameraModuleController.TryGetFirstPersonModule(ref val))
			{
				if ((Object)(object)_inventory != (Object)null && _inventory.IsInFirstPersonAim)
				{
					val.OverrideFovInstantly(GameManager.ItemSettings.RailgunZoomFinalFov);
				}
				else
				{
					val.CancelFovOverrideInstantly();
				}
			}
			if ((Object)(object)_inventory != (Object)null)
			{
				_inventory.LocalPlayerUpdateAimingReticle();
			}
		}
	}
	public class ShadowClone : MonoBehaviour
	{
		private const float ProbeUp = 3f;

		private const float ProbeDown = 12f;

		private static readonly List<ShadowClone> Live;

		private PlayerInfo _owner;

		private Animator _ownerAnimator;

		private Animator _animator;

		private RuntimeAnimatorController _boundController;

		private int[] _floatHashes;

		private int[] _intHashes;

		private int[] _boolHashes;

		private Transform _rightHand;

		private Transform _leftHand;

		private Equipment _rightHeld;

		private Equipment _leftHeld;

		private float _sideOffset;

		private float _expiry;

		static ShadowClone()
		{
			Live = new List<ShadowClone>();
			SceneManager.sceneLoaded -= OnSceneLoaded;
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		public static void Spawn(PlayerInfo owner, float sideOffset, float duration)
		{
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)owner == (Object)null))
			{
				GameObject val = BuildVisualCopy(((Component)owner).gameObject, "Arsenal_ShadowClone", null);
				ShadowClone shadowClone = val.AddComponent<ShadowClone>();
				shadowClone._owner = owner;
				shadowClone._ownerAnimator = GetAnimator(owner);
				shadowClone._animator = FindAnimator(shadowClone._ownerAnimator, ((Component)owner).transform, val);
				shadowClone._sideOffset = sideOffset;
				shadowClone._expiry = Time.time + duration;
				shadowClone._rightHand = FindSame((Component)(object)owner.RightHandEquipmentSwitcher, ((Component)owner).transform, val.transform);
				shadowClone._leftHand = FindSame((Component)(object)owner.LeftHandEquipmentSwitcher, ((Component)owner).transform, val.transform);
				if ((Object)(object)owner.RightHandEquipmentSwitcher != (Object)null)
				{
					shadowClone._rightHeld = owner.RightHandEquipmentSwitcher.CurrentEquipment;
				}
				if ((Object)(object)owner.LeftHandEquipmentSwitcher != (Object)null)
				{
					shadowClone._leftHeld = owner.LeftHandEquipmentSwitcher.CurrentEquipment;
				}
				shadowClone.BindAnimator();
				Live.Add(shadowClone);
				shadowClone.MirrorPose();
				VfxManager.PlayPooledVfxLocalOnly((VfxType)61, val.transform.position, Quaternion.identity, default(Vector3), 0u, false, 0f, (Action<PoolableParticleSystem>)null);
			}
		}

		public static void ClearAll()
		{
			for (int num = Live.Count - 1; num >= 0; num--)
			{
				if ((Object)(object)Live[num] != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)Live[num]).gameObject);
				}
			}
			Live.Clear();
		}

		private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			ClearAll();
		}

		private void LateUpdate()
		{
			//IL_0023: 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)
			//IL_002f: 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)
			if ((Object)(object)_owner == (Object)null || Time.time >= _expiry)
			{
				VfxManager.PlayPooledVfxLocalOnly((VfxType)86, ((Component)this).transform.position, Quaternion.identity, default(Vector3), 0u, false, 0f, (Action<PoolableParticleSystem>)null);
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
			else
			{
				MirrorPose();
				MirrorHeldEquipment();
				CopyAnimatorState();
			}
		}

		private void OnDestroy()
		{
			Live.Remove(this);
		}

		private void MirrorPose()
		{
			//IL_000b: 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_001c: 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_0030: 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_0032: 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_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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)_owner).transform.position;
			Quaternion val = Quaternion.AngleAxis(((Component)_owner).transform.eulerAngles.y, Vector3.up);
			Vector3 val2 = position + val * new Vector3(_sideOffset, 0f, 0f);
			float top = position.y + 3f;
			if (TryGroundHeight(position.x, top, position.z, out var height) && TryGroundHeight(val2.x, top, val2.z, out var height2))
			{
				val2.y = height2 + (position.y - height);
			}
			else
			{
				val2.y = position.y;
			}
			((Component)this).transform.SetPositionAndRotation(val2, ((Component)_owner).transform.rotation);
		}

		private static bool TryGroundHeight(float x, float top, float z, out float height)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			LayerSettings layerSettings = GameManager.LayerSettings;
			RaycastHit val = default(RaycastHit);
			if ((Object)(object)layerSettings != (Object)null && Physics.Raycast(new Vector3(x, top, z), Vector3.down, ref val, 15f, LayerMask.op_Implicit(layerSettings.PlayerGroundableMask), (QueryTriggerInteraction)1))
			{
				height = ((RaycastHit)(ref val)).point.y;
				return true;
			}
			height = 0f;
			return false;
		}

		private void MirrorHeldEquipment()
		{
			EquipmentSwitcher rightHandEquipmentSwitcher = _owner.RightHandEquipmentSwitcher;
			if ((Object)(object)rightHandEquipmentSwitcher != (Object)null && (Object)(object)rightHandEquipmentSwitcher.CurrentEquipment != (Object)(object)_rightHeld)
			{
				_rightHeld = FillHand(_rightHand, rightHandEquipmentSwitcher.CurrentEquipment);
			}
			EquipmentSwitcher leftHandEquipmentSwitcher = _owner.LeftHandEquipmentSwitcher;
			if ((Object)(object)leftHandEquipmentSwitcher != (Object)null && (Object)(object)leftHandEquipmentSwitcher.CurrentEquipment != (Object)(object)_leftHeld)
			{
				_leftHeld = FillHand(_leftHand, leftHandEquipmentSwitcher.CurrentEquipment);
			}
		}

		private static Equipment FillHand(Transform hand, Equipment source)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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)
			if ((Object)(object)hand == (Object)null)
			{
				return source;
			}
			for (int num = hand.childCount - 1; num >= 0; num--)
			{
				Object.DestroyImmediate((Object)(object)((Component)hand.GetChild(num)).gameObject);
			}
			if ((Object)(object)source != (Object)null)
			{
				GameObject obj = BuildVisualCopy(((Component)source).gameObject, ((Object)source).name, hand);
				obj.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
				obj.transform.localScale = Vector3.one;
			}
			return source;
		}

		private void BindAnimator()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Expected I4, but got Unknown
			if ((Object)(object)_animator == (Object)null || (Object)(object)_ownerAnimator == (Object)null)
			{
				return;
			}
			_boundController = _ownerAnimator.runtimeAnimatorController;
			_animator.runtimeAnimatorController = _boundController;
			_animator.fireEvents = false;
			_animator.applyRootMotion = false;
			List<int> list = new List<int>();
			List<int> list2 = new List<int>();
			List<int> list3 = new List<int>();
			AnimatorControllerParameter[] parameters = _ownerAnimator.parameters;
			foreach (AnimatorControllerParameter val in parameters)
			{
				if (!_ownerAnimator.IsParameterControlledByCurve(val.nameHash))
				{
					AnimatorControllerParameterType type = val.type;
					switch (type - 1)
					{
					case 0:
						list.Add(val.nameHash);
						break;
					case 2:
						list2.Add(val.nameHash);
						break;
					case 3:
						list3.Add(val.nameHash);
						break;
					}
				}
			}
			_floatHashes = list.ToArray();
			_intHashes = list2.ToArray();
			_boolHashes = list3.ToArray();
		}

		private void CopyAnimatorState()
		{
			if (!((Object)(object)_animator == (Object)null) && !((Object)(object)_ownerAnimator == (Object)null) && _floatHashes != null)
			{
				if ((Object)(object)_ownerAnimator.runtimeAnimatorController != (Object)(object)_boundController)
				{
					BindAnimator();
				}
				int[] floatHashes = _floatHashes;
				foreach (int num in floatHashes)
				{
					_animator.SetFloat(num, _ownerAnimator.GetFloat(num));
				}
				floatHashes = _intHashes;
				foreach (int num2 in floatHashes)
				{
					_animator.SetInteger(num2, _ownerAnimator.GetInteger(num2));
				}
				floatHashes = _boolHashes;
				foreach (int num3 in floatHashes)
				{
					_animator.SetBool(num3, _ownerAnimator.GetBool(num3));
				}
				for (int j = 0; j < _ownerAnimator.layerCount && j < _animator.layerCount; j++)
				{
					_animator.SetLayerWeight(j, _ownerAnimator.GetLayerWeight(j));
				}
				_animator.speed = _ownerAnimator.speed;
			}
		}

		private static GameObject BuildVisualCopy(GameObject source, string name, Transform destination)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			GameObject val = new GameObject("Arsenal_ShadowCloneHolder");
			val.SetActive(false);
			GameObject val2 = Object.Instantiate<GameObject>(source, val.transform);
			((Object)val2).name = name;
			Canvas[] componentsInChildren = val2.GetComponentsInChildren<Canvas>(true);
			foreach (Canvas val3 in componentsInChildren)
			{
				if ((Object)(object)val3 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)((Component)val3).gameObject);
				}
			}
			ParticleSystem[] componentsInChildren2 = val2.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val4 in componentsInChildren2)
			{
				if ((Object)(object)val4 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)((Component)val4).gameObject);
				}
			}
			NetworkBehaviour[] componentsInChildren3 = val2.GetComponentsInChildren<NetworkBehaviour>(true);
			foreach (NetworkBehaviour val5 in componentsInChildren3)
			{
				if ((Object)(object)val5 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val5);
				}
			}
			NetworkIdentity[] componentsInChildren4 = val2.GetComponentsInChildren<NetworkIdentity>(true);
			foreach (NetworkIdentity val6 in componentsInChildren4)
			{
				if ((Object)(object)val6 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val6);
				}
			}
			MonoBehaviour[] componentsInChildren5 = val2.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val7 in componentsInChildren5)
			{
				if ((Object)(object)val7 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val7);
				}
			}
			TrailRenderer[] componentsInChildren6 = val2.GetComponentsInChildren<TrailRenderer>(true);
			foreach (TrailRenderer val8 in componentsInChildren6)
			{
				if ((Object)(object)val8 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val8);
				}
			}
			AudioSource[] componentsInChildren7 = val2.GetComponentsInChildren<AudioSource>(true);
			foreach (AudioSource val9 in componentsInChildren7)
			{
				if ((Object)(object)val9 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val9);
				}
			}
			Rigidbody[] componentsInChildren8 = val2.GetComponentsInChildren<Rigidbody>(true);
			foreach (Rigidbody val10 in componentsInChildren8)
			{
				if ((Object)(object)val10 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val10);
				}
			}
			Collider[] componentsInChildren9 = val2.GetComponentsInChildren<Collider>(true);
			foreach (Collider val11 in componentsInChildren9)
			{
				if ((Object)(object)val11 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val11);
				}
			}
			val2.transform.SetParent(destination, false);
			val2.SetActive(true);
			Object.Destroy((Object)(object)val);
			return val2;
		}

		private static Transform FindSame(Component node, Transform sourceRoot, Transform copyRoot)
		{
			if ((Object)(object)node == (Object)null)
			{
				return null;
			}
			if ((Object)(object)node.transform == (Object)(object)sourceRoot)
			{
				return copyRoot;
			}
			string text = ((Object)node).name;
			Transform parent = node.transform.parent;
			while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)sourceRoot)
			{
				text = ((Object)parent).name + "/" + text;
				parent = parent.parent;
			}
			return copyRoot.Find(text);
		}

		private static Animator FindAnimator(Animator ownerAnimator, Transform ownerRoot, GameObject puppet)
		{
			Transform val = FindSame((Component)(object)ownerAnimator, ownerRoot, puppet.transform);
			Animator val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Animator>() : null);
			if (!((Object)(object)val2 != (Object)null))
			{
				return puppet.GetComponentInChildren<Animator>();
			}
			return val2;
		}

		private static Animator GetAnimator(PlayerInfo owner)
		{
			PlayerAnimatorIo animatorIo = owner.AnimatorIo;
			if ((Object)(object)animatorIo == (Object)null)
			{
				return ((Component)owner).GetComponentInChildren<Animator>();
			}
			object? obj = typeof(PlayerAnimatorIo).GetField("animator", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(animatorIo);
			return (Animator)(((obj is Animator) ? obj : null) ?? ((Component)owner).GetComponentInChildren<Animator>());
		}
	}
	public class ShadowCloneItem : ArsenalItem
	{
		private readonly ConfigEntry<bool> _enabled;

		private readonly ConfigEntry<float> _spawnWeight;

		private readonly ConfigEntry<int> _maxUses;

		private readonly ConfigEntry<float> _duration;

		private readonly ConfigEntry<float> _sideOffset;

		public override ItemType ItemType => ArsenalIds.Clone;

		public override EquipmentType EquipmentType => ArsenalIds.CloneEquip;

		public override string DisplayName => "Shadow Clone";

		public override Color Tint => new Color(0.35f, 0.3f, 0.6f);

		public override bool Enabled => _enabled.Value;

		public override float SpawnWeight => _spawnWeight.Value;

		public override int MaxUses => _maxUses.Value;

		public override bool CanUsageAffectBalls => false;

		public override EquipmentType BorrowModelFrom => (EquipmentType)18;

		public override float BorrowedModelScale => 1f;

		public ShadowCloneItem()
		{
			_enabled = ArsenalConfig.Bind("Shadow Clone", "Enabled", defaultValue: true, "Add the shadow clone to the game.");
			_spawnWeight = ArsenalConfig.Bind("Shadow Clone", "SpawnWeight", 5f, "Default item-box weight, before the host's slider.");
			_maxUses = ArsenalConfig.Bind("Shadow Clone", "MaxUses", 1, "Clones per pickup.");
			_duration = ArsenalConfig.Bind("Shadow Clone", "Duration", 15f, "Seconds the clone lasts.");
			_sideOffset = ArsenalConfig.Bind("Shadow Clone", "SideOffset", 2.5f, "Metres to the player's right the clone runs. Negative puts it on the left.");
		}

		public override IEnumerator Use(PlayerInventory inventory)
		{
			inventory.SetCurrentItemUse((ItemUseType)1);
			yield return (object)new WaitForSeconds(0.25f);
			Net.BroadcastShadowClone(((NetworkBehaviour)inventory.PlayerInfo).netId, _sideOffset.Value, _duration.Value);
			inventory.DecrementUseFromSlotAt(inventory.EquippedItemIndex);
			yield return (object)new WaitForSeconds(0.2f);
			inventory.SetCurrentItemUse((ItemUseType)0);
			inventory.RemoveIfOutOfUses(inventory.EquippedItemIndex, true);
		}

		public override Color IconPixel(float x, float y)
		{
			//IL_001e: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			if (Silhouette(x - 0.1f, y))
			{
				return new Color(0.2f, 0.18f, 0.3f);
			}
			if (Silhouette(x + 0.08f, y))
			{
				return Tint;
			}
			return Color.clear;
		}

		private static bool Silhouette(float x, float y)
		{
			//IL_0002: 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 (Vector2.Distance(new Vector2(x, y), new Vector2(0.5f, 0.76f)) < 0.11f)
			{
				return true;
			}
			return IconFactory.InRect(x, y, 0.38f, 0.16f, 0.62f, 0.64f);
		}
	}
	public class SliceDriverItem : ArsenalItem
	{
		private readonly ConfigEntry<bool> _enabled;

		private readonly ConfigEntry<float> _spawnWeight;

		private readonly ConfigEntry<int> _maxUses;

		private readonly ConfigEntry<float> _dashSpeed;

		private readonly ConfigEntry<float> _dashPitch;

		private readonly ConfigEntry<float> _dashDuration;

		private readonly ConfigEntry<float> _bladeRadius;

		private readonly ConfigEntry<float> _launchSpeed;

		private const float BladeHeight = 0.9f;

		public override ItemType ItemType => ArsenalIds.Sword;

		public override EquipmentType EquipmentType => ArsenalIds.SwordEquip;

		public override string DisplayName => "Slice Driver";

		public override Color Tint => new Color(0.62f, 0.25f, 0.95f);

		public override bool Enabled => _enabled.Value;

		public override float SpawnWeight => _spawnWeight.Value;

		public override int MaxUses => _maxUses.Value;

		public override bool DealsHits => true;

		public override KnockoutType KnockoutType => (KnockoutType)18;

		public override EliminationReason EliminationReason => (EliminationReason)27;

		public override float BallSwingPower => 0.9f;

		public override Knockback Knockback => new Knockback
		{
			MinDistance = 0f,
			MaxDistance = _bladeRadius.Value,
			MinSpeed = _launchSpeed.Value,
			MaxSpeed = _launchSpeed.Value * 0.6f,
			MinUpwardSpeed = 7f
		};

		public override EquipmentType BorrowModelFrom => (EquipmentType)15;

		public override float BorrowedModelScale => 1.1f;

		public override float BorrowedModelEmission => 2.2f;

		public SliceDriverItem()
		{
			_enabled = ArsenalConfig.Bind("Slice Driver", "Enabled", defaultValue: true, "Add the slice driver to the game.");
			_spawnWeight = ArsenalConfig.Bind("Slice Driver", "SpawnWeight", 5f, "Default item-box weight, before the host's slider.");
			_maxUses = ArsenalConfig.Bind("Slice Driver", "MaxUses", 4, "Lunges per pickup.");
			_dashSpeed = ArsenalConfig.Bind("Slice Driver", "DashSpeed", 26f, "Lunge speed in metres per second.");
			_dashPitch = ArsenalConfig.Bind("Slice Driver", "DashPitchDegrees", 12f, "Upward tilt of the lunge, in degrees. Zero sends it along the ground, where it bites into the first slope it meets.");
			_dashDuration = ArsenalConfig.Bind("Slice Driver", "DashDuration", 0.45f, "How long the blade stays live.");
			_bladeRadius = ArsenalConfig.Bind("Slice Driver", "BladeRadius", 2.2f, "Reach around the player while lunging.");
			_launchSpeed = ArsenalConfig.Bind("Slice Driver", "LaunchSpeed", 26f, "How hard a struck player is thrown.");
		}

		public override IEnumerator Use(PlayerInventory inventory)
		{
			PlayerInfo playerInfo = inventory.PlayerInfo;
			int slotIndex = inventory.EquippedItemIndex;
			inventory.SetCurrentItemUse((ItemUseType)2);
			Transform camera = ((Component)GameManager.Camera).transform;
			if (BMath.Abs(FloatExtensions.WrapAngleDeg(VectorExtensions.GetYawDeg(camera.forward) - playerInfo.Movement.Yaw)) > 10f)
			{
				playerInfo.Movement.AlignWithCameraImmediately();
			}
			yield return (object)new WaitForSeconds(0.1f);
			float value = _dashPitch.Va