Decompiled source of RailgunnerTweaks v1.0.0

RailgunnerTweaks.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using EntityStates.Railgunner.Scope;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using On.EntityStates.Railgunner.Scope;
using On.RoR2.UI;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.CameraModes;
using RoR2.UI;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace RailgunnerTweaks
{
	internal static class CameraFov
	{
		public static float GetUnscopedFov(CameraTargetParams targetParams)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_0036: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			CharacterCameraParamsData basic = CharacterCameraParamsData.basic;
			if (Object.op_Implicit((Object)(object)targetParams) && Object.op_Implicit((Object)(object)targetParams.cameraParams))
			{
				CharacterCameraParamsData data = targetParams.cameraParams.data;
				CharacterCameraParamsData.Blend(ref data, ref basic, 1f);
			}
			return basic.fov.value;
		}
	}
	internal abstract class Feature
	{
		private bool isHooked;

		public abstract string Name { get; }

		protected abstract bool ShouldBeHooked { get; }

		protected abstract void Hook();

		protected abstract void Unhook();

		public virtual void OnConfigChanged(ConfigEntryBase changedSetting)
		{
		}

		public void Refresh()
		{
			bool shouldBeHooked = ShouldBeHooked;
			if (shouldBeHooked == isHooked)
			{
				return;
			}
			try
			{
				if (shouldBeHooked)
				{
					Hook();
				}
				else
				{
					Unhook();
				}
				isHooked = shouldBeHooked;
				Log.Info(Name + ": " + (shouldBeHooked ? "enabled" : "disabled"), "D:\\DEV\\Projects\\RailgunnerTweaks\\RailgunnerTweaks\\Feature.cs", 38);
			}
			catch (Exception arg)
			{
				Log.Error(string.Format("{0}: failed to {1}: {2}", Name, shouldBeHooked ? "enable" : "disable", arg), "D:\\DEV\\Projects\\RailgunnerTweaks\\RailgunnerTweaks\\Feature.cs", 42);
			}
		}
	}
	internal class CrosshairHider : Feature
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static hook_Awake <0>__CrosshairController_Awake;
		}

		private const string NormalCrosshairName = "RailgunnerCrosshair";

		private const string ScopeCrosshairName = "RailgunnerScopeCrosshair";

		private const string HeavyScopeCrosshairName = "RailgunnerScopeCrosshairHeavy";

		private const string FlavorReady = "Flavor, Ready";

		private const string FlavorUnknown = "Flavor, Unknown";

		private const string ScopeAvailable = "Available";

		private const string ScopeOutline = "Outline";

		public override string Name => "Crosshair hiding";

		protected override bool ShouldBeHooked
		{
			get
			{
				if (!PluginConfig.HideCrosshairFlavor.Value)
				{
					return PluginConfig.HideDefaultScopeFrame.Value;
				}
				return true;
			}
		}

		protected override void Hook()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__CrosshairController_Awake;
			if (obj == null)
			{
				hook_Awake val = CrosshairController_Awake;
				<>O.<0>__CrosshairController_Awake = val;
				obj = (object)val;
			}
			CrosshairController.Awake += (hook_Awake)obj;
		}

		protected override void Unhook()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			object obj = <>O.<0>__CrosshairController_Awake;
			if (obj == null)
			{
				hook_Awake val = CrosshairController_Awake;
				<>O.<0>__CrosshairController_Awake = val;
				obj = (object)val;
			}
			CrosshairController.Awake -= (hook_Awake)obj;
		}

		private static void CrosshairController_Awake(orig_Awake orig, CrosshairController self)
		{
			orig.Invoke(self);
			try
			{
				Apply(((Component)self).transform);
			}
			catch (Exception arg)
			{
				Log.Error($"Failed to modify crosshair '{((Object)self).name}': {arg}", "D:\\DEV\\Projects\\RailgunnerTweaks\\RailgunnerTweaks\\Features\\CrosshairHider.cs", 49);
			}
		}

		private static void Apply(Transform crosshair)
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			string name = ((Object)crosshair).name;
			if (!name.StartsWith("RailgunnerCrosshair") && !name.StartsWith("RailgunnerScopeCrosshair"))
			{
				return;
			}
			if (PluginConfig.HideCrosshairFlavor.Value)
			{
				Transform[] componentsInChildren = ((Component)crosshair).GetComponentsInChildren<Transform>(true);
				foreach (Transform val in componentsInChildren)
				{
					if (((Object)val).name == "Flavor, Ready" || ((Object)val).name == "Flavor, Unknown")
					{
						Hide(val);
					}
				}
			}
			if (!PluginConfig.HideDefaultScopeFrame.Value || !name.StartsWith("RailgunnerScopeCrosshairHeavy"))
			{
				return;
			}
			Transform val2 = crosshair.Find("Available");
			if (!Object.op_Implicit((Object)(object)val2))
			{
				return;
			}
			foreach (Transform item in val2)
			{
				Transform val3 = item;
				if (((Object)val3).name == "Outline")
				{
					Hide(val3);
				}
			}
		}

		private static void Hide(Transform target)
		{
			CanvasGroup val = ((Component)target).GetComponent<CanvasGroup>();
			if (!Object.op_Implicit((Object)(object)val))
			{
				val = ((Component)target).gameObject.AddComponent<CanvasGroup>();
			}
			val.alpha = 0f;
			val.interactable = false;
			val.blocksRaycasts = false;
		}
	}
	internal class ScopedSensitivity : Feature
	{
		private const string RailgunnerBodyName = "RailgunnerBody";

		private static readonly MethodInfo CollectLookInput = AccessTools.Method(typeof(CameraModeBase), "CollectLookInput", (Type[])null, (Type[])null);

		private static readonly MethodInfo PostfixMethod = AccessTools.Method(typeof(ScopedSensitivity), "CollectLookInput_Postfix", (Type[])null, (Type[])null);

		private Harmony harmony;

		public override string Name => "Scoped sensitivity";

		protected override bool ShouldBeHooked
		{
			get
			{
				if (!PluginConfig.ZeroMonitorMatch.Value)
				{
					return PluginConfig.ScopedSensitivityPercent.Value != 100;
				}
				return true;
			}
		}

		protected override void Hook()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (harmony == null)
			{
				harmony = new Harmony("Bishey.RailgunnerTweaks.ScopedSensitivity");
			}
			harmony.Patch((MethodBase)CollectLookInput, (HarmonyMethod)null, new HarmonyMethod(PostfixMethod), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		protected override void Unhook()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.Unpatch((MethodBase)CollectLookInput, PostfixMethod);
			}
		}

		private static void CollectLookInput_Postfix(ref CameraModeContext context, ref CollectLookInputResult result)
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			CameraTargetParams targetParams = context.targetInfo.targetParams;
			if (!Object.op_Implicit((Object)(object)targetParams) || !((Object)targetParams).name.StartsWith("RailgunnerBody"))
			{
				return;
			}
			float fov = context.cameraInfo.previousCameraState.fov;
			float value = targetParams.currentCameraParamsData.fov.value;
			float unscopedFov = CameraFov.GetUnscopedFov(targetParams);
			if (!(value < 1f) && !(fov < 1f) && !(value >= unscopedFov - 0.01f))
			{
				float num = (float)PluginConfig.ScopedSensitivityPercent.Value / 100f;
				if (PluginConfig.ZeroMonitorMatch.Value)
				{
					float num2 = fov * unscopedFov / value;
					float num3 = Mathf.Tan(fov * 0.5f * (MathF.PI / 180f)) / Mathf.Tan(num2 * 0.5f * (MathF.PI / 180f));
					num *= num2 / fov * num3;
				}
				ref Vector2 lookInput = ref result.lookInput;
				lookInput *= num;
			}
		}
	}
	internal class VariableZoom : Feature
	{
		private enum Scope
		{
			Default,
			Alternate
		}

		private class TrackedOverride
		{
			public CameraParamsOverride cameraOverride;

			public CameraTargetParams targetParams;

			public Scope scope;

			public float originalFov;
		}

		private class ScopeZoom
		{
			public List<float> levels;

			public int index = -1;

			private float easeFrom;

			private float easeTo;

			private float easeStartTime = float.NegativeInfinity;

			public bool HasValue => easeTo > 0f;

			public float Current
			{
				get
				{
					float value = PluginConfig.ZoomTransitionTime.Value;
					float num = Time.time - easeStartTime;
					if (value <= 0f || num >= value)
					{
						return easeTo;
					}
					float num2 = Mathf.SmoothStep(0f, 1f, num / value);
					return Mathf.Exp(Mathf.Lerp(Mathf.Log(easeFrom), Mathf.Log(easeTo), num2));
				}
			}

			public void SnapTo(float zoom)
			{
				easeFrom = (easeTo = zoom);
				easeStartTime = float.NegativeInfinity;
			}

			public void EaseTo(float zoom)
			{
				easeFrom = (HasValue ? Current : zoom);
				easeTo = zoom;
				easeStartTime = Time.time;
			}
		}

		private class Driver : MonoBehaviour
		{
			public VariableZoom owner;

			private void Update()
			{
				owner.Tick();
			}
		}

		private const string RailgunnerBodyName = "RailgunnerBody";

		private readonly ScopeZoom[] zooms = new ScopeZoom[2]
		{
			new ScopeZoom(),
			new ScopeZoom()
		};

		private readonly List<TrackedOverride> tracked = new List<TrackedOverride>();

		private BaseActive activeState;

		private Scope activeScope;

		private float sprintFovMultiplier = 1f;

		private GameObject driverObject;

		public override string Name => "Variable zoom";

		protected override bool ShouldBeHooked => PluginConfig.EnableVariableZoom.Value;

		protected override void Hook()
		{
			//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
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			BaseScopeState.StartScopeParamsOverride += new hook_StartScopeParamsOverride(BaseScopeState_StartScopeParamsOverride);
			BaseActive.OnExit += new hook_OnExit(BaseActive_OnExit);
			driverObject = new GameObject("RailgunnerTweaks.VariableZoom");
			Object.DontDestroyOnLoad((Object)(object)driverObject);
			((Object)driverObject).hideFlags = (HideFlags)61;
			driverObject.AddComponent<Driver>().owner = this;
		}

		protected override void Unhook()
		{
			//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
			BaseScopeState.StartScopeParamsOverride -= new hook_StartScopeParamsOverride(BaseScopeState_StartScopeParamsOverride);
			BaseActive.OnExit -= new hook_OnExit(BaseActive_OnExit);
			foreach (TrackedOverride item in tracked)
			{
				if (item.cameraOverride != null)
				{
					item.cameraOverride.cameraParamsData.fov.value = item.originalFov;
				}
			}
			tracked.Clear();
			activeState = null;
			if (Object.op_Implicit((Object)(object)driverObject))
			{
				Object.Destroy((Object)(object)driverObject);
			}
			driverObject = null;
		}

		public override void OnConfigChanged(ConfigEntryBase changedSetting)
		{
			if (Contains<ConfigEntry<bool>>(PluginConfig.DefaultLevelEnabled, changedSetting) || Contains<ConfigEntry<float>>(PluginConfig.DefaultLevel, changedSetting))
			{
				ResetScope(Scope.Default);
			}
			else if (Contains<ConfigEntry<bool>>(PluginConfig.AlternateLevelEnabled, changedSetting) || Contains<ConfigEntry<float>>(PluginConfig.AlternateLevel, changedSetting))
			{
				ResetScope(Scope.Alternate);
			}
		}

		private void BaseScopeState_StartScopeParamsOverride(orig_StartScopeParamsOverride orig, BaseScopeState self, float transitionDuration)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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)
			bool isValid = ((CameraParamsOverrideHandle)(ref self.cameraParamsOverrideHandle)).isValid;
			orig.Invoke(self, transitionDuration);
			if (isValid || !((EntityState)self).isAuthority || !Object.op_Implicit((Object)(object)((EntityState)self).characterBody) || !((EntityState)self).characterBody.isPlayerControlled)
			{
				return;
			}
			Scope? scope = GetScope(self);
			CameraParamsOverrideHandle cameraParamsOverrideHandle = self.cameraParamsOverrideHandle;
			if (!scope.HasValue || !((CameraParamsOverrideHandle)(ref cameraParamsOverrideHandle)).isValid || !Object.op_Implicit((Object)(object)((EntityState)self).cameraTargetParams))
			{
				return;
			}
			List<float> levels = GetLevels(scope.Value);
			if (levels.Count != 0)
			{
				ScopeZoom scopeZoom = zooms[(int)scope.Value];
				if (self is BaseWindUp || !scopeZoom.HasValue)
				{
					scopeZoom.SnapTo(levels[GetIndex(scopeZoom, levels)]);
				}
				BaseActive val = (BaseActive)(object)((self is BaseActive) ? self : null);
				if (val != null)
				{
					activeState = val;
					activeScope = scope.Value;
				}
				CameraParamsOverride target = cameraParamsOverrideHandle.target;
				tracked.Add(new TrackedOverride
				{
					cameraOverride = target,
					targetParams = ((EntityState)self).cameraTargetParams,
					scope = scope.Value,
					originalFov = target.cameraParamsData.fov.value
				});
				target.cameraParamsData.fov.value = CalculateOverrideFov(((EntityState)self).cameraTargetParams, scopeZoom.Current);
			}
		}

		private void BaseActive_OnExit(orig_OnExit orig, BaseActive self)
		{
			orig.Invoke(self);
			if (activeState == self)
			{
				activeState = null;
			}
		}

		private void Tick()
		{
			UpdateSprintFovMultiplier();
			HandleScroll();
			UpdateTrackedOverrides();
		}

		private void HandleScroll()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (activeState == null)
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)((EntityState)activeState).outer))
			{
				activeState = null;
				return;
			}
			float y = Input.mouseScrollDelta.y;
			if (y == 0f)
			{
				return;
			}
			int num = ((y > 0f) ? 1 : (-1));
			if (PluginConfig.InvertScroll.Value)
			{
				num = -num;
			}
			ScopeZoom scopeZoom = zooms[(int)activeScope];
			List<float> levels = GetLevels(activeScope);
			if (levels.Count >= 2)
			{
				int index = GetIndex(scopeZoom, levels);
				int num2 = Mathf.Clamp(index + num, 0, levels.Count - 1);
				if (num2 != index)
				{
					scopeZoom.index = num2;
					scopeZoom.EaseTo(levels[num2]);
				}
			}
		}

		private void UpdateTrackedOverrides()
		{
			float time = Time.time;
			for (int num = tracked.Count - 1; num >= 0; num--)
			{
				TrackedOverride trackedOverride = tracked[num];
				if (!Object.op_Implicit((Object)(object)trackedOverride.targetParams) || trackedOverride.cameraOverride == null || trackedOverride.cameraOverride.exitEndTime <= time)
				{
					tracked.RemoveAt(num);
				}
				else
				{
					List<float> levels = GetLevels(trackedOverride.scope);
					trackedOverride.cameraOverride.cameraParamsData.fov.value = ((levels.Count == 0) ? trackedOverride.originalFov : CalculateOverrideFov(trackedOverride.targetParams, zooms[(int)trackedOverride.scope].Current));
				}
			}
		}

		private void UpdateSprintFovMultiplier()
		{
			foreach (CameraRigController readOnlyInstances in CameraRigController.readOnlyInstancesList)
			{
				CharacterBody val = (Object.op_Implicit((Object)(object)readOnlyInstances) ? readOnlyInstances.targetBody : null);
				if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)readOnlyInstances.sceneCam) || !((Object)val).name.StartsWith("RailgunnerBody"))
				{
					continue;
				}
				CameraTargetParams component = ((Component)val).GetComponent<CameraTargetParams>();
				if (Object.op_Implicit((Object)(object)component))
				{
					float value = component.currentCameraParamsData.fov.value;
					if (!(value < 1f))
					{
						float num = Mathf.Clamp(readOnlyInstances.sceneCam.fieldOfView / value, 0.5f, 3f);
						float num2 = 1f - Mathf.Exp((0f - Time.deltaTime) / 0.05f);
						sprintFovMultiplier = Mathf.Lerp(sprintFovMultiplier, num, num2);
						break;
					}
				}
			}
		}

		private float CalculateOverrideFov(CameraTargetParams targetParams, float magnification)
		{
			magnification = Mathf.Max(magnification, 1f);
			float num = sprintFovMultiplier;
			float num2 = CameraFov.GetUnscopedFov(targetParams) * num * 0.5f * (MathF.PI / 180f);
			return 2f * Mathf.Atan(Mathf.Tan(num2) / magnification) * 57.29578f / num;
		}

		private List<float> GetLevels(Scope scope)
		{
			ScopeZoom scopeZoom = zooms[(int)scope];
			if (scopeZoom.levels == null)
			{
				scopeZoom.levels = ((scope == Scope.Default) ? BuildLevels(PluginConfig.DefaultLevelEnabled, PluginConfig.DefaultLevel) : BuildLevels(PluginConfig.AlternateLevelEnabled, PluginConfig.AlternateLevel));
			}
			return scopeZoom.levels;
		}

		private static List<float> BuildLevels(ConfigEntry<bool>[] enabled, ConfigEntry<float>[] values)
		{
			List<float> list = new List<float>();
			for (int i = 0; i < enabled.Length; i++)
			{
				if (enabled[i].Value)
				{
					float value = Mathf.Clamp(values[i].Value, 1f, 10f);
					value = Mathf.Round(value * 100f) / 100f;
					if (!list.Exists((float existing) => Mathf.Abs(existing - value) < 0.001f))
					{
						list.Add(value);
					}
				}
			}
			list.Sort();
			return list;
		}

		private static int GetIndex(ScopeZoom zoom, List<float> levels)
		{
			if (zoom.index < 0 || zoom.index >= levels.Count)
			{
				zoom.index = levels.Count / 2;
			}
			return zoom.index;
		}

		private void ResetScope(Scope scope)
		{
			ScopeZoom scopeZoom = zooms[(int)scope];
			scopeZoom.levels = null;
			scopeZoom.index = -1;
			List<float> levels = GetLevels(scope);
			if (levels.Count > 0 && tracked.Exists((TrackedOverride t) => t.scope == scope))
			{
				scopeZoom.EaseTo(levels[GetIndex(scopeZoom, levels)]);
			}
		}

		private static Scope? GetScope(BaseScopeState state)
		{
			if (state is WindUpScopeHeavy || state is ActiveScopeHeavy || state is WindDownScopeHeavy)
			{
				return Scope.Default;
			}
			if (state is WindUpScopeLight || state is ActiveScopeLight || state is WindDownScopeLight)
			{
				return Scope.Alternate;
			}
			return null;
		}

		private static bool Contains<T>(T[] entries, ConfigEntryBase setting) where T : ConfigEntryBase
		{
			for (int i = 0; i < entries.Length; i++)
			{
				if ((object)entries[i] == setting)
				{
					return true;
				}
			}
			return false;
		}
	}
	internal static class Log
	{
		private static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		private static string Format(object data, string file, int line)
		{
			string fileName = Path.GetFileName(file);
			return $"[{fileName}:{line}] {data}";
		}

		internal static void Debug(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0)
		{
			_logSource.LogDebug((object)Format(data, file, line));
		}

		internal static void Error(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0)
		{
			_logSource.LogError((object)Format(data, file, line));
		}

		internal static void Fatal(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0)
		{
			_logSource.LogFatal((object)Format(data, file, line));
		}

		internal static void Info(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0)
		{
			_logSource.LogInfo((object)Format(data, file, line));
		}

		internal static void Message(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0)
		{
			_logSource.LogMessage((object)Format(data, file, line));
		}

		internal static void Warning(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0)
		{
			_logSource.LogWarning((object)Format(data, file, line));
		}
	}
	internal static class PluginConfig
	{
		public const string GeneralSection = "General";

		public const string DefaultZoomSection = "Zoom - Default";

		public const string AlternateZoomSection = "Zoom - Alternate";

		public const float MinZoom = 1f;

		public const float MaxZoom = 10f;

		public const float ZoomStep = 0.1f;

		public const float MaxTransitionTime = 1f;

		public const int MinScopedSensitivity = 1;

		public const int MaxScopedSensitivity = 100;

		public static ConfigEntry<bool> HideCrosshairFlavor;

		public static ConfigEntry<bool> HideDefaultScopeFrame;

		public static ConfigEntry<bool> EnableVariableZoom;

		public static ConfigEntry<bool> InvertScroll;

		public static ConfigEntry<float> ZoomTransitionTime;

		public static ConfigEntry<bool> ZeroMonitorMatch;

		public static ConfigEntry<int> ScopedSensitivityPercent;

		public static readonly ConfigEntry<bool>[] DefaultLevelEnabled = new ConfigEntry<bool>[3];

		public static readonly ConfigEntry<float>[] DefaultLevel = new ConfigEntry<float>[3];

		public static readonly ConfigEntry<bool>[] AlternateLevelEnabled = new ConfigEntry<bool>[3];

		public static readonly ConfigEntry<float>[] AlternateLevel = new ConfigEntry<float>[3];

		public static void Bind(ConfigFile config)
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Expected O, but got Unknown
			HideCrosshairFlavor = config.Bind<bool>("General", "HideCrosshairFlavor", true, "Hides the decorative yellow frame and status text around Railgunner's crosshair. Takes effect on your next scope-in.");
			HideDefaultScopeFrame = config.Bind<bool>("General", "HideDefaultScopeFrame", true, "Hides the pink frame and zoom text inside the default sniper's scope. Takes effect on your next scope-in.");
			EnableVariableZoom = config.Bind<bool>("General", "EnableVariableZoom", true, "Lets you change the scope's zoom with the mouse wheel.");
			InvertScroll = config.Bind<bool>("General", "InvertScroll", false, "When off, scrolling up zooms in. When on, scrolling down zooms in.");
			ZoomTransitionTime = config.Bind<float>("General", "ZoomTransitionTime", 0.1f, new ConfigDescription("How long a zoom change takes, in seconds. 0 makes it instant.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			ZeroMonitorMatch = config.Bind<bool>("General", "ZeroMonitorMatch", true, "While scoped, scales mouse sensitivity with 0% monitor match (focal length scaling), so aiming feels consistent at every zoom level.");
			ScopedSensitivityPercent = config.Bind<int>("General", "ScopedSensitivityPercent", 100, new ConfigDescription("Mouse sensitivity while scoped, as a percentage, applied on top of the scaling above. 100 means same sensitivity scoped or unscoped.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			BindLevels(config, "Zoom - Default", "Default", "default sniper", 3.6f, new float[3] { 2f, 4f, 8f }, DefaultLevelEnabled, DefaultLevel);
			BindLevels(config, "Zoom - Alternate", "Alternate", "alternate sniper", 2.2f, new float[3] { 2f, 3f, 5f }, AlternateLevelEnabled, AlternateLevel);
		}

		private static void BindLevels(ConfigFile config, string section, string keyPrefix, string weaponName, float vanillaZoom, float[] defaults, ConfigEntry<bool>[] enabled, ConfigEntry<float>[] values)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			string text = Format(vanillaZoom);
			for (int i = 0; i < 3; i++)
			{
				int num = i + 1;
				enabled[i] = config.Bind<bool>(section, $"{keyPrefix}Level{num}Enabled", true, $"Whether zoom level {num} is available for the {weaponName}. If every level is disabled, this scope uses vanilla zoom.");
				values[i] = config.Bind<float>(section, $"{keyPrefix}Level{num}", defaults[i], new ConfigDescription($"Level {num} zoom amount for {weaponName}. Vanilla zoom is {text}x at 60 FOV, mod default is {Format(defaults[i])}x.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 10f), Array.Empty<object>()));
			}
		}

		private static string Format(float value)
		{
			return value.ToString("0.##", CultureInfo.InvariantCulture);
		}
	}
	[BepInPlugin("Bishey.RailgunnerTweaks", "RailgunnerTweaks", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class RailgunnerTweaksPlugin : BaseUnityPlugin
	{
		public const string PluginAuthor = "Bishey";

		public const string PluginName = "RailgunnerTweaks";

		public const string PluginGUID = "Bishey.RailgunnerTweaks";

		public const string PluginVersion = "1.0.0";

		private Feature[] features;

		public void Awake()
		{
			Log.Init(((BaseUnityPlugin)this).Logger);
			PluginConfig.Bind(((BaseUnityPlugin)this).Config);
			features = new Feature[3]
			{
				new CrosshairHider(),
				new VariableZoom(),
				new ScopedSensitivity()
			};
			Feature[] array = features;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].Refresh();
			}
			((BaseUnityPlugin)this).Config.SettingChanged += delegate(object _, SettingChangedEventArgs args)
			{
				Feature[] array2 = features;
				foreach (Feature obj in array2)
				{
					obj.Refresh();
					obj.OnConfigChanged(args.ChangedSetting);
				}
			};
			if (RiskOfOptionsCompat.IsInstalled)
			{
				RiskOfOptionsCompat.Register();
			}
			Log.Info("RailgunnerTweaks loaded.", "D:\\DEV\\Projects\\RailgunnerTweaks\\RailgunnerTweaks\\RailgunnerTweaks.cs", 47);
		}
	}
	internal static class RiskOfOptionsCompat
	{
		public const string PluginGUID = "com.rune580.riskofoptions";

		public static bool IsInstalled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");

		[MethodImpl(MethodImplOptions.NoInlining)]
		public static void Register()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_0085: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			Sprite val = LoadIcon();
			if (Object.op_Implicit((Object)(object)val))
			{
				ModSettingsManager.SetModIcon(val);
			}
			ModSettingsManager.SetModDescription("Quality-of-life tweaks for Railgunner: variable scope zoom, scoped sensitivity options, and optional removal of decorative HUD elements. Every feature can be turned off, in which case the game behaves as vanilla.");
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.EnableVariableZoom));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.InvertScroll));
			ModSettingsManager.AddOption((BaseOption)new StepSliderOption(PluginConfig.ZoomTransitionTime, new StepSliderConfig
			{
				min = 0f,
				max = 1f,
				increment = 0.05f
			}));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.ZeroMonitorMatch));
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(PluginConfig.ScopedSensitivityPercent, new IntSliderConfig
			{
				min = 1,
				max = 100
			}));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.HideCrosshairFlavor));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.HideDefaultScopeFrame));
			AddLevels(PluginConfig.DefaultLevelEnabled, PluginConfig.DefaultLevel);
			AddLevels(PluginConfig.AlternateLevelEnabled, PluginConfig.AlternateLevel);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static void AddLevels(ConfigEntry<bool>[] enabled, ConfigEntry<float>[] values)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			for (int i = 0; i < enabled.Length; i++)
			{
				ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(enabled[i]));
				ModSettingsManager.AddOption((BaseOption)new StepSliderOption(values[i], new StepSliderConfig
				{
					min = 1f,
					max = 10f,
					increment = 0.1f
				}));
			}
		}

		private static Sprite LoadIcon()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			using Stream stream = typeof(RiskOfOptionsCompat).Assembly.GetManifestResourceStream("RailgunnerTweaks.icon.png");
			if (stream == null)
			{
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val, memoryStream.ToArray()))
			{
				return null;
			}
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}
	}
}