Decompiled source of ThirdPersonComfort v1.0.1

plugins/BigWalkThirdPerson.dll

Decompiled 5 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.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Microsoft.CodeAnalysis;
using Mirror;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BigWalkThirdPerson
{
	[BepInPlugin("dev.sopur.bigwalk.thirdperson", "Big Walk Third Person", "1.0.0")]
	public class Plugin : BasePlugin
	{
		public const string Guid = "dev.sopur.bigwalk.thirdperson";

		public const string Name = "Big Walk Third Person";

		public const string Version = "1.0.0";

		internal static ManualLogSource LogSource;

		internal static ConfigEntry<CameraMode> Mode;

		internal static ConfigEntry<KeyCode> ToggleKey;

		internal static ConfigEntry<KeyCode> DumpKey;

		internal static ConfigEntry<bool> StartEnabled;

		internal static ConfigEntry<float> Distance;

		internal static ConfigEntry<float> MinDistance;

		internal static ConfigEntry<float> MaxDistance;

		internal static ConfigEntry<float> Height;

		internal static ConfigEntry<float> Shoulder;

		internal static ConfigEntry<float> ZoomSpeed;

		internal static ConfigEntry<bool> Collision;

		internal static ConfigEntry<float> CollisionRadius;

		internal static ConfigEntry<bool> Stabilize;

		internal static ConfigEntry<float> StabilizeAmount;

		internal static ConfigEntry<float> StabilizeSmoothTime;

		internal static ConfigEntry<bool> LevelHorizon;

		internal static ConfigEntry<bool> ShowBody;

		internal static ConfigEntry<bool> HideHead;

		internal static ConfigEntry<bool> ShowStatus;

		public override void Load()
		{
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Expected O, but got Unknown
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Expected O, but got Unknown
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			LogSource = ((BasePlugin)this).Log;
			string text = "Camera";
			Mode = ((BasePlugin)this).Config.Bind<CameraMode>(text, "Mode", CameraMode.Direct, "Direct = move the camera itself before rendering (recommended). Guide = reroute the game's camera guide mechanism (experimental).");
			ToggleKey = ((BasePlugin)this).Config.Bind<KeyCode>(text, "ToggleKey", (KeyCode)285, "Key that toggles third person.");
			DumpKey = ((BasePlugin)this).Config.Bind<KeyCode>(text, "DumpKey", (KeyCode)289, "Key that dumps the local player hierarchy to the BepInEx log (for troubleshooting).");
			StartEnabled = ((BasePlugin)this).Config.Bind<bool>(text, "StartEnabled", true, "Start in third person as soon as a local player exists.");
			Distance = ((BasePlugin)this).Config.Bind<float>(text, "Distance", 3.2f, "Camera distance behind the player (meters).");
			MinDistance = ((BasePlugin)this).Config.Bind<float>(text, "MinDistance", 1f, "Minimum zoom distance.");
			MaxDistance = ((BasePlugin)this).Config.Bind<float>(text, "MaxDistance", 7f, "Maximum zoom distance.");
			Height = ((BasePlugin)this).Config.Bind<float>(text, "Height", 0.45f, "Camera pivot height above the eye position.");
			Shoulder = ((BasePlugin)this).Config.Bind<float>(text, "Shoulder", 0.45f, "Sideways (over-shoulder) offset of the camera.");
			ZoomSpeed = ((BasePlugin)this).Config.Bind<float>(text, "ZoomSpeed", 1.6f, "Mouse wheel zoom speed.");
			Collision = ((BasePlugin)this).Config.Bind<bool>(text, "Collision", true, "Pull the camera in when geometry blocks the view.");
			CollisionRadius = ((BasePlugin)this).Config.Bind<float>(text, "CollisionRadius", 0.22f, "Sphere radius used for camera collision.");
			Stabilize = ((BasePlugin)this).Config.Bind<bool>(text, "Stabilize", true, "Smooth the camera pivot to remove head bob. Main motion-sickness comfort feature.");
			StabilizeAmount = ((BasePlugin)this).Config.Bind<float>(text, "StabilizeAmount", 0.85f, "How much of the pivot bob is removed (0 = off, 1 = fully smoothed).");
			StabilizeSmoothTime = ((BasePlugin)this).Config.Bind<float>(text, "StabilizeSmoothTime", 0.12f, "Seconds of smoothing on the pivot. Higher = steadier but laggier.");
			LevelHorizon = ((BasePlugin)this).Config.Bind<bool>(text, "LevelHorizon", false, "Force the camera level with the horizon (removes roll).");
			string text2 = "Body";
			ShowBody = ((BasePlugin)this).Config.Bind<bool>(text2, "ShowBody", true, "Show the full (remote-mode) body on the local player while in third person.");
			HideHead = ((BasePlugin)this).Config.Bind<bool>(text2, "HideHead", false, "Hide the head renderers in third person (use if the head blocks the view).");
			string text3 = "UI";
			ShowStatus = ((BasePlugin)this).Config.Bind<bool>(text3, "ShowStatus", true, "Show a small on-screen label while third person is active.");
			ClassInjector.RegisterTypeInIl2Cpp<ThirdPersonComponent>();
			ClassInjector.RegisterTypeInIl2Cpp<CameraDriver>();
			GameObject val = new GameObject("BigWalkThirdPerson");
			Object.DontDestroyOnLoad((Object)val);
			((Object)val).hideFlags = (HideFlags)61;
			val.AddComponent(Il2CppType.Of<ThirdPersonComponent>());
			ManualLogSource logSource = LogSource;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(23, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("Big Walk Third Person");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("1.0.0");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" loaded. Toggle with ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<KeyCode>(ToggleKey.Value);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
			}
			logSource.LogInfo(val2);
		}
	}
	public enum CameraMode
	{
		Guide,
		Direct
	}
	public class ThirdPersonComponent : MonoBehaviour
	{
		private PlayerCharacter pc;

		private PlayerCameraReferences pcr;

		private PlayerCameraMinder minder;

		private Camera cam;

		private Transform pivot;

		private Transform guide;

		private Transform gameGuide;

		private CameraDriver driver;

		private bool active;

		private bool suspended;

		private float curDistance;

		private float nextResolve;

		private float nextBodyCheck;

		private bool wantEnabled;

		private bool bodyApplied;

		private bool origHideTorso;

		private Vector3 origCamLocalPos;

		private int collideMode = -1;

		private int collisionMask;

		private string lastError;

		private float lastErrorTime;

		private Vector3 smoothPivot;

		private bool hasSmoothPivot;

		public ThirdPersonComponent(IntPtr ptr)
			: base(ptr)
		{
		}

		public ThirdPersonComponent()
			: base(ClassInjector.DerivedConstructorPointer<ThirdPersonComponent>())
		{
			ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this);
		}

		private void Awake()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			GameObject val = new GameObject("BigWalkThirdPersonGuide");
			Object.DontDestroyOnLoad((Object)(object)val);
			((Object)val).hideFlags = (HideFlags)61;
			guide = val.transform;
			curDistance = Plugin.Distance.Value;
			wantEnabled = Plugin.StartEnabled.Value;
		}

		private void Update()
		{
			//IL_0005: 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_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (Input.GetKeyDown(Plugin.ToggleKey.Value))
				{
					wantEnabled = !wantEnabled;
				}
				if (Input.GetKeyDown(Plugin.DumpKey.Value))
				{
					Dump();
				}
				if (active && !suspended)
				{
					float axis = Input.GetAxis("Mouse ScrollWheel");
					if (axis != 0f)
					{
						curDistance = Mathf.Clamp(curDistance - axis * Plugin.ZoomSpeed.Value, Plugin.MinDistance.Value, Plugin.MaxDistance.Value);
					}
				}
			}
			catch (Exception ex)
			{
				LogThrottled("input", "Input handling failed: " + ex.Message);
			}
			if (Time.unscaledTime >= nextResolve)
			{
				nextResolve = Time.unscaledTime + 0.5f;
				try
				{
					ResolveRefs();
				}
				catch (Exception ex2)
				{
					LogThrottled("resolve", "ResolveRefs: " + ex2.Message);
				}
			}
			try
			{
				if (wantEnabled && !active && RefsOk())
				{
					Enter();
				}
				if (!wantEnabled && active)
				{
					Exit();
				}
			}
			catch (Exception value)
			{
				LogThrottled("enterexit", $"Enter/Exit: {value}");
			}
			if (active && !suspended && Plugin.ShowBody.Value && Time.unscaledTime >= nextBodyCheck)
			{
				nextBodyCheck = Time.unscaledTime + 0.5f;
				try
				{
					ApplyBody();
				}
				catch (Exception ex3)
				{
					LogThrottled("body", "ApplyBody: " + ex3.Message);
				}
			}
			if (active && RefsOk() && (Object)(object)pivot != (Object)null)
			{
				Vector3 position = pivot.position;
				if (hasSmoothPivot)
				{
					Vector3 val = position - smoothPivot;
					if (!(((Vector3)(ref val)).sqrMagnitude > 2.25f))
					{
						float num = Mathf.Max(0.01f, Plugin.StabilizeSmoothTime.Value);
						smoothPivot = Vector3.Lerp(smoothPivot, position, 1f - Mathf.Exp((0f - Time.deltaTime) / num));
						return;
					}
				}
				smoothPivot = position;
				hasSmoothPivot = true;
			}
			else
			{
				hasSmoothPivot = false;
			}
		}

		private void LateUpdate()
		{
			if (!active || !RefsOk())
			{
				return;
			}
			try
			{
				if (Plugin.Mode.Value == CameraMode.Guide)
				{
					LateUpdateGuide();
				}
				else
				{
					ApplyDirect();
				}
			}
			catch (Exception ex)
			{
				LogThrottled("lateupdate", "LateUpdate: " + ex.Message);
			}
		}

		private bool RefsOk()
		{
			if ((Object)(object)pc != (Object)null)
			{
				return (Object)(object)cam != (Object)null;
			}
			return false;
		}

		private void ResolveRefs()
		{
			if ((Object)(object)pcr == (Object)null)
			{
				pcr = Object.FindObjectOfType<PlayerCameraReferences>();
			}
			if ((Object)(object)cam == (Object)null)
			{
				cam = (((Object)(object)pcr != (Object)null && (Object)(object)pcr.playerCamera != (Object)null) ? pcr.playerCamera : Camera.main);
			}
			if ((Object)(object)pc == (Object)null && PlayerCharacter.allPlayerCharacters != null)
			{
				PlayerCharacter val = null;
				for (int i = 0; i < PlayerCharacter.allPlayerCharacters.Count; i++)
				{
					PlayerCharacter val2 = PlayerCharacter.allPlayerCharacters[i];
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					try
					{
						if (((NetworkBehaviour)val2).isLocalPlayer)
						{
							pc = val2;
							break;
						}
					}
					catch (Exception)
					{
					}
					if ((Object)(object)val == (Object)null && (Object)(object)val2.cameraTransform != (Object)null && val2.cameraMinder != null)
					{
						val = val2;
					}
				}
				if ((Object)(object)pc == (Object)null)
				{
					pc = val;
				}
			}
			if ((Object)(object)pc != (Object)null)
			{
				minder = pc.cameraMinder;
				if ((Object)(object)cam == (Object)null && (Object)(object)pc.cameraTransform != (Object)null)
				{
					cam = ((Component)pc.cameraTransform).GetComponent<Camera>();
				}
				if ((Object)(object)pivot == (Object)null && (Object)(object)cam != (Object)null && (Object)(object)((Component)cam).transform.parent != (Object)null)
				{
					pivot = ((Component)cam).transform.parent;
				}
				if ((Object)(object)pivot == (Object)null && pc.registry != null && (Object)(object)pc.registry.headBone != (Object)null)
				{
					pivot = pc.registry.headBone;
				}
			}
		}

		private void Enter()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			active = true;
			suspended = false;
			origCamLocalPos = ((Component)cam).transform.localPosition;
			BuildCollisionMask();
			if (Plugin.Mode.Value == CameraMode.Guide)
			{
				if (minder != null)
				{
					gameGuide = minder._cameraGuide;
					minder.cameraGuide = guide;
				}
			}
			else
			{
				EnsureDriver();
			}
			if (Plugin.ShowBody.Value)
			{
				origHideTorso = pc.looks.hideLocalTorso;
				ApplyBody();
			}
			ManualLogSource logSource = Plugin.LogSource;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Third person ON (");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<CameraMode>(Plugin.Mode.Value);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")");
			}
			logSource.LogInfo(val);
		}

		private void Exit()
		{
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			active = false;
			suspended = false;
			try
			{
				if (Plugin.Mode.Value == CameraMode.Guide && minder != null)
				{
					if ((Object)(object)minder._cameraGuide == (Object)null || ((Il2CppObjectBase)minder._cameraGuide).Pointer == ((Il2CppObjectBase)guide).Pointer)
					{
						minder.cameraGuide = gameGuide;
					}
				}
				else
				{
					if ((Object)(object)driver != (Object)null)
					{
						((Behaviour)driver).enabled = false;
					}
					if ((Object)(object)cam != (Object)null)
					{
						((Component)cam).transform.localPosition = origCamLocalPos;
					}
				}
				RestoreBody();
				Plugin.LogSource.LogInfo((object)"Third person OFF");
			}
			catch (Exception ex)
			{
				ManualLogSource logSource = Plugin.LogSource;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(13, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Exit failed: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex);
				}
				logSource.LogError(val);
			}
		}

		private void EnsureDriver()
		{
			if (!((Object)(object)driver != (Object)null) && !((Object)(object)cam == (Object)null))
			{
				driver = ((Il2CppObjectBase)((Component)cam).gameObject.AddComponent(Il2CppType.Of<CameraDriver>())).TryCast<CameraDriver>();
				if ((Object)(object)driver != (Object)null)
				{
					driver.owner = this;
				}
			}
		}

		private void BuildCollisionMask()
		{
			int num = 4;
			if ((Object)(object)pc != (Object)null)
			{
				Il2CppArrayBase<Collider> componentsInChildren = ((Component)pc).GetComponentsInChildren<Collider>(true);
				if (componentsInChildren != null)
				{
					for (int i = 0; i < componentsInChildren.Count; i++)
					{
						if ((Object)(object)componentsInChildren[i] != (Object)null)
						{
							num |= 1 << ((Component)componentsInChildren[i]).gameObject.layer;
						}
					}
				}
				num |= 1 << ((Component)pc).gameObject.layer;
			}
			collisionMask = ~num;
		}

		private int CollideMode()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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)
			if (collideMode != -1)
			{
				return collideMode;
			}
			Vector3 val = (((Object)(object)pivot != (Object)null) ? pivot.position : Vector3.zero);
			Ray val2 = default(Ray);
			((Ray)(ref val2))..ctor(val, Vector3.down);
			RaycastHit val3 = default(RaycastHit);
			try
			{
				Physics.SphereCast(val2, 0.1f, ref val3, 1f, collisionMask, (QueryTriggerInteraction)1);
				collideMode = 1;
			}
			catch (Exception)
			{
				collideMode = -2;
			}
			if (collideMode == -2)
			{
				try
				{
					Physics.Raycast(val2, ref val3, 1f, collisionMask, (QueryTriggerInteraction)1);
					collideMode = 2;
				}
				catch (Exception)
				{
					collideMode = 0;
				}
			}
			if (collideMode == 0)
			{
				Plugin.LogSource.LogWarning((object)"No usable physics query found (all stripped); camera collision disabled.");
			}
			else
			{
				ManualLogSource logSource = Plugin.LogSource;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(39, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("Collision probe: mode ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<int>(collideMode);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" (1=sphere,2=ray)");
				}
				logSource.LogInfo(val4);
			}
			return collideMode;
		}

		internal bool ComputeBoom(out Vector3 pos, out Quaternion rot)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0036: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: 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_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			pos = default(Vector3);
			rot = default(Quaternion);
			if (!RefsOk())
			{
				return false;
			}
			Vector3 val = (((Object)(object)pivot != (Object)null) ? pivot.position : (((Component)pc).transform.position + Vector3.up * 1.5f));
			if (Plugin.Stabilize.Value && hasSmoothPivot)
			{
				val = Vector3.Lerp(val, smoothPivot, Mathf.Clamp01(Plugin.StabilizeAmount.Value));
			}
			rot = ((Component)cam).transform.rotation;
			if (Plugin.LevelHorizon.Value)
			{
				Vector3 eulerAngles = ((Quaternion)(ref rot)).eulerAngles;
				rot = Quaternion.Euler(eulerAngles.x, eulerAngles.y, 0f);
			}
			Vector3 val2 = rot * Vector3.forward;
			Vector3 val3 = rot * Vector3.right;
			Vector3 val4 = val + Vector3.up * Plugin.Height.Value + val3 * Plugin.Shoulder.Value;
			float num = curDistance;
			Vector3 val5 = val4 - val2 * num;
			if (Plugin.Collision.Value && CollideMode() != 0)
			{
				Vector3 val6 = val5 - val4;
				Vector3 normalized = ((Vector3)(ref val6)).normalized;
				float num2 = 0.25f;
				RaycastHit val7 = default(RaycastHit);
				bool flag = ((collideMode != 1) ? Physics.Raycast(val4, normalized, ref val7, num, collisionMask, (QueryTriggerInteraction)1) : Physics.SphereCast(val4, Plugin.CollisionRadius.Value, normalized, ref val7, num, collisionMask, (QueryTriggerInteraction)1));
				if (flag && ((RaycastHit)(ref val7)).distance < num)
				{
					val5 = val4 + normalized * Mathf.Max(((RaycastHit)(ref val7)).distance, num2);
				}
			}
			pos = val5;
			return true;
		}

		private void LateUpdateGuide()
		{
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			if (minder == null)
			{
				return;
			}
			Transform cameraGuide = minder._cameraGuide;
			if ((Object)(object)cameraGuide == (Object)null || ((Il2CppObjectBase)cameraGuide).Pointer == ((Il2CppObjectBase)guide).Pointer)
			{
				suspended = false;
				if ((Object)(object)cameraGuide == (Object)null || ((Il2CppObjectBase)cameraGuide).Pointer != ((Il2CppObjectBase)guide).Pointer)
				{
					minder.cameraGuide = guide;
				}
			}
			else
			{
				if ((Object)(object)gameGuide == (Object)null || ((Il2CppObjectBase)cameraGuide).Pointer != ((Il2CppObjectBase)gameGuide).Pointer)
				{
					suspended = true;
					gameGuide = cameraGuide;
					return;
				}
				suspended = false;
				minder.cameraGuide = guide;
			}
			suspended = false;
			if (ComputeBoom(out var pos, out var rot))
			{
				guide.SetPositionAndRotation(pos, rot);
			}
		}

		internal void ApplyDirect()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (ComputeBoom(out var pos, out var rot))
			{
				((Component)cam).transform.SetPositionAndRotation(pos, rot);
			}
		}

		private void ApplyBody()
		{
			if (!((Object)(object)pc == (Object)null) && pc.looks != null)
			{
				if (!bodyApplied)
				{
					pc.looks.SetBodyToRemoteMode();
				}
				if (pc.looks.hideLocalTorso)
				{
					pc.looks.SetHideLocalTorso(false);
				}
				SetHeadVisible(!Plugin.HideHead.Value);
				bodyApplied = true;
			}
		}

		private void RestoreBody()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			if ((Object)(object)pc == (Object)null || pc.looks == null || !bodyApplied)
			{
				return;
			}
			try
			{
				SetHeadVisible(visible: true);
				pc.looks.SetBodyToLocalMode();
				if (pc.looks.hideLocalTorso != origHideTorso)
				{
					pc.looks.SetHideLocalTorso(origHideTorso);
				}
				bodyApplied = false;
			}
			catch (Exception ex)
			{
				ManualLogSource logSource = Plugin.LogSource;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(13, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("RestoreBody: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				logSource.LogWarning(val);
			}
		}

		private void SetHeadVisible(bool visible)
		{
			Il2CppReferenceArray<LooksRenderer> headRenderers = pc.looks.headRenderers;
			if (headRenderers == null)
			{
				return;
			}
			for (int i = 0; i < ((Il2CppArrayBase<LooksRenderer>)(object)headRenderers).Count; i++)
			{
				if (((Il2CppArrayBase<LooksRenderer>)(object)headRenderers)[i] != null && (Object)(object)((Il2CppArrayBase<LooksRenderer>)(object)headRenderers)[i].renderer != (Object)null)
				{
					((Il2CppArrayBase<LooksRenderer>)(object)headRenderers)[i].renderer.enabled = visible;
				}
			}
		}

		private void OnGUI()
		{
			//IL_0054: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (active && Plugin.ShowStatus.Value)
				{
					Rect val = default(Rect);
					((Rect)(ref val))..ctor(12f, (float)(Screen.height - 34), 340f, 22f);
					string text = $"3rd person [{Plugin.ToggleKey.Value}]  zoom:{curDistance:0.0}m{(suspended ? " (cutscene)" : "")}";
					GUI.color = new Color(0f, 0f, 0f, 0.7f);
					GUI.Label(new Rect(((Rect)(ref val)).x + 1f, ((Rect)(ref val)).y + 1f, ((Rect)(ref val)).width, ((Rect)(ref val)).height), text);
					GUI.color = Color.white;
					GUI.Label(val, text);
				}
			}
			catch (Exception ex)
			{
				LogThrottled("gui", "OnGUI: " + ex.Message);
			}
		}

		private void LogThrottled(string key, string msg)
		{
			if (!(lastError == key) || !(Time.unscaledTime - lastErrorTime < 5f))
			{
				lastError = key;
				lastErrorTime = Time.unscaledTime;
				Plugin.LogSource.LogError((object)msg);
			}
		}

		private void Dump()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)pc == (Object)null)
			{
				Plugin.LogSource.LogInfo((object)"Dump: no local player yet");
				return;
			}
			Plugin.LogSource.LogInfo((object)"=== ThirdPerson dump ===");
			ManualLogSource logSource = Plugin.LogSource;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(40, 5, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("cam=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)(object)cam != (Object)null) ? ((Object)cam).name : "null");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" pivot=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)(object)pivot != (Object)null) ? ((Object)pivot).name : "null");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("camLocal=");
				Camera obj = cam;
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Vector3?>((obj != null) ? new Vector3?(((Component)obj).transform.localPosition) : ((Vector3?)null));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" collideMode=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(collideMode);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" mask=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(collisionMask);
			}
			logSource.LogInfo(val);
			DumpTransform(((Component)pc).transform, 0);
		}

		private void DumpTransform(Transform t, int depth)
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			Renderer component = ((Component)t).GetComponent<Renderer>();
			string text = (((Object)(object)component != (Object)null) ? $" renderer.enabled={component.enabled} layer={((Component)t).gameObject.layer}" : $" layer={((Component)t).gameObject.layer}");
			ManualLogSource logSource = Plugin.LogSource;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(0, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(new string(' ', depth * 2));
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Object)t).name);
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
			}
			logSource.LogInfo(val);
			for (int i = 0; i < t.childCount; i++)
			{
				DumpTransform(t.GetChild(i), depth + 1);
			}
		}

		private void OnDestroy()
		{
			if (active)
			{
				Exit();
			}
		}
	}
	public class CameraDriver : MonoBehaviour
	{
		internal ThirdPersonComponent owner;

		public CameraDriver(IntPtr ptr)
			: base(ptr)
		{
		}

		public CameraDriver()
			: base(ClassInjector.DerivedConstructorPointer<CameraDriver>())
		{
			ClassInjector.DerivedConstructorBody((Il2CppObjectBase)(object)this);
		}

		private void OnPreRender()
		{
			try
			{
				owner?.ApplyDirect();
			}
			catch (Exception)
			{
			}
		}
	}
}