Decompiled source of ScoutCannonHelper v0.3.0

plugins/ScoutCannonHelper.dll

Decompiled a month 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 static class CannonHoldState
	{
		public static ScoutCannon Cannon;

		public static float ExpireAt;

		public static bool IsHolding(ScoutCannon cannon)
		{
			if ((Object)(object)cannon != (Object)null && (Object)(object)Cannon == (Object)(object)cannon)
			{
				return Time.unscaledTime < ExpireAt;
			}
			return false;
		}

		public static void Begin(ScoutCannon cannon, float keepAlive)
		{
			Cannon = cannon;
			ExpireAt = Time.unscaledTime + keepAlive;
		}

		public static void Release()
		{
			Cannon = null;
			ExpireAt = 0f;
		}
	}
	internal sealed class CannonController : MonoBehaviour
	{
		private float _enterHold;

		private bool _enterConsumed;

		private bool _viewWasHolding;

		private float _igniteHold;

		private float _igniteBlockUntil;

		private const float IgniteCooldown = 1f;

		private const float HoldKeepAlive = 2f;

		private const float HoldReleaseRadius = 3f;

		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);
			TickHold(localCharacter);
		}

		private void TickViewToggle()
		{
			//IL_0067: 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;
				_viewWasHolding = false;
				return;
			}
			if (!_viewWasHolding)
			{
				_viewWasHolding = true;
				CannonViewState.Aiming = ModConfig.ScopeDefaultOn != null && ModConfig.ScopeDefaultOn.Value;
				if (CannonViewState.Aiming)
				{
					ModConfig.Log("已进入炮口视角(默认开启)。");
				}
			}
			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_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: 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) || (Object)(object)CannonUtil.GetEntry(cannon) == (Object)null)
			{
				return;
			}
			if (ModConfig.EnterBackpack.Value && CannonUtil.IsHoldingBackpack(local))
			{
				_enterConsumed = true;
				_enterHold = 0f;
				Vector3 backpackDropPosition = CannonUtil.GetBackpackDropPosition(cannon);
				if (CannonUtil.TryDropHeldBackpack(local, backpackDropPosition))
				{
					ModConfig.Log("已把背包放入大炮内。");
					return;
				}
				ManualLogSource loggerRef = Plugin.LoggerRef;
				if (loggerRef != null)
				{
					loggerRef.LogWarning((object)"[童子军大炮] 手持背包但放入失败,已跳过本次进入。");
				}
			}
			else
			{
				InvokeWarp(local, CannonUtil.GetPlayerWarpPosition(cannon), poof: false);
				CannonHoldState.Begin(cannon, 2f);
				_enterConsumed = true;
				_enterHold = 0f;
				ModConfig.Log("已进入大炮内。");
			}
		}

		private static void TickHold(Character local)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			ScoutCannon cannon = CannonHoldState.Cannon;
			if ((Object)(object)cannon == (Object)null)
			{
				return;
			}
			if ((Object)(object)local == (Object)null || (Object)(object)local.data == (Object)null || local.data.sinceJump < 0.3f)
			{
				CannonHoldState.Release();
				return;
			}
			Transform entry = CannonUtil.GetEntry(cannon);
			if ((Object)(object)entry == (Object)null || Vector3.Distance(local.Center, entry.position) > 3f)
			{
				CannonHoldState.Release();
			}
			else
			{
				CannonHoldState.Begin(cannon, 2f);
			}
		}

		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 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 ConstructablePreview _muzzlePreviewKey;

		private static Transform _muzzleTransform;

		private static readonly RaycastHit[] AimHits = (RaycastHit[])(object)new RaycastHit[128];

		private static readonly bool[] AimConsumed = new bool[128];

		private const float PlayerInsetFromMuzzle = 0.25f;

		private const float BackpackInsetFromCenter = 0.15f;

		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_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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;
			if ((Object)(object)currentPreview == (Object)(object)_muzzlePreviewKey && (Object)(object)_muzzleTransform != (Object)null)
			{
				val = _muzzleTransform;
			}
			else
			{
				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;
				}
				_muzzlePreviewKey = currentPreview;
				_muzzleTransform = val;
			}
			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;
			}
			int num;
			try
			{
				num = Physics.RaycastNonAlloc(((Component)cam).transform.position, ((Component)cam).transform.forward, AimHits, range, -1, (QueryTriggerInteraction)2);
			}
			catch
			{
				return false;
			}
			for (int i = 0; i < num; i++)
			{
				AimConsumed[i] = false;
			}
			int num2 = -1;
			float num3 = float.MaxValue;
			for (int j = 0; j < num; j++)
			{
				if (!AimConsumed[j] && !((Object)(object)((RaycastHit)(ref AimHits[j])).collider == (Object)null) && ((RaycastHit)(ref AimHits[j])).distance < num3)
				{
					num3 = ((RaycastHit)(ref AimHits[j])).distance;
					num2 = j;
				}
			}
			while (num2 >= 0)
			{
				ScoutCannon componentInParent = ((Component)((RaycastHit)(ref AimHits[num2])).collider).GetComponentInParent<ScoutCannon>();
				if ((Object)(object)componentInParent != (Object)null)
				{
					cannon = componentInParent;
					return true;
				}
				AimConsumed[num2] = true;
				num2 = -1;
				num3 = float.MaxValue;
				for (int k = 0; k < num; k++)
				{
					if (!AimConsumed[k] && (Object)(object)((RaycastHit)(ref AimHits[k])).collider != (Object)null && ((RaycastHit)(ref AimHits[k])).distance < num3)
					{
						num3 = ((RaycastHit)(ref AimHits[k])).distance;
						num2 = k;
					}
				}
			}
			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);
		}

		public static Vector3 GetPlayerWarpPosition(ScoutCannon cannon)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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)
			Transform entry = GetEntry(cannon);
			if ((Object)(object)entry == (Object)null)
			{
				if (!((Object)(object)cannon != (Object)null))
				{
					return Vector3.zero;
				}
				return ((Component)cannon).transform.position;
			}
			Transform tube = GetTube(cannon);
			if ((Object)(object)tube == (Object)null)
			{
				return entry.position;
			}
			Vector3 val = entry.position - tube.forward * 0.25f;
			ModConfig.Log($"[童子军大炮] 角色落点:entry={entry.position} forward={tube.forward} point={val}");
			return val;
		}

		public static Vector3 GetBackpackDropPosition(ScoutCannon cannon)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			Transform tube = GetTube(cannon);
			if ((Object)(object)tube == (Object)null)
			{
				Transform entry = GetEntry(cannon);
				if (!((Object)(object)entry != (Object)null))
				{
					if (!((Object)(object)cannon != (Object)null))
					{
						return Vector3.zero;
					}
					return ((Component)cannon).transform.position;
				}
				return entry.position;
			}
			Vector3 val = tube.position - tube.forward * 0.15f;
			ModConfig.Log($"[童子军大炮] 背包落点:tube={tube.position} forward={tube.forward} point={val}");
			return val;
		}

		public static bool IsHoldingBackpack(Character local)
		{
			if ((Object)(object)local != (Object)null && (Object)(object)local.data != (Object)null)
			{
				return local.data.currentItem is Backpack;
			}
			return false;
		}

		public static bool TryDropHeldBackpack(Character local, Vector3 position)
		{
			//IL_009d: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
			if (!IsHoldingBackpack(local))
			{
				return false;
			}
			CharacterItems val = ((local.refs != null) ? local.refs.items : null);
			Player player = local.player;
			if ((Object)(object)val == (Object)null || (Object)(object)player == (Object)null || !val.currentSelectedSlot.IsSome)
			{
				return false;
			}
			byte value = val.currentSelectedSlot.Value;
			ItemSlot itemSlot = player.GetItemSlot(value);
			if (itemSlot == null)
			{
				return false;
			}
			PhotonView component = ((Component)val).GetComponent<PhotonView>();
			if ((Object)(object)component == (Object)null)
			{
				return false;
			}
			try
			{
				component.RPC("DropItemRpc", (RpcTarget)0, new object[7]
				{
					0f,
					value,
					position,
					Vector3.zero,
					local.data.currentItem.transform.rotation,
					itemSlot.data,
					false
				});
				return true;
			}
			catch (Exception arg)
			{
				ManualLogSource loggerRef = Plugin.LoggerRef;
				if (loggerRef != null)
				{
					loggerRef.LogError((object)$"[童子军大炮] 放入背包失败:{arg}");
				}
				return false;
			}
		}
	}
	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> ScopeEnabled;

		public static ConfigEntry<bool> ScopeDefaultOn;

		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<bool> EnterBackpack;

		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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Expected O, but got Unknown
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Expected O, but got Unknown
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Expected O, but got Unknown
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Expected O, but got Unknown
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Expected O, but got Unknown
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Expected O, but got Unknown
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Expected O, but got Unknown
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: 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, "仅当“锁定视角到炮口”开启时生效。开启:俯仰与水平都锁定为炮口方向(屏幕中心即炮口指向);关闭:只对齐俯仰,水平方向仍可自由转动(大炮预览的水平朝向本就跟随视线,因此通常也一致)。");
			ScopeEnabled = config.Bind<bool>("瞄准小窗", "启用瞄准小窗", true, "开启后,处于炮口瞄准状态时,在屏幕一角实时显示从炮口沿炮口方向看出去的画面(画中画)。这样你可以一边用主视角查看地面、移动并放置大炮,一边在小窗里直接看到炮口对准的远方,不必再靠准星猜测。需额外渲染一遍场景,有少量性能开销;不需要时可关闭。");
			ScopeDefaultOn = config.Bind<bool>("瞄准小窗", "默认开启瞄准状态", false, "开启后,只要手持大炮建造卷轴,无需按切换键就自动进入炮口瞄准状态(小窗随之显示);按一下切换键仍可临时关闭。关闭时保持原行为:必须按切换键才显示。未手持卷轴、或瞄准状态关闭时,小窗相机不会创建、也不渲染,无额外性能开销。");
			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>()));
			EnterBackpack = config.Bind<bool>("进入大炮", "手持背包时放入背包", true, "开启后,对准大炮长按进入键时:若手里正拿着背包,则把背包丢进炮管最里面(背包会被大炮以更高发射力射出),角色自己不进炮;手里没拿背包时角色照常进入。关闭后进入键始终让角色进炮。");
			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 CannonHoldState.IsHolding(__instance);
			}
			return true;
		}
	}
	[BepInPlugin("ScoutCannonHelper", "童子军大炮", "0.3.0")]
	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("ScoutCannonHelper");
			try
			{
				_harmony.PatchAll(Assembly.GetExecutingAssembly());
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[童子军大炮] v0.3.0 已加载,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 = "ScoutCannonHelper";

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

		public const string PLUGIN_VERSION = "0.3.0";
	}
}
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
			{
			}
		}
	}
}