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;
}
}
}