Decompiled source of FreeCamera v0.1.5

FreeCamera.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using StolenRealmModAPI;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("FreeCamera")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+52158c7d25a1953ef0dc1b873b569982776fd2a0")]
[assembly: AssemblyProduct("FreeCamera")]
[assembly: AssemblyTitle("FreeCamera")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 FreeCamera
{
	[HarmonyPatch(typeof(CameraController), "Update")]
	internal static class CameraController_Update_Patch
	{
		private static void Prefix(CameraController __instance)
		{
			try
			{
				FreeCam.Apply(__instance);
			}
			catch (Exception e)
			{
				FreeCam.LogOnce(e);
			}
		}
	}
	internal static class FreeCam
	{
		private sealed class State
		{
			public readonly Vector3 OffsetPers;

			public readonly Vector3 OffsetOrtho;

			public readonly Vector3 RotPers;

			public readonly Vector3 RotOrtho;

			public readonly RFX4_CameraShake Shake;

			public Vector3 ShakeRot;

			public bool Modified;

			public State(CameraController cc)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0114: Unknown result type (might be due to invalid IL or missing references)
				//IL_011f: 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)
				OffsetPers = FreeCam.OffsetPers.Invoke(cc);
				OffsetOrtho = FreeCam.OffsetOrtho.Invoke(cc);
				RotPers = FreeCam.RotPers.Invoke(cc);
				RotOrtho = FreeCam.RotOrtho.Invoke(cc);
				Shake = ((Component)Cam.Invoke(cc)).GetComponent<RFX4_CameraShake>();
				if ((Object)(object)Shake != (Object)null)
				{
					ShakeRot = ShakeRestRot.Invoke(Shake);
					ShakeSmoother shakeSmoother = ((Component)cc).gameObject.GetComponent<ShakeSmoother>();
					if ((Object)(object)shakeSmoother == (Object)null)
					{
						shakeSmoother = ((Component)cc).gameObject.AddComponent<ShakeSmoother>();
					}
					shakeSmoother.Controller = cc;
					shakeSmoother.Shake = Shake;
					shakeSmoother.CamT = ((Component)Cam.Invoke(cc)).transform;
				}
				Plugin.ModLog.LogInfo((object)($"Camera found: perspective offset {OffsetPers} tilt {RotPers}, " + $"ortho offset {OffsetOrtho} tilt {RotOrtho}, rotationSpeed {RotationSpeed.Invoke(cc)}, " + $"rotationSlerpSpeed {SlerpSpeedRef.Invoke(cc)}."));
			}
		}

		private static readonly FieldRef<CameraController, Camera> Cam = AccessTools.FieldRefAccess<CameraController, Camera>("cam");

		private static readonly FieldRef<CameraController, Vector3> OffsetPers = AccessTools.FieldRefAccess<CameraController, Vector3>("camOffsetPers");

		private static readonly FieldRef<CameraController, Vector3> OffsetOrtho = AccessTools.FieldRefAccess<CameraController, Vector3>("camOffsetOrtho");

		private static readonly FieldRef<CameraController, Vector3> RotPers = AccessTools.FieldRefAccess<CameraController, Vector3>("camRotPers");

		private static readonly FieldRef<CameraController, Vector3> RotOrtho = AccessTools.FieldRefAccess<CameraController, Vector3>("camRotOrtho");

		private static readonly FieldRef<CameraController, Vector3> GoalRotVert = AccessTools.FieldRefAccess<CameraController, Vector3>("goalRotVert");

		private static readonly FieldRef<CameraController, bool> DraggingRight = AccessTools.FieldRefAccess<CameraController, bool>("isDraggingRightMouse");

		private static readonly FieldRef<CameraController, bool> AllowControls = AccessTools.FieldRefAccess<CameraController, bool>("allowCameraControls");

		private static readonly FieldRef<CameraController, float> SlerpSpeedRef = AccessTools.FieldRefAccess<CameraController, float>("rotationSlerpSpeed");

		private static readonly FieldRef<CameraController, Vector3> Speed = AccessTools.FieldRefAccess<CameraController, Vector3>("speed");

		private static readonly FieldRef<CameraController, float> RotationSpeed = AccessTools.FieldRefAccess<CameraController, float>("rotationSpeed");

		private static readonly FieldRef<RFX4_CameraShake, Vector3> ShakeRestRot = AccessTools.FieldRefAccess<RFX4_CameraShake, Vector3>("originalCamRot");

		private static readonly ConditionalWeakTable<CameraController, State> States = new ConditionalWeakTable<CameraController, State>();

		private static float _pitchDelta;

		private static float _shownDelta;

		internal static float PitchStep;

		internal static int PitchStepFrame = -1;

		private static bool _mouseAxisWorks = true;

		private static float _lastMouseY;

		private static string _lastError;

		private const float LegacyDegreesPerUnit = 3f;

		private static int _dragFrames;

		private static float _sumGameDy;

		private static float _sumLegacyDy;

		private static float _sumTilt;

		internal static Vector3 GoalRot(CameraController cc)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			return GoalRotVert.Invoke(cc);
		}

		internal static float SlerpSpeed(CameraController cc)
		{
			return SlerpSpeedRef.Invoke(cc);
		}

		internal static bool CaptureRunning()
		{
			SequenceCaptureManager instance = SequenceCaptureManager.Instance;
			if ((Object)(object)instance != (Object)null)
			{
				return instance.SequenceCaptureRunning;
			}
			return false;
		}

		internal static void Apply(CameraController cc)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: 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_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: 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_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: 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_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: 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_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_0256: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			Camera val = Cam.Invoke(cc);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			State value = States.GetValue(cc, (CameraController c) => new State(c));
			float legacyDy = MouseDeltaY();
			if (!Plugin.Enabled.Value)
			{
				if (value.Modified)
				{
					Restore(cc, value, val.orthographic);
				}
			}
			else if (!CaptureRunning())
			{
				bool orthographic = val.orthographic;
				Vector3 val2 = (orthographic ? value.RotOrtho : value.RotPers);
				if (ControlsAllowed(cc))
				{
					ReadInput(cc, legacyDy);
				}
				float num = Mathf.Min(Plugin.MaxPitch.Value, 89.9f);
				float num2 = Mathf.Min(Plugin.MinPitch.Value, num);
				_pitchDelta = Mathf.Clamp(val2.x + _pitchDelta, num2, num) - val2.x;
				float shownDelta = _shownDelta;
				float value2 = Plugin.TiltSmoothing.Value;
				_shownDelta = ((value2 <= 0f) ? _pitchDelta : Mathf.Lerp(_shownDelta, _pitchDelta, 1f - Mathf.Exp((0f - Time.unscaledDeltaTime) / value2)));
				float num3 = val2.x + _shownDelta;
				float value3 = Plugin.Distance.Value;
				Vector3 val3 = Orbit(orthographic ? value.OffsetOrtho : value.OffsetPers, val2, val2.x + shownDelta, value3);
				OffsetPers.Invoke(cc) = Orbit(value.OffsetPers, value.RotPers, value.RotPers.x + _shownDelta, value3);
				OffsetOrtho.Invoke(cc) = Orbit(value.OffsetOrtho, value.RotOrtho, value.RotOrtho.x + _shownDelta, value3);
				GoalRotVert.Invoke(cc) = new Vector3(num3, val2.y, val2.z);
				float num4 = _shownDelta - shownDelta;
				if (value.Modified && num4 != 0f)
				{
					Transform transform = ((Component)val).transform;
					Vector3 val4 = (orthographic ? OffsetOrtho.Invoke(cc) : OffsetPers.Invoke(cc));
					transform.localPosition += val4 - val3;
					transform.localRotation *= Quaternion.Euler(num4, 0f, 0f);
					PitchStep = num4;
					PitchStepFrame = Time.frameCount;
				}
				if ((Object)(object)value.Shake != (Object)null)
				{
					ShakeRestRot.Invoke(value.Shake) = GoalRotVert.Invoke(cc);
				}
				value.Modified = true;
			}
		}

		private static bool ControlsAllowed(CameraController cc)
		{
			if (!AllowControls.Invoke(cc))
			{
				return false;
			}
			GUIManager instance = GUIManager.instance;
			if (!((Object)(object)instance == (Object)null))
			{
				return !instance.InMenus;
			}
			return true;
		}

		private static void ReadInput(CameraController cc, float legacyDy)
		{
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: 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)
			bool flag = DraggingRight.Invoke(cc);
			if (Plugin.MouseTilt.Value && flag)
			{
				float y = Speed.Invoke(cc).y;
				float num = ((y != 0f) ? (y * RotationSpeed.Invoke(cc)) : (legacyDy * 3f));
				float num2 = (Plugin.InvertMouse.Value ? 1f : (-1f));
				_pitchDelta += num2 * num * Plugin.MouseSensitivity.Value;
				TrackDrag(y, legacyDy, num2 * num * Plugin.MouseSensitivity.Value);
			}
			else if (_dragFrames > 0)
			{
				EndDrag();
			}
			MessageWindowManager instance = MessageWindowManager.instance;
			if (!((Object)(object)instance != (Object)null) || !instance.TextInputIsFocused)
			{
				float num3 = Plugin.KeyTiltSpeed.Value * Time.unscaledDeltaTime;
				KeyboardShortcut value = Plugin.TiltUpKey.Value;
				if (((KeyboardShortcut)(ref value)).IsPressed())
				{
					_pitchDelta -= num3;
				}
				value = Plugin.TiltDownKey.Value;
				if (((KeyboardShortcut)(ref value)).IsPressed())
				{
					_pitchDelta += num3;
				}
				value = Plugin.ResetKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					_pitchDelta = 0f;
				}
			}
		}

		private static void TrackDrag(float gameDy, float legacyDy, float tilt)
		{
			_dragFrames++;
			_sumGameDy += gameDy;
			_sumLegacyDy += legacyDy;
			_sumTilt += tilt;
		}

		private static void EndDrag()
		{
			//IL_0026: 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)
			if (Plugin.LogDrags.Value)
			{
				GUIManager instance = GUIManager.instance;
				string arg = (((Object)(object)instance != (Object)null) ? ((object)instance.CurrentGuiState/*cast due to .constrained prefix*/).ToString() : "?");
				Plugin.ModLog.LogInfo((object)($"Drag in {arg}: {_dragFrames} frames, game mouseY {_sumGameDy:0.##}, " + $"legacy mouseY {_sumLegacyDy:0.##}, tilt {_sumTilt:+0.#;-0.#;0}°, now {_pitchDelta:+0.#;-0.#;0}° from default."));
			}
			_dragFrames = 0;
			_sumGameDy = (_sumLegacyDy = (_sumTilt = 0f));
		}

		private static Vector3 Orbit(Vector3 offset, Vector3 rotEuler, float pitch, float distScale)
		{
			//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_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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)
			//IL_0044: 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_004e: 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_0054: 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)
			Vector3 val = Quaternion.Euler(rotEuler) * Vector3.forward;
			float num = 0f - Vector3.Dot(offset, val);
			if (num < 0.01f)
			{
				num = ((Vector3)(ref offset)).magnitude;
			}
			Vector3 val2 = offset + val * num;
			Vector3 val3 = Quaternion.Euler(pitch, rotEuler.y, rotEuler.z) * Vector3.forward;
			return val2 - val3 * (num * distScale);
		}

		private static void Restore(CameraController cc, State state, bool ortho)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			OffsetPers.Invoke(cc) = state.OffsetPers;
			OffsetOrtho.Invoke(cc) = state.OffsetOrtho;
			GoalRotVert.Invoke(cc) = (ortho ? state.RotOrtho : state.RotPers);
			if ((Object)(object)state.Shake != (Object)null)
			{
				ShakeRestRot.Invoke(state.Shake) = state.ShakeRot;
			}
			state.Modified = false;
		}

		private static float MouseDeltaY()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			float y = Input.mousePosition.y;
			float result = (y - _lastMouseY) * 0.1f;
			_lastMouseY = y;
			if (_mouseAxisWorks)
			{
				try
				{
					return Input.GetAxisRaw("Mouse Y");
				}
				catch (ArgumentException)
				{
					_mouseAxisWorks = false;
					Plugin.ModLog.LogWarning((object)"No 'Mouse Y' axis; using cursor movement.");
				}
			}
			return result;
		}

		internal static void LogOnce(Exception e)
		{
			string text = e.ToString();
			if (!(text == _lastError))
			{
				_lastError = text;
				Plugin.ModLog.LogError((object)text);
			}
		}
	}
	[BepInPlugin("com.helvetica.freecamera", "Free Camera", "0.1.5")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : StolenRealmMod
	{
		public const string PluginGuid = "com.helvetica.freecamera";

		public const string PluginName = "Free Camera";

		public const string PluginVersion = "0.1.5";

		internal static ManualLogSource ModLog;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<bool> MouseTilt;

		internal static ConfigEntry<float> MouseSensitivity;

		internal static ConfigEntry<bool> InvertMouse;

		internal static ConfigEntry<float> TiltSmoothing;

		internal static ConfigEntry<KeyboardShortcut> TiltUpKey;

		internal static ConfigEntry<KeyboardShortcut> TiltDownKey;

		internal static ConfigEntry<float> KeyTiltSpeed;

		internal static ConfigEntry<KeyboardShortcut> ResetKey;

		internal static ConfigEntry<float> MinPitch;

		internal static ConfigEntry<float> MaxPitch;

		internal static ConfigEntry<float> Distance;

		internal static ConfigEntry<bool> LogDrags;

		protected override void OnModLoaded()
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Expected O, but got Unknown
			//IL_0198: 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_01e4: Expected O, but got Unknown
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Expected O, but got Unknown
			//IL_0254: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Expected O, but got Unknown
			ModLog = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Turn Free Camera on or off. Off puts the camera back at the game's normal angle.");
			MouseTilt = ((BaseUnityPlugin)this).Config.Bind<bool>("Mouse", "TiltWithRightDrag", true, "While holding right mouse to rotate, moving the mouse up/down also tilts the camera.");
			MouseSensitivity = ((BaseUnityPlugin)this).Config.Bind<float>("Mouse", "TiltSensitivity", 1f, new ConfigDescription("Tilt speed for mouse movement. 1 = same speed as left/right rotation.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 3f), Array.Empty<object>()));
			InvertMouse = ((BaseUnityPlugin)this).Config.Bind<bool>("Mouse", "Invert", false, "Flip the tilt direction for mouse movement.");
			TiltSmoothing = ((BaseUnityPlugin)this).Config.Bind<float>("Mouse", "TiltSmoothing", 0.05f, new ConfigDescription("Seconds for the tilt to catch up with the mouse/keys. 0 = instant.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.5f), Array.Empty<object>()));
			TiltUpKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keys", "TiltUp", new KeyboardShortcut((KeyCode)280, Array.Empty<KeyCode>()), "Hold to tilt toward the horizon. Set to None to disable.");
			TiltDownKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keys", "TiltDown", new KeyboardShortcut((KeyCode)281, Array.Empty<KeyCode>()), "Hold to tilt toward top-down. Set to None to disable.");
			KeyTiltSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Keys", "TiltSpeed", 60f, new ConfigDescription("Degrees per second when tilting with keys.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 180f), Array.Empty<object>()));
			ResetKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keys", "ResetTilt", new KeyboardShortcut((KeyCode)278, Array.Empty<KeyCode>()), "Put the tilt back to the game's default angle.");
			MinPitch = ((BaseUnityPlugin)this).Config.Bind<float>("Limits", "MinPitch", 10f, new ConfigDescription("Lowest angle in degrees (0 = level with the ground).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>()));
			MaxPitch = ((BaseUnityPlugin)this).Config.Bind<float>("Limits", "MaxPitch", 89f, new ConfigDescription("Highest angle in degrees (90 = straight down).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(30f, 90f), Array.Empty<object>()));
			Distance = ((BaseUnityPlugin)this).Config.Bind<float>("Limits", "Distance", 1f, new ConfigDescription("Camera distance from the focus point, as a multiple of the game's default.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 2.5f), Array.Empty<object>()));
			LogDrags = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "LogDrags", false, "Write one line per right-drag to LogOutput.log (game state, mouse input, tilt applied). For troubleshooting.");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Free Camera v0.1.5 loaded.");
		}
	}
	[DefaultExecutionOrder(10000)]
	internal class ShakeSmoother : MonoBehaviour
	{
		internal CameraController Controller;

		internal RFX4_CameraShake Shake;

		internal Transform CamT;

		private Quaternion _base;

		private bool _wasShaking;

		private void LateUpdate()
		{
			try
			{
				Step();
			}
			catch (Exception e)
			{
				FreeCam.LogOnce(e);
			}
		}

		private void Step()
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Controller == (Object)null || (Object)(object)Shake == (Object)null || (Object)(object)CamT == (Object)null || !Plugin.Enabled.Value || FreeCam.CaptureRunning())
			{
				_wasShaking = false;
				return;
			}
			bool flag = ShakeAccess.IsShaking(Shake);
			if (!flag && !_wasShaking)
			{
				_base = CamT.localRotation;
				return;
			}
			if (FreeCam.PitchStepFrame == Time.frameCount)
			{
				_base *= Quaternion.Euler(FreeCam.PitchStep, 0f, 0f);
			}
			_base = Quaternion.Slerp(_base, Quaternion.Euler(FreeCam.GoalRot(Controller)), Time.deltaTime * FreeCam.SlerpSpeed(Controller));
			Vector3 val = (flag ? ShakeAccess.Jitter(Shake) : Vector3.zero);
			CamT.localRotation = Quaternion.Euler(((Quaternion)(ref _base)).eulerAngles + val);
			_wasShaking = flag;
		}
	}
	[HarmonyPatch(typeof(RFX4_CameraShake), "Shake")]
	internal static class RFX4_CameraShake_Shake_Patch
	{
		private static void Postfix(RFX4_CameraShake __instance, IEnumerator __result)
		{
			ShakeAccess.Track(__instance, __result);
		}
	}
	internal static class ShakeAccess
	{
		private sealed class Box
		{
			public IEnumerator Routine;
		}

		private static readonly FieldRef<RFX4_CameraShake, bool> IsShakingRef = AccessTools.FieldRefAccess<RFX4_CameraShake, bool>("isShaking");

		private static readonly ConditionalWeakTable<RFX4_CameraShake, Box> Routines = new ConditionalWeakTable<RFX4_CameraShake, Box>();

		private static FieldInfo _jitterField;

		private static bool _warned;

		internal static bool IsShaking(RFX4_CameraShake s)
		{
			return IsShakingRef.Invoke(s);
		}

		internal static void Track(RFX4_CameraShake s, IEnumerator routine)
		{
			if ((Object)(object)s == (Object)null || routine == null)
			{
				return;
			}
			if (_jitterField == null || _jitterField.DeclaringType != routine.GetType())
			{
				_jitterField = AccessTools.GetDeclaredFields(routine.GetType()).Find((FieldInfo f) => f.FieldType == typeof(Vector3) && f.Name.Contains("oldRotation"));
				if (_jitterField == null && !_warned)
				{
					_warned = true;
					Plugin.ModLog.LogWarning((object)"Camera shake layout changed; shakes will keep the tilt but lose their wobble.");
				}
			}
			Routines.GetOrCreateValue(s).Routine = routine;
		}

		internal static Vector3 Jitter(RFX4_CameraShake s)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (_jitterField == null || !Routines.TryGetValue(s, out var value) || value.Routine == null)
			{
				return Vector3.zero;
			}
			if (value.Routine.GetType() != _jitterField.DeclaringType)
			{
				return Vector3.zero;
			}
			return (Vector3)_jitterField.GetValue(value.Routine);
		}
	}
}