Decompiled source of ScoutCannonHelper v0.1.6

plugins/ScoutCannonHelper.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.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 ScoutCannonHelper
{
	internal sealed class AimScope : MonoBehaviour
	{
		private GameObject _camObj;

		private Camera _cam;

		private RenderTexture _rt;

		private int _rtWidth;

		private int _rtHeight;

		private bool _visible;

		private static Type _urpCameraDataType;

		private static bool _urpTypeResolved;

		private void Update()
		{
			try
			{
				Tick();
			}
			catch (Exception arg)
			{
				ManualLogSource loggerRef = Plugin.LoggerRef;
				if (loggerRef != null)
				{
					loggerRef.LogError((object)$"[童子军大炮] 瞄准小窗异常:{arg}");
				}
			}
		}

		private void Tick()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			if (ModConfig.ScopeEnabled == null || !ModConfig.ScopeEnabled.Value || !CannonViewState.Aiming)
			{
				SetVisible(visible: false);
				return;
			}
			if (!CannonUtil.TryGetHeldMuzzle(out var muzzle, out var direction))
			{
				SetVisible(visible: false);
				return;
			}
			EnsureCamera();
			UpdateCamera(muzzle, direction);
			SetVisible(visible: true);
		}

		private void EnsureCamera()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Expected O, but got Unknown
			if ((Object)(object)_camObj == (Object)null)
			{
				_camObj = new GameObject("ScoutCannonHelper_AimScopeCamera");
				_camObj.transform.SetParent(((Component)this).transform, false);
				((Object)_camObj).hideFlags = (HideFlags)61;
				_cam = _camObj.AddComponent<Camera>();
				((Behaviour)_cam).enabled = false;
				_cam.depth = -50f;
				_cam.clearFlags = (CameraClearFlags)1;
				_cam.nearClipPlane = 0.03f;
				_cam.farClipPlane = 1500f;
				_cam.allowHDR = false;
				_cam.allowMSAA = false;
				_cam.stereoTargetEye = (StereoTargetEyeMask)0;
				int num = LayerMask.NameToLayer("UI");
				_cam.cullingMask = ((num >= 0) ? (~(1 << num)) : (-1));
				EnsureUrpCameraData();
			}
			int num2 = Mathf.Clamp(Mathf.RoundToInt(ModConfig.ScopeWidth.Value), 96, 1280);
			int num3 = Mathf.Clamp(Mathf.RoundToInt((float)num2 * 9f / 16f), 54, 720);
			if ((Object)(object)_rt == (Object)null || _rtWidth != num2 || _rtHeight != num3)
			{
				if ((Object)(object)_rt != (Object)null)
				{
					_cam.targetTexture = null;
					_rt.Release();
					Object.Destroy((Object)(object)_rt);
				}
				_rt = new RenderTexture(num2, num3, 24, (RenderTextureFormat)7);
				((Object)_rt).hideFlags = (HideFlags)61;
				_rt.Create();
				_cam.targetTexture = _rt;
				_rtWidth = num2;
				_rtHeight = num3;
			}
			_cam.fieldOfView = Mathf.Clamp(ModConfig.ScopeFov.Value, 20f, 110f);
		}

		private void EnsureUrpCameraData()
		{
			Type urpCameraDataType = GetUrpCameraDataType();
			if (urpCameraDataType == null)
			{
				return;
			}
			try
			{
				if ((Object)(object)_camObj.GetComponent(urpCameraDataType) == (Object)null)
				{
					_camObj.AddComponent(urpCameraDataType);
				}
			}
			catch
			{
			}
		}

		private static Type GetUrpCameraDataType()
		{
			if (_urpTypeResolved)
			{
				return _urpCameraDataType;
			}
			_urpTypeResolved = true;
			try
			{
				_urpCameraDataType = Type.GetType("UnityEngine.Rendering.Universal.UniversalAdditionalCameraData, Unity.RenderPipelines.Universal.Runtime");
				if (_urpCameraDataType == null)
				{
					Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
					for (int i = 0; i < assemblies.Length; i++)
					{
						Type type = assemblies[i].GetType("UnityEngine.Rendering.Universal.UniversalAdditionalCameraData", throwOnError: false);
						if (type != null)
						{
							_urpCameraDataType = type;
							break;
						}
					}
				}
			}
			catch
			{
				_urpCameraDataType = null;
			}
			return _urpCameraDataType;
		}

		private void UpdateCamera(Transform muzzle, Vector3 direction)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (((Vector3)(ref direction)).sqrMagnitude < 1E-06f)
			{
				direction = muzzle.forward;
			}
			direction = ((Vector3)(ref direction)).normalized;
			float num = Mathf.Max(0f, ModConfig.ScopeForwardOffset.Value);
			_camObj.transform.position = muzzle.position + direction * num;
			_camObj.transform.rotation = Quaternion.LookRotation(direction, Vector3.up);
		}

		private void SetVisible(bool visible)
		{
			_visible = visible;
			if ((Object)(object)_cam != (Object)null)
			{
				((Behaviour)_cam).enabled = visible;
			}
		}

		private void OnDestroy()
		{
			try
			{
				if ((Object)(object)_cam != (Object)null)
				{
					_cam.targetTexture = null;
				}
				if ((Object)(object)_rt != (Object)null)
				{
					_rt.Release();
					Object.Destroy((Object)(object)_rt);
				}
			}
			catch
			{
			}
		}

		private void OnGUI()
		{
			if (!_visible || (Object)(object)_rt == (Object)null)
			{
				return;
			}
			try
			{
				DrawScope();
			}
			catch
			{
			}
		}

		private void DrawScope()
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp(ModConfig.ScopeWidth.Value, 96f, Mathf.Max(96f, (float)Screen.width - 16f));
			float num2 = num * 9f / 16f;
			float num3 = Mathf.Clamp(ModConfig.ScopeMargin.Value, 0f, 200f);
			int num4 = Mathf.Clamp(ModConfig.ScopeCorner.Value, 0, 3);
			bool num5 = num4 == 2 || num4 == 3;
			bool flag = num4 == 1 || num4 == 3;
			float num6 = (num5 ? num3 : ((float)Screen.width - num3 - num));
			float num7 = (flag ? num3 : ((float)Screen.height - num3 - num2));
			Rect val = default(Rect);
			((Rect)(ref val))..ctor(num6, num7, num, num2);
			Color color = GUI.color;
			GUI.color = new Color(0f, 0f, 0f, 0.85f);
			GUI.DrawTexture(new Rect(((Rect)(ref val)).x - 2f, ((Rect)(ref val)).y - 2f, ((Rect)(ref val)).width + 4f, ((Rect)(ref val)).height + 4f), (Texture)(object)Texture2D.whiteTexture);
			GUI.color = color;
			GUI.DrawTexture(val, (Texture)(object)_rt, (ScaleMode)0, false);
			if (ModConfig.ScopeCrosshair.Value)
			{
				float num8 = ((Rect)(ref val)).x + ((Rect)(ref val)).width * 0.5f;
				float num9 = ((Rect)(ref val)).y + ((Rect)(ref val)).height * 0.5f;
				GUI.color = new Color(1f, 1f, 1f, 0.8f);
				GUI.DrawTexture(new Rect(num8 - 9f, num9 - 1f, 18f, 2f), (Texture)(object)Texture2D.whiteTexture);
				GUI.DrawTexture(new Rect(num8 - 1f, num9 - 9f, 2f, 18f), (Texture)(object)Texture2D.whiteTexture);
				GUI.color = color;
			}
		}
	}
	internal static class CannonViewState
	{
		public static bool Aiming;
	}
	internal sealed class CannonController : MonoBehaviour
	{
		private float _enterHold;

		private bool _enterConsumed;

		private float _igniteHold;

		private float _igniteBlockUntil;

		private Texture2D _crosshairTex;

		private string _colorCachedKey;

		private Color _colorCachedValue = new Color(0.22f, 1f, 0.42f, 1f);

		private const float IgniteCooldown = 1f;

		private const int CrosshairTexSize = 64;

		private static MethodInfo _warp2;

		private static MethodInfo _warp3;

		private static bool _warpResolved;

		private static void ResolveWarpMethod()
		{
			if (_warpResolved)
			{
				return;
			}
			_warpResolved = true;
			Type typeFromHandle = typeof(Character);
			_warp2 = typeFromHandle.GetMethod("WarpPlayerRPC", BindingFlags.Instance | BindingFlags.Public, null, new Type[2]
			{
				typeof(Vector3),
				typeof(bool)
			}, null);
			_warp3 = typeFromHandle.GetMethod("WarpPlayerRPC", BindingFlags.Instance | BindingFlags.Public, null, new Type[3]
			{
				typeof(Vector3),
				typeof(bool),
				typeof(PhotonMessageInfo)
			}, null);
			if (_warp2 == null && _warp3 == null)
			{
				ManualLogSource loggerRef = Plugin.LoggerRef;
				if (loggerRef != null)
				{
					loggerRef.LogWarning((object)"[童子军大炮] 未找到 Character.WarpPlayerRPC,进入大炮功能不可用。");
				}
			}
		}

		private static void InvokeWarp(Character target, Vector3 position, bool poof)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			ResolveWarpMethod();
			try
			{
				if (_warp2 != null)
				{
					_warp2.Invoke(target, new object[2] { position, poof });
				}
				else if (_warp3 != null)
				{
					_warp3.Invoke(target, new object[3]
					{
						position,
						poof,
						(object)default(PhotonMessageInfo)
					});
				}
			}
			catch (TargetInvocationException ex)
			{
				ManualLogSource loggerRef = Plugin.LoggerRef;
				if (loggerRef != null)
				{
					loggerRef.LogError((object)$"[童子军大炮] WarpPlayerRPC 调用异常:{ex.InnerException ?? ex}");
				}
			}
			catch (Exception arg)
			{
				ManualLogSource loggerRef2 = Plugin.LoggerRef;
				if (loggerRef2 != null)
				{
					loggerRef2.LogError((object)$"[童子军大炮] WarpPlayerRPC 反射异常:{arg}");
				}
			}
		}

		private void Update()
		{
			try
			{
				Tick();
			}
			catch (Exception arg)
			{
				ManualLogSource loggerRef = Plugin.LoggerRef;
				if (loggerRef != null)
				{
					loggerRef.LogError((object)$"[童子军大炮] Update 异常:{arg}");
				}
			}
		}

		private void Tick()
		{
			Character localCharacter = Character.localCharacter;
			bool alive = (Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null && !localCharacter.data.dead;
			TickViewToggle();
			TickEnter(localCharacter, alive);
			TickIgnite(localCharacter, alive);
		}

		private void TickViewToggle()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			bool flag = false;
			if (ModConfig.ViewEnabled.Value)
			{
				flag = CannonUtil.TryGetHeldScroll(out var _, out var _);
			}
			if (!flag)
			{
				CannonViewState.Aiming = false;
			}
			else if (KeyPressedThisFrame(ModConfig.ViewKey.Value))
			{
				CannonViewState.Aiming = !CannonViewState.Aiming;
				ModConfig.Log(CannonViewState.Aiming ? "已进入炮口视角。" : "已恢复自由视角。");
			}
		}

		private void TickEnter(Character local, bool alive)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			if (!ModConfig.EnterEnabled.Value)
			{
				_enterHold = 0f;
				_enterConsumed = false;
				return;
			}
			if (!KeyHeld(ModConfig.EnterKey.Value))
			{
				_enterHold = 0f;
				_enterConsumed = false;
				return;
			}
			_enterHold += Time.deltaTime;
			if (!_enterConsumed && !(_enterHold < ModConfig.EnterHold.Value) && alive && !((Object)(object)local == (Object)null) && CannonUtil.TryGetAimedCannon(CannonUtil.GetCamera(), ModConfig.EnterRange.Value, out var cannon))
			{
				Transform entry = CannonUtil.GetEntry(cannon);
				if (!((Object)(object)entry == (Object)null))
				{
					InvokeWarp(local, entry.position, poof: false);
					_enterConsumed = true;
					_enterHold = 0f;
					ModConfig.Log("已进入大炮内。");
				}
			}
		}

		private void TickIgnite(Character local, bool alive)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (!ModConfig.IgniteEnabled.Value || !alive || Time.time < _igniteBlockUntil)
			{
				_igniteHold = 0f;
				return;
			}
			if (!KeyHeld(ModConfig.IgniteKey.Value))
			{
				_igniteHold = 0f;
				return;
			}
			if (!CannonUtil.TryGetNearbyUnlitCannon(local, ModConfig.IgniteRadius.Value, out var cannon, out var _))
			{
				_igniteHold = 0f;
				return;
			}
			_igniteHold += Time.deltaTime;
			if (!(_igniteHold < ModConfig.IgniteHold.Value))
			{
				_igniteHold = 0f;
				_igniteBlockUntil = Time.time + 1f;
				if (!cannon.lit)
				{
					cannon.Light();
					ModConfig.Log("炮内点火成功。");
				}
			}
		}

		private void OnGUI()
		{
			try
			{
				DrawCrosshair();
			}
			catch
			{
			}
		}

		private void DrawCrosshair()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: 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_0243: 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_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: 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_021a: Unknown result type (might be due to invalid IL or missing references)
			if (!ModConfig.ViewEnabled.Value || !ModConfig.ViewCrosshair.Value || !CannonViewState.Aiming || !CannonUtil.TryGetHeldMuzzle(out var muzzle, out var direction))
			{
				return;
			}
			Camera camera = CannonUtil.GetCamera();
			if ((Object)(object)camera == (Object)null)
			{
				return;
			}
			float value = ModConfig.CrosshairRange.Value;
			Vector3 val = muzzle.position + direction * value;
			Vector3 val2 = camera.WorldToScreenPoint(val);
			float num = (float)Screen.width * 0.5f;
			float num2 = (float)Screen.height * 0.5f;
			float x = val2.x;
			float num3 = (float)Screen.height - val2.y;
			EnsureCrosshairTexture();
			float num4 = ModConfig.CrosshairSize.Value * Mathf.Max(1f, (float)Screen.height / 1080f);
			float num5 = num4 + 6f;
			bool num6 = val2.z > 0f && x >= num5 && x <= (float)Screen.width - num5 && num3 >= num5 && num3 <= (float)Screen.height - num5;
			float num7 = 1f;
			float num15;
			float num16;
			if (!num6)
			{
				if (!ModConfig.ViewEdgeIndicator.Value)
				{
					return;
				}
				float num8 = ((val2.z > 0f) ? (x - num) : (num - x));
				float num9 = ((val2.z > 0f) ? (num3 - num2) : (num2 - num3));
				Vector2 val3 = default(Vector2);
				((Vector2)(ref val3))..ctor(num8, num9);
				if (((Vector2)(ref val3)).sqrMagnitude < 0.0001f)
				{
					((Vector2)(ref val3))..ctor(0f, -1f);
				}
				((Vector2)(ref val3)).Normalize();
				float num10 = Mathf.Max(1f, num - num5);
				float num11 = Mathf.Max(1f, num2 - num5);
				float num12 = ((Mathf.Abs(val3.x) > 0.0001f) ? (num10 / Mathf.Abs(val3.x)) : float.MaxValue);
				float num13 = ((Mathf.Abs(val3.y) > 0.0001f) ? (num11 / Mathf.Abs(val3.y)) : float.MaxValue);
				float num14 = Mathf.Min(num12, num13);
				num15 = num + val3.x * num14;
				num16 = num2 + val3.y * num14;
				num7 = 0.55f;
			}
			else
			{
				num15 = x;
				num16 = num3;
			}
			Color color = GUI.color;
			Color crosshairColor = GetCrosshairColor();
			crosshairColor.a *= num7;
			GUI.color = crosshairColor;
			GUI.DrawTexture(new Rect(num15 - num4, num16 - num4, num4 * 2f, num4 * 2f), (Texture)(object)_crosshairTex, (ScaleMode)0, true);
			GUI.color = color;
		}

		private Color GetCrosshairColor()
		{
			//IL_001a: 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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			string value = ModConfig.CrosshairColor.Value;
			if (value == _colorCachedKey)
			{
				return _colorCachedValue;
			}
			_colorCachedKey = value;
			Color colorCachedValue = default(Color);
			if (!string.IsNullOrEmpty(value) && ColorUtility.TryParseHtmlString(value, ref colorCachedValue))
			{
				_colorCachedValue = colorCachedValue;
			}
			return _colorCachedValue;
		}

		private void EnsureCrosshairTexture()
		{
			//IL_002e: 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_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_crosshairTex != (Object)null)
			{
				return;
			}
			int num = 64;
			Color32[] array = (Color32[])(object)new Color32[num * num];
			Color32 val = default(Color32);
			((Color32)(ref val))..ctor((byte)0, (byte)0, (byte)0, (byte)0);
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = val;
			}
			float num2 = (float)(num - 1) * 0.5f;
			float num3 = num2 - 2f;
			float num4 = num3 - 3f;
			for (int j = 0; j < num; j++)
			{
				for (int k = 0; k < num; k++)
				{
					float num5 = (float)k - num2;
					float num6 = (float)j - num2;
					float num7 = Mathf.Sqrt(num5 * num5 + num6 * num6);
					bool num8 = num7 >= num4 && num7 <= num3;
					bool flag = num7 <= 1.6f;
					bool flag2 = false;
					if (!num8 && !flag)
					{
						bool num9 = Mathf.Abs(num5) <= 1f && Mathf.Abs(num6) >= num3 + 1f && Mathf.Abs(num6) <= num3 + 6f;
						bool flag3 = Mathf.Abs(num6) <= 1f && Mathf.Abs(num5) >= num3 + 1f && Mathf.Abs(num5) <= num3 + 6f;
						flag2 = num9 || flag3;
					}
					if (num8 || flag || flag2)
					{
						array[j * num + k] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue);
					}
				}
			}
			_crosshairTex = new Texture2D(num, num, (TextureFormat)4, false);
			_crosshairTex.SetPixels32(array);
			_crosshairTex.Apply();
			((Object)_crosshairTex).hideFlags = (HideFlags)61;
		}

		private static bool KeyHeld(KeyCode key)
		{
			//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)
			if ((int)key == 0)
			{
				return false;
			}
			return Input.GetKey(key);
		}

		private static bool KeyPressedThisFrame(KeyCode key)
		{
			//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)
			if ((int)key == 0)
			{
				return false;
			}
			return Input.GetKeyDown(key);
		}
	}
	internal static class CannonUtil
	{
		private static readonly FieldInfo[] ScoutCannonFields = typeof(ScoutCannon).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static FieldInfo _tubeField;

		private static FieldInfo _entryField;

		private static bool _fieldsResolved;

		private static readonly FieldInfo MainCameraCamField = typeof(MainCamera).GetField("cam", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly List<ScoutCannon> CannonCache = new List<ScoutCannon>();

		private static float _cannonCacheTime = -999f;

		private const float CannonCacheInterval = 2f;

		private static Constructable _lastConstructable;

		private static bool _lastConstructableIsCannon;

		private static void ResolveFields()
		{
			if (_fieldsResolved)
			{
				return;
			}
			_fieldsResolved = true;
			FieldInfo[] scoutCannonFields = ScoutCannonFields;
			foreach (FieldInfo fieldInfo in scoutCannonFields)
			{
				if (fieldInfo.Name == "tube")
				{
					_tubeField = fieldInfo;
				}
				else if (fieldInfo.Name == "entry")
				{
					_entryField = fieldInfo;
				}
			}
		}

		public static bool TryGetHeldScroll(out Constructable constructable, out Item item)
		{
			constructable = null;
			item = null;
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null)
			{
				return false;
			}
			item = localCharacter.data.currentItem;
			if ((Object)(object)item == (Object)null)
			{
				return false;
			}
			Constructable component = ((Component)item).GetComponent<Constructable>();
			if ((Object)(object)component == (Object)null || !IsCannonScroll(component))
			{
				return false;
			}
			constructable = component;
			return true;
		}

		private static bool IsCannonScroll(Constructable c)
		{
			if ((Object)(object)c == (Object)(object)_lastConstructable)
			{
				return _lastConstructableIsCannon;
			}
			_lastConstructable = c;
			_lastConstructableIsCannon = false;
			try
			{
				if ((Object)(object)c.constructedPrefab != (Object)null)
				{
					_lastConstructableIsCannon = (Object)(object)c.constructedPrefab.GetComponentInChildren<ScoutCannon>(true) != (Object)null;
				}
				if (!_lastConstructableIsCannon)
				{
					string text = (((Object)(object)((Component)c).gameObject != (Object)null) ? ((Object)((Component)c).gameObject).name : string.Empty);
					if ((Object)(object)c.constructedPrefab != (Object)null)
					{
						text = text + " " + ((Object)c.constructedPrefab).name;
					}
					if ((Object)(object)c.previewPrefab != (Object)null)
					{
						text = text + " " + ((Object)c.previewPrefab).name;
					}
					_lastConstructableIsCannon = text.IndexOf("cannon", StringComparison.OrdinalIgnoreCase) >= 0;
				}
			}
			catch
			{
				_lastConstructableIsCannon = false;
			}
			return _lastConstructableIsCannon;
		}

		public static bool TryGetHeldMuzzle(out Transform muzzle, out Vector3 direction)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			muzzle = null;
			direction = Vector3.zero;
			if (!TryGetHeldScroll(out var constructable, out var _))
			{
				return false;
			}
			ConstructablePreview currentPreview = constructable.currentPreview;
			if ((Object)(object)currentPreview == (Object)null)
			{
				return false;
			}
			Transform transform = ((Component)currentPreview).transform;
			Transform val = null;
			val = FindChildByName(transform, "Entry");
			if ((Object)(object)val == (Object)null)
			{
				val = FindChildByName(transform, "Cannon");
			}
			if ((Object)(object)val == (Object)null && transform.childCount > 0)
			{
				Transform child = transform.GetChild(0);
				if ((Object)(object)child != (Object)null && child.childCount > 0)
				{
					val = child.GetChild(0);
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				val = transform;
			}
			muzzle = val;
			direction = val.forward;
			return ((Vector3)(ref direction)).sqrMagnitude > 1E-06f;
		}

		private static Transform FindChildByName(Transform root, string name)
		{
			if ((Object)(object)root == (Object)null || string.IsNullOrEmpty(name))
			{
				return null;
			}
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if ((Object)(object)componentsInChildren[i] != (Object)null && ((Object)componentsInChildren[i]).name == name)
				{
					return componentsInChildren[i];
				}
			}
			return null;
		}

		public static Camera GetCamera()
		{
			try
			{
				MainCamera instance = MainCamera.instance;
				if ((Object)(object)instance != (Object)null && MainCameraCamField != null)
				{
					object? value = MainCameraCamField.GetValue(instance);
					Camera val = (Camera)((value is Camera) ? value : null);
					if ((Object)(object)val != (Object)null)
					{
						return val;
					}
				}
			}
			catch
			{
			}
			return Camera.main;
		}

		public static List<ScoutCannon> GetCannons()
		{
			if (Time.unscaledTime - _cannonCacheTime < 2f)
			{
				return CannonCache;
			}
			_cannonCacheTime = Time.unscaledTime;
			CannonCache.Clear();
			try
			{
				ScoutCannon[] array = Object.FindObjectsByType<ScoutCannon>((FindObjectsSortMode)0);
				for (int i = 0; i < array.Length; i++)
				{
					if ((Object)(object)array[i] != (Object)null)
					{
						CannonCache.Add(array[i]);
					}
				}
			}
			catch
			{
			}
			return CannonCache;
		}

		public static void InvalidateCannonCache()
		{
			_cannonCacheTime = -999f;
		}

		public static Transform GetTube(ScoutCannon cannon)
		{
			ResolveFields();
			object? obj = _tubeField?.GetValue(cannon);
			Transform val = (Transform)((obj is Transform) ? obj : null);
			if ((Object)(object)val == (Object)null && (Object)(object)cannon != (Object)null)
			{
				val = ((Component)cannon).transform.Find("Cannon");
			}
			return val;
		}

		public static Transform GetEntry(ScoutCannon cannon)
		{
			ResolveFields();
			object? obj = _entryField?.GetValue(cannon);
			Transform val = (Transform)((obj is Transform) ? obj : null);
			if ((Object)(object)val == (Object)null && (Object)(object)cannon != (Object)null)
			{
				val = ((Component)cannon).transform.Find("Cannon/Entry");
			}
			return val;
		}

		public static bool TryGetAimedCannon(Camera cam, float range, out ScoutCannon cannon)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			cannon = null;
			if ((Object)(object)cam == (Object)null)
			{
				return false;
			}
			RaycastHit[] array;
			try
			{
				array = Physics.RaycastAll(((Component)cam).transform.position, ((Component)cam).transform.forward, range, -1, (QueryTriggerInteraction)2);
			}
			catch
			{
				return false;
			}
			if (array == null || array.Length == 0)
			{
				return false;
			}
			Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance));
			for (int num = 0; num < array.Length; num++)
			{
				if (!((Object)(object)((RaycastHit)(ref array[num])).collider == (Object)null))
				{
					ScoutCannon componentInParent = ((Component)((RaycastHit)(ref array[num])).collider).GetComponentInParent<ScoutCannon>();
					if ((Object)(object)componentInParent != (Object)null)
					{
						cannon = componentInParent;
						return true;
					}
				}
			}
			return false;
		}

		public static bool TryGetNearbyUnlitCannon(Character local, float radius, out ScoutCannon cannon, out float distance)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			cannon = null;
			distance = float.MaxValue;
			if ((Object)(object)local == (Object)null)
			{
				return false;
			}
			Vector3 center = local.Center;
			List<ScoutCannon> cannons = GetCannons();
			for (int i = 0; i < cannons.Count; i++)
			{
				ScoutCannon val = cannons[i];
				if ((Object)(object)val == (Object)null || val.lit)
				{
					continue;
				}
				Transform entry = GetEntry(val);
				if (!((Object)(object)entry == (Object)null))
				{
					float num = Vector3.Distance(center, entry.position);
					if (num <= radius && num < distance)
					{
						cannon = val;
						distance = num;
					}
				}
			}
			return (Object)(object)cannon != (Object)null;
		}

		public static Vector2 DirectionToLook(Vector3 dir)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_0031: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			Quaternion val = Quaternion.LookRotation(dir, Vector3.up);
			Vector3 eulerAngles = ((Quaternion)(ref val)).eulerAngles;
			if (eulerAngles.x > 180f)
			{
				eulerAngles.x -= 360f;
			}
			return new Vector2(eulerAngles.y, 0f - eulerAngles.x);
		}
	}
	internal static class ModConfig
	{
		public static ConfigEntry<bool> ViewEnabled;

		public static ConfigEntry<KeyCode> ViewKey;

		public static ConfigEntry<bool> ViewLockCamera;

		public static ConfigEntry<bool> ViewFullAlign;

		public static ConfigEntry<bool> ViewCrosshair;

		public static ConfigEntry<bool> ViewEdgeIndicator;

		public static ConfigEntry<float> CrosshairSize;

		public static ConfigEntry<float> CrosshairRange;

		public static ConfigEntry<string> CrosshairColor;

		public static ConfigEntry<bool> ScopeEnabled;

		public static ConfigEntry<int> ScopeCorner;

		public static ConfigEntry<float> ScopeWidth;

		public static ConfigEntry<float> ScopeMargin;

		public static ConfigEntry<float> ScopeFov;

		public static ConfigEntry<float> ScopeForwardOffset;

		public static ConfigEntry<bool> ScopeCrosshair;

		public static ConfigEntry<bool> EnterEnabled;

		public static ConfigEntry<KeyCode> EnterKey;

		public static ConfigEntry<float> EnterHold;

		public static ConfigEntry<float> EnterRange;

		public static ConfigEntry<bool> BlockAutoPull;

		public static ConfigEntry<bool> IgniteEnabled;

		public static ConfigEntry<KeyCode> IgniteKey;

		public static ConfigEntry<float> IgniteHold;

		public static ConfigEntry<float> IgniteRadius;

		public static ConfigEntry<bool> DebugLog;

		public static void Init(ConfigFile config)
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Expected O, but got Unknown
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Expected O, but got Unknown
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Expected O, but got Unknown
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Expected O, but got Unknown
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Expected O, but got Unknown
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Expected O, but got Unknown
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Expected O, but got Unknown
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Expected O, but got Unknown
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Expected O, but got Unknown
			ViewEnabled = config.Bind<bool>("视角对准炮口", "启用炮口瞄准指示", true, "开启后,手持童子军大炮建造卷轴、地面出现大炮放置预览时,按切换键显示炮口瞄准指示(准星;炮口指向上方或屏幕外时在屏幕边缘提示),据此看清大炮将打向哪里、方便决定放在什么位置。默认不改变相机朝向,因此移动、瞄准地面落点、放置大炮都不受影响;若还想让相机也贴齐炮口方向(便于直视远方目标),请打开下面的“锁定视角到炮口”。再按一下切换键关闭。");
			ViewKey = config.Bind<KeyCode>("视角对准炮口", "切换按键", (KeyCode)118, "按下一次显示炮口瞄准指示,再按一次关闭。");
			ViewLockCamera = config.Bind<bool>("视角对准炮口", "锁定视角到炮口", false, "开启后,瞄准状态下把相机朝向(俯仰与水平)锁定为放置预览的炮口方向,屏幕中心即炮口指向,便于直视远方目标。注意:大炮放置依赖相机朝地面发射线判定落点(Constructable.TryUpdatePreview),锁住相机后相机无法下看地面,会导致无法放置大炮;建议只在观察远方时临时开启,放置时保持关闭。默认关闭。");
			ViewFullAlign = config.Bind<bool>("视角对准炮口", "完全对齐炮口方向", true, "仅当“锁定视角到炮口”开启时生效。开启:俯仰与水平都锁定为炮口方向(屏幕中心即炮口指向);关闭:只对齐俯仰,水平方向仍可自由转动(大炮预览的水平朝向本就跟随视线,因此通常也一致)。");
			ViewCrosshair = config.Bind<bool>("视角对准炮口", "显示炮口准星", true, "处于炮口瞄准状态时,在炮口方向的投影点上绘制准星。");
			ViewEdgeIndicator = config.Bind<bool>("视角对准炮口", "屏幕外显示边缘指示", true, "炮口指向上方或屏幕外时,在屏幕边缘显示准星提示,便于俯视地面放置大炮时也能知道炮口朝向。");
			CrosshairSize = config.Bind<float>("视角对准炮口", "准星基础尺寸", 26f, new ConfigDescription("准星基础半径(像素),会随分辨率与界面缩放自动适配。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(6f, 80f), Array.Empty<object>()));
			CrosshairRange = config.Bind<float>("视角对准炮口", "准星投影距离", 300f, new ConfigDescription("准星绘制在炮口方向该距离处的屏幕投影上。数值越大,准星越接近炮口指向的“正前方”,且不受近距离物体视差影响(推荐 200 以上)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 1000f), Array.Empty<object>()));
			CrosshairColor = config.Bind<string>("视角对准炮口", "准星颜色", "#39FF6A", "准星颜色,十六进制,例如 #39FF6A(绿色)、#FF3B30(红色)、#FFFFFF(白色)。");
			ScopeEnabled = config.Bind<bool>("瞄准小窗", "启用瞄准小窗", true, "开启后,处于炮口瞄准状态时,在屏幕一角实时显示从炮口沿炮口方向看出去的画面(画中画)。这样你可以一边用主视角查看地面、移动并放置大炮,一边在小窗里直接看到炮口对准的远方,不必再靠准星猜测。需额外渲染一遍场景,有少量性能开销;不需要时可关闭。");
			ScopeCorner = config.Bind<int>("瞄准小窗", "小窗位置", 0, new ConfigDescription("小窗贴着屏幕哪个角:0=右下,1=右上,2=左下,3=左上。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 3), Array.Empty<object>()));
			ScopeWidth = config.Bind<float>("瞄准小窗", "小窗宽度(像素)", 320f, new ConfigDescription("小窗的宽度,高度自动按 16:9 计算。数值越大越清晰、开销越高。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(96f, 800f), Array.Empty<object>()));
			ScopeMargin = config.Bind<float>("瞄准小窗", "小窗边距(像素)", 16f, new ConfigDescription("小窗与屏幕边缘的距离。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), Array.Empty<object>()));
			ScopeFov = config.Bind<float>("瞄准小窗", "视野角度", 60f, new ConfigDescription("小窗的相机视野角度(FOV)。数值越小画面越“拉近”,便于看远处目标。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 110f), Array.Empty<object>()));
			ScopeForwardOffset = config.Bind<float>("瞄准小窗", "相机前移(米)", 0.25f, new ConfigDescription("小窗相机从炮口节点沿炮口方向前移的距离。若小窗里看到炮管内壁或角色手臂,可适当加大。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>()));
			ScopeCrosshair = config.Bind<bool>("瞄准小窗", "小窗内准星", true, "在小窗画面中心绘制一个十字准星,表示炮口正指向的位置。");
			EnterEnabled = config.Bind<bool>("进入大炮", "启用进入大炮", true, "开启后,对准一门已放置的童子军大炮,长按进入键即可直接把角色送入炮口内。");
			EnterKey = config.Bind<KeyCode>("进入大炮", "进入按键", (KeyCode)120, "对准大炮长按该键进入炮内。");
			EnterHold = config.Bind<float>("进入大炮", "长按时间(秒)", 0.3f, new ConfigDescription("对准大炮后需要持续按住的时长,达到后执行进入。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 3f), Array.Empty<object>()));
			EnterRange = config.Bind<float>("进入大炮", "瞄准射线距离(米)", 25f, new ConfigDescription("对准判定所用的最大射线距离。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 200f), Array.Empty<object>()));
			BlockAutoPull = config.Bind<bool>("进入大炮", "禁止自动吸附本地玩家", true, "原版大炮会把走到炮口 1 米内的最近角色自动吸进炮内(这是原版装载队友的机制,见 ScoutCannon.FixedUpdate)。开启本项后,当你自己位于吸附范围内时跳过该自动吸附,避免只是在大炮附近走动就被吸进去;只有按进入键才会进入。关闭则保留原版自动吸附行为。注意:该逻辑由主机执行,因此仅当你是主机时生效。");
			IgniteEnabled = config.Bind<bool>("炮内点火", "启用炮内点火", true, "开启后,当角色处于某门未点火大炮的炮口附近时,长按点火键即可点燃。已点火或正在点火的大炮不会重复触发。");
			IgniteKey = config.Bind<KeyCode>("炮内点火", "点火按键", (KeyCode)101, "在大炮内长按该键点火(默认 E,与游戏交互键一致)。");
			IgniteHold = config.Bind<float>("炮内点火", "长按时间(秒)", 1f, new ConfigDescription("在炮内按住点火键的时长,达到后点火。默认与原版引信交互时长一致。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>()));
			IgniteRadius = config.Bind<float>("炮内点火", "炮内判定半径(米)", 2.2f, new ConfigDescription("角色与炮口 Distance 在该半径内即视为“在大炮内”,可点火。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 6f), Array.Empty<object>()));
			DebugLog = config.Bind<bool>("调试", "详细日志", false, "开启后在 BepInEx 控制台输出进入/点火/切换视角的调试信息。");
		}

		public static void Log(string message)
		{
			if (DebugLog != null && DebugLog.Value)
			{
				ManualLogSource loggerRef = Plugin.LoggerRef;
				if (loggerRef != null)
				{
					loggerRef.LogInfo((object)("[童子军大炮] " + message));
				}
			}
		}
	}
	[HarmonyPatch(typeof(ScoutCannon), "FixedUpdate")]
	internal static class AutoPullPatch
	{
		private const float VanillaPullRadius = 1f;

		[HarmonyPrefix]
		private static bool Prefix(ScoutCannon __instance)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			if (!ModConfig.BlockAutoPull.Value)
			{
				return true;
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null)
			{
				return true;
			}
			Transform entry = CannonUtil.GetEntry(__instance);
			if ((Object)(object)entry == (Object)null)
			{
				return true;
			}
			if (Vector3.Distance(localCharacter.Center, entry.position) < 1f)
			{
				return false;
			}
			return true;
		}
	}
	[BepInPlugin("com.fufu.scoutcannonhelper", "童子军大炮", "0.1.6")]
	internal sealed class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		private GameObject _host;

		internal static Plugin Instance { get; private set; }

		internal static ManualLogSource LoggerRef { get; private set; }

		private void Awake()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			Instance = this;
			LoggerRef = ((BaseUnityPlugin)this).Logger;
			ModConfig.Init(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("com.fufu.scoutcannonhelper");
			try
			{
				_harmony.PatchAll(Assembly.GetExecutingAssembly());
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[童子军大炮] v0.1.6 已加载,Harmony 补丁应用成功。");
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"[童子军大炮] Harmony 补丁应用失败:{arg}");
			}
			_host = new GameObject("ScoutCannonHelper_Host");
			Object.DontDestroyOnLoad((Object)(object)_host);
			((Object)_host).hideFlags = (HideFlags)61;
			_host.AddComponent<CannonController>();
			_host.AddComponent<AimScope>();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[童子军大炮] 控制器已挂载。");
		}

		private void OnDestroy()
		{
			try
			{
				Harmony harmony = _harmony;
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}
			catch
			{
			}
		}
	}
	internal static class PluginInfo
	{
		public const string PLUGIN_GUID = "com.fufu.scoutcannonhelper";

		public const string PLUGIN_NAME = "童子军大炮";

		public const string PLUGIN_VERSION = "0.1.6";
	}
}
namespace ScoutCannonHelper.Patches
{
	[HarmonyPatch(typeof(Character), "RecalculateLookDirections")]
	internal static class LookPatch
	{
		private static void Prefix(Character __instance)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (!((Object)(object)__instance == (Object)null) && __instance.IsLocal && ModConfig.ViewLockCamera.Value && CannonViewState.Aiming && CannonUtil.TryGetHeldMuzzle(out var _, out var direction))
				{
					Vector2 val = CannonUtil.DirectionToLook(direction);
					float num = Mathf.Clamp(val.y, -85f, 85f);
					if (ModConfig.ViewFullAlign.Value)
					{
						__instance.data.lookValues = new Vector2(val.x, num);
						return;
					}
					Vector2 lookValues = __instance.data.lookValues;
					lookValues.y = num;
					__instance.data.lookValues = lookValues;
				}
			}
			catch
			{
			}
		}
	}
}