Decompiled source of ScopedBlowguns v1.3.0

ScopedBlowguns.dll

Decompiled 12 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using DG.Tweening;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Rendering;
using UnityEngine.UI;

[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("Rombusz")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("ScopedBlowguns development project.")]
[assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: AssemblyInformationalVersion("1.3.0")]
[assembly: AssemblyProduct("ScopedBlowguns")]
[assembly: AssemblyTitle("ScopedBlowguns")]
[assembly: AssemblyVersion("1.3.0.0")]
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;
		}
	}
}
namespace ScopedBlowguns
{
	internal sealed class ModConfig
	{
		public ConfigEntry<int> BlowgunPreset { get; }

		public ConfigEntry<int> RescueClawPreset { get; }

		public ConfigEntry<float> ZoomLevelOneFov { get; }

		public ConfigEntry<float> ZoomLevelTwoFov { get; }

		public ConfigEntry<float> ZoomLevelThreeFov { get; }

		public ModConfig(ConfigFile config)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Expected O, but got Unknown
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected O, but got Unknown
			BlowgunPreset = config.Bind<int>("Settings", "Blowguns Preset", 1, new ConfigDescription("Scope overlay: 1 = scope-1, 2 = scope-2, 3 = scope-3, 4 = scope-4, 5 = scope-5.", (AcceptableValueBase)(object)new AcceptableValueList<int>(new int[5] { 1, 2, 3, 4, 5 }), Array.Empty<object>()));
			RescueClawPreset = config.Bind<int>("Settings", "Rescue Claws Preset", 1, new ConfigDescription("Scope overlay: 1 = scope-rescueclaw-1, 2 = scope-rescueclaw-2, 3 = scope-rescueclaw-3, 4 = scope-rescueclaw-4, 5 = scope-rescueclaw-5.", (AcceptableValueBase)(object)new AcceptableValueList<int>(new int[5] { 1, 2, 3, 4, 5 }), Array.Empty<object>()));
			ZoomLevelOneFov = config.Bind<float>("Settings", "ZoomLevel One FOV", 40f, new ConfigDescription("Field of view in degrees. Smaller values mean stronger zoom.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(15f, 60f), Array.Empty<object>()));
			ZoomLevelTwoFov = config.Bind<float>("Settings", "ZoomLevel Two FOV", 25f, new ConfigDescription("Field of view in degrees. Smaller values mean stronger zoom.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(15f, 60f), Array.Empty<object>()));
			ZoomLevelThreeFov = config.Bind<float>("Settings", "ZoomLevel Three FOV", 15f, new ConfigDescription("Field of view in degrees. Smaller values mean stronger zoom.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(15f, 60f), Array.Empty<object>()));
		}
	}
	[DefaultExecutionOrder(1000)]
	[BepInPlugin("Rombusz.ScopedBlowguns", "ScopedBlowguns", "1.3.0")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Id = "Rombusz.ScopedBlowguns";

		public const string Name = "ScopedBlowguns";

		public const string Version = "1.3.0";

		private static Plugin? _instance;

		private ModConfig? _settings;

		private ScopeOverlay? _overlay;

		private ScopeController? _controller;

		private ScopeReticleFade? _reticleFade;

		private ScopePlayerFade? _playerFade;

		private ScopeItemVisibility? _itemVisibility;

		private ScopeChargeIndicator? _chargeIndicator;

		private Harmony? _harmony;

		internal static ScopeController? ActiveController
		{
			get
			{
				Plugin instance = _instance;
				if ((Object)(object)instance == (Object)null || !((Behaviour)instance).isActiveAndEnabled || instance._overlay == null || instance._overlay.LoadedCount == 0)
				{
					return null;
				}
				return instance._controller;
			}
		}

		private void Awake()
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			_settings = new ModConfig(((BaseUnityPlugin)this).Config);
			ScopePreset scopePreset = ScopePreset.FromId(_settings.BlowgunPreset.Value);
			((BaseUnityPlugin)this).Logger.LogMessage((object)"Plugin ScopedBlowguns 1.3.0 is loaded!");
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"Selected blowgun preset: {scopePreset.Id} - {scopePreset.DisplayName}");
			string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
			if (directoryName == null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Could not determine the plugin directory.");
				return;
			}
			_overlay = new ScopeOverlay(directoryName, ((BaseUnityPlugin)this).Logger);
			_controller = new ScopeController(_settings);
			_reticleFade = new ScopeReticleFade();
			_itemVisibility = new ScopeItemVisibility();
			_playerFade = new ScopePlayerFade(((BaseUnityPlugin)this).Logger);
			_chargeIndicator = new ScopeChargeIndicator();
			_instance = this;
			_harmony = new Harmony("Rombusz.ScopedBlowguns");
			_harmony.PatchAll(typeof(Plugin).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Harmony patches installed.");
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"Loaded {_overlay.LoadedCount}/10 scope textures.");
		}

		private void Update()
		{
			if (_controller != null)
			{
				_controller.Tick(_overlay?.HasBlowgunScopes ?? false, _overlay?.HasRescueClawScopes ?? false);
			}
		}

		private void LateUpdate()
		{
			_itemVisibility?.Tick();
		}

		private void OnGUI()
		{
			if (_settings != null && _overlay != null && _controller != null && _controller.CanAim)
			{
				int presetId = _settings.BlowgunPreset.Value;
				if (_controller.IsRescueClawScope)
				{
					presetId = ScopePreset.RescueClawScopeOne.Id + (_settings.RescueClawPreset.Value - 1);
				}
				_overlay.Draw(presetId, _controller.AimBlend);
			}
		}

		private void OnDisable()
		{
			_controller?.Reset();
			_reticleFade?.Reset();
			_itemVisibility?.Reset();
			_playerFade?.Reset();
			_chargeIndicator?.Reset();
		}

		private void OnDestroy()
		{
			_instance = null;
			_chargeIndicator?.Dispose();
			_chargeIndicator = null;
			_playerFade?.Dispose();
			_playerFade = null;
			_itemVisibility?.Dispose();
			_itemVisibility = null;
			_reticleFade?.Dispose();
			_reticleFade = null;
			_controller?.Reset();
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			_harmony = null;
			_controller = null;
			_overlay?.DestroyTextures();
			_overlay = null;
		}
	}
	internal sealed class ScopeChargeIndicator : IDisposable
	{
		private const float ChargeCircleSizeMultiplier = 1f;

		private readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4];

		private GUIManager? _gui;

		private UI_UseItemProgress? _indicator;

		private RectTransform? _root;

		private Vector3 _originalPosition;

		private Vector3 _originalScale;

		private bool _applied;

		private bool _wasCharging;

		public ScopeChargeIndicator()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			Canvas.willRenderCanvases += new WillRenderCanvases(BeforeCanvasRender);
		}

		private void BeforeCanvasRender()
		{
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: 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_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			ScopeController activeController = Plugin.ActiveController;
			if (activeController == null || !activeController.CanAim || !activeController.WantsAim)
			{
				Reset();
				return;
			}
			GUIManager instance = GUIManager.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.hudCanvas == (Object)null)
			{
				Reset();
				return;
			}
			if ((Object)(object)_gui != (Object)(object)instance)
			{
				Reset();
				_gui = instance;
				_indicator = null;
				_root = null;
			}
			if ((Object)(object)_indicator == (Object)null)
			{
				_indicator = ((Component)instance.hudCanvas).GetComponentInChildren<UI_UseItemProgress>(true);
				if ((Object)(object)_indicator == (Object)null)
				{
					return;
				}
				ref RectTransform? root = ref _root;
				Transform transform = ((Component)_indicator).transform;
				root = (RectTransform?)(object)((transform is RectTransform) ? transform : null);
			}
			if ((Object)(object)_root == (Object)null || (Object)(object)_indicator.fill == (Object)null || (Object)(object)_indicator.empty == (Object)null)
			{
				Reset();
				return;
			}
			Canvas canvas = ((Graphic)_indicator.empty).canvas;
			if ((Object)(object)canvas == (Object)null)
			{
				Reset();
				return;
			}
			canvas = canvas.rootCanvas;
			Camera val = (((int)canvas.renderMode == 0) ? null : canvas.worldCamera);
			if ((int)canvas.renderMode != 0 && (Object)(object)val == (Object)null)
			{
				Reset();
				return;
			}
			bool enabled = ((Behaviour)_indicator.fill).enabled;
			if (!_applied || (enabled && !_wasCharging))
			{
				ShortcutExtensions.DOKill((Component)(object)_root, true);
			}
			if (!_applied)
			{
				_originalPosition = _root.anchoredPosition3D;
				_originalScale = ((Transform)_root).localScale;
				_applied = true;
			}
			_root.anchoredPosition3D = _originalPosition;
			((Transform)_root).localScale = _originalScale;
			RectTransform rectTransform = ((Graphic)_indicator.empty).rectTransform;
			if (GetScreenDiameter(rectTransform, val) <= 0.001f)
			{
				Reset();
				return;
			}
			float num = (float)Mathf.Min(Screen.width, Screen.height) * 0.95f;
			((Transform)_root).localScale = _originalScale * 1f;
			float num2 = num * 0.15f;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor((float)Screen.width * 0.5f - num2, (float)Screen.height * 0.5f - num2);
			Vector3 val3 = default(Vector3);
			if (!RectTransformUtility.ScreenPointToWorldPointInRectangle(_root, val2, val, ref val3))
			{
				Reset();
				return;
			}
			Rect rect = rectTransform.rect;
			Vector3 val4 = ((Transform)rectTransform).TransformPoint(Vector2.op_Implicit(((Rect)(ref rect)).center));
			RectTransform? root2 = _root;
			((Transform)root2).position = ((Transform)root2).position + (val3 - val4);
			((Behaviour)_indicator.empty).enabled = enabled;
			_wasCharging = enabled;
		}

		private float GetScreenDiameter(RectTransform rect, Camera? uiCamera)
		{
			//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_001e: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0043: 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_005b: 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_0061: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			rect.GetWorldCorners(_corners);
			Vector2 val = RectTransformUtility.WorldToScreenPoint(uiCamera, _corners[0]);
			Vector2 val2 = val;
			for (int i = 1; i < _corners.Length; i++)
			{
				Vector2 val3 = RectTransformUtility.WorldToScreenPoint(uiCamera, _corners[i]);
				val = Vector2.Min(val, val3);
				val2 = Vector2.Max(val2, val3);
			}
			Vector2 val4 = val2 - val;
			return Mathf.Max(val4.x, val4.y);
		}

		public void Reset()
		{
			//IL_0020: 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)
			if (_applied)
			{
				if ((Object)(object)_root != (Object)null)
				{
					_root.anchoredPosition3D = _originalPosition;
					((Transform)_root).localScale = _originalScale;
				}
				if ((Object)(object)_indicator != (Object)null && (Object)(object)_indicator.empty != (Object)null)
				{
					((Behaviour)_indicator.empty).enabled = (Object)(object)_indicator.fill != (Object)null && ((Behaviour)_indicator.fill).enabled;
				}
			}
			_applied = false;
			_wasCharging = false;
		}

		public void Dispose()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			Canvas.willRenderCanvases -= new WillRenderCanvases(BeforeCanvasRender);
			Reset();
			_gui = null;
			_indicator = null;
			_root = null;
		}
	}
	internal sealed class ScopeController
	{
		private readonly ModConfig _settings;

		private Character? _postShotCharacter;

		private Item? _postShotItem;

		private bool _postShotReleased;

		private int _zoomIndex;

		private int _lastZoomInputFrame = -1;

		private float _smoothedZoomFov;

		private float _zoomVelocity;

		private float _aimVelocity;

		private float _mouseSensitivityMultiplier = 1f;

		private Camera? _ownedCamera;

		private float _lastNormalFov;

		private float _lastAppliedFov;

		private bool _ownsFov;

		private bool _normalFovEvaluatedThisFrame;

		private bool _cameraAllowsScope;

		private const float AimInSmoothTime = 0.12f;

		private const float AimOutSmoothTime = 0.16f;

		private const float ZoomSwitchSmoothTime = 0.1f;

		private const float SettleTolerance = 0.001f;

		public Item? HeldScopeItem { get; private set; }

		public bool CanAim { get; private set; }

		public bool WantsAim { get; private set; }

		public bool IsRescueClawScope { get; private set; }

		public float AimBlend { get; private set; }

		public ScopeController(ModConfig settings)
		{
			_settings = settings;
			_smoothedZoomFov = GetSelectedZoomFov();
		}

		internal static bool IsArrowBlowgun(Item item)
		{
			return item.UIData?.itemName == "ARROW_BLOWGUN";
		}

		private static Item? FindHeldScopeItem()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Invalid comparison between Unknown and I4
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null)
			{
				return null;
			}
			if (!localCharacter.data.fullyConscious)
			{
				return null;
			}
			Item currentItem = localCharacter.data.currentItem;
			if ((Object)(object)currentItem == (Object)null || !((Component)currentItem).gameObject.activeInHierarchy)
			{
				return null;
			}
			if ((int)currentItem.itemState != 1 || (Object)(object)currentItem.holderCharacter != (Object)(object)localCharacter)
			{
				return null;
			}
			if (currentItem.UIData == null)
			{
				return null;
			}
			if (currentItem.UIData.itemName == "Blowgun" && (Object)(object)((Component)currentItem).GetComponentInChildren<Action_RaycastDart>() != (Object)null)
			{
				return currentItem;
			}
			if (IsArrowBlowgun(currentItem))
			{
				return currentItem;
			}
			if (currentItem.UIData.itemName == "Rescue Claw" && (Object)(object)((Component)currentItem).GetComponent<RescueHook>() != (Object)null)
			{
				return currentItem;
			}
			return null;
		}

		private static bool IsGameplayInputAllowed()
		{
			if (!Application.isFocused || GUIManager.InPauseMenu)
			{
				return false;
			}
			GUIManager instance = GUIManager.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return false;
			}
			if (instance.windowBlockingInput || instance.windowShowingCursor || instance.wheelActive)
			{
				return false;
			}
			return true;
		}

		public void RememberScopedShot(Item? item)
		{
			Mouse current = Mouse.current;
			if (CanAim && WantsAim && !((Object)(object)item == (Object)null) && !((Object)(object)item != (Object)(object)HeldScopeItem) && !((Object)(object)FindHeldScopeItem() != (Object)(object)item) && IsGameplayInputAllowed() && current != null && current.rightButton.isPressed)
			{
				_postShotCharacter = Character.localCharacter;
				_postShotItem = item;
				_postShotReleased = false;
			}
		}

		private void ClearPostShotScope()
		{
			_postShotCharacter = null;
			_postShotItem = null;
			_postShotReleased = false;
		}

		private bool CanContinueAfterShot()
		{
			if ((Object)(object)_postShotCharacter == (Object)null)
			{
				return false;
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter != (Object)(object)_postShotCharacter || (Object)(object)localCharacter.data == (Object)null || !localCharacter.data.fullyConscious || !IsGameplayInputAllowed())
			{
				ClearPostShotScope();
				return false;
			}
			Item currentItem = localCharacter.data.currentItem;
			if ((Object)(object)currentItem != (Object)null && (Object)(object)currentItem != (Object)(object)_postShotItem)
			{
				ClearPostShotScope();
				return false;
			}
			Mouse current = Mouse.current;
			if (current == null || !current.rightButton.isPressed || current.rightButton.wasReleasedThisFrame)
			{
				_postShotReleased = true;
			}
			if (_postShotReleased && AimBlend <= 0f)
			{
				ClearPostShotScope();
				return false;
			}
			return true;
		}

		public bool HasValidAimSource()
		{
			if ((Object)(object)HeldScopeItem != (Object)null && (Object)(object)FindHeldScopeItem() == (Object)(object)HeldScopeItem)
			{
				return true;
			}
			return CanContinueAfterShot();
		}

		public void Tick(bool hasBlowgunScopes, bool hasRescueClawScopes)
		{
			Item heldScopeItem = HeldScopeItem;
			HeldScopeItem = FindHeldScopeItem();
			bool flag = CanContinueAfterShot();
			if ((Object)(object)HeldScopeItem != (Object)(object)heldScopeItem && !flag)
			{
				IsRescueClawScope = (Object)(object)HeldScopeItem != (Object)null && (Object)(object)((Component)HeldScopeItem).GetComponent<RescueHook>() != (Object)null;
				ResetBlend();
			}
			bool flag2 = (IsRescueClawScope ? hasRescueClawScopes : hasBlowgunScopes);
			CanAim = flag2 && _cameraAllowsScope && IsGameplayInputAllowed() && ((Object)(object)HeldScopeItem != (Object)null || flag);
			Mouse current = Mouse.current;
			bool flag3 = current != null && current.rightButton.isPressed;
			WantsAim = CanAim && flag3 && ((Object)(object)HeldScopeItem != (Object)null || (flag && !_postShotReleased));
			UpdateAimBlend(Time.unscaledDeltaTime);
			UpdateZoomFov(Time.unscaledDeltaTime);
			if (_postShotReleased && AimBlend <= 0f)
			{
				ClearPostShotScope();
			}
		}

		private void UpdateAimBlend(float deltaTime)
		{
			if (!CanAim)
			{
				ResetBlend();
			}
			else if (!(deltaTime <= 0f))
			{
				float num = (WantsAim ? 1f : 0f);
				float num2 = (WantsAim ? 0.12f : 0.16f);
				AimBlend = Mathf.SmoothDamp(AimBlend, num, ref _aimVelocity, num2, float.PositiveInfinity, deltaTime);
				AimBlend = Mathf.Clamp01(AimBlend);
				if (Mathf.Abs(AimBlend - num) < 0.001f && Mathf.Abs(_aimVelocity) < 0.001f)
				{
					AimBlend = num;
					_aimVelocity = 0f;
				}
			}
		}

		private float GetSelectedZoomFov()
		{
			float value = _settings.ZoomLevelOneFov.Value;
			float value2 = _settings.ZoomLevelTwoFov.Value;
			float value3 = _settings.ZoomLevelThreeFov.Value;
			float num = Mathf.Max(value, Mathf.Max(value2, value3));
			float num2 = Mathf.Min(value, Mathf.Min(value2, value3));
			float num3 = value + value2 + value3 - num - num2;
			return _zoomIndex switch
			{
				0 => num, 
				1 => num3, 
				_ => num2, 
			};
		}

		private void UpdateZoomFov(float deltaTime)
		{
			float selectedZoomFov = GetSelectedZoomFov();
			if (!CanAim || AimBlend <= 0f)
			{
				_smoothedZoomFov = selectedZoomFov;
				_zoomVelocity = 0f;
			}
			else if (!(deltaTime <= 0f))
			{
				_smoothedZoomFov = Mathf.SmoothDamp(_smoothedZoomFov, selectedZoomFov, ref _zoomVelocity, 0.1f, float.PositiveInfinity, deltaTime);
			}
		}

		public void HandleZoomInput(CharacterInput input)
		{
			Mouse current = Mouse.current;
			if (!CanAim || !WantsAim || current == null || !current.rightButton.isPressed || !IsGameplayInputAllowed())
			{
				return;
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.input != (Object)(object)input || !HasValidAimSource())
			{
				return;
			}
			bool flag = input.scrollInput > 0f || input.scrollForwardWasPressed;
			bool flag2 = input.scrollInput < 0f || input.scrollBackwardWasPressed;
			if ((flag || flag2) && _lastZoomInputFrame != Time.frameCount)
			{
				_lastZoomInputFrame = Time.frameCount;
				if (flag != flag2)
				{
					int num = (flag ? 1 : (-1));
					_zoomIndex = Mathf.Clamp(_zoomIndex + num, 0, 2);
				}
			}
			input.scrollInput = 0f;
			input.scrollForwardWasPressed = false;
			input.scrollBackwardWasPressed = false;
			input.scrollForwardIsPressed = false;
			input.scrollBackwardIsPressed = false;
			input.selectSlotForwardWasPressed = false;
			input.selectSlotBackwardWasPressed = false;
		}

		public void ScaleMouseLook(CharacterInput input)
		{
			//IL_006a: 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)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			if (!CanAim || AimBlend <= 0f || !IsGameplayInputAllowed())
			{
				return;
			}
			Character localCharacter = Character.localCharacter;
			if (!((Object)(object)localCharacter == (Object)null) && !((Object)(object)localCharacter.input != (Object)(object)input) && HasValidAimSource())
			{
				InputAction action_look = CharacterInput.action_look;
				object obj;
				if (action_look == null)
				{
					obj = null;
				}
				else
				{
					InputControl activeControl = action_look.activeControl;
					obj = ((activeControl != null) ? activeControl.device : null);
				}
				if (obj is Mouse)
				{
					input.lookInput *= _mouseSensitivityMultiplier;
				}
			}
		}

		public bool ShouldPreservePrimaryCharge(Item item)
		{
			if (!_cameraAllowsScope || !IsGameplayInputAllowed())
			{
				return false;
			}
			if ((Object)(object)item == (Object)null || (Object)(object)FindHeldScopeItem() != (Object)(object)item)
			{
				return false;
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.input == (Object)null || item.UIData == null)
			{
				return false;
			}
			if (!item.isUsingPrimary || item.isUsingSecondary || item.UIData.hasSecondInteract || item.canUseOnFriend)
			{
				return false;
			}
			Mouse current = Mouse.current;
			if (current != null && current.rightButton.wasReleasedThisFrame)
			{
				return localCharacter.input.useSecondaryWasReleased;
			}
			return false;
		}

		public void BeginCameraFrame()
		{
			RestoreCamera();
			_normalFovEvaluatedThisFrame = false;
		}

		public float ApplyScopeFov(Camera? camera, float normalFov)
		{
			_mouseSensitivityMultiplier = 1f;
			_normalFovEvaluatedThisFrame = true;
			if ((Object)(object)camera == (Object)null)
			{
				Reset();
				return normalFov;
			}
			if (!CanAim || AimBlend <= 0f)
			{
				return normalFov;
			}
			if (!HasValidAimSource() || !IsGameplayInputAllowed())
			{
				Reset();
				return normalFov;
			}
			float num = Mathf.Min(_smoothedZoomFov, normalFov);
			float num2 = Mathf.Lerp(normalFov, num, AimBlend);
			float num3 = Mathf.Clamp(normalFov, 1f, 179f) * (MathF.PI / 180f) * 0.5f;
			float num4 = Mathf.Clamp(num2, 1f, 179f) * (MathF.PI / 180f) * 0.5f;
			_mouseSensitivityMultiplier = Mathf.Clamp01(Mathf.Tan(num4) / Mathf.Tan(num3));
			if (!Mathf.Approximately(num2, normalFov))
			{
				_ownedCamera = camera;
				_lastNormalFov = normalFov;
				_lastAppliedFov = num2;
				_ownsFov = true;
			}
			return num2;
		}

		public void EndCameraFrame()
		{
			_cameraAllowsScope = _normalFovEvaluatedThisFrame;
			if (!_cameraAllowsScope)
			{
				Reset();
			}
		}

		private void RestoreCamera()
		{
			if (_ownsFov && (Object)(object)_ownedCamera != (Object)null && Mathf.Approximately(_ownedCamera.fieldOfView, _lastAppliedFov))
			{
				_ownedCamera.fieldOfView = _lastNormalFov;
			}
			_ownsFov = false;
			_ownedCamera = null;
		}

		private void ResetBlend()
		{
			RestoreCamera();
			AimBlend = 0f;
			_aimVelocity = 0f;
			_mouseSensitivityMultiplier = 1f;
		}

		public void Reset()
		{
			ClearPostShotScope();
			HeldScopeItem = null;
			IsRescueClawScope = false;
			CanAim = false;
			WantsAim = false;
			_cameraAllowsScope = false;
			ResetBlend();
		}
	}
	internal sealed class ScopeItemVisibility : IDisposable
	{
		private readonly List<Renderer> _renderers = new List<Renderer>();

		private readonly Dictionary<Renderer, bool> _savedStates = new Dictionary<Renderer, bool>();

		private Item? _hiddenItem;

		public void Tick()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Invalid comparison between Unknown and I4
			ScopeController activeController = Plugin.ActiveController;
			if (activeController == null || !activeController.CanAim || !activeController.WantsAim)
			{
				Reset();
				return;
			}
			Item heldScopeItem = activeController.HeldScopeItem;
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)heldScopeItem == (Object)null || (Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null || !localCharacter.data.fullyConscious || (Object)(object)localCharacter.data.currentItem != (Object)(object)heldScopeItem || (Object)(object)heldScopeItem.holderCharacter != (Object)(object)localCharacter || (int)heldScopeItem.itemState != 1 || !((Component)heldScopeItem).gameObject.activeInHierarchy)
			{
				Reset();
				return;
			}
			if ((Object)(object)_hiddenItem != (Object)(object)heldScopeItem)
			{
				Reset();
				_hiddenItem = heldScopeItem;
			}
			_renderers.Clear();
			((Component)heldScopeItem).GetComponentsInChildren<Renderer>(true, _renderers);
			foreach (Renderer renderer in _renderers)
			{
				if (!((Object)(object)renderer == (Object)null) && (renderer is MeshRenderer || renderer is SkinnedMeshRenderer) && !((Object)(object)((Component)renderer).GetComponentInParent<Item>() != (Object)(object)heldScopeItem))
				{
					if (!_savedStates.ContainsKey(renderer))
					{
						_savedStates.Add(renderer, renderer.forceRenderingOff);
					}
					if (!renderer.forceRenderingOff)
					{
						renderer.forceRenderingOff = true;
					}
				}
			}
		}

		public void Reset()
		{
			foreach (KeyValuePair<Renderer, bool> savedState in _savedStates)
			{
				if ((Object)(object)savedState.Key != (Object)null)
				{
					savedState.Key.forceRenderingOff = savedState.Value;
				}
			}
			_savedStates.Clear();
			_renderers.Clear();
			_hiddenItem = null;
		}

		public void Dispose()
		{
			Reset();
		}
	}
	internal sealed class ScopeOverlay
	{
		private readonly ManualLogSource _logger;

		private readonly Dictionary<int, Texture2D> _textures = new Dictionary<int, Texture2D>();

		private readonly Dictionary<int, Texture2D> _masks = new Dictionary<int, Texture2D>();

		public int LoadedCount => _textures.Count;

		public bool HasBlowgunScopes { get; }

		public bool HasRescueClawScopes { get; }

		public ScopeOverlay(string pluginDirectory, ManualLogSource logger)
		{
			_logger = logger;
			LoadPreset(pluginDirectory, ScopePreset.ScopeOne);
			LoadPreset(pluginDirectory, ScopePreset.ScopeTwo);
			LoadPreset(pluginDirectory, ScopePreset.ScopeThree);
			LoadPreset(pluginDirectory, ScopePreset.ScopeFour);
			LoadPreset(pluginDirectory, ScopePreset.ScopeFive);
			int loadedCount = LoadedCount;
			HasBlowgunScopes = loadedCount > 0;
			LoadPreset(pluginDirectory, ScopePreset.RescueClawScopeOne);
			LoadPreset(pluginDirectory, ScopePreset.RescueClawScopeTwo);
			LoadPreset(pluginDirectory, ScopePreset.RescueClawScopeThree);
			LoadPreset(pluginDirectory, ScopePreset.RescueClawScopeFour);
			LoadPreset(pluginDirectory, ScopePreset.RescueClawScopeFive);
			HasRescueClawScopes = LoadedCount > loadedCount;
			foreach (int key in _textures.Keys)
			{
				ScopePreset scopePreset = ScopePreset.FromId(key);
				_masks.Add(key, CreateMask(scopePreset.MaskRadius));
			}
		}

		private void LoadPreset(string pluginDirectory, ScopePreset preset)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			string text = Path.Combine(pluginDirectory, "Scopes", preset.FileName);
			if (!File.Exists(text))
			{
				text = Path.Combine(pluginDirectory, preset.FileName);
			}
			Texture2D val = null;
			try
			{
				byte[] array = File.ReadAllBytes(text);
				val = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!ImageConversion.LoadImage(val, array, true))
				{
					throw new InvalidDataException("Unity could not decode the image.");
				}
				((Texture)val).wrapMode = (TextureWrapMode)1;
				((Texture)val).filterMode = (FilterMode)1;
				_textures.Add(preset.Id, val);
			}
			catch (Exception ex)
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
				_logger.LogError((object)("Failed to load scope image '" + text + "': " + ex.Message));
				return;
			}
			_logger.LogInfo((object)("Loaded scope image: " + preset.DisplayName));
		}

		private static Texture2D CreateMask(float radius)
		{
			//IL_00c6: 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_00d2: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Expected O, but got Unknown
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			Color32[] array = (Color32[])(object)new Color32[262144];
			for (int i = 0; i < 512; i++)
			{
				for (int j = 0; j < 512; j++)
				{
					float num = ((float)j + 0.5f) / 512f - 0.5f;
					float num2 = ((float)i + 0.5f) / 512f - 0.5f;
					float num3 = Mathf.Sqrt(num * num + num2 * num2);
					float num4 = Mathf.InverseLerp(radius, radius + 0.004f, num3);
					num4 = Mathf.SmoothStep(0f, 1f, num4);
					byte b = (byte)Mathf.RoundToInt(num4 * 255f);
					array[i * 512 + j] = new Color32((byte)0, (byte)0, (byte)0, b);
				}
			}
			Texture2D val = new Texture2D(512, 512, (TextureFormat)4, false)
			{
				wrapMode = (TextureWrapMode)1,
				filterMode = (FilterMode)1
			};
			val.SetPixels32(array);
			val.Apply(false, true);
			return val;
		}

		private ScopePreset? FindAvailablePreset(int presetId)
		{
			if (_textures.ContainsKey(presetId))
			{
				return ScopePreset.FromId(presetId);
			}
			bool num = presetId >= ScopePreset.RescueClawScopeOne.Id;
			int num2 = (num ? ScopePreset.RescueClawScopeOne.Id : ScopePreset.ScopeOne.Id);
			int num3 = (num ? ScopePreset.RescueClawScopeFive.Id : ScopePreset.ScopeFive.Id);
			for (int i = num2; i <= num3; i++)
			{
				if (_textures.ContainsKey(i))
				{
					return ScopePreset.FromId(i);
				}
			}
			return null;
		}

		public void Draw(int presetId, float aimBlend)
		{
			//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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: 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_0092: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			if (aimBlend <= 0f || Event.current == null || (int)Event.current.type != 7)
			{
				return;
			}
			ScopePreset scopePreset = FindAvailablePreset(presetId);
			if (scopePreset == null)
			{
				return;
			}
			Texture2D val = _textures[scopePreset.Id];
			float num = (float)Mathf.Min(Screen.width, Screen.height) * 0.95f;
			if (num <= 0f)
			{
				return;
			}
			float num2 = ((float)Screen.width - num) * 0.5f;
			float num3 = ((float)Screen.height - num) * 0.5f;
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(num2, num3, num, num);
			Color color = GUI.color;
			Matrix4x4 matrix = GUI.matrix;
			try
			{
				GUI.matrix = Matrix4x4.identity;
				float opacity = Mathf.Clamp01(aimBlend);
				DrawMask(val2, _masks[scopePreset.Id], opacity);
				GUI.DrawTexture(val2, (Texture)(object)val, (ScaleMode)0, true);
			}
			finally
			{
				GUI.color = color;
				GUI.matrix = matrix;
			}
		}

		private static void DrawMask(Rect scopeRect, Texture2D mask, float opacity)
		{
			//IL_0010: 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_0060: 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_00bb: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			GUI.color = new Color(0f, 0f, 0f, opacity);
			GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, ((Rect)(ref scopeRect)).yMin), (Texture)(object)Texture2D.whiteTexture);
			GUI.DrawTexture(new Rect(0f, ((Rect)(ref scopeRect)).yMax, (float)Screen.width, (float)Screen.height - ((Rect)(ref scopeRect)).yMax), (Texture)(object)Texture2D.whiteTexture);
			GUI.DrawTexture(new Rect(0f, ((Rect)(ref scopeRect)).yMin, ((Rect)(ref scopeRect)).xMin, ((Rect)(ref scopeRect)).height), (Texture)(object)Texture2D.whiteTexture);
			GUI.DrawTexture(new Rect(((Rect)(ref scopeRect)).xMax, ((Rect)(ref scopeRect)).yMin, (float)Screen.width - ((Rect)(ref scopeRect)).xMax, ((Rect)(ref scopeRect)).height), (Texture)(object)Texture2D.whiteTexture);
			GUI.color = new Color(1f, 1f, 1f, opacity);
			GUI.DrawTexture(scopeRect, (Texture)(object)mask, (ScaleMode)0, true);
		}

		public void DestroyTextures()
		{
			foreach (Texture2D value in _textures.Values)
			{
				Object.Destroy((Object)(object)value);
			}
			foreach (Texture2D value2 in _masks.Values)
			{
				Object.Destroy((Object)(object)value2);
			}
			_textures.Clear();
			_masks.Clear();
		}
	}
	[HarmonyPatch(typeof(MainCameraMovement))]
	internal static class ScopePatches
	{
		private static ScopeController? GetControllerFor(MainCameraMovement movement)
		{
			if ((Object)(object)movement == (Object)null || (Object)(object)MainCamera.instance == (Object)null || (Object)(object)((Component)movement).GetComponent<MainCamera>() != (Object)(object)MainCamera.instance)
			{
				return null;
			}
			return Plugin.ActiveController;
		}

		[HarmonyPatch("LateUpdate")]
		[HarmonyPrefix]
		private static void BeforeCameraUpdate(MainCameraMovement __instance)
		{
			GetControllerFor(__instance)?.BeginCameraFrame();
		}

		[HarmonyPatch("GetFov")]
		[HarmonyPostfix]
		private static void AfterGetFov(MainCameraMovement __instance, ref float __result)
		{
			ScopeController controllerFor = GetControllerFor(__instance);
			if (controllerFor != null)
			{
				Camera component = ((Component)__instance).GetComponent<Camera>();
				__result = controllerFor.ApplyScopeFov(component, __result);
			}
		}

		[HarmonyPatch("LateUpdate")]
		[HarmonyPostfix]
		private static void AfterCameraUpdate(MainCameraMovement __instance)
		{
			GetControllerFor(__instance)?.EndCameraFrame();
		}
	}
	[HarmonyPatch(typeof(Item), "CancelUseSecondary")]
	internal static class ScopedItemInputPatch
	{
		[HarmonyPrefix]
		private static bool BeforeCancelUseSecondary(Item __instance)
		{
			ScopeController activeController = Plugin.ActiveController;
			if (activeController == null)
			{
				return true;
			}
			return !activeController.ShouldPreservePrimaryCharge(__instance);
		}
	}
	[HarmonyPatch(typeof(CharacterInput), "Sample")]
	internal static class ScopeInputPatch
	{
		[HarmonyPostfix]
		private static void AfterSample(CharacterInput __instance, bool playerMovementActive)
		{
			if (playerMovementActive)
			{
				ScopeController? activeController = Plugin.ActiveController;
				activeController?.HandleZoomInput(__instance);
				activeController?.ScaleMouseLook(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Action_RaycastDart), "RunAction")]
	internal static class BlowgunShotPatch
	{
		[HarmonyPostfix]
		private static void AfterRunAction(Action_RaycastDart __instance)
		{
			ScopeController activeController = Plugin.ActiveController;
			if (activeController != null && !((Object)(object)__instance == (Object)null))
			{
				Item componentInParent = ((Component)__instance).GetComponentInParent<Item>();
				activeController.RememberScopedShot(componentInParent);
			}
		}
	}
	[HarmonyPatch(typeof(Item), "Consume")]
	internal static class ScopedItemConsumePatch
	{
		[HarmonyPrefix]
		private static void BeforeConsume(Item __instance)
		{
			ScopeController activeController = Plugin.ActiveController;
			if (activeController != null && !((Object)(object)activeController.HeldScopeItem != (Object)(object)__instance) && (ScopeController.IsArrowBlowgun(__instance) || !((Object)(object)((Component)__instance).GetComponent<RescueHook>() == (Object)null)))
			{
				activeController.RememberScopedShot(__instance);
			}
		}
	}
	internal sealed class ScopePlayerFade : IDisposable
	{
		private sealed class MaterialSlot
		{
			private readonly Renderer _renderer;

			private readonly int _index;

			private readonly MaterialPropertyBlock _original = new MaterialPropertyBlock();

			private readonly MaterialPropertyBlock _working = new MaterialPropertyBlock();

			private readonly List<Material> _currentMaterials = new List<Material>();

			private bool _applied;

			public MaterialSlot(Renderer renderer, int index)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Expected O, but got Unknown
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Expected O, but got Unknown
				_renderer = renderer;
				_index = index;
			}

			public void Apply(Material material, float visibility)
			{
				_renderer.GetPropertyBlock(_original, _index);
				if (_original.isEmpty)
				{
					_renderer.GetPropertyBlock(_working);
				}
				else
				{
					_renderer.GetPropertyBlock(_working, _index);
				}
				float num = (_working.HasFloat(OpacityId) ? _working.GetFloat(OpacityId) : material.GetFloat(OpacityId));
				_working.SetFloat(OpacityId, num * visibility);
				_renderer.SetPropertyBlock(_working, _index);
				_applied = true;
			}

			public void Restore()
			{
				if (!_applied)
				{
					return;
				}
				_applied = false;
				if ((Object)(object)_renderer == (Object)null)
				{
					return;
				}
				_currentMaterials.Clear();
				_renderer.GetSharedMaterials(_currentMaterials);
				if (_index < _currentMaterials.Count)
				{
					if (_original.isEmpty)
					{
						_renderer.SetPropertyBlock((MaterialPropertyBlock)null, _index);
					}
					else
					{
						_renderer.SetPropertyBlock(_original, _index);
					}
				}
			}
		}

		private static readonly int OpacityId = Shader.PropertyToID("_Opacity");

		private readonly ManualLogSource _logger;

		private readonly Dictionary<(Renderer, int), MaterialSlot> _slots = new Dictionary<(Renderer, int), MaterialSlot>();

		private readonly List<Material> _materials = new List<Material>();

		private readonly HashSet<Renderer> _visited = new HashSet<Renderer>();

		private readonly HashSet<string> _warnedShaders = new HashSet<string>();

		private Character? _character;

		private Camera? _renderingCamera;

		public ScopePlayerFade(ManualLogSource logger)
		{
			_logger = logger;
			RenderPipelineManager.beginCameraRendering += BeforeCamera;
			RenderPipelineManager.endCameraRendering += AfterCamera;
		}

		private void BeforeCamera(ScriptableRenderContext context, Camera camera)
		{
			MainCamera instance = MainCamera.instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)camera != (Object)(object)((Component)instance).GetComponent<Camera>())
			{
				return;
			}
			RestoreApplied();
			ScopeController activeController = Plugin.ActiveController;
			Character localCharacter = Character.localCharacter;
			if (activeController == null || !activeController.CanAim || activeController.AimBlend <= 0f || (Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null || !localCharacter.data.fullyConscious)
			{
				Reset();
				return;
			}
			if (!activeController.HasValidAimSource())
			{
				Reset();
				return;
			}
			if ((Object)(object)localCharacter != (Object)(object)_character)
			{
				Reset();
				_character = localCharacter;
			}
			if (localCharacter.refs == null || (Object)(object)localCharacter.refs.customization == (Object)null)
			{
				return;
			}
			CustomizationRefs refs = localCharacter.refs.customization.refs;
			if ((Object)(object)refs == (Object)null)
			{
				return;
			}
			float visibility = 1f - Mathf.Clamp01(activeController.AimBlend);
			_visited.Clear();
			_renderingCamera = camera;
			ApplyRenderer((Renderer?)(object)refs.mainRenderer, visibility);
			if (refs.AllRenderers != null)
			{
				Renderer[] allRenderers = refs.AllRenderers;
				foreach (Renderer renderer in allRenderers)
				{
					ApplyRenderer(renderer, visibility);
				}
			}
			if (refs.playerHats != null)
			{
				Renderer[] allRenderers = refs.playerHats;
				foreach (Renderer renderer2 in allRenderers)
				{
					ApplyRenderer(renderer2, visibility);
				}
			}
			ApplyRenderer(refs.skeletonRenderer, visibility);
			ApplyRenderer(refs.chickenRenderer, visibility);
		}

		private void ApplyRenderer(Renderer? renderer, float visibility)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			if ((Object)(object)renderer == (Object)null || !renderer.enabled || !((Component)renderer).gameObject.activeInHierarchy || (int)renderer.shadowCastingMode == 3 || !_visited.Add(renderer) || (Object)(object)((Component)renderer).GetComponentInParent<Character>() != (Object)(object)_character)
			{
				return;
			}
			_materials.Clear();
			renderer.GetSharedMaterials(_materials);
			for (int i = 0; i < _materials.Count; i++)
			{
				Material val = _materials[i];
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				if (!val.HasProperty(OpacityId))
				{
					string text = (((Object)(object)val.shader != (Object)null) ? ((Object)val.shader).name : "(missing shader)");
					if (_warnedShaders.Add(text))
					{
						_logger.LogWarning((object)("Player fade: shader '" + text + "' has no _Opacity property. Its materials were left unchanged."));
					}
					continue;
				}
				(Renderer, int) key = (renderer, i);
				if (!_slots.TryGetValue(key, out MaterialSlot value) || value == null)
				{
					value = new MaterialSlot(renderer, i);
					_slots[key] = value;
				}
				value.Apply(val, visibility);
			}
		}

		private void AfterCamera(ScriptableRenderContext context, Camera camera)
		{
			if ((Object)(object)camera == (Object)(object)_renderingCamera)
			{
				RestoreApplied();
			}
		}

		private void RestoreApplied()
		{
			foreach (MaterialSlot value in _slots.Values)
			{
				value.Restore();
			}
			_renderingCamera = null;
		}

		public void Reset()
		{
			RestoreApplied();
			_slots.Clear();
			_materials.Clear();
			_visited.Clear();
			_character = null;
		}

		public void Dispose()
		{
			RenderPipelineManager.beginCameraRendering -= BeforeCamera;
			RenderPipelineManager.endCameraRendering -= AfterCamera;
			Reset();
			_warnedShaders.Clear();
		}
	}
	internal sealed class ScopePreset
	{
		public int Id { get; }

		public string DisplayName { get; }

		public string FileName { get; }

		public float MaskRadius { get; }

		public static ScopePreset ScopeOne { get; } = new ScopePreset(1, "ScopeOne", "scope-1.png", 0.44f);

		public static ScopePreset ScopeTwo { get; } = new ScopePreset(2, "ScopeTwo", "scope-2.png", 0.44f);

		public static ScopePreset ScopeThree { get; } = new ScopePreset(3, "ScopeThree", "scope-3.png", 0.44f);

		public static ScopePreset ScopeFour { get; } = new ScopePreset(4, "ScopeFour", "scope-4.png", 0.44f);

		public static ScopePreset ScopeFive { get; } = new ScopePreset(5, "ScopeFive", "scope-5.png", 0.44f);

		public static ScopePreset RescueClawScopeOne { get; } = new ScopePreset(6, "RescueClawScopeOne", "scope-rescueclaw-1.png", 0.44f);

		public static ScopePreset RescueClawScopeTwo { get; } = new ScopePreset(7, "RescueClawScopeTwo", "scope-rescueclaw-2.png", 0.44f);

		public static ScopePreset RescueClawScopeThree { get; } = new ScopePreset(8, "RescueClawScopeThree", "scope-rescueclaw-3.png", 0.44f);

		public static ScopePreset RescueClawScopeFour { get; } = new ScopePreset(9, "RescueClawScopeFour", "scope-rescueclaw-4.png", 0.44f);

		public static ScopePreset RescueClawScopeFive { get; } = new ScopePreset(10, "RescueClawScopeFive", "scope-rescueclaw-5.png", 0.44f);

		private ScopePreset(int id, string displayName, string fileName, float maskRadius)
		{
			Id = id;
			DisplayName = displayName;
			FileName = fileName;
			MaskRadius = maskRadius;
		}

		public static ScopePreset FromId(int id)
		{
			return id switch
			{
				1 => ScopeOne, 
				2 => ScopeTwo, 
				3 => ScopeThree, 
				4 => ScopeFour, 
				5 => ScopeFive, 
				6 => RescueClawScopeOne, 
				7 => RescueClawScopeTwo, 
				8 => RescueClawScopeThree, 
				9 => RescueClawScopeFour, 
				10 => RescueClawScopeFive, 
				_ => ScopeOne, 
			};
		}
	}
	internal sealed class ScopeReticleFade : IDisposable
	{
		private GUIManager? _gui;

		private readonly List<CanvasGroup> _groups = new List<CanvasGroup>();

		private readonly HashSet<GameObject> _roots = new HashSet<GameObject>();

		public ScopeReticleFade()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			Canvas.willRenderCanvases += new WillRenderCanvases(BeforeCanvasRender);
		}

		private void AddReticle(GameObject? root)
		{
			if (!((Object)(object)root == (Object)null) && _roots.Add(root))
			{
				CanvasGroup val = root.AddComponent<CanvasGroup>();
				val.alpha = 1f;
				val.ignoreParentGroups = false;
				val.interactable = true;
				val.blocksRaycasts = true;
				_groups.Add(val);
			}
		}

		private void BeforeCanvasRender()
		{
			ScopeController activeController = Plugin.ActiveController;
			if (activeController == null || !activeController.CanAim || activeController.IsRescueClawScope || activeController.AimBlend <= 0f)
			{
				Reset();
				return;
			}
			GUIManager instance = GUIManager.instance;
			if ((Object)(object)instance == (Object)null)
			{
				Reset();
				return;
			}
			if ((Object)(object)instance != (Object)(object)_gui)
			{
				ClearGroups();
				_gui = instance;
				AddReticle(instance.reticleDefault);
				AddReticle(instance.reticleX);
				AddReticle(instance.reticleClimb);
				AddReticle(instance.reticleClimbJump);
				AddReticle(instance.reticleThrow);
				AddReticle(instance.reticleReach);
				AddReticle(instance.reticleGrasp);
				AddReticle(instance.reticleSpike);
				AddReticle(instance.reticleRope);
				AddReticle(instance.reticleClimbTry);
				AddReticle(instance.reticleVine);
				AddReticle(instance.reticleBoost);
				AddReticle(instance.reticleShoot);
				AddReticle(instance.reticleKick);
				AddReticle(instance.reticleLadder);
			}
			float alpha = 1f - Mathf.Clamp01(activeController.AimBlend);
			foreach (CanvasGroup group in _groups)
			{
				if ((Object)(object)group != (Object)null)
				{
					group.alpha = alpha;
				}
			}
		}

		public void Reset()
		{
			foreach (CanvasGroup group in _groups)
			{
				if ((Object)(object)group != (Object)null)
				{
					group.alpha = 1f;
				}
			}
		}

		private void ClearGroups()
		{
			Reset();
			foreach (CanvasGroup group in _groups)
			{
				if ((Object)(object)group != (Object)null)
				{
					Object.Destroy((Object)(object)group);
				}
			}
			_groups.Clear();
			_roots.Clear();
			_gui = null;
		}

		public void Dispose()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			Canvas.willRenderCanvases -= new WillRenderCanvases(BeforeCanvasRender);
			ClearGroups();
		}
	}
}