Decompiled source of ThirdPersonSelfCam v1.0.1

plugins\ThirdPersonSelfCam.dll

Decompiled 8 hours ago
using System;
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 UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("ThirdPersonSelfCam")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("ThirdPersonSelfCam")]
[assembly: AssemblyTitle("ThirdPersonSelfCam")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
namespace ThirdPersonSelfCam
{
	[BepInPlugin("com.sleepylemon.thirdpersonselfcam", "ThirdPersonSelfCam", "1.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		internal static Plugin Instance;

		internal static ManualLogSource Log;

		public static ConfigEntry<KeyCode> ToggleKey;

		public static ConfigEntry<float> Distance;

		public static ConfigEntry<float> Height;

		public static ConfigEntry<float> Shoulder;

		public static ConfigEntry<float> Smoothing;

		public static ConfigEntry<float> CollisionRadius;

		public static ConfigEntry<float> CollisionBuffer;

		public static ConfigEntry<bool> AllowScrollZoom;

		public static ConfigEntry<float> MinDistance;

		public static ConfigEntry<float> MaxDistance;

		public static ConfigEntry<bool> StartInThirdPerson;

		private ThirdPersonCamera cam;

		private void Awake()
		{
			//IL_01a2: 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)
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkey", "ToggleKey", (KeyCode)118, "Key used to switch between first and third person.");
			Distance = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "Distance", 2.5f, "How far behind the player the camera sits.");
			Height = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "Height", 0.2f, "Vertical offset from the eye point.");
			Shoulder = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "Shoulder", 0f, "Sideways (over the shoulder) offset. 0 = centred.");
			Smoothing = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "Smoothing", 12f, "How quickly the camera moves between first and third person.");
			CollisionRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Collision", "Radius", 0.2f, "Radius of the sphere cast used to keep the camera out of walls.");
			CollisionBuffer = ((BaseUnityPlugin)this).Config.Bind<float>("Collision", "Buffer", 0.15f, "Gap kept between the camera and any wall it hits.");
			AllowScrollZoom = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "AllowScrollZoom", false, "Allow the mouse scroll wheel to change the camera distance while in third person.");
			MinDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "MinDistance", 1f, "Minimum distance when scroll zoom is enabled.");
			MaxDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Camera", "MaxDistance", 6f, "Maximum distance when scroll zoom is enabled.");
			StartInThirdPerson = ((BaseUnityPlugin)this).Config.Bind<bool>("Camera", "StartInThirdPerson", false, "If enabled, third person is active as soon as you spawn.");
			cam = new ThirdPersonCamera();
			new Harmony("com.sleepylemon.thirdpersonselfcam").PatchAll();
			Log.LogInfo((object)string.Format("{0} {1} loaded. Toggle key: {2}.", "ThirdPersonSelfCam", "1.0.1", ToggleKey.Value));
		}

		internal void DriveTick()
		{
			cam?.Tick();
		}

		private void OnDestroy()
		{
			cam?.RestoreFirstPerson();
		}
	}
	[HarmonyPatch(typeof(CameraAim), "Update")]
	internal static class CameraAimUpdatePatch
	{
		private static void Postfix()
		{
			Plugin.Instance?.DriveTick();
		}
	}
	internal static class PluginInfo
	{
		public const string Guid = "com.sleepylemon.thirdpersonselfcam";

		public const string Name = "ThirdPersonSelfCam";

		public const string Version = "1.0.1";
	}
	public class ThirdPersonCamera
	{
		public static ThirdPersonCamera Instance;

		private bool thirdPersonEnabled;

		private bool visualsApplied;

		private bool startApplied;

		private Camera mainCamera;

		private static FieldInfo menuManagerCurrentMenuPageField;

		public ThirdPersonCamera()
		{
			Instance = this;
			if (menuManagerCurrentMenuPageField == null)
			{
				menuManagerCurrentMenuPageField = typeof(MenuManager).GetField("currentMenuPage", BindingFlags.Instance | BindingFlags.NonPublic);
				if (menuManagerCurrentMenuPageField == null)
				{
					Plugin.Log.LogWarning((object)"Could not find MenuManager.currentMenuPage field via reflection. Menu checks will be skipped.");
				}
			}
		}

		private MenuPage GetCurrentMenuPage()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			if (!Object.op_Implicit((Object)(object)MenuManager.instance))
			{
				return null;
			}
			if (menuManagerCurrentMenuPageField != null)
			{
				return (MenuPage)menuManagerCurrentMenuPageField.GetValue(MenuManager.instance);
			}
			return null;
		}

		public void Tick()
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Invalid comparison between Unknown and I4
			try
			{
				if (!Object.op_Implicit((Object)(object)mainCamera) && Object.op_Implicit((Object)(object)GameDirector.instance))
				{
					mainCamera = GameDirector.instance.MainCamera;
				}
				if (!Object.op_Implicit((Object)(object)mainCamera) || (Object)(object)((Component)mainCamera).transform.parent == (Object)null)
				{
					return;
				}
				if (Object.op_Implicit((Object)(object)SpectateCamera.instance))
				{
					visualsApplied = false;
					return;
				}
				PlayerAvatar instance = PlayerAvatar.instance;
				bool num = Object.op_Implicit((Object)(object)GameDirector.instance) && (int)GameDirector.instance.currentState >= 2;
				bool flag = Object.op_Implicit((Object)(object)instance) && !instance.isDisabled;
				bool flag2 = !SemiFunc.MenuLevel();
				bool flag3 = num && flag && flag2;
				if (flag3 && !startApplied)
				{
					startApplied = true;
					if (Plugin.StartInThirdPerson.Value)
					{
						thirdPersonEnabled = true;
					}
				}
				HandleToggleInput(flag3);
				if (thirdPersonEnabled && flag3)
				{
					ApplyThirdPerson(instance);
				}
				else
				{
					ApplyFirstPerson(instance);
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Exception in LateUpdate: {arg}");
			}
		}

		private void HandleToggleInput(bool canSpectateSelf)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (canSpectateSelf && !Object.op_Implicit((Object)(object)GetCurrentMenuPage()) && Input.GetKeyDown(Plugin.ToggleKey.Value))
			{
				thirdPersonEnabled = !thirdPersonEnabled;
			}
		}

		private void ApplyThirdPerson(PlayerAvatar localPlayer)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: 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_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			Transform parent = ((Component)mainCamera).transform.parent;
			float num = Plugin.Distance.Value;
			float value = Plugin.Height.Value;
			float value2 = Plugin.Shoulder.Value;
			if (Plugin.AllowScrollZoom.Value)
			{
				float num2 = SemiFunc.InputScrollY();
				if (num2 != 0f)
				{
					num = Mathf.Clamp(num - num2 * 0.0025f, Plugin.MinDistance.Value, Plugin.MaxDistance.Value);
					Plugin.Distance.Value = num;
				}
			}
			Vector3 val = parent.position + parent.up * value + parent.right * value2;
			Vector3 val2 = -parent.forward;
			float num3 = num;
			RaycastHit val3 = default(RaycastHit);
			if (Physics.SphereCast(val, Plugin.CollisionRadius.Value, val2, ref val3, num, LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct()), (QueryTriggerInteraction)1))
			{
				num3 = Mathf.Max(0f, ((RaycastHit)(ref val3)).distance - Plugin.CollisionBuffer.Value);
			}
			Vector3 val4 = default(Vector3);
			((Vector3)(ref val4))..ctor(value2, value, 0f - num3);
			((Component)mainCamera).transform.localPosition = Vector3.Lerp(((Component)mainCamera).transform.localPosition, val4, Plugin.Smoothing.Value * Time.deltaTime);
			SetThirdPersonVisuals(localPlayer, state: true);
			if (Object.op_Implicit((Object)(object)localPlayer.playerAvatarVisuals))
			{
				localPlayer.playerAvatarVisuals.ShowSelfOverride(0.5f);
			}
		}

		private void ApplyFirstPerson(PlayerAvatar localPlayer)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_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_0074: Unknown result type (might be due to invalid IL or missing references)
			Vector3 localPosition = ((Component)mainCamera).transform.localPosition;
			if (((Vector3)(ref localPosition)).sqrMagnitude > 0.0001f)
			{
				((Component)mainCamera).transform.localPosition = Vector3.Lerp(localPosition, Vector3.zero, Plugin.Smoothing.Value * Time.deltaTime);
				Vector3 localPosition2 = ((Component)mainCamera).transform.localPosition;
				if (((Vector3)(ref localPosition2)).sqrMagnitude < 0.0001f)
				{
					((Component)mainCamera).transform.localPosition = Vector3.zero;
				}
			}
			SetThirdPersonVisuals(localPlayer, state: false);
		}

		private void SetThirdPersonVisuals(PlayerAvatar localPlayer, bool state)
		{
			if (visualsApplied == state)
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)localPlayer))
			{
				PhysGrabber physGrabber = localPlayer.physGrabber;
				if (physGrabber != null)
				{
					physGrabber.SetThirdPerson(state);
				}
				FlashlightController flashlightController = localPlayer.flashlightController;
				if (flashlightController != null)
				{
					flashlightController.SetThirdPerson(state);
				}
			}
			visualsApplied = state;
		}

		public void RestoreFirstPerson()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)mainCamera))
			{
				((Component)mainCamera).transform.localPosition = Vector3.zero;
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}