Decompiled source of Squidos Sprint Crosshair v1.2.1

SquidosSprintCrosshair.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.UI;
using UnityEngine;
using UnityEngine.UI;

[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace FluxSquido.SprintCrosshairOverlay;

[BepInPlugin("FluxSquido.SquidosSprintCrosshair", "Squido's Sprint Crosshair", "1.2.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class SprintCrosshairOverlayPlugin : BaseUnityPlugin
{
	public const string GUID = "FluxSquido.SquidosSprintCrosshair";

	public const string NAME = "Squido's Sprint Crosshair";

	public const string VERSION = "1.2.1";

	internal const string RiskOfOptionsGuid = "com.rune580.riskofoptions";

	internal static ManualLogSource Log;

	internal const string ColorSection = "Crosshair Coloring";

	internal const string GlobalSection = "Global Crosshair Behaviors";

	internal static ConfigEntry<bool> CfgEnabled;

	internal static ConfigEntry<float> CfgMaxOpacity;

	internal static ConfigEntry<float> CfgFadeIn;

	internal static ConfigEntry<float> CfgFadeOut;

	internal static ConfigEntry<string> CfgColorHex;

	internal static ConfigEntry<bool> CfgColorAll;

	internal static ConfigEntry<bool> CfgSpreadAll;

	internal static ConfigEntry<bool> CfgRemoveAll;

	internal const float SpreadStep = 0.15f;

	private static string _lastHex;

	private static Color _cachedColor = new Color(0.639f, 0.89f, 1f, 1f);

	private void Awake()
	{
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		Log = ((BaseUnityPlugin)this).Logger;
		CfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master toggle. When off, the vanilla sprint crosshair behavior returns for everyone.");
		CfgMaxOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Max Opacity", 1f, "Opacity of the sprint arrow while sprinting, for all characters (0 = invisible, 1 = fully opaque).");
		CfgFadeIn = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Fade In Seconds", 0f, "How long the sprint arrow (or color tint) takes to fade IN when you start sprinting. 0 = instant.");
		CfgFadeOut = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Fade Out Seconds", 0f, "How long the sprint arrow (or color tint) takes to fade OUT when you stop sprinting. 0 = instant.");
		CfgColorHex = ((BaseUnityPlugin)this).Config.Bind<string>("Crosshair Coloring", "Crosshair Sprint Color", "A3E3FF", "Global hex color (RRGGBB) the crosshair fades to while sprinting, for any character that has 'Color Crosshair' turned on.");
		CfgColorAll = ((BaseUnityPlugin)this).Config.Bind<bool>("Global Crosshair Behaviors", "Color Crosshair For All Characters", false, "When on, every character's crosshair tints to the Crosshair Sprint Color while sprinting, ignoring each character's own 'Color Crosshair' setting (their settings are kept for when you turn this off). Characters using the vanilla sprint crosshair are still left alone.");
		CfgSpreadAll = ((BaseUnityPlugin)this).Config.Bind<bool>("Global Crosshair Behaviors", "Increase Spread For All Characters", false, "When on, every character's crosshair visually spreads while sprinting, ignoring each character's own 'Increase Spread While Sprinting' setting (their settings are kept for when you turn this off). Each character's 'Spread Increase Multiplier' still sets how much. Characters using the vanilla sprint crosshair are still left alone.");
		CfgRemoveAll = ((BaseUnityPlugin)this).Config.Bind<bool>("Global Crosshair Behaviors", "Remove Sprint Crosshair For All Characters", false, "When on, no character shows the sprint arrow: everyone just keeps their normal crosshair while sprinting, ignoring each character's own 'Remove Sprint Crosshair' setting (their settings are kept for when you turn this off). Color and spread still work. Characters using the vanilla sprint crosshair are still left alone.");
		CharacterSettings.BindOther(((BaseUnityPlugin)this).Config);
		RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(OnGameLoaded));
		new Harmony("FluxSquido.SquidosSprintCrosshair").PatchAll();
		Log.LogInfo((object)"Squido's Sprint Crosshair 1.2.1 loaded.");
	}

	private void OnGameLoaded()
	{
		try
		{
			CharacterSettings.BindSurvivors(((BaseUnityPlugin)this).Config);
		}
		catch (Exception ex)
		{
			Log.LogError((object)("Failed to build per-survivor settings: " + ex));
		}
		if (Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"))
		{
			try
			{
				RiskOfOptionsCompat.Register();
			}
			catch (Exception ex2)
			{
				Log.LogError((object)("RiskOfOptions registration failed: " + ex2));
			}
		}
	}

	internal static Color SprintColor()
	{
		//IL_005c: 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)
		string value = CfgColorHex.Value;
		if (value != _lastHex)
		{
			_lastHex = value;
			string text = ((value == null || !value.StartsWith("#")) ? ("#" + value) : value);
			Color cachedColor = default(Color);
			if (ColorUtility.TryParseHtmlString(text, ref cachedColor))
			{
				_cachedColor = cachedColor;
			}
		}
		return _cachedColor;
	}

	internal static float FadeDelta(float current, float target)
	{
		float num = ((!(target > current)) ? CfgFadeOut.Value : CfgFadeIn.Value);
		return (!(num <= 0f)) ? (Time.deltaTime / num) : 1f;
	}
}
internal class CharacterSettings
{
	internal struct Defaults
	{
		public bool Vanilla;

		public bool Generic;

		public float Scale;

		public float VOffset;

		public float HOffset;

		public float Tilt;

		public static Defaults Base => new Defaults
		{
			Scale = 1f,
			VOffset = 35f,
			HOffset = 0f,
			Tilt = 0f
		};
	}

	public string Section;

	public ConfigEntry<bool> UseVanilla;

	public ConfigEntry<bool> RemoveOnly;

	public ConfigEntry<bool> GenericArrow;

	public ConfigEntry<float> Scale;

	public ConfigEntry<float> VerticalOffset;

	public ConfigEntry<float> HorizontalOffset;

	public ConfigEntry<float> Tilt;

	public ConfigEntry<bool> Color;

	public ConfigEntry<bool> Spread;

	public ConfigEntry<float> SpreadMult;

	internal const string OtherSection = "Other Characters";

	internal static CharacterSettings Other;

	internal static readonly List<CharacterSettings> Survivors = new List<CharacterSettings>();

	private static readonly Dictionary<int, CharacterSettings> BySurvivorIndex = new Dictionary<int, CharacterSettings>();

	private static readonly Dictionary<string, Defaults> Tuned = new Dictionary<string, Defaults>
	{
		["voidfiend"] = D(45f),
		["acrid"] = D(25f),
		["artificer"] = D(70f),
		["bandit"] = D(30f),
		["captain"] = D(15f),
		["chef"] = D(17f),
		["engineer"] = D(30f),
		["falseson"] = D(25f, 1f, 180f),
		["huntress"] = D(20f, 1f, 0f, vanilla: true),
		["loader"] = D(25f),
		["mercenary"] = D(20f, 1f, 0f, vanilla: true),
		["mult"] = D(40f, 1.5f),
		["operator"] = D(14f, 1f, 0f, vanilla: false, generic: true),
		["railgunner"] = D(8f),
		["rex"] = D(25f),
		["seeker"] = D(17f)
	};

	private static Defaults D(float v = 35f, float scale = 1f, float tilt = 0f, bool vanilla = false, bool generic = false)
	{
		return new Defaults
		{
			VOffset = v,
			Scale = scale,
			Tilt = tilt,
			HOffset = 0f,
			Vanilla = vanilla,
			Generic = generic
		};
	}

	private static string Norm(string s)
	{
		if (string.IsNullOrEmpty(s))
		{
			return "";
		}
		StringBuilder stringBuilder = new StringBuilder(s.Length);
		foreach (char c in s)
		{
			if (c >= 'a' && c <= 'z')
			{
				stringBuilder.Append(c);
			}
			else if (c >= '0' && c <= '9')
			{
				stringBuilder.Append(c);
			}
			else if (c >= 'A' && c <= 'Z')
			{
				stringBuilder.Append((char)(c + 32));
			}
		}
		return stringBuilder.ToString();
	}

	private static Defaults DefaultsFor(string sectionName)
	{
		Defaults value;
		return (!Tuned.TryGetValue(Norm(sectionName), out value)) ? Defaults.Base : value;
	}

	private static CharacterSettings Bind(ConfigFile cfg, string section, string who, bool hasCustomSprint, Defaults d)
	{
		CharacterSettings characterSettings = new CharacterSettings();
		characterSettings.Section = section;
		characterSettings.UseVanilla = cfg.Bind<bool>(section, "Use Vanilla Sprint Crosshair", d.Vanilla, "When on, " + who + " goes back to the game's default: the crosshair is replaced by the sprint crosshair while sprinting, and this mod's arrow/color and offsets are ignored for them.");
		characterSettings.RemoveOnly = cfg.Bind<bool>(section, "Remove Sprint Crosshair", false, "When on, " + who + " simply keeps their normal crosshair while sprinting with no arrow and no color added. Just removes the sprint-crosshair swap. Ignored if Use Vanilla Sprint Crosshair is on, or while 'Remove Sprint Crosshair For All Characters' is on.");
		characterSettings.Scale = cfg.Bind<float>(section, "Scale", d.Scale, "Size of the sprint arrow for " + who + " (1 = the vanilla sprint crosshair size).");
		characterSettings.VerticalOffset = cfg.Bind<float>(section, "Vertical Offset", d.VOffset, "How many pixels above the crosshair the sprint arrow sits for " + who + " (negative = below).");
		characterSettings.HorizontalOffset = cfg.Bind<float>(section, "Horizontal Offset", d.HOffset, "Left/right nudge of the sprint arrow in pixels for " + who + " (positive = right). Leave at 0 for centered.");
		characterSettings.Tilt = cfg.Bind<float>(section, "Tilt", d.Tilt, "Rotation of the sprint arrow in degrees for " + who + " (positive = clockwise).");
		CharacterSettings characterSettings2 = characterSettings;
		if (hasCustomSprint)
		{
			characterSettings2.GenericArrow = cfg.Bind<bool>(section, "Use Generic Sprint Arrow", d.Generic, "When on, " + who + " uses the plain generic sprint arrow instead of their custom sprint crosshair (for example Operator's, which shows primary charges).");
		}
		characterSettings2.Color = cfg.Bind<bool>(section, "Color Crosshair", false, "When on, " + who + "'s normal crosshair (not the sprint arrow) tints to the global Crosshair Sprint Color while sprinting. Works alongside the other options. Ignored while 'Color Crosshair For All Characters' is on.");
		characterSettings2.Spread = cfg.Bind<bool>(section, "Increase Spread While Sprinting", false, "When on, " + who + "'s crosshair visually spreads a little more while sprinting. Purely cosmetic; it does not change your actual spread. Ignored while 'Increase Spread For All Characters' is on.");
		characterSettings2.SpreadMult = cfg.Bind<float>(section, "Spread Increase Multiplier", 1f, "How much extra spread to show for " + who + " when spread is on for them, either from 'Increase Spread While Sprinting' or 'Increase Spread For All Characters' (1 = the full default amount).");
		return characterSettings2;
	}

	internal static void BindOther(ConfigFile cfg)
	{
		Other = Bind(cfg, "Other Characters", "bodies that aren't survivors (e.g. Heretic)", hasCustomSprint: false, D(15f));
	}

	private static bool HasCustomSprintCrosshair(SurvivorDef def)
	{
		CharacterBody val = ((!((Object)(object)def.bodyPrefab != (Object)null)) ? null : def.bodyPrefab.GetComponent<CharacterBody>());
		return (Object)(object)val != (Object)null && (Object)(object)val.sprintCrosshairPrefabOverride != (Object)null;
	}

	internal static void BindSurvivors(ConfigFile cfg)
	{
		//IL_0109: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Expected I4, but got Unknown
		Survivors.Clear();
		BySurvivorIndex.Clear();
		HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
		hashSet.Add("General");
		hashSet.Add("Crosshair Coloring");
		hashSet.Add("Global Crosshair Behaviors");
		hashSet.Add("Other Characters");
		HashSet<string> hashSet2 = hashSet;
		foreach (SurvivorDef orderedSurvivorDef in SurvivorCatalog.orderedSurvivorDefs)
		{
			if ((Object)(object)orderedSurvivorDef == (Object)null || orderedSurvivorDef.hidden || (Object)(object)orderedSurvivorDef.bodyPrefab == (Object)null)
			{
				continue;
			}
			string text = SectionNameFor(orderedSurvivorDef);
			Defaults d = DefaultsFor(text);
			if (!hashSet2.Add(text))
			{
				text = Sanitize(text + " (" + orderedSurvivorDef.cachedName + ")");
				if (!hashSet2.Add(text))
				{
					continue;
				}
			}
			CharacterSettings characterSettings = Bind(cfg, text, text, HasCustomSprintCrosshair(orderedSurvivorDef), d);
			Survivors.Add(characterSettings);
			BySurvivorIndex[(int)orderedSurvivorDef.survivorIndex] = characterSettings;
		}
		SprintCrosshairOverlayPlugin.Log.LogInfo((object)("Built sprint crosshair settings for " + Survivors.Count + " survivors."));
	}

	private static string SectionNameFor(SurvivorDef def)
	{
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Expected I4, but got Unknown
		string text = null;
		try
		{
			if (Language.english != null && !string.IsNullOrEmpty(def.displayNameToken))
			{
				text = Language.english.GetLocalizedStringByToken(def.displayNameToken);
				if (text == def.displayNameToken)
				{
					text = null;
				}
			}
		}
		catch
		{
			text = null;
		}
		text = Sanitize(text);
		if (string.IsNullOrEmpty(text))
		{
			text = Sanitize(def.cachedName);
		}
		if (string.IsNullOrEmpty(text))
		{
			text = "Survivor " + (int)def.survivorIndex;
		}
		return text;
	}

	private static string Sanitize(string s)
	{
		if (string.IsNullOrEmpty(s))
		{
			return s;
		}
		StringBuilder stringBuilder = new StringBuilder(s.Length);
		foreach (char c in s)
		{
			if (c != '[' && c != ']' && c != '=' && c != '"' && c != '\'' && c != '\\' && c != '\n' && c != '\r' && c != '\t')
			{
				stringBuilder.Append(c);
			}
		}
		return stringBuilder.ToString().Trim();
	}

	internal static CharacterSettings For(CharacterBody body)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Expected I4, but got Unknown
		if ((Object)(object)body != (Object)null)
		{
			int num = (int)SurvivorCatalog.GetSurvivorIndexFromBodyIndex(body.bodyIndex);
			if (num >= 0 && BySurvivorIndex.TryGetValue(num, out var value))
			{
				return value;
			}
		}
		return Other;
	}
}
[HarmonyPatch(typeof(CrosshairManager), "UpdateCrosshair")]
internal static class CrosshairManager_UpdateCrosshair_Patch
{
	private static readonly FieldInfo ContainerField = typeof(CrosshairManager).GetField("container", BindingFlags.Instance | BindingFlags.NonPublic);

	private static readonly FieldInfo SprintingCrosshairField = typeof(CrosshairManager).GetField("_sprintingCrosshair", BindingFlags.Static | BindingFlags.NonPublic);

	private static void Prefix(CharacterBody targetBody, out bool __state)
	{
		__state = false;
		if (!((Object)(object)targetBody == (Object)null) && SprintCrosshairOverlayPlugin.CfgEnabled.Value)
		{
			CharacterSettings characterSettings = CharacterSettings.For(targetBody);
			if ((characterSettings == null || !characterSettings.UseVanilla.Value) && targetBody.useSprintCrosshair)
			{
				targetBody.useSprintCrosshair = false;
				__state = true;
			}
		}
	}

	private static void Postfix(CrosshairManager __instance, CharacterBody targetBody, bool __state)
	{
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		if (__state && (Object)(object)targetBody != (Object)null)
		{
			targetBody.useSprintCrosshair = true;
		}
		SprintArrowIndicator sprintArrowIndicator = ((Component)__instance).gameObject.GetComponent<SprintArrowIndicator>();
		if ((Object)(object)sprintArrowIndicator == (Object)null)
		{
			sprintArrowIndicator = ((Component)__instance).gameObject.AddComponent<SprintArrowIndicator>();
		}
		bool value = SprintCrosshairOverlayPlugin.CfgEnabled.Value;
		CharacterSettings characterSettings = CharacterSettings.For(targetBody);
		bool flag = characterSettings?.UseVanilla.Value ?? false;
		GameObject sprintPrefab = null;
		if (value && (Object)(object)targetBody != (Object)null)
		{
			GameObject val = ((!(SprintingCrosshairField != null)) ? ((GameObject)null) : ((GameObject)SprintingCrosshairField.GetValue(null)));
			sprintPrefab = (((characterSettings != null && characterSettings.GenericArrow != null && characterSettings.GenericArrow.Value) || !((Object)(object)targetBody.sprintCrosshairPrefabOverride != (Object)null)) ? val : targetBody.sprintCrosshairPrefabOverride);
		}
		bool flag2 = SprintCrosshairOverlayPlugin.CfgRemoveAll.Value || (characterSettings?.RemoveOnly.Value ?? false);
		sprintArrowIndicator.Container = GetContainer(__instance);
		sprintArrowIndicator.Configure(sprintPrefab, targetBody);
		sprintArrowIndicator.Sprinting = value && !flag && !flag2 && (Object)(object)targetBody != (Object)null && targetBody.isSprinting;
	}

	private static Transform GetContainer(CrosshairManager mgr)
	{
		if (ContainerField != null)
		{
			object? value = ContainerField.GetValue(mgr);
			Transform val = (Transform)((value is Transform) ? value : null);
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
		}
		if ((Object)(object)mgr.crosshairController != (Object)null)
		{
			return ((Component)mgr.crosshairController).transform.parent;
		}
		return null;
	}
}
[HarmonyPatch(typeof(CrosshairController), "LateUpdate")]
internal static class CrosshairController_LateUpdate_Patch
{
	private static void Postfix(CrosshairController __instance)
	{
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0218: Unknown result type (might be due to invalid IL or missing references)
		//IL_021d: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0245: Unknown result type (might be due to invalid IL or missing references)
		//IL_024c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0251: Unknown result type (might be due to invalid IL or missing references)
		//IL_0258: Unknown result type (might be due to invalid IL or missing references)
		//IL_025d: Unknown result type (might be due to invalid IL or missing references)
		if (!SprintCrosshairOverlayPlugin.CfgEnabled.Value || (Object)(object)((Component)__instance).GetComponent<SprintArrowTag>() != (Object)null)
		{
			return;
		}
		CrosshairTint crosshairTint = ((Component)__instance).GetComponent<CrosshairTint>();
		if ((Object)(object)crosshairTint == (Object)null)
		{
			crosshairTint = ((Component)__instance).gameObject.AddComponent<CrosshairTint>();
		}
		HudElement hudElement = __instance.hudElement;
		CharacterBody val = ((!((Object)(object)hudElement != (Object)null)) ? null : hudElement.targetCharacterBody);
		if ((Object)(object)val == (Object)null)
		{
			val = LocalBody();
		}
		CharacterSettings characterSettings = CharacterSettings.For(val);
		bool flag = characterSettings?.UseVanilla.Value ?? false;
		float num = ((!((Object)(object)val != (Object)null) || !val.isSprinting || flag) ? 0f : 1f);
		crosshairTint.T = Mathf.MoveTowards(crosshairTint.T, num, SprintCrosshairOverlayPlugin.FadeDelta(crosshairTint.T, num));
		bool flag2 = SprintCrosshairOverlayPlugin.CfgColorAll.Value || (characterSettings != null && characterSettings.Color != null && characterSettings.Color.Value);
		bool flag3 = SprintCrosshairOverlayPlugin.CfgSpreadAll.Value || (characterSettings != null && characterSettings.Spread != null && characterSettings.Spread.Value);
		if (flag2 && crosshairTint.T > 0f)
		{
			crosshairTint.Capture(__instance);
			crosshairTint.Apply(SprintCrosshairOverlayPlugin.SprintColor());
		}
		else if (crosshairTint.Applied)
		{
			crosshairTint.Restore();
		}
		if (!flag3 || !(crosshairTint.T > 0f) || __instance.spriteSpreadPositions == null)
		{
			return;
		}
		float num2 = ((characterSettings == null || characterSettings.SpreadMult == null) ? 1f : characterSettings.SpreadMult.Value);
		float num3 = 0.15f * Mathf.Max(0f, num2) * crosshairTint.T;
		if (!(num3 > 0f))
		{
			return;
		}
		SpritePosition[] spriteSpreadPositions = __instance.spriteSpreadPositions;
		for (int i = 0; i < spriteSpreadPositions.Length; i++)
		{
			SpritePosition val2 = spriteSpreadPositions[i];
			if (!((Object)(object)val2.target == (Object)null))
			{
				RectTransform target = val2.target;
				((Transform)target).localPosition = ((Transform)target).localPosition + (val2.onePosition - val2.zeroPosition) * num3;
			}
		}
	}

	private static CharacterBody LocalBody()
	{
		LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
		CharacterMaster val = ((firstLocalUser == null) ? null : firstLocalUser.cachedMaster);
		return (!((Object)(object)val != (Object)null)) ? null : val.GetBody();
	}
}
internal class SprintArrowTag : MonoBehaviour
{
}
internal class CrosshairTint : MonoBehaviour
{
	public float T;

	public bool Applied;

	private Graphic[] _whites;

	private Color[] _orig;

	private bool _captured;

	public void Capture(CrosshairController cc)
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_004f: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		if (_captured)
		{
			return;
		}
		_captured = true;
		Graphic[] componentsInChildren = ((Component)cc).GetComponentsInChildren<Graphic>(true);
		List<Graphic> list = new List<Graphic>();
		List<Color> list2 = new List<Color>();
		Graphic[] array = componentsInChildren;
		foreach (Graphic val in array)
		{
			if (!((Object)(object)val == (Object)null))
			{
				Color color = val.color;
				if (color.r > 0.8f && color.g > 0.8f && color.b > 0.8f)
				{
					list.Add(val);
					list2.Add(color);
				}
			}
		}
		_whites = list.ToArray();
		_orig = list2.ToArray();
	}

	public void Apply(Color tgt)
	{
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		if (_whites == null)
		{
			return;
		}
		for (int i = 0; i < _whites.Length; i++)
		{
			Graphic val = _whites[i];
			if (!((Object)(object)val == (Object)null))
			{
				Color color = val.color;
				Color val2 = _orig[i];
				color.r = Mathf.Lerp(val2.r, tgt.r, T);
				color.g = Mathf.Lerp(val2.g, tgt.g, T);
				color.b = Mathf.Lerp(val2.b, tgt.b, T);
				val.color = color;
			}
		}
		Applied = true;
	}

	public void Restore()
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		if (_whites != null)
		{
			for (int i = 0; i < _whites.Length; i++)
			{
				Graphic val = _whites[i];
				if (!((Object)(object)val == (Object)null))
				{
					Color color = val.color;
					Color val2 = _orig[i];
					color.r = val2.r;
					color.g = val2.g;
					color.b = val2.b;
					val.color = color;
				}
			}
		}
		Applied = false;
	}
}
internal class SprintArrowIndicator : MonoBehaviour
{
	public Transform Container;

	public bool Sprinting;

	private static readonly Vector2 CrosshairBasePos = new Vector2(0.5f, 0.5f);

	private GameObject _builtFrom;

	private CharacterBody _body;

	private RectTransform _arrowRt;

	private CanvasGroup _group;

	private GameObject _arrow;

	private HudElement _arrowHud;

	private float _alpha;

	public void Configure(GameObject sprintPrefab, CharacterBody body)
	{
		_body = body;
		if ((Object)(object)sprintPrefab != (Object)(object)_builtFrom)
		{
			Build(sprintPrefab);
		}
	}

	private void Build(GameObject sprintPrefab)
	{
		if ((Object)(object)_arrow != (Object)null)
		{
			Object.Destroy((Object)(object)_arrow);
		}
		_arrow = null;
		_arrowRt = null;
		_group = null;
		_arrowHud = null;
		_alpha = 0f;
		_builtFrom = sprintPrefab;
		if ((Object)(object)sprintPrefab == (Object)null || (Object)(object)Container == (Object)null)
		{
			_builtFrom = null;
			return;
		}
		_arrow = Object.Instantiate<GameObject>(sprintPrefab, Container);
		ref RectTransform arrowRt = ref _arrowRt;
		Transform transform = _arrow.transform;
		arrowRt = (RectTransform)(object)((transform is RectTransform) ? transform : null);
		if ((Object)(object)_arrow.GetComponent<SprintArrowTag>() == (Object)null)
		{
			_arrow.AddComponent<SprintArrowTag>();
		}
		_group = _arrow.GetComponent<CanvasGroup>();
		if ((Object)(object)_group == (Object)null)
		{
			_group = _arrow.AddComponent<CanvasGroup>();
		}
		_group.blocksRaycasts = false;
		_group.interactable = false;
		_group.alpha = 0f;
		_arrowHud = _arrow.GetComponent<HudElement>();
	}

	private void LateUpdate()
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)_arrowRt == (Object)null))
		{
			CharacterSettings characterSettings = CharacterSettings.For(_body);
			if (characterSettings != null)
			{
				_arrowRt.anchoredPosition = CrosshairBasePos + new Vector2(characterSettings.HorizontalOffset.Value, characterSettings.VerticalOffset.Value);
				((Transform)_arrowRt).localScale = Vector3.one * Mathf.Max(0f, characterSettings.Scale.Value);
				((Transform)_arrowRt).localEulerAngles = new Vector3(0f, 0f, 0f - characterSettings.Tilt.Value);
			}
			if ((Object)(object)_arrowHud != (Object)null && (Object)(object)_body != (Object)null)
			{
				_arrowHud.targetCharacterBody = _body;
			}
			float num = ((!Sprinting) ? 0f : Mathf.Clamp01(SprintCrosshairOverlayPlugin.CfgMaxOpacity.Value));
			_alpha = Mathf.MoveTowards(_alpha, num, SprintCrosshairOverlayPlugin.FadeDelta(_alpha, num));
			_group.alpha = _alpha;
		}
	}

	private void OnDestroy()
	{
		if ((Object)(object)_arrow != (Object)null)
		{
			Object.Destroy((Object)(object)_arrow);
		}
	}
}
internal static class RiskOfOptionsCompat
{
	private const string G = "FluxSquido.SquidosSprintCrosshair";

	private const string N = "Squido's Sprint Crosshair";

	[MethodImpl(MethodImplOptions.NoInlining)]
	internal static void Register()
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Expected O, but got Unknown
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Expected O, but got Unknown
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Expected O, but got Unknown
		//IL_0072: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Expected O, but got Unknown
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Expected O, but got Unknown
		//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Expected O, but got Unknown
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Expected O, but got Unknown
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f9: Expected O, but got Unknown
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Expected O, but got Unknown
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Expected O, but got Unknown
		ModSettingsManager.SetModDescription("Keeps your normal crosshair while sprinting and shows the sprint arrow as a faint indicator above it. Opacity and fade are global; every survivor has its own vanilla toggle, scale, offset and tilt.", "FluxSquido.SquidosSprintCrosshair", "Squido's Sprint Crosshair");
		TrySetIcon();
		ConfigEntry<bool> master = SprintCrosshairOverlayPlugin.CfgEnabled;
		IsDisabledDelegate val = (IsDisabledDelegate)(() => !master.Value);
		Add((BaseOption)new CheckBoxOption(master, new CheckBoxConfig()));
		ConfigEntry<bool> removeAll = SprintCrosshairOverlayPlugin.CfgRemoveAll;
		Add((BaseOption)(object)Slider(SprintCrosshairOverlayPlugin.CfgMaxOpacity, 0f, 1f, "{0:0.00}", (IsDisabledDelegate)(() => !master.Value || removeAll.Value)));
		Add((BaseOption)(object)Slider(SprintCrosshairOverlayPlugin.CfgFadeIn, 0f, 1f, "{0:0.00}s", val));
		Add((BaseOption)(object)Slider(SprintCrosshairOverlayPlugin.CfgFadeOut, 0f, 1f, "{0:0.00}s", val));
		ConfigEntry<bool> cfgColorAll = SprintCrosshairOverlayPlugin.CfgColorAll;
		CheckBoxConfig val2 = new CheckBoxConfig();
		((BaseOptionConfig)val2).checkIfDisabled = val;
		Add((BaseOption)new CheckBoxOption(cfgColorAll, val2));
		ConfigEntry<bool> cfgSpreadAll = SprintCrosshairOverlayPlugin.CfgSpreadAll;
		val2 = new CheckBoxConfig();
		((BaseOptionConfig)val2).checkIfDisabled = val;
		Add((BaseOption)new CheckBoxOption(cfgSpreadAll, val2));
		ConfigEntry<bool> obj = removeAll;
		val2 = new CheckBoxConfig();
		((BaseOptionConfig)val2).checkIfDisabled = val;
		Add((BaseOption)new CheckBoxOption(obj, val2));
		foreach (CharacterSettings survivor in CharacterSettings.Survivors)
		{
			AddCharacter(survivor, master);
		}
		if (CharacterSettings.Other != null)
		{
			AddCharacter(CharacterSettings.Other, master);
		}
	}

	private static void AddCharacter(CharacterSettings s, ConfigEntry<bool> master)
	{
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Expected O, but got Unknown
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Expected O, but got Unknown
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Expected O, but got Unknown
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Expected O, but got Unknown
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Expected O, but got Unknown
		//IL_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Expected O, but got Unknown
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Expected O, but got Unknown
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Expected O, but got Unknown
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Expected O, but got Unknown
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: Expected O, but got Unknown
		//IL_0197: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Expected O, but got Unknown
		//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Expected O, but got Unknown
		//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Expected O, but got Unknown
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Expected O, but got Unknown
		//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Expected O, but got Unknown
		//IL_0107: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Expected O, but got Unknown
		ConfigEntry<bool> colorAll = SprintCrosshairOverlayPlugin.CfgColorAll;
		ConfigEntry<bool> spreadAll = SprintCrosshairOverlayPlugin.CfgSpreadAll;
		ConfigEntry<bool> removeAll = SprintCrosshairOverlayPlugin.CfgRemoveAll;
		ConfigEntry<bool> vanilla = s.UseVanilla;
		ConfigEntry<bool> removeOnly = s.RemoveOnly;
		ConfigEntry<bool> spread = s.Spread;
		IsDisabledDelegate checkIfDisabled = (IsDisabledDelegate)(() => !master.Value);
		IsDisabledDelegate checkIfDisabled2 = (IsDisabledDelegate)(() => !master.Value || vanilla.Value || removeAll.Value);
		IsDisabledDelegate val = (IsDisabledDelegate)(() => !master.Value || vanilla.Value || removeOnly.Value || removeAll.Value);
		IsDisabledDelegate checkIfDisabled3 = (IsDisabledDelegate)(() => !master.Value || vanilla.Value || colorAll.Value);
		IsDisabledDelegate checkIfDisabled4 = (IsDisabledDelegate)(() => !master.Value || vanilla.Value || spreadAll.Value);
		IsDisabledDelegate disabled = (IsDisabledDelegate)(() => !master.Value || vanilla.Value || (!spread.Value && !spreadAll.Value));
		ConfigEntry<bool> obj = vanilla;
		CheckBoxConfig val2 = new CheckBoxConfig();
		((BaseOptionConfig)val2).checkIfDisabled = checkIfDisabled;
		Add((BaseOption)new CheckBoxOption(obj, val2));
		ConfigEntry<bool> obj2 = removeOnly;
		val2 = new CheckBoxConfig();
		((BaseOptionConfig)val2).checkIfDisabled = checkIfDisabled2;
		Add((BaseOption)new CheckBoxOption(obj2, val2));
		if (s.GenericArrow != null)
		{
			ConfigEntry<bool> genericArrow = s.GenericArrow;
			val2 = new CheckBoxConfig();
			((BaseOptionConfig)val2).checkIfDisabled = val;
			Add((BaseOption)new CheckBoxOption(genericArrow, val2));
		}
		Add((BaseOption)(object)Slider(s.Scale, 0.1f, 2f, "{0:0.00}x", val));
		Add((BaseOption)(object)Slider(s.VerticalOffset, -200f, 300f, "{0:0}px", val));
		Add((BaseOption)(object)Slider(s.HorizontalOffset, -200f, 200f, "{0:0}px", val));
		Add((BaseOption)(object)Slider(s.Tilt, -180f, 180f, "{0:0}°", val));
		ConfigEntry<bool> color = s.Color;
		val2 = new CheckBoxConfig();
		((BaseOptionConfig)val2).checkIfDisabled = checkIfDisabled3;
		Add((BaseOption)new CheckBoxOption(color, val2));
		ConfigEntry<bool> spread2 = s.Spread;
		val2 = new CheckBoxConfig();
		((BaseOptionConfig)val2).checkIfDisabled = checkIfDisabled4;
		Add((BaseOption)new CheckBoxOption(spread2, val2));
		Add((BaseOption)(object)Slider(s.SpreadMult, 0f, 3f, "{0:0.00}x", disabled));
	}

	private static SliderOption Slider(ConfigEntry<float> entry, float min, float max, string format, IsDisabledDelegate disabled)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Expected O, but got Unknown
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Expected O, but got Unknown
		SliderConfig val = new SliderConfig();
		val.min = min;
		val.max = max;
		((BaseOptionConfig)val).checkIfDisabled = disabled;
		SliderConfig val2 = val;
		val2.FormatString = format;
		return new SliderOption(entry, val2);
	}

	private static void Add(BaseOption option)
	{
		ModSettingsManager.AddOption(option, "FluxSquido.SquidosSprintCrosshair", "Squido's Sprint Crosshair");
	}

	private static void TrySetIcon()
	{
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Expected O, but got Unknown
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			string directoryName = Path.GetDirectoryName(typeof(SprintCrosshairOverlayPlugin).Assembly.Location);
			string text = null;
			for (int i = 0; i < 2; i++)
			{
				if (directoryName == null)
				{
					break;
				}
				string text2 = Path.Combine(directoryName, "icon.png");
				if (File.Exists(text2))
				{
					text = text2;
					break;
				}
				directoryName = Path.GetDirectoryName(directoryName);
			}
			if (text != null)
			{
				Texture2D val = new Texture2D(2, 2);
				if (ImageConversion.LoadImage(val, File.ReadAllBytes(text)))
				{
					Sprite val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
					ModSettingsManager.SetModIcon(val2, "FluxSquido.SquidosSprintCrosshair", "Squido's Sprint Crosshair");
				}
			}
		}
		catch (Exception ex)
		{
			SprintCrosshairOverlayPlugin.Log.LogWarning((object)("Couldn't load icon for RiskOfOptions: " + ex.Message));
		}
	}
}