Decompiled source of AccurateCrosshair v1.5.0

AccurateCrosshair.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using AccurateCrosshair.CrosshairPatches;
using AccurateCrosshair.PluginDependencies;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using ColorCrosshair.API;
using FirstPersonItem;
using GTFO.API;
using GTFO.API.Utilities;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppSystem;
using Microsoft.CodeAnalysis;
using Player;
using UnityEngine;

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

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

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

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

		public static bool FollowsRecoil { get; private set; }

		public static FirstShotType FirstShotType { get; private set; }

		public static float FirstShotMinDelay { get; private set; }

		public static bool PopEnabled { get; private set; }

		public static float MinSize { get; private set; }

		public static float SpeedScalar { get; private set; }

		public static event Action? OnReload;

		static Configuration()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			FollowsRecoil = true;
			FirstShotType = FirstShotType.Inner;
			FirstShotMinDelay = 0.15f;
			PopEnabled = false;
			MinSize = 10f;
			SpeedScalar = 1f;
			configFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "AccurateCrosshair.cfg"), true);
			BindAll(configFile);
		}

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

		private static void OnFileChanged(LiveEditEventArgs _)
		{
			configFile.Reload();
			string text = "General Settings";
			FollowsRecoil = (bool)configFile[text, "Follow Recoil"].BoxedValue;
			FirstShotType = (FirstShotType)configFile[text, "First Shot Display Mode"].BoxedValue;
			FirstShotMinDelay = (float)configFile[text, "First Shot Min Delay"].BoxedValue;
			PopEnabled = (bool)configFile[text, "Pop Enabled"].BoxedValue;
			MinSize = (float)configFile[text, "Minimum Size"].BoxedValue;
			SpeedScalar = (float)configFile[text, "Resize Modifier"].BoxedValue;
			if (SpeedScalar <= 0f)
			{
				SpeedScalar = 1f;
			}
			Configuration.OnReload?.Invoke();
		}

		private static void BindAll(ConfigFile config)
		{
			string text = "General Settings";
			string text2 = "Follow Recoil";
			string text3 = "Enables or disables the crosshair moving to match weapon recoil that is independent of your aim.";
			FollowsRecoil = config.Bind<bool>(text, text2, FollowsRecoil, text3).Value;
			text2 = "First Shot Display Mode";
			text3 = "Determines how the crosshair shows the hidden bonus accuracy after waiting 2 seconds to shoot.\r\nInner: Shows another circle. Match: Reduces crosshair size to match. None: Turns this off.";
			FirstShotType = config.Bind<FirstShotType>(text, text2, FirstShotType, text3).Value;
			text2 = "First Shot Min Delay";
			text3 = "If First Shot Display Mode is set to Match, the minimum shot delay non-semi automatic weapons need for the first shot effect to appear.";
			FirstShotMinDelay = config.Bind<float>(text, text2, FirstShotMinDelay, text3).Value;
			text2 = "Pop Enabled";
			text3 = "Enables or disables the visual crosshair bloom when shooting.\r\nNote: Pop is not scaled to the accurate size and may be disproportionately large.";
			PopEnabled = config.Bind<bool>(text, text2, PopEnabled, text3).Value;
			text2 = "Minimum Size";
			text3 = "The minimum size of the reticle. Does not scale with field of view.\r\nNote: Cannot be smaller than 10.";
			MinSize = config.Bind<float>(text, text2, MinSize, text3).Value;
			text2 = "Resize Modifier";
			text3 = "Scalar applied to the speed at which the crosshair resizes to its target spread.\r\nNote: Must be larger than 0. Does not affect the resize speed of pop.";
			SpeedScalar = config.Bind<float>(text, text2, SpeedScalar, text3).Value;
			if (SpeedScalar <= 0f)
			{
				SpeedScalar = 1f;
			}
		}
	}
	[BepInPlugin("Dinorush.AccurateCrosshair", "AccurateCrosshair", "1.5.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal sealed class Loader : BasePlugin
	{
		public const string MODNAME = "AccurateCrosshair";

		[Conditional("DEBUG")]
		public static void DebugLog(object data)
		{
		}

		public override void Load()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			((BasePlugin)this).Log.LogMessage((object)"Loading AccurateCrosshair");
			Configuration.Init();
			new Harmony("AccurateCrosshair").PatchAll();
			AssetAPI.OnStartupAssetsLoaded += AssetAPI_OnStartupAssetsLoaded;
			LevelAPI.OnLevelCleanup += LevelAPI_OnLevelCleanup;
			((BasePlugin)this).Log.LogMessage((object)"Loaded AccurateCrosshair");
		}

		private void AssetAPI_OnStartupAssetsLoaded()
		{
			ColorCrosshairDependency.Init();
		}

		private void LevelAPI_OnLevelCleanup()
		{
			SpreadPatches.OnCleanup();
		}
	}
}
namespace AccurateCrosshair.PluginDependencies
{
	internal static class ColorCrosshairDependency
	{
		public static bool HasColorCrosshair => ((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("Dinorush.ColorCrosshair");

		public static Color DefaultColor => ColorCrosshairAPI.DefaultColor;

		public static Color ChargeColor => ColorCrosshairAPI.ChargeColor;

		public static Color ChargeBlinkColor => ColorCrosshairAPI.ChargeBlinkColor;

		public static Color ChargeWarningColor => ColorCrosshairAPI.ChargeWarningColor;

		public static Color EnemyBlinkColor => ColorCrosshairAPI.EnemyBlinkColor;

		public static void Init()
		{
			if (HasColorCrosshair)
			{
				UnsafeInit();
			}
		}

		private static void UnsafeInit()
		{
			FirstShotGuiPatches.RefreshCrosshairColor();
			ColorCrosshairAPI.OnReload += ApplyColorChanges;
		}

		private static void ApplyColorChanges()
		{
			FirstShotGuiPatches.RefreshCrosshairColor();
		}
	}
}
namespace AccurateCrosshair.CrosshairPatches
{
	internal sealed class FirstShotGui : GuiLayer
	{
		private CircleCrosshair? smallCrosshair;

		public override void OnLevelCleanup()
		{
			CircleCrosshair? obj = smallCrosshair;
			if (obj != null)
			{
				((GuiLayerComp)obj).SetVisible(false, false);
			}
		}

		public override void Setup(Transform root, string name)
		{
			//IL_0011: 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)
			((GuiLayer)this).Setup(root, name);
			GuiLayerComp val = ((GuiLayer)this).AddComp("Gui/Crosshairs/CanvasCircleCrosshair", (GuiAnchor)3, default(Vector2), (Transform)null);
			smallCrosshair = ((Il2CppObjectBase)val).TryCast<CircleCrosshair>();
			if ((Object)(object)smallCrosshair != (Object)null)
			{
				smallCrosshair.UpdateAlphaMul(CellSettingsManager.SettingsData.HUD.Player_CrosshairOpacity.Value);
				RefreshColor();
				((GuiLayerComp)smallCrosshair).SetVisible(false, false);
			}
		}

		public void Disable()
		{
			CircleCrosshair? obj = smallCrosshair;
			if (obj != null)
			{
				((GuiLayerComp)obj).SetVisible(false, false);
			}
		}

		public void Enable()
		{
			if (!((Object)(object)smallCrosshair == (Object)null))
			{
				((GuiLayerComp)smallCrosshair).SetVisible(true, false);
				smallCrosshair.SetScale(SpreadPatches.GetCrosshairSize(0.2f) / smallCrosshair.m_circleRadius);
			}
		}

		public void RefreshAlpha()
		{
			CircleCrosshair? obj = smallCrosshair;
			if (obj != null)
			{
				obj.UpdateAlphaMul(CellSettingsManager.SettingsData.HUD.Player_CrosshairOpacity.Value);
			}
		}

		public void RefreshColor()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)smallCrosshair == (Object)null) && ColorCrosshairDependency.HasColorCrosshair)
			{
				CircleCrosshair? obj = smallCrosshair;
				Color color = (smallCrosshair.m_crosshairColOrg = ColorCrosshairDependency.DefaultColor);
				obj.SetColor(color);
			}
		}

		public void RefreshSize()
		{
			CircleCrosshair? obj = smallCrosshair;
			if (obj != null)
			{
				obj.SetScale(SpreadPatches.GetCrosshairSize(0.2f) / smallCrosshair.m_circleRadius);
			}
		}
	}
	[HarmonyPatch]
	internal static class FirstShotGuiPatches
	{
		public static FirstShotGui crosshairGui = new FirstShotGui();

		public static void Disable()
		{
			crosshairGui.Disable();
		}

		public static void Enable(bool forceOn = false)
		{
			if (forceOn || ((GuiLayerComp)SpreadPatches.CrosshairLayer.m_circleCrosshair).GetVisible())
			{
				crosshairGui.Enable();
			}
		}

		public static void RefreshCrosshairColor()
		{
			crosshairGui.RefreshColor();
		}

		public static void RefreshCrosshairSize()
		{
			crosshairGui.RefreshSize();
		}

		[HarmonyPatch(typeof(GuiManager), "Setup")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void SetupSmallCrosshair(GuiManager __instance)
		{
			((GuiLayer)crosshairGui).Setup(__instance.m_root, "SmallCrosshairLayer");
		}

		[HarmonyPatch(typeof(CrosshairGuiLayer), "OnSetVisible")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void MatchLayerVisibility(bool visible)
		{
			((GuiLayer)crosshairGui).SetVisible(visible);
		}

		[HarmonyPatch(typeof(CrosshairGuiLayer), "HideCircleCrosshair")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void MatchCrosshairVisibility()
		{
			crosshairGui.Disable();
		}

		[HarmonyPatch(typeof(CrosshairGuiLayer), "UpdateAlphaFromSettings")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void MatchCrosshairAlpha()
		{
			crosshairGui.RefreshAlpha();
		}
	}
	[HarmonyPatch]
	internal static class FirstShotPatches
	{
		private static Coroutine? firstShotRoutine = null;

		private static float firstShotTime = 0f;

		private static float fireRecoilCooldown = 2f;

		private static void EnableSmallCrosshair(bool forceGuiOn = false)
		{
			if (Configuration.FirstShotType == FirstShotType.Match)
			{
				SpreadPatches.UpdateSpreadScalar(0.2f);
			}
			else if (Configuration.FirstShotType == FirstShotType.Inner)
			{
				FirstShotGuiPatches.Enable(forceGuiOn);
			}
		}

		private static IEnumerator MinimizeAfterDelay()
		{
			while (firstShotTime > Clock.Time)
			{
				yield return (object)new WaitForSeconds(firstShotTime - Clock.Time);
			}
			firstShotRoutine = null;
			EnableSmallCrosshair();
		}

		public static void SetStoredCrosshair(BulletWeapon weapon)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			ArchetypeDataBlock archetypeData = ((ItemEquippable)weapon).ArchetypeData;
			if (Configuration.FirstShotType == FirstShotType.Match && (int)archetypeData.FireMode != 0 && archetypeData.ShotDelay < Configuration.FirstShotMinDelay)
			{
				return;
			}
			fireRecoilCooldown = weapon.m_fireRecoilCooldown;
			firstShotTime = weapon.m_lastFireTime + fireRecoilCooldown;
			if (firstShotTime > Clock.Time)
			{
				if (firstShotRoutine == null)
				{
					firstShotRoutine = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(MinimizeAfterDelay()), (Action)null);
				}
			}
			else
			{
				EnableSmallCrosshair(forceGuiOn: true);
			}
		}

		public static void ResetStoredCrosshair()
		{
			if (firstShotRoutine != null)
			{
				CoroutineManager.StopCoroutine(firstShotRoutine);
				firstShotRoutine = null;
			}
			SpreadPatches.UpdateSpreadScalar(1f);
			FirstShotGuiPatches.Disable();
		}

		[HarmonyPatch(typeof(BulletWeapon), "Fire")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void ResetFirstShotTimer()
		{
			firstShotTime = Clock.Time + fireRecoilCooldown;
			SpreadPatches.UpdateSpreadScalar(1f);
			FirstShotGuiPatches.Disable();
			if (firstShotRoutine == null)
			{
				firstShotRoutine = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(MinimizeAfterDelay()), (Action)null);
			}
		}
	}
	public enum FirstShotType
	{
		None,
		Match,
		Inner
	}
	[HarmonyPatch]
	internal static class PopPatches
	{
		[HarmonyPatch(typeof(CrosshairGuiLayer), "PopCircleCrosshair")]
		[HarmonyPrefix]
		public static bool CancelRecoilPop()
		{
			return Configuration.PopEnabled;
		}
	}
	[HarmonyPatch]
	internal static class RecoilPatches
	{
		[HarmonyPatch(typeof(CrosshairGuiLayer), "ShowSpreadCircle")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void EnableCrosshairMovement(CrosshairGuiLayer __instance)
		{
			if (Configuration.FollowsRecoil)
			{
				__instance.m_moveCircleCrosshair = !SpreadPatches.isShotgun;
			}
		}

		[HarmonyPatch(typeof(FPS_RecoilSystem), "FPS_Update")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void TightCrosshairMovement(FPS_RecoilSystem __instance)
		{
			//IL_0019: 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_002d: 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_0048: 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_0059: 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)
			if (Configuration.FollowsRecoil)
			{
				float scale = SpreadPatches.CrosshairLayer.m_circleCrosshair.GetScale();
				Vector2 val = __instance.CurrentVSPos - new Vector2(0.5f, 0.5f);
				val.y *= 0.78f;
				SpreadPatches.CrosshairLayer.SetCrosshairPosition(val / scale + new Vector2(0.5f, 0.5f));
			}
		}
	}
	[HarmonyPatch]
	internal static class SpreadPatches
	{
		private const float BASE_CROSSHAIR_SIZE = 20f;

		private const float EXTRA_BUFFER_SIZE = 10f;

		public static bool isShotgun;

		private static bool _cachedAim;

		private static bool _validGun;

		public static CrosshairGuiLayer CrosshairLayer;

		private static float _crosshairSpeed;

		private static FirstPersonItemHolder? _cachedHolder;

		private static LerpingPairFloat? _cachedLookFoV;

		private static Coroutine? _smoothRoutine;

		private static float _spreadScalar;

		private static float _targetSpread;

		static SpreadPatches()
		{
			isShotgun = false;
			_cachedAim = false;
			_validGun = false;
			_spreadScalar = 1f;
			Configuration.OnReload += OnConfigReload;
		}

		private static void OnConfigReload()
		{
			if (CrosshairLayer != null)
			{
				CrosshairLayer.m_circleSpeed = _crosshairSpeed * Configuration.SpeedScalar;
				UpdateCrosshairSize();
			}
		}

		public static void UpdateSpreadScalar(float scalar)
		{
			_spreadScalar = scalar;
			UpdateCrosshairSize();
		}

		public static void UpdateCrosshairSize()
		{
			if (_validGun)
			{
				CrosshairGuiLayer crosshairLayer = CrosshairLayer;
				float num = (CrosshairLayer.m_neutralCircleSize = GetCrosshairSize());
				crosshairLayer.ScaleToSize(num);
				if (Configuration.FirstShotType == FirstShotType.Inner)
				{
					FirstShotGuiPatches.RefreshCrosshairSize();
				}
			}
		}

		public static void OnCleanup()
		{
			_cachedAim = false;
			_spreadScalar = 1f;
			_validGun = false;
		}

		[HarmonyPatch(typeof(FirstPersonItemHolder), "Setup")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void UpdateCache(FirstPersonItemHolder __instance)
		{
			_cachedHolder = __instance;
			_cachedLookFoV = __instance.LookCamFov;
		}

		[HarmonyPatch(typeof(FPIS_Aim), "Enter")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void EnterAimState(FPIS_Aim __instance)
		{
			_cachedAim = true;
			if (((Item)((FPItemState)__instance).Holder.WieldedItem).ItemDataBlock.ShowCrosshairWhenAiming)
			{
				CrosshairLayer.ShowSpreadCircle(CrosshairLayer.m_dotSize);
			}
			else if (_smoothRoutine != null)
			{
				CoroutineManager.StopCoroutine(_smoothRoutine);
				_smoothRoutine = null;
			}
		}

		[HarmonyPatch(typeof(FPIS_Aim), "Exit")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void ExitAimState()
		{
			_cachedAim = false;
		}

		[HarmonyPatch(typeof(CrosshairGuiLayer), "ShowSpreadCircle")]
		[HarmonyWrapSafe]
		[HarmonyPrefix]
		private static void AdjustCrosshairSize(ref float crosshairSize)
		{
			if (!OverrideCrosshairSize(ref crosshairSize) && _smoothRoutine != null)
			{
				CoroutineManager.StopCoroutine(_smoothRoutine);
				_smoothRoutine = null;
			}
			else if (_smoothRoutine == null)
			{
				_smoothRoutine = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(ScaleSpreadCircle()), (Action)null);
			}
		}

		private static bool OverrideCrosshairSize(ref float crosshairSize)
		{
			_validGun = false;
			if (_cachedLookFoV == null)
			{
				return false;
			}
			if (Configuration.FirstShotType != 0)
			{
				FirstShotPatches.ResetStoredCrosshair();
			}
			ItemEquippable wieldedItem = PlayerManager.GetLocalPlayerAgent().Inventory.m_wieldedItem;
			BulletWeapon val = ((wieldedItem != null) ? ((Il2CppObjectBase)wieldedItem).TryCast<BulletWeapon>() : null);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			isShotgun = (Object)(object)((Il2CppObjectBase)val).TryCast<Shotgun>() != (Object)null;
			ArchetypeDataBlock archetypeData = ((ItemEquippable)val).ArchetypeData;
			if (archetypeData == null)
			{
				return false;
			}
			_validGun = true;
			float targetSpread = ((!isShotgun) ? (_cachedAim ? archetypeData.AimSpread : archetypeData.HipFireSpread) : ((float)(archetypeData.ShotgunConeSize + archetypeData.ShotgunBulletSpread)));
			_targetSpread = targetSpread;
			if (!isShotgun && Configuration.FirstShotType != 0)
			{
				FirstShotPatches.SetStoredCrosshair(val);
			}
			crosshairSize = GetCrosshairSize();
			return true;
		}

		private static IEnumerator ScaleSpreadCircle()
		{
			while (_validGun && _cachedLookFoV != null && ((LerpingPair<float>)(object)_cachedLookFoV).CurrentLerp < 1f)
			{
				UpdateCrosshairSize();
				yield return null;
			}
			_smoothRoutine = null;
			if (_cachedLookFoV != null)
			{
				UpdateCrosshairSize();
			}
		}

		public static float GetCrosshairSize(float scalar)
		{
			float num = (float)(20.0 / Math.Tan(Math.PI / 180.0 * (double)((LerpingPair<float>)(object)_cachedLookFoV).Current / 2.0));
			return Math.Max(Configuration.MinSize, _targetSpread * num * scalar + 10f);
		}

		public static float GetCrosshairSize()
		{
			return GetCrosshairSize(_spreadScalar);
		}

		[HarmonyPatch(typeof(CrosshairGuiLayer), "Setup")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void AdjustResizeSpeed(CrosshairGuiLayer __instance)
		{
			CrosshairLayer = __instance;
			_crosshairSpeed = __instance.m_circleSpeed;
			__instance.m_circleSpeed *= Configuration.SpeedScalar;
		}
	}
}