Decompiled source of CustomCrosshair v0.1.0

src/RoR2CustomCrosshair/bin/Debug/netstandard2.1/RoR2CustomCrosshair.dll

Decompiled 21 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using On.RoR2.UI;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.UI;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RoR2CustomCrosshair")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("RoR2CustomCrosshair")]
[assembly: AssemblyTitle("RoR2CustomCrosshair")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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;
		}
	}
	[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 RoR2CustomCrosshair
{
	internal static class CrosshairConfig
	{
		private const int CurrentConfigVersion = 2;

		private const float SliderStep = 0.5f;

		internal static ConfigEntry<bool> Enabled;

		internal static BarsSettings InnerBars;

		internal static BarsSettings OuterBars;

		internal static CircleSettings Circle;

		internal static DotSettings CenterDot;

		internal static int Revision { get; private set; }

		internal static void Bind(ConfigFile config)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			bool saveOnConfigSet = config.SaveOnConfigSet;
			config.SaveOnConfigSet = false;
			Enabled = config.Bind<bool>("General", "Enabled", true, "Replace the ordinary crosshair of your own survivor with the custom crosshair.");
			InnerBars = new BarsSettings(config, "Inner Bars", new BarsDefaults
			{
				Enabled = true,
				Length = 8f,
				Thickness = 2f,
				Gap = 4f,
				GapMax = 64f,
				Fill = new Color32((byte)0, byte.MaxValue, (byte)0, byte.MaxValue)
			});
			OuterBars = new BarsSettings(config, "Outer Bars", new BarsDefaults
			{
				Enabled = false,
				Length = 10f,
				Thickness = 2f,
				Gap = 14f,
				GapMax = 128f,
				Fill = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue)
			});
			Circle = new CircleSettings(config, "Circle");
			CenterDot = new DotSettings(config, "Center Dot");
			MigrateFromVersion1(config);
			config.Save();
			config.SaveOnConfigSet = saveOnConfigSet;
			config.SettingChanged += delegate
			{
				Revision++;
			};
		}

		internal static void RegisterRiskOfOptions()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			ModSettingsManager.SetModDescription("Procedural crosshair with Inner Bars, Outer Bars, Circle and Center Dot layers. Sizes are pixels at 1920x1080 and scale with resolution.");
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Enabled));
			InnerBars.Register();
			OuterBars.Register();
			Circle.Register();
			CenterDot.Register();
		}

		private static void MigrateFromVersion1(ConfigFile config)
		{
			ConfigEntry<int> val = config.Bind<int>("Internal", "Config Version", 0, "Settings layout version, used for migration. Do not edit.");
			if (val.Value < 2)
			{
				BarsSettings innerBars = InnerBars;
				Move<float>(config, "Crosshair", "Length", innerBars.Length);
				Move<float>(config, "Crosshair", "Thickness", innerBars.Thickness);
				Move<float>(config, "Crosshair", "Gap", innerBars.Gap);
				Move<int>(config, "Crosshair Color", "Opacity", innerBars.Fill.Opacity);
				Move<int>(config, "Crosshair Color", "R", innerBars.Fill.Red);
				Move<int>(config, "Crosshair Color", "G", innerBars.Fill.Green);
				Move<int>(config, "Crosshair Color", "B", innerBars.Fill.Blue);
				Move<bool>(config, "Outline", "Enabled", innerBars.Outline.Enabled);
				Move<float>(config, "Outline", "Thickness", innerBars.Outline.Thickness);
				Move<int>(config, "Outline Color", "Opacity", innerBars.Outline.Color.Opacity);
				Move<int>(config, "Outline Color", "R", innerBars.Outline.Color.Red);
				Move<int>(config, "Outline Color", "G", innerBars.Outline.Color.Green);
				Move<int>(config, "Outline Color", "B", innerBars.Outline.Color.Blue);
				val.Value = 2;
				Plugin.Log.LogInfo((object)"Migrated crosshair settings to the layered layout (old values now under 'Inner Bars').");
			}
		}

		private static void Move<T>(ConfigFile config, string oldSection, string oldKey, ConfigEntry<T> target)
		{
			ConfigEntry<T> val = config.Bind<T>(oldSection, oldKey, (T)((ConfigEntryBase)target).DefaultValue, (ConfigDescription)null);
			target.Value = val.Value;
			config.Remove(((ConfigEntryBase)val).Definition);
		}

		internal static ConfigEntry<float> BindFloat(ConfigFile config, string section, string key, float defaultValue, float min, float max, string description)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			return config.Bind<float>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), Array.Empty<object>()));
		}

		internal static ConfigEntry<int> BindByte(ConfigFile config, string section, string key, int defaultValue)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			return config.Bind<int>(section, key, defaultValue, new ConfigDescription(key + " value from 0 to 255.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 255), Array.Empty<object>()));
		}

		internal static void AddFloatOption(ConfigEntry<float> entry, float min, float max)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new StepSliderOption(entry, new StepSliderConfig
			{
				min = min,
				max = max,
				increment = 0.5f,
				FormatString = "{0:0.0}"
			}));
		}

		internal static void AddByteOption(ConfigEntry<int> entry)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(entry, new IntSliderConfig
			{
				min = 0,
				max = 255
			}));
		}
	}
	internal sealed class ColorSettings
	{
		internal readonly ConfigEntry<int> Red;

		internal readonly ConfigEntry<int> Green;

		internal readonly ConfigEntry<int> Blue;

		internal readonly ConfigEntry<int> Opacity;

		internal Color Value => new Color((float)Red.Value / 255f, (float)Green.Value / 255f, (float)Blue.Value / 255f, (float)Opacity.Value / 255f);

		internal ColorSettings(ConfigFile config, string section, string keyPrefix, Color32 defaults)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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)
			Red = CrosshairConfig.BindByte(config, section, keyPrefix + "R", defaults.r);
			Green = CrosshairConfig.BindByte(config, section, keyPrefix + "G", defaults.g);
			Blue = CrosshairConfig.BindByte(config, section, keyPrefix + "B", defaults.b);
			Opacity = CrosshairConfig.BindByte(config, section, keyPrefix + "Opacity", defaults.a);
		}

		internal void Register()
		{
			CrosshairConfig.AddByteOption(Red);
			CrosshairConfig.AddByteOption(Green);
			CrosshairConfig.AddByteOption(Blue);
			CrosshairConfig.AddByteOption(Opacity);
		}
	}
	internal sealed class OutlineSettings
	{
		internal const float MaxThickness = 10f;

		internal readonly ConfigEntry<bool> Enabled;

		internal readonly ConfigEntry<float> Thickness;

		internal readonly ColorSettings Color;

		internal bool Visible => Enabled.Value && Thickness.Value > 0.001f;

		internal OutlineSettings(ConfigFile config, string section)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			Enabled = config.Bind<bool>(section, "Outline Enabled", true, "Draw a border around this layer.");
			Thickness = CrosshairConfig.BindFloat(config, section, "Outline Thickness", 1f, 0f, 10f, "Border width on each side, in pixels at 1920x1080.");
			Color = new ColorSettings(config, section, "Outline ", new Color32((byte)0, (byte)0, (byte)0, byte.MaxValue));
		}

		internal void Register()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Enabled));
			CrosshairConfig.AddFloatOption(Thickness, 0f, 10f);
			Color.Register();
		}
	}
	internal struct BarsDefaults
	{
		internal bool Enabled;

		internal float Length;

		internal float Thickness;

		internal float Gap;

		internal float GapMax;

		internal Color32 Fill;
	}
	internal sealed class BarsSettings
	{
		internal const float MaxLength = 64f;

		internal const float MaxThickness = 20f;

		private readonly float _gapMax;

		internal readonly ConfigEntry<bool> Enabled;

		internal readonly ConfigEntry<CrosshairMode> Mode;

		internal readonly ConfigEntry<float> Length;

		internal readonly ConfigEntry<float> Thickness;

		internal readonly ConfigEntry<float> Gap;

		internal readonly ColorSettings Fill;

		internal readonly OutlineSettings Outline;

		internal BarsSettings(ConfigFile config, string section, BarsDefaults defaults)
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			_gapMax = defaults.GapMax;
			Enabled = config.Bind<bool>(section, "Enabled", defaults.Enabled, "Show the " + section + ".");
			Mode = config.Bind<CrosshairMode>(section, "Mode", CrosshairMode.Static, "Static: fixed gap. Dynamic: gap will follow actual weapon spread (not implemented yet; currently same as Static).");
			Length = CrosshairConfig.BindFloat(config, section, "Length", defaults.Length, 0.5f, 64f, "Length of each arm, in pixels at 1920x1080.");
			Thickness = CrosshairConfig.BindFloat(config, section, "Thickness", defaults.Thickness, 0.5f, 20f, "Thickness of each arm, in pixels at 1920x1080.");
			Gap = CrosshairConfig.BindFloat(config, section, "Gap", defaults.Gap, 0f, _gapMax, "Distance from screen center to the inner edge of each arm, in pixels at 1920x1080.");
			Fill = new ColorSettings(config, section, "", defaults.Fill);
			Outline = new OutlineSettings(config, section);
		}

		internal void Register()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Enabled));
			ModSettingsManager.AddOption((BaseOption)new ChoiceOption((ConfigEntryBase)(object)Mode));
			CrosshairConfig.AddFloatOption(Length, 0.5f, 64f);
			CrosshairConfig.AddFloatOption(Thickness, 0.5f, 20f);
			CrosshairConfig.AddFloatOption(Gap, 0f, _gapMax);
			Fill.Register();
			Outline.Register();
		}
	}
	internal sealed class CircleSettings
	{
		internal const float MaxRadius = 128f;

		internal const float MaxThickness = 20f;

		internal readonly ConfigEntry<bool> Enabled;

		internal readonly ConfigEntry<CrosshairMode> Mode;

		internal readonly ConfigEntry<float> Radius;

		internal readonly ConfigEntry<float> Thickness;

		internal readonly ColorSettings Fill;

		internal readonly OutlineSettings Outline;

		internal CircleSettings(ConfigFile config, string section)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			Enabled = config.Bind<bool>(section, "Enabled", false, "Show the circle.");
			Mode = config.Bind<CrosshairMode>(section, "Mode", CrosshairMode.Static, "Static: fixed radius. Dynamic: radius will follow actual weapon spread (not implemented yet; currently same as Static).");
			Radius = CrosshairConfig.BindFloat(config, section, "Radius", 16f, 0f, 128f, "Distance from screen center to the inner edge of the ring, in pixels at 1920x1080.");
			Thickness = CrosshairConfig.BindFloat(config, section, "Thickness", 2f, 0.5f, 20f, "Ring thickness, in pixels at 1920x1080.");
			Fill = new ColorSettings(config, section, "", new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue));
			Outline = new OutlineSettings(config, section);
		}

		internal void Register()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Enabled));
			ModSettingsManager.AddOption((BaseOption)new ChoiceOption((ConfigEntryBase)(object)Mode));
			CrosshairConfig.AddFloatOption(Radius, 0f, 128f);
			CrosshairConfig.AddFloatOption(Thickness, 0.5f, 20f);
			Fill.Register();
			Outline.Register();
		}
	}
	internal sealed class DotSettings
	{
		internal const float MaxSize = 20f;

		internal readonly ConfigEntry<bool> Enabled;

		internal readonly ConfigEntry<float> Size;

		internal readonly ColorSettings Fill;

		internal readonly OutlineSettings Outline;

		internal DotSettings(ConfigFile config, string section)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			Enabled = config.Bind<bool>(section, "Enabled", false, "Show the center dot.");
			Size = CrosshairConfig.BindFloat(config, section, "Size", 2f, 0.5f, 20f, "Width and height of the dot, in pixels at 1920x1080.");
			Fill = new ColorSettings(config, section, "", new Color32((byte)0, byte.MaxValue, (byte)0, byte.MaxValue));
			Outline = new OutlineSettings(config, section);
		}

		internal void Register()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Enabled));
			CrosshairConfig.AddFloatOption(Size, 0.5f, 20f);
			Fill.Register();
			Outline.Register();
		}
	}
	internal readonly struct PixelFrame
	{
		internal readonly float ResolutionScale;

		internal readonly float PixelsPerUnit;

		internal readonly float CenterFraction;

		internal readonly Vector2 Center;

		internal readonly Vector2 OriginOffset;

		internal PixelFrame(float resolutionScale, float pixelsPerUnit, float centerFraction, Vector2 anchorScreen, Vector2 rootScreen)
		{
			//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_0031: 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_0042: 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)
			ResolutionScale = resolutionScale;
			PixelsPerUnit = pixelsPerUnit;
			CenterFraction = centerFraction;
			Center = new Vector2(SnapToGrid(anchorScreen.x, centerFraction), SnapToGrid(anchorScreen.y, centerFraction));
			OriginOffset = Center - rootScreen;
		}

		internal static float FractionFor(float logicalSize, float resolutionScale)
		{
			return (Mathf.Max(1, RoundPx(logicalSize * resolutionScale)) % 2 == 0) ? 0f : 0.5f;
		}

		internal int Width(float logical)
		{
			return Mathf.Max(1, RoundPx(logical * ResolutionScale));
		}

		internal int CenteredSize(float logical)
		{
			float num = logical * ResolutionScale;
			if (CenterFraction == 0f)
			{
				return Mathf.Max(2, 2 * RoundPx(num * 0.5f));
			}
			return Mathf.Max(1, 2 * (int)Mathf.Floor(num * 0.5f) + 1);
		}

		internal float EdgeDistance(float logical)
		{
			return Mathf.Floor(CenterFraction + Mathf.Max(0f, logical) * ResolutionScale + 0.5f) - CenterFraction;
		}

		internal float ToLocal(float pixels)
		{
			return pixels / PixelsPerUnit;
		}

		internal void Place(RectTransform rect, Vector4 pixelRect)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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)
			//IL_001c: 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_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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor((pixelRect.x + pixelRect.z) * 0.5f, (pixelRect.y + pixelRect.w) * 0.5f);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(pixelRect.z - pixelRect.x, pixelRect.w - pixelRect.y);
			rect.anchoredPosition = (OriginOffset + val) / PixelsPerUnit;
			rect.sizeDelta = val2 / PixelsPerUnit;
		}

		internal static int RoundPx(float value)
		{
			return (int)Mathf.Floor(value + 0.5f);
		}

		private static float SnapToGrid(float value, float fraction)
		{
			return Mathf.Floor(value - fraction + 0.5f) + fraction;
		}
	}
	internal sealed class BorderedRect
	{
		private static readonly string[] SideNames = new string[4] { "Top", "Bottom", "Left", "Right" };

		private readonly Image _fill;

		private readonly Image[] _strips = (Image[])(object)new Image[4];

		private BorderedRect(Transform layer, string name)
		{
			_fill = Find(layer, "Fill" + name);
			for (int i = 0; i < 4; i++)
			{
				_strips[i] = Find(layer, "Outline" + name + SideNames[i]);
			}
		}

		internal static BorderedRect Bind(Transform layer, string name)
		{
			return new BorderedRect(layer, name);
		}

		internal static void BuildBorder(Transform layer, string name)
		{
			string[] sideNames = SideNames;
			foreach (string text in sideNames)
			{
				CrosshairPrefabFactory.CreateImage("Outline" + name + text, layer);
			}
		}

		internal static void BuildFill(Transform layer, string name)
		{
			CrosshairPrefabFactory.CreateImage("Fill" + name, layer);
		}

		internal void Apply(in PixelFrame frame, Vector4 r, Color fill, int border, Color borderColor)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00a1: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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)
			//IL_00ed: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			Show(_fill, in frame, r, fill);
			if (border <= 0)
			{
				Image[] strips = _strips;
				foreach (Image val in strips)
				{
					((Behaviour)val).enabled = false;
				}
			}
			else
			{
				float num = border;
				Show(_strips[0], in frame, new Vector4(r.x - num, r.w, r.z + num, r.w + num), borderColor);
				Show(_strips[1], in frame, new Vector4(r.x - num, r.y - num, r.z + num, r.y), borderColor);
				Show(_strips[2], in frame, new Vector4(r.x - num, r.y, r.x, r.w), borderColor);
				Show(_strips[3], in frame, new Vector4(r.z, r.y, r.z + num, r.w), borderColor);
			}
		}

		internal void Hide()
		{
			((Behaviour)_fill).enabled = false;
			Image[] strips = _strips;
			foreach (Image val in strips)
			{
				((Behaviour)val).enabled = false;
			}
		}

		private static void Show(Image image, in PixelFrame frame, Vector4 r, Color color)
		{
			//IL_0008: 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)
			frame.Place(((Graphic)image).rectTransform, r);
			((Graphic)image).color = color;
			((Behaviour)image).enabled = true;
		}

		private static Image Find(Transform layer, string name)
		{
			return ((Component)layer.Find(name)).GetComponent<Image>();
		}
	}
	internal sealed class BarsLayer
	{
		private static readonly string[] ArmNames = new string[4] { "Left", "Right", "Top", "Bottom" };

		private readonly BarsSettings _settings;

		private readonly BorderedRect[] _arms = new BorderedRect[4];

		internal bool Enabled => _settings.Enabled.Value;

		internal float Thickness => _settings.Thickness.Value;

		internal BarsLayer(Transform root, string layerName, BarsSettings settings)
		{
			_settings = settings;
			Transform layer = root.Find(layerName);
			for (int i = 0; i < 4; i++)
			{
				_arms[i] = BorderedRect.Bind(layer, ArmNames[i]);
			}
		}

		internal static void Build(Transform root, string layerName)
		{
			Transform layer = (Transform)(object)CrosshairPrefabFactory.CreateRect(layerName, root);
			string[] armNames = ArmNames;
			foreach (string name in armNames)
			{
				BorderedRect.BuildBorder(layer, name);
			}
			string[] armNames2 = ArmNames;
			foreach (string name2 in armNames2)
			{
				BorderedRect.BuildFill(layer, name2);
			}
		}

		internal void Apply(in PixelFrame frame, float dynamicOffset)
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			if (!Enabled)
			{
				BorderedRect[] arms = _arms;
				foreach (BorderedRect borderedRect in arms)
				{
					borderedRect.Hide();
				}
				return;
			}
			float num = _settings.Gap.Value;
			if (_settings.Mode.Value == CrosshairMode.Dynamic)
			{
				num += dynamicOffset;
			}
			float num2 = (float)frame.CenteredSize(_settings.Thickness.Value) * 0.5f;
			float num3 = frame.EdgeDistance(num);
			float num4 = num3 + (float)frame.Width(_settings.Length.Value);
			Color value = _settings.Fill.Value;
			Color value2 = _settings.Outline.Color.Value;
			int border = (_settings.Outline.Visible ? frame.Width(_settings.Outline.Thickness.Value) : 0);
			_arms[0].Apply(in frame, new Vector4(0f - num4, 0f - num2, 0f - num3, num2), value, border, value2);
			_arms[1].Apply(in frame, new Vector4(num3, 0f - num2, num4, num2), value, border, value2);
			_arms[2].Apply(in frame, new Vector4(0f - num2, num3, num2, num4), value, border, value2);
			_arms[3].Apply(in frame, new Vector4(0f - num2, 0f - num4, num2, 0f - num3), value, border, value2);
		}
	}
	internal sealed class CenterDotLayer
	{
		private const string DotName = "Dot";

		private readonly DotSettings _settings;

		private readonly BorderedRect _dot;

		internal bool Enabled => _settings.Enabled.Value;

		internal float Size => _settings.Size.Value;

		internal CenterDotLayer(Transform root, string layerName, DotSettings settings)
		{
			_settings = settings;
			_dot = BorderedRect.Bind(root.Find(layerName), "Dot");
		}

		internal static void Build(Transform root, string layerName)
		{
			Transform layer = (Transform)(object)CrosshairPrefabFactory.CreateRect(layerName, root);
			BorderedRect.BuildBorder(layer, "Dot");
			BorderedRect.BuildFill(layer, "Dot");
		}

		internal void Apply(in PixelFrame frame)
		{
			//IL_007c: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			if (!Enabled)
			{
				_dot.Hide();
				return;
			}
			float num = (float)frame.CenteredSize(_settings.Size.Value) * 0.5f;
			int border = (_settings.Outline.Visible ? frame.Width(_settings.Outline.Thickness.Value) : 0);
			_dot.Apply(in frame, new Vector4(0f - num, 0f - num, num, num), _settings.Fill.Value, border, _settings.Outline.Color.Value);
		}
	}
	internal sealed class CircleLayer
	{
		private const string RingName = "Ring";

		private const float SegmentPixels = 1.5f;

		private const int MinSegments = 24;

		private const int MaxSegments = 512;

		private readonly CircleSettings _settings;

		private readonly RingMesh _ring;

		private readonly Image _image;

		internal CircleLayer(Transform root, string layerName, CircleSettings settings)
		{
			_settings = settings;
			_ring = ((Component)root.Find(layerName).Find("Ring")).GetComponent<RingMesh>();
			_image = _ring.Image;
		}

		internal static void Build(Transform root, string layerName)
		{
			Transform val = (Transform)(object)CrosshairPrefabFactory.CreateRect(layerName, root);
			CrosshairPrefabFactory.CreateImage("Ring", val);
			((Component)val.Find("Ring")).gameObject.AddComponent<RingMesh>();
		}

		internal void Apply(in PixelFrame frame, float dynamicOffset)
		{
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			if (!_settings.Enabled.Value)
			{
				((Behaviour)_image).enabled = false;
				return;
			}
			float num = _settings.Radius.Value;
			if (_settings.Mode.Value == CrosshairMode.Dynamic)
			{
				num += dynamicOffset;
			}
			float num2 = frame.EdgeDistance(num);
			float num3 = num2 + (float)frame.Width(_settings.Thickness.Value);
			int num4 = (_settings.Outline.Visible ? frame.Width(_settings.Outline.Thickness.Value) : 0);
			float num5 = num3 + (float)num4 + 1f;
			int segments = Mathf.Clamp(Mathf.CeilToInt(MathF.PI * 2f * (num3 + (float)num4) / 1.5f), 24, 512);
			frame.Place(((Graphic)_image).rectTransform, new Vector4(0f - num5, 0f - num5, num5, num5));
			((Graphic)_image).color = Color.white;
			_ring.SetShape(frame.ToLocal(num2), frame.ToLocal(num3), frame.ToLocal(num4), frame.ToLocal(1f), _settings.Fill.Value, _settings.Outline.Color.Value, segments);
			((Behaviour)_image).enabled = true;
		}
	}
	internal enum CrosshairMode
	{
		Static,
		Dynamic
	}
	internal static class CrosshairPrefabFactory
	{
		private const string StandardCrosshairAddress = "RoR2/Base/UI/StandardCrosshair.prefab";

		internal const string ProceduralRootName = "ProceduralCrosshair";

		internal const string CircleLayerName = "Circle";

		internal const string OuterBarsLayerName = "OuterBars";

		internal const string InnerBarsLayerName = "InnerBars";

		internal const string CenterDotLayerName = "CenterDot";

		internal static void CreateAsync(Transform holder, Action<GameObject?> onCreated)
		{
			//IL_001a: 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)
			AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/UI/StandardCrosshair.prefab");
			val.Completed += delegate(AsyncOperationHandle<GameObject> op)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Invalid comparison between Unknown and I4
				if ((int)op.Status != 1 || (Object)(object)op.Result == (Object)null)
				{
					Plugin.Log.LogError((object)string.Format("Could not load '{0}': {1}", "RoR2/Base/UI/StandardCrosshair.prefab", op.OperationException));
					onCreated(null);
					return;
				}
				try
				{
					onCreated(Build(op.Result, holder));
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"Could not build crosshair template: {arg}");
					onCreated(null);
				}
			};
		}

		private static GameObject Build(GameObject standardCrosshair, Transform holder)
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(standardCrosshair, holder, false);
			((Object)val).name = "RoR2CustomCrosshair";
			Plugin.Log.LogDebug((object)("StandardCrosshair components: " + string.Join(", ", from c in val.GetComponents<Component>()
				select ((object)c).GetType().Name)));
			CrosshairController val2 = default(CrosshairController);
			HudElement val3 = default(HudElement);
			if (!val.TryGetComponent<CrosshairController>(ref val2) || !val.TryGetComponent<HudElement>(ref val3))
			{
				throw new InvalidOperationException("StandardCrosshair no longer has CrosshairController + HudElement.");
			}
			val2.spriteSpreadPositions = Array.Empty<SpritePosition>();
			val2.skillStockSpriteDisplays = Array.Empty<SkillStockSpriteDisplay>();
			val2.remapSprites = Array.Empty<RawImage>();
			foreach (Transform item in val.transform)
			{
				Transform val4 = item;
				((Component)val4).gameObject.SetActive(false);
			}
			Graphic[] components = val.GetComponents<Graphic>();
			foreach (Graphic val5 in components)
			{
				((Behaviour)val5).enabled = false;
			}
			RectTransform root = CreateRect("ProceduralCrosshair", val.transform);
			CircleLayer.Build((Transform)(object)root, "Circle");
			BarsLayer.Build((Transform)(object)root, "OuterBars");
			BarsLayer.Build((Transform)(object)root, "InnerBars");
			CenterDotLayer.Build((Transform)(object)root, "CenterDot");
			val.AddComponent<ProceduralCrosshairView>();
			return val;
		}

		internal static RectTransform CreateRect(string name, Transform parent)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_007f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent(parent, false);
			val2.anchorMin = new Vector2(0.5f, 0.5f);
			val2.anchorMax = new Vector2(0.5f, 0.5f);
			val2.pivot = new Vector2(0.5f, 0.5f);
			val2.anchoredPosition = Vector2.zero;
			val2.sizeDelta = Vector2.zero;
			return val2;
		}

		internal static void CreateImage(string name, Transform parent)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = CreateRect(name, parent);
			((Component)val).gameObject.AddComponent<CanvasRenderer>();
			Image val2 = ((Component)val).gameObject.AddComponent<Image>();
			((Graphic)val2).raycastTarget = false;
			((MaskableGraphic)val2).maskable = false;
			((Graphic)val2).color = Color.clear;
			((Behaviour)val2).enabled = false;
		}
	}
	internal sealed class HudCrosshairDriver : MonoBehaviour
	{
		private const string GenericSprintCrosshairPath = "Prefabs/Crosshair/SprintingCrosshair";

		private static GameObject? _genericSprintCrosshair;

		private static bool _genericSprintCrosshairLoaded;

		private CrosshairManager? _crosshairManager;

		private bool _replacing;

		internal static void Attach(HUD hud)
		{
			if (!Object.op_Implicit((Object)(object)((Component)hud).GetComponent<HudCrosshairDriver>()))
			{
				((Component)hud).gameObject.AddComponent<HudCrosshairDriver>();
			}
		}

		private void Awake()
		{
			_crosshairManager = ((Component)this).GetComponent<CrosshairManager>();
			if (!Object.op_Implicit((Object)(object)_crosshairManager))
			{
				Plugin.Log.LogWarning((object)("HUD '" + ((Object)this).name + "' has no CrosshairManager; custom crosshair unavailable."));
			}
		}

		private void OnEnable()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			if (Object.op_Implicit((Object)(object)_crosshairManager))
			{
				_crosshairManager.pickCrosshairGlobal += new PickCrosshairDelegate(OnPickCrosshair);
			}
		}

		private void OnDisable()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			if (Object.op_Implicit((Object)(object)_crosshairManager))
			{
				_crosshairManager.pickCrosshairGlobal -= new PickCrosshairDelegate(OnPickCrosshair);
			}
			SetReplacing(replacing: false, null);
		}

		private void OnPickCrosshair(CrosshairManager manager, ref GameObject crosshairPrefab)
		{
			GameObject crosshairPrefab2 = Plugin.CrosshairPrefab;
			CharacterBody ownLiveBody = GetOwnLiveBody(manager);
			bool flag = (Object)(object)crosshairPrefab2 != (Object)null && (Object)(object)ownLiveBody != (Object)null && CrosshairConfig.Enabled.Value && (IsOrdinaryCrosshair(ownLiveBody, crosshairPrefab) || IsGenericSprintCrosshair(ownLiveBody, crosshairPrefab));
			if (flag)
			{
				crosshairPrefab = crosshairPrefab2;
			}
			SetReplacing(flag, ownLiveBody);
		}

		private static CharacterBody? GetOwnLiveBody(CrosshairManager manager)
		{
			CameraRigController cameraRigController = manager.cameraRigController;
			if (!Object.op_Implicit((Object)(object)cameraRigController) || cameraRigController.hasOverride)
			{
				return null;
			}
			LocalUser localUserViewer = cameraRigController.localUserViewer;
			CharacterBody targetBody = cameraRigController.targetBody;
			if (localUserViewer == null || !Object.op_Implicit((Object)(object)targetBody) || (Object)(object)localUserViewer.cachedBodyObject != (Object)(object)((Component)targetBody).gameObject)
			{
				return null;
			}
			if (!Object.op_Implicit((Object)(object)targetBody.healthComponent) || !targetBody.healthComponent.alive)
			{
				return null;
			}
			return targetBody;
		}

		private static bool IsOrdinaryCrosshair(CharacterBody body, GameObject picked)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Invalid comparison between Unknown and I4
			if (!Object.op_Implicit((Object)(object)picked))
			{
				return false;
			}
			if ((Object)(object)picked == (Object)(object)body.defaultCrosshairPrefab)
			{
				return true;
			}
			SkillCrosshairController val = default(SkillCrosshairController);
			if (((Component)body).TryGetComponent<SkillCrosshairController>(ref val) && val.options != null)
			{
				SkillDefCrosshairOptions[] options = val.options;
				foreach (SkillDefCrosshairOptions val2 in options)
				{
					if (val2 != null && (int)val2.priority < 1 && (Object)(object)val2.crosshairPrefab == (Object)(object)picked)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool IsGenericSprintCrosshair(CharacterBody body, GameObject picked)
		{
			if (!Object.op_Implicit((Object)(object)picked) || !body.isSprinting || !body.useSprintCrosshair || Object.op_Implicit((Object)(object)body.sprintCrosshairPrefabOverride))
			{
				return false;
			}
			GameObject genericSprintCrosshair = GetGenericSprintCrosshair();
			return (Object)(object)genericSprintCrosshair != (Object)null && (Object)(object)picked == (Object)(object)genericSprintCrosshair;
		}

		private static GameObject? GetGenericSprintCrosshair()
		{
			if (!_genericSprintCrosshairLoaded)
			{
				_genericSprintCrosshairLoaded = true;
				_genericSprintCrosshair = LegacyResourcesAPI.Load<GameObject>("Prefabs/Crosshair/SprintingCrosshair");
				if ((Object)(object)_genericSprintCrosshair == (Object)null)
				{
					Plugin.Log.LogWarning((object)"Could not load 'Prefabs/Crosshair/SprintingCrosshair'; the vanilla sprint crosshair will be shown.");
				}
			}
			return _genericSprintCrosshair;
		}

		private void SetReplacing(bool replacing, CharacterBody? body)
		{
			if (replacing != _replacing)
			{
				_replacing = replacing;
				Plugin.Log.LogDebug((object)(replacing ? ("Custom crosshair active for " + body.GetDisplayName() + " (" + ((Object)body).name + ").") : "Custom crosshair released; vanilla crosshair logic in control."));
			}
		}
	}
	[BepInPlugin("com.example.ror2customcrosshair", "RoR2 Custom Crosshair", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__HUD_Awake;
		}

		public const string PluginGuid = "com.example.ror2customcrosshair";

		public const string PluginName = "RoR2 Custom Crosshair";

		public const string PluginVersion = "0.1.0";

		private GameObject? _prefabHolder;

		internal static ManualLogSource Log { get; private set; }

		internal static GameObject? CrosshairPrefab { get; private set; }

		private void Awake()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			CrosshairConfig.Bind(((BaseUnityPlugin)this).Config);
			CrosshairConfig.RegisterRiskOfOptions();
			_prefabHolder = new GameObject("RoR2CustomCrosshair_Templates");
			_prefabHolder.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)_prefabHolder);
			CrosshairPrefabFactory.CreateAsync(_prefabHolder.transform, delegate(GameObject? template)
			{
				CrosshairPrefab = template;
				if ((Object)(object)template != (Object)null)
				{
					Log.LogInfo((object)"Crosshair template ready.");
				}
				else
				{
					Log.LogError((object)"Crosshair template unavailable; vanilla crosshairs will be used.");
				}
			});
			object obj = <>O.<0>__HUD_Awake;
			if (obj == null)
			{
				hook_Awake val = HUD_Awake;
				<>O.<0>__HUD_Awake = val;
				obj = (object)val;
			}
			HUD.Awake += (hook_Awake)obj;
			Log.LogInfo((object)"RoR2 Custom Crosshair 0.1.0 loaded.");
		}

		private static void HUD_Awake(orig_Awake orig, HUD self)
		{
			orig.Invoke(self);
			HudCrosshairDriver.Attach(self);
		}

		private void OnDestroy()
		{
			//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)
			//IL_001c: Expected O, but got Unknown
			object obj = <>O.<0>__HUD_Awake;
			if (obj == null)
			{
				hook_Awake val = HUD_Awake;
				<>O.<0>__HUD_Awake = val;
				obj = (object)val;
			}
			HUD.Awake -= (hook_Awake)obj;
			HudCrosshairDriver[] array = Object.FindObjectsOfType<HudCrosshairDriver>();
			foreach (HudCrosshairDriver hudCrosshairDriver in array)
			{
				Object.Destroy((Object)(object)hudCrosshairDriver);
			}
			CrosshairPrefab = null;
			if ((Object)(object)_prefabHolder != (Object)null)
			{
				Object.Destroy((Object)(object)_prefabHolder);
			}
		}
	}
	internal readonly struct DynamicOffsets : IEquatable<DynamicOffsets>
	{
		internal readonly float InnerBars;

		internal readonly float OuterBars;

		internal readonly float Circle;

		internal DynamicOffsets(float innerBars, float outerBars, float circle)
		{
			InnerBars = innerBars;
			OuterBars = outerBars;
			Circle = circle;
		}

		public bool Equals(DynamicOffsets other)
		{
			return InnerBars == other.InnerBars && OuterBars == other.OuterBars && Circle == other.Circle;
		}
	}
	internal sealed class ProceduralCrosshairView : MonoBehaviour
	{
		private const float ReferenceWidth = 1920f;

		private const float ReferenceHeight = 1080f;

		private static int _loggedScreenWidth = -1;

		private static int _loggedScreenHeight = -1;

		private static float _loggedPixelsPerUnit = -1f;

		private RectTransform _rect = null;

		private RectTransform _root = null;

		private CircleLayer _circle = null;

		private BarsLayer _outerBars = null;

		private BarsLayer _innerBars = null;

		private CenterDotLayer _centerDot = null;

		private Canvas? _canvas;

		private int _lastRevision = -1;

		private int _lastScreenWidth = -1;

		private int _lastScreenHeight = -1;

		private float _lastPixelsPerUnit = -1f;

		private Vector2 _lastRootScreen;

		private Vector2 _lastAnchorScreen;

		private DynamicOffsets _lastOffsets;

		internal DynamicOffsets Offsets { get; set; }

		private void Awake()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			_rect = (RectTransform)((Component)this).transform;
			_root = (RectTransform)((Component)this).transform.Find("ProceduralCrosshair");
			_circle = new CircleLayer((Transform)(object)_root, "Circle", CrosshairConfig.Circle);
			_outerBars = new BarsLayer((Transform)(object)_root, "OuterBars", CrosshairConfig.OuterBars);
			_innerBars = new BarsLayer((Transform)(object)_root, "InnerBars", CrosshairConfig.InnerBars);
			_centerDot = new CenterDotLayer((Transform)(object)_root, "CenterDot", CrosshairConfig.CenterDot);
			Refresh();
		}

		private void OnTransformParentChanged()
		{
			_canvas = null;
		}

		private void LateUpdate()
		{
			Refresh();
		}

		private void Refresh()
		{
			//IL_0065: 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_0087: 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_008f: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_canvas == (Object)null)
			{
				_canvas = ((Component)this).GetComponentInParent<Canvas>();
				if ((Object)(object)_canvas == (Object)null)
				{
					return;
				}
			}
			Canvas rootCanvas = _canvas.rootCanvas;
			float pixelsPerUnit = GetPixelsPerUnit(rootCanvas);
			if (pixelsPerUnit <= 0f)
			{
				return;
			}
			Camera val = (((int)rootCanvas.renderMode == 0) ? null : rootCanvas.worldCamera);
			Vector2 val2 = RectTransformUtility.WorldToScreenPoint(val, ((Transform)_root).position);
			Vector2 val3 = RectTransformUtility.WorldToScreenPoint(val, GetIntendedCenterWorld());
			DynamicOffsets offsets = Offsets;
			if (_lastRevision == CrosshairConfig.Revision && _lastScreenWidth == Screen.width && _lastScreenHeight == Screen.height && Mathf.Approximately(_lastPixelsPerUnit, pixelsPerUnit))
			{
				Vector2 val4 = _lastRootScreen - val2;
				if (((Vector2)(ref val4)).sqrMagnitude < 1E-06f)
				{
					val4 = _lastAnchorScreen - val3;
					if (((Vector2)(ref val4)).sqrMagnitude < 1E-06f && _lastOffsets.Equals(offsets))
					{
						return;
					}
				}
			}
			PixelFrame frame = CreateFrame(pixelsPerUnit, val3, val2);
			_circle.Apply(in frame, offsets.Circle);
			_outerBars.Apply(in frame, offsets.OuterBars);
			_innerBars.Apply(in frame, offsets.InnerBars);
			_centerDot.Apply(in frame);
			LogLayoutOnce(rootCanvas, in frame, val2, val3);
			_lastRevision = CrosshairConfig.Revision;
			_lastScreenWidth = Screen.width;
			_lastScreenHeight = Screen.height;
			_lastPixelsPerUnit = pixelsPerUnit;
			_lastRootScreen = val2;
			_lastAnchorScreen = val3;
			_lastOffsets = offsets;
		}

		private PixelFrame CreateFrame(float pixelsPerUnit, Vector2 anchorScreen, Vector2 rootScreen)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			float resolutionScale = Mathf.Min((float)Screen.width / 1920f, (float)Screen.height / 1080f);
			float centerFraction = (_innerBars.Enabled ? PixelFrame.FractionFor(_innerBars.Thickness, resolutionScale) : (_outerBars.Enabled ? PixelFrame.FractionFor(_outerBars.Thickness, resolutionScale) : (_centerDot.Enabled ? PixelFrame.FractionFor(_centerDot.Size, resolutionScale) : 0f)));
			return new PixelFrame(resolutionScale, pixelsPerUnit, centerFraction, anchorScreen, rootScreen);
		}

		private float GetPixelsPerUnit(Canvas rootCanvas)
		{
			//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)
			float x = ((Component)rootCanvas).transform.lossyScale.x;
			if (x <= 0f)
			{
				return 0f;
			}
			return rootCanvas.scaleFactor * (((Transform)_root).lossyScale.x / x);
		}

		private Vector3 GetIntendedCenterWorld()
		{
			//IL_002d: 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_003e: 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_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_0050: Unknown result type (might be due to invalid IL or missing references)
			Transform parent = ((Transform)_rect).parent;
			if ((Object)(object)parent == (Object)null)
			{
				return ((Transform)_root).position;
			}
			return ((Transform)_root).position - parent.TransformVector(Vector2.op_Implicit(_rect.anchoredPosition));
		}

		private void LogLayoutOnce(Canvas rootCanvas, in PixelFrame frame, Vector2 rootScreen, Vector2 anchorScreen)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: 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_00f4: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			if (_loggedScreenWidth != Screen.width || _loggedScreenHeight != Screen.height || !Mathf.Approximately(_loggedPixelsPerUnit, frame.PixelsPerUnit))
			{
				_loggedScreenWidth = Screen.width;
				_loggedScreenHeight = Screen.height;
				_loggedPixelsPerUnit = frame.PixelsPerUnit;
				Plugin.Log.LogDebug((object)($"Crosshair layout: screen {Screen.width}x{Screen.height}, canvas {rootCanvas.renderMode} " + $"scaleFactor {rootCanvas.scaleFactor:0.###} pixelPerfect {rootCanvas.pixelPerfect}, " + $"px/unit {frame.PixelsPerUnit:0.###}, crosshair anchoredPosition {_rect.anchoredPosition}, " + $"root at {rootScreen.x:0.###},{rootScreen.y:0.###} px, anchor {anchorScreen.x:0.###},{anchorScreen.y:0.###} px, " + $"snapped center {frame.Center.x},{frame.Center.y}."));
			}
		}
	}
	[RequireComponent(typeof(Image))]
	internal sealed class RingMesh : MonoBehaviour, IMeshModifier
	{
		private readonly struct Stop
		{
			internal readonly float Radius;

			internal readonly Color32 Color;

			internal Stop(float radius, Color32 color)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				Radius = radius;
				Color = color;
			}
		}

		private readonly struct Shape : IEquatable<Shape>
		{
			internal readonly float Inner;

			internal readonly float Outer;

			internal readonly float Border;

			internal readonly float Feather;

			internal readonly Color32 Fill;

			internal readonly Color32 BorderColor;

			internal readonly int Segments;

			internal Shape(float inner, float outer, float border, float feather, Color32 fill, Color32 borderColor, int segments)
			{
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				Inner = inner;
				Outer = outer;
				Border = border;
				Feather = feather;
				Fill = fill;
				BorderColor = borderColor;
				Segments = segments;
			}

			public bool Equals(Shape o)
			{
				//IL_0047: 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_005a: 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)
				return Inner == o.Inner && Outer == o.Outer && Border == o.Border && Feather == o.Feather && Segments == o.Segments && Same(Fill, o.Fill) && Same(BorderColor, o.BorderColor);
			}

			private static bool Same(Color32 a, Color32 b)
			{
				//IL_0000: 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_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_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)
				//IL_002a: 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)
				return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
			}
		}

		private readonly List<Stop> _stops = new List<Stop>();

		private Shape _shape;

		private bool _hasShape;

		private Image? _image;

		internal Image Image => ((Object)(object)_image != (Object)null) ? _image : (_image = ((Component)this).GetComponent<Image>());

		internal void SetShape(float inner, float outer, float border, float feather, Color fill, Color borderColor, int segments)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Shape shape = new Shape(inner, outer, border, feather, Color32.op_Implicit(fill), Color32.op_Implicit(borderColor), segments);
			if (!_hasShape || !shape.Equals(_shape))
			{
				_shape = shape;
				_hasShape = true;
				((Graphic)Image).SetVerticesDirty();
			}
		}

		public void ModifyMesh(Mesh mesh)
		{
		}

		public void ModifyMesh(VertexHelper vh)
		{
			//IL_0083: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			vh.Clear();
			if (!_hasShape)
			{
				return;
			}
			BuildStops(_shape);
			int segments = _shape.Segments;
			float num = MathF.PI * 2f / (float)segments;
			Vector3 val = default(Vector3);
			for (int i = 0; i < _stops.Count; i++)
			{
				Stop stop = _stops[i];
				for (int j = 0; j < segments; j++)
				{
					float num2 = (float)j * num;
					((Vector3)(ref val))..ctor(Mathf.Cos(num2) * stop.Radius, Mathf.Sin(num2) * stop.Radius);
					vh.AddVert(val, stop.Color, Vector4.zero);
				}
			}
			for (int k = 0; k + 1 < _stops.Count; k++)
			{
				int num3 = k * segments;
				int num4 = (k + 1) * segments;
				for (int l = 0; l < segments; l++)
				{
					int num5 = (l + 1) % segments;
					vh.AddTriangle(num3 + l, num4 + l, num4 + num5);
					vh.AddTriangle(num3 + l, num4 + num5, num3 + num5);
				}
			}
		}

		private void BuildStops(Shape shape)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			_stops.Clear();
			float num = shape.Feather * 0.5f;
			bool flag = shape.Border > 0f;
			List<float> list = new List<float>(4);
			List<Color32> list2 = new List<Color32>(3);
			if (flag && shape.Inner > 0f)
			{
				list.Add(Mathf.Max(0f, shape.Inner - shape.Border));
				list2.Add(shape.BorderColor);
			}
			list.Add(shape.Inner);
			list2.Add(shape.Fill);
			list.Add(shape.Outer);
			if (flag)
			{
				list2.Add(shape.BorderColor);
				list.Add(shape.Outer + shape.Border);
			}
			for (int i = 0; i < list.Count; i++)
			{
				Color32 color = ((i == 0) ? Transparent(list2[0]) : list2[i - 1]);
				Color32 color2 = ((i == list.Count - 1) ? Transparent(list2[i - 1]) : list2[i]);
				if (i == 0 && list[0] <= 0f)
				{
					AddStop(0f, color2);
					continue;
				}
				AddStop(list[i] - num, color);
				AddStop(list[i] + num, color2);
			}
		}

		private void AddStop(float radius, Color32 color)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			float num = ((_stops.Count > 0) ? _stops[_stops.Count - 1].Radius : 0f);
			_stops.Add(new Stop(Mathf.Max(radius, num), color));
		}

		private static Color32 Transparent(Color32 color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			return new Color32(color.r, color.g, color.b, (byte)0);
		}
	}
}

src/RoR2CustomCrosshair/obj/Debug/netstandard2.1/RoR2CustomCrosshair.dll

Decompiled 20 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using On.RoR2.UI;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.UI;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RoR2CustomCrosshair")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("RoR2CustomCrosshair")]
[assembly: AssemblyTitle("RoR2CustomCrosshair")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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;
		}
	}
	[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 RoR2CustomCrosshair
{
	internal static class CrosshairConfig
	{
		private const int CurrentConfigVersion = 2;

		private const float SliderStep = 0.5f;

		internal static ConfigEntry<bool> Enabled;

		internal static BarsSettings InnerBars;

		internal static BarsSettings OuterBars;

		internal static CircleSettings Circle;

		internal static DotSettings CenterDot;

		internal static int Revision { get; private set; }

		internal static void Bind(ConfigFile config)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			bool saveOnConfigSet = config.SaveOnConfigSet;
			config.SaveOnConfigSet = false;
			Enabled = config.Bind<bool>("General", "Enabled", true, "Replace the ordinary crosshair of your own survivor with the custom crosshair.");
			InnerBars = new BarsSettings(config, "Inner Bars", new BarsDefaults
			{
				Enabled = true,
				Length = 8f,
				Thickness = 2f,
				Gap = 4f,
				GapMax = 64f,
				Fill = new Color32((byte)0, byte.MaxValue, (byte)0, byte.MaxValue)
			});
			OuterBars = new BarsSettings(config, "Outer Bars", new BarsDefaults
			{
				Enabled = false,
				Length = 10f,
				Thickness = 2f,
				Gap = 14f,
				GapMax = 128f,
				Fill = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue)
			});
			Circle = new CircleSettings(config, "Circle");
			CenterDot = new DotSettings(config, "Center Dot");
			MigrateFromVersion1(config);
			config.Save();
			config.SaveOnConfigSet = saveOnConfigSet;
			config.SettingChanged += delegate
			{
				Revision++;
			};
		}

		internal static void RegisterRiskOfOptions()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			ModSettingsManager.SetModDescription("Procedural crosshair with Inner Bars, Outer Bars, Circle and Center Dot layers. Sizes are pixels at 1920x1080 and scale with resolution.");
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Enabled));
			InnerBars.Register();
			OuterBars.Register();
			Circle.Register();
			CenterDot.Register();
		}

		private static void MigrateFromVersion1(ConfigFile config)
		{
			ConfigEntry<int> val = config.Bind<int>("Internal", "Config Version", 0, "Settings layout version, used for migration. Do not edit.");
			if (val.Value < 2)
			{
				BarsSettings innerBars = InnerBars;
				Move<float>(config, "Crosshair", "Length", innerBars.Length);
				Move<float>(config, "Crosshair", "Thickness", innerBars.Thickness);
				Move<float>(config, "Crosshair", "Gap", innerBars.Gap);
				Move<int>(config, "Crosshair Color", "Opacity", innerBars.Fill.Opacity);
				Move<int>(config, "Crosshair Color", "R", innerBars.Fill.Red);
				Move<int>(config, "Crosshair Color", "G", innerBars.Fill.Green);
				Move<int>(config, "Crosshair Color", "B", innerBars.Fill.Blue);
				Move<bool>(config, "Outline", "Enabled", innerBars.Outline.Enabled);
				Move<float>(config, "Outline", "Thickness", innerBars.Outline.Thickness);
				Move<int>(config, "Outline Color", "Opacity", innerBars.Outline.Color.Opacity);
				Move<int>(config, "Outline Color", "R", innerBars.Outline.Color.Red);
				Move<int>(config, "Outline Color", "G", innerBars.Outline.Color.Green);
				Move<int>(config, "Outline Color", "B", innerBars.Outline.Color.Blue);
				val.Value = 2;
				Plugin.Log.LogInfo((object)"Migrated crosshair settings to the layered layout (old values now under 'Inner Bars').");
			}
		}

		private static void Move<T>(ConfigFile config, string oldSection, string oldKey, ConfigEntry<T> target)
		{
			ConfigEntry<T> val = config.Bind<T>(oldSection, oldKey, (T)((ConfigEntryBase)target).DefaultValue, (ConfigDescription)null);
			target.Value = val.Value;
			config.Remove(((ConfigEntryBase)val).Definition);
		}

		internal static ConfigEntry<float> BindFloat(ConfigFile config, string section, string key, float defaultValue, float min, float max, string description)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			return config.Bind<float>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), Array.Empty<object>()));
		}

		internal static ConfigEntry<int> BindByte(ConfigFile config, string section, string key, int defaultValue)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			return config.Bind<int>(section, key, defaultValue, new ConfigDescription(key + " value from 0 to 255.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 255), Array.Empty<object>()));
		}

		internal static void AddFloatOption(ConfigEntry<float> entry, float min, float max)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new StepSliderOption(entry, new StepSliderConfig
			{
				min = min,
				max = max,
				increment = 0.5f,
				FormatString = "{0:0.0}"
			}));
		}

		internal static void AddByteOption(ConfigEntry<int> entry)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(entry, new IntSliderConfig
			{
				min = 0,
				max = 255
			}));
		}
	}
	internal sealed class ColorSettings
	{
		internal readonly ConfigEntry<int> Red;

		internal readonly ConfigEntry<int> Green;

		internal readonly ConfigEntry<int> Blue;

		internal readonly ConfigEntry<int> Opacity;

		internal Color Value => new Color((float)Red.Value / 255f, (float)Green.Value / 255f, (float)Blue.Value / 255f, (float)Opacity.Value / 255f);

		internal ColorSettings(ConfigFile config, string section, string keyPrefix, Color32 defaults)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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)
			Red = CrosshairConfig.BindByte(config, section, keyPrefix + "R", defaults.r);
			Green = CrosshairConfig.BindByte(config, section, keyPrefix + "G", defaults.g);
			Blue = CrosshairConfig.BindByte(config, section, keyPrefix + "B", defaults.b);
			Opacity = CrosshairConfig.BindByte(config, section, keyPrefix + "Opacity", defaults.a);
		}

		internal void Register()
		{
			CrosshairConfig.AddByteOption(Red);
			CrosshairConfig.AddByteOption(Green);
			CrosshairConfig.AddByteOption(Blue);
			CrosshairConfig.AddByteOption(Opacity);
		}
	}
	internal sealed class OutlineSettings
	{
		internal const float MaxThickness = 10f;

		internal readonly ConfigEntry<bool> Enabled;

		internal readonly ConfigEntry<float> Thickness;

		internal readonly ColorSettings Color;

		internal bool Visible => Enabled.Value && Thickness.Value > 0.001f;

		internal OutlineSettings(ConfigFile config, string section)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			Enabled = config.Bind<bool>(section, "Outline Enabled", true, "Draw a border around this layer.");
			Thickness = CrosshairConfig.BindFloat(config, section, "Outline Thickness", 1f, 0f, 10f, "Border width on each side, in pixels at 1920x1080.");
			Color = new ColorSettings(config, section, "Outline ", new Color32((byte)0, (byte)0, (byte)0, byte.MaxValue));
		}

		internal void Register()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Enabled));
			CrosshairConfig.AddFloatOption(Thickness, 0f, 10f);
			Color.Register();
		}
	}
	internal struct BarsDefaults
	{
		internal bool Enabled;

		internal float Length;

		internal float Thickness;

		internal float Gap;

		internal float GapMax;

		internal Color32 Fill;
	}
	internal sealed class BarsSettings
	{
		internal const float MaxLength = 64f;

		internal const float MaxThickness = 20f;

		private readonly float _gapMax;

		internal readonly ConfigEntry<bool> Enabled;

		internal readonly ConfigEntry<CrosshairMode> Mode;

		internal readonly ConfigEntry<float> Length;

		internal readonly ConfigEntry<float> Thickness;

		internal readonly ConfigEntry<float> Gap;

		internal readonly ColorSettings Fill;

		internal readonly OutlineSettings Outline;

		internal BarsSettings(ConfigFile config, string section, BarsDefaults defaults)
		{
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			_gapMax = defaults.GapMax;
			Enabled = config.Bind<bool>(section, "Enabled", defaults.Enabled, "Show the " + section + ".");
			Mode = config.Bind<CrosshairMode>(section, "Mode", CrosshairMode.Static, "Static: fixed gap. Dynamic: gap will follow actual weapon spread (not implemented yet; currently same as Static).");
			Length = CrosshairConfig.BindFloat(config, section, "Length", defaults.Length, 0.5f, 64f, "Length of each arm, in pixels at 1920x1080.");
			Thickness = CrosshairConfig.BindFloat(config, section, "Thickness", defaults.Thickness, 0.5f, 20f, "Thickness of each arm, in pixels at 1920x1080.");
			Gap = CrosshairConfig.BindFloat(config, section, "Gap", defaults.Gap, 0f, _gapMax, "Distance from screen center to the inner edge of each arm, in pixels at 1920x1080.");
			Fill = new ColorSettings(config, section, "", defaults.Fill);
			Outline = new OutlineSettings(config, section);
		}

		internal void Register()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Enabled));
			ModSettingsManager.AddOption((BaseOption)new ChoiceOption((ConfigEntryBase)(object)Mode));
			CrosshairConfig.AddFloatOption(Length, 0.5f, 64f);
			CrosshairConfig.AddFloatOption(Thickness, 0.5f, 20f);
			CrosshairConfig.AddFloatOption(Gap, 0f, _gapMax);
			Fill.Register();
			Outline.Register();
		}
	}
	internal sealed class CircleSettings
	{
		internal const float MaxRadius = 128f;

		internal const float MaxThickness = 20f;

		internal readonly ConfigEntry<bool> Enabled;

		internal readonly ConfigEntry<CrosshairMode> Mode;

		internal readonly ConfigEntry<float> Radius;

		internal readonly ConfigEntry<float> Thickness;

		internal readonly ColorSettings Fill;

		internal readonly OutlineSettings Outline;

		internal CircleSettings(ConfigFile config, string section)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			Enabled = config.Bind<bool>(section, "Enabled", false, "Show the circle.");
			Mode = config.Bind<CrosshairMode>(section, "Mode", CrosshairMode.Static, "Static: fixed radius. Dynamic: radius will follow actual weapon spread (not implemented yet; currently same as Static).");
			Radius = CrosshairConfig.BindFloat(config, section, "Radius", 16f, 0f, 128f, "Distance from screen center to the inner edge of the ring, in pixels at 1920x1080.");
			Thickness = CrosshairConfig.BindFloat(config, section, "Thickness", 2f, 0.5f, 20f, "Ring thickness, in pixels at 1920x1080.");
			Fill = new ColorSettings(config, section, "", new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue));
			Outline = new OutlineSettings(config, section);
		}

		internal void Register()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Enabled));
			ModSettingsManager.AddOption((BaseOption)new ChoiceOption((ConfigEntryBase)(object)Mode));
			CrosshairConfig.AddFloatOption(Radius, 0f, 128f);
			CrosshairConfig.AddFloatOption(Thickness, 0.5f, 20f);
			Fill.Register();
			Outline.Register();
		}
	}
	internal sealed class DotSettings
	{
		internal const float MaxSize = 20f;

		internal readonly ConfigEntry<bool> Enabled;

		internal readonly ConfigEntry<float> Size;

		internal readonly ColorSettings Fill;

		internal readonly OutlineSettings Outline;

		internal DotSettings(ConfigFile config, string section)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			Enabled = config.Bind<bool>(section, "Enabled", false, "Show the center dot.");
			Size = CrosshairConfig.BindFloat(config, section, "Size", 2f, 0.5f, 20f, "Width and height of the dot, in pixels at 1920x1080.");
			Fill = new ColorSettings(config, section, "", new Color32((byte)0, byte.MaxValue, (byte)0, byte.MaxValue));
			Outline = new OutlineSettings(config, section);
		}

		internal void Register()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Enabled));
			CrosshairConfig.AddFloatOption(Size, 0.5f, 20f);
			Fill.Register();
			Outline.Register();
		}
	}
	internal readonly struct PixelFrame
	{
		internal readonly float ResolutionScale;

		internal readonly float PixelsPerUnit;

		internal readonly float CenterFraction;

		internal readonly Vector2 Center;

		internal readonly Vector2 OriginOffset;

		internal PixelFrame(float resolutionScale, float pixelsPerUnit, float centerFraction, Vector2 anchorScreen, Vector2 rootScreen)
		{
			//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_0031: 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_0042: 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)
			ResolutionScale = resolutionScale;
			PixelsPerUnit = pixelsPerUnit;
			CenterFraction = centerFraction;
			Center = new Vector2(SnapToGrid(anchorScreen.x, centerFraction), SnapToGrid(anchorScreen.y, centerFraction));
			OriginOffset = Center - rootScreen;
		}

		internal static float FractionFor(float logicalSize, float resolutionScale)
		{
			return (Mathf.Max(1, RoundPx(logicalSize * resolutionScale)) % 2 == 0) ? 0f : 0.5f;
		}

		internal int Width(float logical)
		{
			return Mathf.Max(1, RoundPx(logical * ResolutionScale));
		}

		internal int CenteredSize(float logical)
		{
			float num = logical * ResolutionScale;
			if (CenterFraction == 0f)
			{
				return Mathf.Max(2, 2 * RoundPx(num * 0.5f));
			}
			return Mathf.Max(1, 2 * (int)Mathf.Floor(num * 0.5f) + 1);
		}

		internal float EdgeDistance(float logical)
		{
			return Mathf.Floor(CenterFraction + Mathf.Max(0f, logical) * ResolutionScale + 0.5f) - CenterFraction;
		}

		internal float ToLocal(float pixels)
		{
			return pixels / PixelsPerUnit;
		}

		internal void Place(RectTransform rect, Vector4 pixelRect)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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)
			//IL_001c: 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_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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor((pixelRect.x + pixelRect.z) * 0.5f, (pixelRect.y + pixelRect.w) * 0.5f);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(pixelRect.z - pixelRect.x, pixelRect.w - pixelRect.y);
			rect.anchoredPosition = (OriginOffset + val) / PixelsPerUnit;
			rect.sizeDelta = val2 / PixelsPerUnit;
		}

		internal static int RoundPx(float value)
		{
			return (int)Mathf.Floor(value + 0.5f);
		}

		private static float SnapToGrid(float value, float fraction)
		{
			return Mathf.Floor(value - fraction + 0.5f) + fraction;
		}
	}
	internal sealed class BorderedRect
	{
		private static readonly string[] SideNames = new string[4] { "Top", "Bottom", "Left", "Right" };

		private readonly Image _fill;

		private readonly Image[] _strips = (Image[])(object)new Image[4];

		private BorderedRect(Transform layer, string name)
		{
			_fill = Find(layer, "Fill" + name);
			for (int i = 0; i < 4; i++)
			{
				_strips[i] = Find(layer, "Outline" + name + SideNames[i]);
			}
		}

		internal static BorderedRect Bind(Transform layer, string name)
		{
			return new BorderedRect(layer, name);
		}

		internal static void BuildBorder(Transform layer, string name)
		{
			string[] sideNames = SideNames;
			foreach (string text in sideNames)
			{
				CrosshairPrefabFactory.CreateImage("Outline" + name + text, layer);
			}
		}

		internal static void BuildFill(Transform layer, string name)
		{
			CrosshairPrefabFactory.CreateImage("Fill" + name, layer);
		}

		internal void Apply(in PixelFrame frame, Vector4 r, Color fill, int border, Color borderColor)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00a1: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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)
			//IL_00ed: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			Show(_fill, in frame, r, fill);
			if (border <= 0)
			{
				Image[] strips = _strips;
				foreach (Image val in strips)
				{
					((Behaviour)val).enabled = false;
				}
			}
			else
			{
				float num = border;
				Show(_strips[0], in frame, new Vector4(r.x - num, r.w, r.z + num, r.w + num), borderColor);
				Show(_strips[1], in frame, new Vector4(r.x - num, r.y - num, r.z + num, r.y), borderColor);
				Show(_strips[2], in frame, new Vector4(r.x - num, r.y, r.x, r.w), borderColor);
				Show(_strips[3], in frame, new Vector4(r.z, r.y, r.z + num, r.w), borderColor);
			}
		}

		internal void Hide()
		{
			((Behaviour)_fill).enabled = false;
			Image[] strips = _strips;
			foreach (Image val in strips)
			{
				((Behaviour)val).enabled = false;
			}
		}

		private static void Show(Image image, in PixelFrame frame, Vector4 r, Color color)
		{
			//IL_0008: 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)
			frame.Place(((Graphic)image).rectTransform, r);
			((Graphic)image).color = color;
			((Behaviour)image).enabled = true;
		}

		private static Image Find(Transform layer, string name)
		{
			return ((Component)layer.Find(name)).GetComponent<Image>();
		}
	}
	internal sealed class BarsLayer
	{
		private static readonly string[] ArmNames = new string[4] { "Left", "Right", "Top", "Bottom" };

		private readonly BarsSettings _settings;

		private readonly BorderedRect[] _arms = new BorderedRect[4];

		internal bool Enabled => _settings.Enabled.Value;

		internal float Thickness => _settings.Thickness.Value;

		internal BarsLayer(Transform root, string layerName, BarsSettings settings)
		{
			_settings = settings;
			Transform layer = root.Find(layerName);
			for (int i = 0; i < 4; i++)
			{
				_arms[i] = BorderedRect.Bind(layer, ArmNames[i]);
			}
		}

		internal static void Build(Transform root, string layerName)
		{
			Transform layer = (Transform)(object)CrosshairPrefabFactory.CreateRect(layerName, root);
			string[] armNames = ArmNames;
			foreach (string name in armNames)
			{
				BorderedRect.BuildBorder(layer, name);
			}
			string[] armNames2 = ArmNames;
			foreach (string name2 in armNames2)
			{
				BorderedRect.BuildFill(layer, name2);
			}
		}

		internal void Apply(in PixelFrame frame, float dynamicOffset)
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			if (!Enabled)
			{
				BorderedRect[] arms = _arms;
				foreach (BorderedRect borderedRect in arms)
				{
					borderedRect.Hide();
				}
				return;
			}
			float num = _settings.Gap.Value;
			if (_settings.Mode.Value == CrosshairMode.Dynamic)
			{
				num += dynamicOffset;
			}
			float num2 = (float)frame.CenteredSize(_settings.Thickness.Value) * 0.5f;
			float num3 = frame.EdgeDistance(num);
			float num4 = num3 + (float)frame.Width(_settings.Length.Value);
			Color value = _settings.Fill.Value;
			Color value2 = _settings.Outline.Color.Value;
			int border = (_settings.Outline.Visible ? frame.Width(_settings.Outline.Thickness.Value) : 0);
			_arms[0].Apply(in frame, new Vector4(0f - num4, 0f - num2, 0f - num3, num2), value, border, value2);
			_arms[1].Apply(in frame, new Vector4(num3, 0f - num2, num4, num2), value, border, value2);
			_arms[2].Apply(in frame, new Vector4(0f - num2, num3, num2, num4), value, border, value2);
			_arms[3].Apply(in frame, new Vector4(0f - num2, 0f - num4, num2, 0f - num3), value, border, value2);
		}
	}
	internal sealed class CenterDotLayer
	{
		private const string DotName = "Dot";

		private readonly DotSettings _settings;

		private readonly BorderedRect _dot;

		internal bool Enabled => _settings.Enabled.Value;

		internal float Size => _settings.Size.Value;

		internal CenterDotLayer(Transform root, string layerName, DotSettings settings)
		{
			_settings = settings;
			_dot = BorderedRect.Bind(root.Find(layerName), "Dot");
		}

		internal static void Build(Transform root, string layerName)
		{
			Transform layer = (Transform)(object)CrosshairPrefabFactory.CreateRect(layerName, root);
			BorderedRect.BuildBorder(layer, "Dot");
			BorderedRect.BuildFill(layer, "Dot");
		}

		internal void Apply(in PixelFrame frame)
		{
			//IL_007c: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			if (!Enabled)
			{
				_dot.Hide();
				return;
			}
			float num = (float)frame.CenteredSize(_settings.Size.Value) * 0.5f;
			int border = (_settings.Outline.Visible ? frame.Width(_settings.Outline.Thickness.Value) : 0);
			_dot.Apply(in frame, new Vector4(0f - num, 0f - num, num, num), _settings.Fill.Value, border, _settings.Outline.Color.Value);
		}
	}
	internal sealed class CircleLayer
	{
		private const string RingName = "Ring";

		private const float SegmentPixels = 1.5f;

		private const int MinSegments = 24;

		private const int MaxSegments = 512;

		private readonly CircleSettings _settings;

		private readonly RingMesh _ring;

		private readonly Image _image;

		internal CircleLayer(Transform root, string layerName, CircleSettings settings)
		{
			_settings = settings;
			_ring = ((Component)root.Find(layerName).Find("Ring")).GetComponent<RingMesh>();
			_image = _ring.Image;
		}

		internal static void Build(Transform root, string layerName)
		{
			Transform val = (Transform)(object)CrosshairPrefabFactory.CreateRect(layerName, root);
			CrosshairPrefabFactory.CreateImage("Ring", val);
			((Component)val.Find("Ring")).gameObject.AddComponent<RingMesh>();
		}

		internal void Apply(in PixelFrame frame, float dynamicOffset)
		{
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			if (!_settings.Enabled.Value)
			{
				((Behaviour)_image).enabled = false;
				return;
			}
			float num = _settings.Radius.Value;
			if (_settings.Mode.Value == CrosshairMode.Dynamic)
			{
				num += dynamicOffset;
			}
			float num2 = frame.EdgeDistance(num);
			float num3 = num2 + (float)frame.Width(_settings.Thickness.Value);
			int num4 = (_settings.Outline.Visible ? frame.Width(_settings.Outline.Thickness.Value) : 0);
			float num5 = num3 + (float)num4 + 1f;
			int segments = Mathf.Clamp(Mathf.CeilToInt(MathF.PI * 2f * (num3 + (float)num4) / 1.5f), 24, 512);
			frame.Place(((Graphic)_image).rectTransform, new Vector4(0f - num5, 0f - num5, num5, num5));
			((Graphic)_image).color = Color.white;
			_ring.SetShape(frame.ToLocal(num2), frame.ToLocal(num3), frame.ToLocal(num4), frame.ToLocal(1f), _settings.Fill.Value, _settings.Outline.Color.Value, segments);
			((Behaviour)_image).enabled = true;
		}
	}
	internal enum CrosshairMode
	{
		Static,
		Dynamic
	}
	internal static class CrosshairPrefabFactory
	{
		private const string StandardCrosshairAddress = "RoR2/Base/UI/StandardCrosshair.prefab";

		internal const string ProceduralRootName = "ProceduralCrosshair";

		internal const string CircleLayerName = "Circle";

		internal const string OuterBarsLayerName = "OuterBars";

		internal const string InnerBarsLayerName = "InnerBars";

		internal const string CenterDotLayerName = "CenterDot";

		internal static void CreateAsync(Transform holder, Action<GameObject?> onCreated)
		{
			//IL_001a: 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)
			AsyncOperationHandle<GameObject> val = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/UI/StandardCrosshair.prefab");
			val.Completed += delegate(AsyncOperationHandle<GameObject> op)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Invalid comparison between Unknown and I4
				if ((int)op.Status != 1 || (Object)(object)op.Result == (Object)null)
				{
					Plugin.Log.LogError((object)string.Format("Could not load '{0}': {1}", "RoR2/Base/UI/StandardCrosshair.prefab", op.OperationException));
					onCreated(null);
					return;
				}
				try
				{
					onCreated(Build(op.Result, holder));
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"Could not build crosshair template: {arg}");
					onCreated(null);
				}
			};
		}

		private static GameObject Build(GameObject standardCrosshair, Transform holder)
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(standardCrosshair, holder, false);
			((Object)val).name = "RoR2CustomCrosshair";
			Plugin.Log.LogDebug((object)("StandardCrosshair components: " + string.Join(", ", from c in val.GetComponents<Component>()
				select ((object)c).GetType().Name)));
			CrosshairController val2 = default(CrosshairController);
			HudElement val3 = default(HudElement);
			if (!val.TryGetComponent<CrosshairController>(ref val2) || !val.TryGetComponent<HudElement>(ref val3))
			{
				throw new InvalidOperationException("StandardCrosshair no longer has CrosshairController + HudElement.");
			}
			val2.spriteSpreadPositions = Array.Empty<SpritePosition>();
			val2.skillStockSpriteDisplays = Array.Empty<SkillStockSpriteDisplay>();
			val2.remapSprites = Array.Empty<RawImage>();
			foreach (Transform item in val.transform)
			{
				Transform val4 = item;
				((Component)val4).gameObject.SetActive(false);
			}
			Graphic[] components = val.GetComponents<Graphic>();
			foreach (Graphic val5 in components)
			{
				((Behaviour)val5).enabled = false;
			}
			RectTransform root = CreateRect("ProceduralCrosshair", val.transform);
			CircleLayer.Build((Transform)(object)root, "Circle");
			BarsLayer.Build((Transform)(object)root, "OuterBars");
			BarsLayer.Build((Transform)(object)root, "InnerBars");
			CenterDotLayer.Build((Transform)(object)root, "CenterDot");
			val.AddComponent<ProceduralCrosshairView>();
			return val;
		}

		internal static RectTransform CreateRect(string name, Transform parent)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_007f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			RectTransform val2 = (RectTransform)val.transform;
			((Transform)val2).SetParent(parent, false);
			val2.anchorMin = new Vector2(0.5f, 0.5f);
			val2.anchorMax = new Vector2(0.5f, 0.5f);
			val2.pivot = new Vector2(0.5f, 0.5f);
			val2.anchoredPosition = Vector2.zero;
			val2.sizeDelta = Vector2.zero;
			return val2;
		}

		internal static void CreateImage(string name, Transform parent)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = CreateRect(name, parent);
			((Component)val).gameObject.AddComponent<CanvasRenderer>();
			Image val2 = ((Component)val).gameObject.AddComponent<Image>();
			((Graphic)val2).raycastTarget = false;
			((MaskableGraphic)val2).maskable = false;
			((Graphic)val2).color = Color.clear;
			((Behaviour)val2).enabled = false;
		}
	}
	internal sealed class HudCrosshairDriver : MonoBehaviour
	{
		private const string GenericSprintCrosshairPath = "Prefabs/Crosshair/SprintingCrosshair";

		private static GameObject? _genericSprintCrosshair;

		private static bool _genericSprintCrosshairLoaded;

		private CrosshairManager? _crosshairManager;

		private bool _replacing;

		internal static void Attach(HUD hud)
		{
			if (!Object.op_Implicit((Object)(object)((Component)hud).GetComponent<HudCrosshairDriver>()))
			{
				((Component)hud).gameObject.AddComponent<HudCrosshairDriver>();
			}
		}

		private void Awake()
		{
			_crosshairManager = ((Component)this).GetComponent<CrosshairManager>();
			if (!Object.op_Implicit((Object)(object)_crosshairManager))
			{
				Plugin.Log.LogWarning((object)("HUD '" + ((Object)this).name + "' has no CrosshairManager; custom crosshair unavailable."));
			}
		}

		private void OnEnable()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			if (Object.op_Implicit((Object)(object)_crosshairManager))
			{
				_crosshairManager.pickCrosshairGlobal += new PickCrosshairDelegate(OnPickCrosshair);
			}
		}

		private void OnDisable()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			if (Object.op_Implicit((Object)(object)_crosshairManager))
			{
				_crosshairManager.pickCrosshairGlobal -= new PickCrosshairDelegate(OnPickCrosshair);
			}
			SetReplacing(replacing: false, null);
		}

		private void OnPickCrosshair(CrosshairManager manager, ref GameObject crosshairPrefab)
		{
			GameObject crosshairPrefab2 = Plugin.CrosshairPrefab;
			CharacterBody ownLiveBody = GetOwnLiveBody(manager);
			bool flag = (Object)(object)crosshairPrefab2 != (Object)null && (Object)(object)ownLiveBody != (Object)null && CrosshairConfig.Enabled.Value && (IsOrdinaryCrosshair(ownLiveBody, crosshairPrefab) || IsGenericSprintCrosshair(ownLiveBody, crosshairPrefab));
			if (flag)
			{
				crosshairPrefab = crosshairPrefab2;
			}
			SetReplacing(flag, ownLiveBody);
		}

		private static CharacterBody? GetOwnLiveBody(CrosshairManager manager)
		{
			CameraRigController cameraRigController = manager.cameraRigController;
			if (!Object.op_Implicit((Object)(object)cameraRigController) || cameraRigController.hasOverride)
			{
				return null;
			}
			LocalUser localUserViewer = cameraRigController.localUserViewer;
			CharacterBody targetBody = cameraRigController.targetBody;
			if (localUserViewer == null || !Object.op_Implicit((Object)(object)targetBody) || (Object)(object)localUserViewer.cachedBodyObject != (Object)(object)((Component)targetBody).gameObject)
			{
				return null;
			}
			if (!Object.op_Implicit((Object)(object)targetBody.healthComponent) || !targetBody.healthComponent.alive)
			{
				return null;
			}
			return targetBody;
		}

		private static bool IsOrdinaryCrosshair(CharacterBody body, GameObject picked)
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Invalid comparison between Unknown and I4
			if (!Object.op_Implicit((Object)(object)picked))
			{
				return false;
			}
			if ((Object)(object)picked == (Object)(object)body.defaultCrosshairPrefab)
			{
				return true;
			}
			SkillCrosshairController val = default(SkillCrosshairController);
			if (((Component)body).TryGetComponent<SkillCrosshairController>(ref val) && val.options != null)
			{
				SkillDefCrosshairOptions[] options = val.options;
				foreach (SkillDefCrosshairOptions val2 in options)
				{
					if (val2 != null && (int)val2.priority < 1 && (Object)(object)val2.crosshairPrefab == (Object)(object)picked)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool IsGenericSprintCrosshair(CharacterBody body, GameObject picked)
		{
			if (!Object.op_Implicit((Object)(object)picked) || !body.isSprinting || !body.useSprintCrosshair || Object.op_Implicit((Object)(object)body.sprintCrosshairPrefabOverride))
			{
				return false;
			}
			GameObject genericSprintCrosshair = GetGenericSprintCrosshair();
			return (Object)(object)genericSprintCrosshair != (Object)null && (Object)(object)picked == (Object)(object)genericSprintCrosshair;
		}

		private static GameObject? GetGenericSprintCrosshair()
		{
			if (!_genericSprintCrosshairLoaded)
			{
				_genericSprintCrosshairLoaded = true;
				_genericSprintCrosshair = LegacyResourcesAPI.Load<GameObject>("Prefabs/Crosshair/SprintingCrosshair");
				if ((Object)(object)_genericSprintCrosshair == (Object)null)
				{
					Plugin.Log.LogWarning((object)"Could not load 'Prefabs/Crosshair/SprintingCrosshair'; the vanilla sprint crosshair will be shown.");
				}
			}
			return _genericSprintCrosshair;
		}

		private void SetReplacing(bool replacing, CharacterBody? body)
		{
			if (replacing != _replacing)
			{
				_replacing = replacing;
				Plugin.Log.LogDebug((object)(replacing ? ("Custom crosshair active for " + body.GetDisplayName() + " (" + ((Object)body).name + ").") : "Custom crosshair released; vanilla crosshair logic in control."));
			}
		}
	}
	[BepInPlugin("com.example.ror2customcrosshair", "RoR2 Custom Crosshair", "0.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__HUD_Awake;
		}

		public const string PluginGuid = "com.example.ror2customcrosshair";

		public const string PluginName = "RoR2 Custom Crosshair";

		public const string PluginVersion = "0.1.0";

		private GameObject? _prefabHolder;

		internal static ManualLogSource Log { get; private set; }

		internal static GameObject? CrosshairPrefab { get; private set; }

		private void Awake()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			CrosshairConfig.Bind(((BaseUnityPlugin)this).Config);
			CrosshairConfig.RegisterRiskOfOptions();
			_prefabHolder = new GameObject("RoR2CustomCrosshair_Templates");
			_prefabHolder.SetActive(false);
			Object.DontDestroyOnLoad((Object)(object)_prefabHolder);
			CrosshairPrefabFactory.CreateAsync(_prefabHolder.transform, delegate(GameObject? template)
			{
				CrosshairPrefab = template;
				if ((Object)(object)template != (Object)null)
				{
					Log.LogInfo((object)"Crosshair template ready.");
				}
				else
				{
					Log.LogError((object)"Crosshair template unavailable; vanilla crosshairs will be used.");
				}
			});
			object obj = <>O.<0>__HUD_Awake;
			if (obj == null)
			{
				hook_Awake val = HUD_Awake;
				<>O.<0>__HUD_Awake = val;
				obj = (object)val;
			}
			HUD.Awake += (hook_Awake)obj;
			Log.LogInfo((object)"RoR2 Custom Crosshair 0.1.0 loaded.");
		}

		private static void HUD_Awake(orig_Awake orig, HUD self)
		{
			orig.Invoke(self);
			HudCrosshairDriver.Attach(self);
		}

		private void OnDestroy()
		{
			//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)
			//IL_001c: Expected O, but got Unknown
			object obj = <>O.<0>__HUD_Awake;
			if (obj == null)
			{
				hook_Awake val = HUD_Awake;
				<>O.<0>__HUD_Awake = val;
				obj = (object)val;
			}
			HUD.Awake -= (hook_Awake)obj;
			HudCrosshairDriver[] array = Object.FindObjectsOfType<HudCrosshairDriver>();
			foreach (HudCrosshairDriver hudCrosshairDriver in array)
			{
				Object.Destroy((Object)(object)hudCrosshairDriver);
			}
			CrosshairPrefab = null;
			if ((Object)(object)_prefabHolder != (Object)null)
			{
				Object.Destroy((Object)(object)_prefabHolder);
			}
		}
	}
	internal readonly struct DynamicOffsets : IEquatable<DynamicOffsets>
	{
		internal readonly float InnerBars;

		internal readonly float OuterBars;

		internal readonly float Circle;

		internal DynamicOffsets(float innerBars, float outerBars, float circle)
		{
			InnerBars = innerBars;
			OuterBars = outerBars;
			Circle = circle;
		}

		public bool Equals(DynamicOffsets other)
		{
			return InnerBars == other.InnerBars && OuterBars == other.OuterBars && Circle == other.Circle;
		}
	}
	internal sealed class ProceduralCrosshairView : MonoBehaviour
	{
		private const float ReferenceWidth = 1920f;

		private const float ReferenceHeight = 1080f;

		private static int _loggedScreenWidth = -1;

		private static int _loggedScreenHeight = -1;

		private static float _loggedPixelsPerUnit = -1f;

		private RectTransform _rect = null;

		private RectTransform _root = null;

		private CircleLayer _circle = null;

		private BarsLayer _outerBars = null;

		private BarsLayer _innerBars = null;

		private CenterDotLayer _centerDot = null;

		private Canvas? _canvas;

		private int _lastRevision = -1;

		private int _lastScreenWidth = -1;

		private int _lastScreenHeight = -1;

		private float _lastPixelsPerUnit = -1f;

		private Vector2 _lastRootScreen;

		private Vector2 _lastAnchorScreen;

		private DynamicOffsets _lastOffsets;

		internal DynamicOffsets Offsets { get; set; }

		private void Awake()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			_rect = (RectTransform)((Component)this).transform;
			_root = (RectTransform)((Component)this).transform.Find("ProceduralCrosshair");
			_circle = new CircleLayer((Transform)(object)_root, "Circle", CrosshairConfig.Circle);
			_outerBars = new BarsLayer((Transform)(object)_root, "OuterBars", CrosshairConfig.OuterBars);
			_innerBars = new BarsLayer((Transform)(object)_root, "InnerBars", CrosshairConfig.InnerBars);
			_centerDot = new CenterDotLayer((Transform)(object)_root, "CenterDot", CrosshairConfig.CenterDot);
			Refresh();
		}

		private void OnTransformParentChanged()
		{
			_canvas = null;
		}

		private void LateUpdate()
		{
			Refresh();
		}

		private void Refresh()
		{
			//IL_0065: 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_0087: 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_008f: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_canvas == (Object)null)
			{
				_canvas = ((Component)this).GetComponentInParent<Canvas>();
				if ((Object)(object)_canvas == (Object)null)
				{
					return;
				}
			}
			Canvas rootCanvas = _canvas.rootCanvas;
			float pixelsPerUnit = GetPixelsPerUnit(rootCanvas);
			if (pixelsPerUnit <= 0f)
			{
				return;
			}
			Camera val = (((int)rootCanvas.renderMode == 0) ? null : rootCanvas.worldCamera);
			Vector2 val2 = RectTransformUtility.WorldToScreenPoint(val, ((Transform)_root).position);
			Vector2 val3 = RectTransformUtility.WorldToScreenPoint(val, GetIntendedCenterWorld());
			DynamicOffsets offsets = Offsets;
			if (_lastRevision == CrosshairConfig.Revision && _lastScreenWidth == Screen.width && _lastScreenHeight == Screen.height && Mathf.Approximately(_lastPixelsPerUnit, pixelsPerUnit))
			{
				Vector2 val4 = _lastRootScreen - val2;
				if (((Vector2)(ref val4)).sqrMagnitude < 1E-06f)
				{
					val4 = _lastAnchorScreen - val3;
					if (((Vector2)(ref val4)).sqrMagnitude < 1E-06f && _lastOffsets.Equals(offsets))
					{
						return;
					}
				}
			}
			PixelFrame frame = CreateFrame(pixelsPerUnit, val3, val2);
			_circle.Apply(in frame, offsets.Circle);
			_outerBars.Apply(in frame, offsets.OuterBars);
			_innerBars.Apply(in frame, offsets.InnerBars);
			_centerDot.Apply(in frame);
			LogLayoutOnce(rootCanvas, in frame, val2, val3);
			_lastRevision = CrosshairConfig.Revision;
			_lastScreenWidth = Screen.width;
			_lastScreenHeight = Screen.height;
			_lastPixelsPerUnit = pixelsPerUnit;
			_lastRootScreen = val2;
			_lastAnchorScreen = val3;
			_lastOffsets = offsets;
		}

		private PixelFrame CreateFrame(float pixelsPerUnit, Vector2 anchorScreen, Vector2 rootScreen)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			float resolutionScale = Mathf.Min((float)Screen.width / 1920f, (float)Screen.height / 1080f);
			float centerFraction = (_innerBars.Enabled ? PixelFrame.FractionFor(_innerBars.Thickness, resolutionScale) : (_outerBars.Enabled ? PixelFrame.FractionFor(_outerBars.Thickness, resolutionScale) : (_centerDot.Enabled ? PixelFrame.FractionFor(_centerDot.Size, resolutionScale) : 0f)));
			return new PixelFrame(resolutionScale, pixelsPerUnit, centerFraction, anchorScreen, rootScreen);
		}

		private float GetPixelsPerUnit(Canvas rootCanvas)
		{
			//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)
			float x = ((Component)rootCanvas).transform.lossyScale.x;
			if (x <= 0f)
			{
				return 0f;
			}
			return rootCanvas.scaleFactor * (((Transform)_root).lossyScale.x / x);
		}

		private Vector3 GetIntendedCenterWorld()
		{
			//IL_002d: 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_003e: 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_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_0050: Unknown result type (might be due to invalid IL or missing references)
			Transform parent = ((Transform)_rect).parent;
			if ((Object)(object)parent == (Object)null)
			{
				return ((Transform)_root).position;
			}
			return ((Transform)_root).position - parent.TransformVector(Vector2.op_Implicit(_rect.anchoredPosition));
		}

		private void LogLayoutOnce(Canvas rootCanvas, in PixelFrame frame, Vector2 rootScreen, Vector2 anchorScreen)
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: 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_00f4: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			if (_loggedScreenWidth != Screen.width || _loggedScreenHeight != Screen.height || !Mathf.Approximately(_loggedPixelsPerUnit, frame.PixelsPerUnit))
			{
				_loggedScreenWidth = Screen.width;
				_loggedScreenHeight = Screen.height;
				_loggedPixelsPerUnit = frame.PixelsPerUnit;
				Plugin.Log.LogDebug((object)($"Crosshair layout: screen {Screen.width}x{Screen.height}, canvas {rootCanvas.renderMode} " + $"scaleFactor {rootCanvas.scaleFactor:0.###} pixelPerfect {rootCanvas.pixelPerfect}, " + $"px/unit {frame.PixelsPerUnit:0.###}, crosshair anchoredPosition {_rect.anchoredPosition}, " + $"root at {rootScreen.x:0.###},{rootScreen.y:0.###} px, anchor {anchorScreen.x:0.###},{anchorScreen.y:0.###} px, " + $"snapped center {frame.Center.x},{frame.Center.y}."));
			}
		}
	}
	[RequireComponent(typeof(Image))]
	internal sealed class RingMesh : MonoBehaviour, IMeshModifier
	{
		private readonly struct Stop
		{
			internal readonly float Radius;

			internal readonly Color32 Color;

			internal Stop(float radius, Color32 color)
			{
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				Radius = radius;
				Color = color;
			}
		}

		private readonly struct Shape : IEquatable<Shape>
		{
			internal readonly float Inner;

			internal readonly float Outer;

			internal readonly float Border;

			internal readonly float Feather;

			internal readonly Color32 Fill;

			internal readonly Color32 BorderColor;

			internal readonly int Segments;

			internal Shape(float inner, float outer, float border, float feather, Color32 fill, Color32 borderColor, int segments)
			{
				//IL_001f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Unknown result type (might be due to invalid IL or missing references)
				Inner = inner;
				Outer = outer;
				Border = border;
				Feather = feather;
				Fill = fill;
				BorderColor = borderColor;
				Segments = segments;
			}

			public bool Equals(Shape o)
			{
				//IL_0047: 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_005a: 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)
				return Inner == o.Inner && Outer == o.Outer && Border == o.Border && Feather == o.Feather && Segments == o.Segments && Same(Fill, o.Fill) && Same(BorderColor, o.BorderColor);
			}

			private static bool Same(Color32 a, Color32 b)
			{
				//IL_0000: 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_000e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_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)
				//IL_002a: 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)
				return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
			}
		}

		private readonly List<Stop> _stops = new List<Stop>();

		private Shape _shape;

		private bool _hasShape;

		private Image? _image;

		internal Image Image => ((Object)(object)_image != (Object)null) ? _image : (_image = ((Component)this).GetComponent<Image>());

		internal void SetShape(float inner, float outer, float border, float feather, Color fill, Color borderColor, int segments)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Shape shape = new Shape(inner, outer, border, feather, Color32.op_Implicit(fill), Color32.op_Implicit(borderColor), segments);
			if (!_hasShape || !shape.Equals(_shape))
			{
				_shape = shape;
				_hasShape = true;
				((Graphic)Image).SetVerticesDirty();
			}
		}

		public void ModifyMesh(Mesh mesh)
		{
		}

		public void ModifyMesh(VertexHelper vh)
		{
			//IL_0083: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			vh.Clear();
			if (!_hasShape)
			{
				return;
			}
			BuildStops(_shape);
			int segments = _shape.Segments;
			float num = MathF.PI * 2f / (float)segments;
			Vector3 val = default(Vector3);
			for (int i = 0; i < _stops.Count; i++)
			{
				Stop stop = _stops[i];
				for (int j = 0; j < segments; j++)
				{
					float num2 = (float)j * num;
					((Vector3)(ref val))..ctor(Mathf.Cos(num2) * stop.Radius, Mathf.Sin(num2) * stop.Radius);
					vh.AddVert(val, stop.Color, Vector4.zero);
				}
			}
			for (int k = 0; k + 1 < _stops.Count; k++)
			{
				int num3 = k * segments;
				int num4 = (k + 1) * segments;
				for (int l = 0; l < segments; l++)
				{
					int num5 = (l + 1) % segments;
					vh.AddTriangle(num3 + l, num4 + l, num4 + num5);
					vh.AddTriangle(num3 + l, num4 + num5, num3 + num5);
				}
			}
		}

		private void BuildStops(Shape shape)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			_stops.Clear();
			float num = shape.Feather * 0.5f;
			bool flag = shape.Border > 0f;
			List<float> list = new List<float>(4);
			List<Color32> list2 = new List<Color32>(3);
			if (flag && shape.Inner > 0f)
			{
				list.Add(Mathf.Max(0f, shape.Inner - shape.Border));
				list2.Add(shape.BorderColor);
			}
			list.Add(shape.Inner);
			list2.Add(shape.Fill);
			list.Add(shape.Outer);
			if (flag)
			{
				list2.Add(shape.BorderColor);
				list.Add(shape.Outer + shape.Border);
			}
			for (int i = 0; i < list.Count; i++)
			{
				Color32 color = ((i == 0) ? Transparent(list2[0]) : list2[i - 1]);
				Color32 color2 = ((i == list.Count - 1) ? Transparent(list2[i - 1]) : list2[i]);
				if (i == 0 && list[0] <= 0f)
				{
					AddStop(0f, color2);
					continue;
				}
				AddStop(list[i] - num, color);
				AddStop(list[i] + num, color2);
			}
		}

		private void AddStop(float radius, Color32 color)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			float num = ((_stops.Count > 0) ? _stops[_stops.Count - 1].Radius : 0f);
			_stops.Add(new Stop(Mathf.Max(radius, num), color));
		}

		private static Color32 Transparent(Color32 color)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			return new Color32(color.r, color.g, color.b, (byte)0);
		}
	}
}