Decompiled source of Unswayed v1.0.2

Unswayed.dll

Decompiled 2 days 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 HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using Unswayed.Configuration;
using Unswayed.Core;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("Unswayed")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+0da1cae3147c46d2bc627672b90c5f98e3fbfcff")]
[assembly: AssemblyProduct("Unswayed")]
[assembly: AssemblyTitle("Unswayed")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 Unswayed
{
	[BepInPlugin("djc.valheim.unswayed", "Unswayed", "1.0.2")]
	public sealed class UnswayedPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "djc.valheim.unswayed";

		public const string PluginName = "Unswayed";

		public const string PluginVersion = "1.0.2";

		private Harmony? _harmony;

		public static UnswayedPlugin? Instance { get; private set; }

		private void Awake()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			PluginConfig.BindConfig(((BaseUnityPlugin)this).Config);
			_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "djc.valheim.unswayed");
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} v{1} initialized. Bobbing Suppression: {2} (Damping: {3:F2}), Dungeon Ergonomics: {4}, Shake Scale: {5:F2}. Hotkey: [{6}]", "Unswayed", "1.0.2", PluginConfig.EnableBobSuppression.Value, PluginConfig.VerticalDamping.Value, PluginConfig.EnableDungeonErgonomics.Value, PluginConfig.CameraShakeScale.Value, PluginConfig.ToggleHotkey.Value));
		}

		private void Update()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			if (PluginConfig.ToggleHotkey != null && Input.GetKeyDown(PluginConfig.ToggleHotkey.Value))
			{
				StabilizerManager.ToggleStabilization(out string message);
				((BaseUnityPlugin)this).Logger.LogInfo((object)message);
				if ((Object)(object)Console.instance != (Object)null)
				{
					((Terminal)Console.instance).AddString(message);
				}
			}
		}

		private void OnDestroy()
		{
			Harmony? harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Instance = null;
		}
	}
}
namespace Unswayed.Patches
{
	[HarmonyPatch(typeof(GameCamera))]
	public static class CameraStabilizerPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("GetCameraBaseOffset")]
		public static void GetCameraBaseOffsetPostfix(GameCamera __instance, Player player, ref Vector3 __result)
		{
			//IL_0061: 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)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			if (!PluginConfig.IsModEnabled.Value || !PluginConfig.EnableBobSuppression.Value || ((Character)player).InBed() || ((Character)player).IsAttached() || ((Character)player).IsSitting())
			{
				return;
			}
			switch (PluginConfig.Mode.Value)
			{
			case SuppressionMode.RunningOnly:
				if (!((Character)player).IsRunning() && !((Character)player).IsWalking())
				{
					return;
				}
				break;
			case SuppressionMode.DungeonsOnly:
				if (!StabilizerManager.IsInDungeonOrTightSpace(__instance))
				{
					return;
				}
				break;
			}
			Vector3 val = Vector3.up * PluginConfig.StabilizedEyeHeight.Value;
			float num = Mathf.Clamp01(PluginConfig.VerticalDamping.Value);
			__result = Vector3.Lerp(__result, val, num);
		}

		[HarmonyPostfix]
		[HarmonyPatch("GetCameraPosition")]
		public static void GetCameraPositionPostfix(GameCamera __instance, float dt, ref Vector3 pos, ref Quaternion rot)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0043: 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_0056: 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_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			if (!PluginConfig.IsModEnabled.Value)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer))
			{
				return;
			}
			Vector3 val = (Object.op_Implicit((Object)(object)((Character)localPlayer).m_eye) ? ((Character)localPlayer).m_eye.position : (((Component)localPlayer).transform.position + Vector3.up * 1.6f));
			float num = (StabilizerManager.LastCameraDistance = Vector3.Distance(val, pos));
			bool flag = (StabilizerManager.IsTightSpace = num < PluginConfig.DungeonProximityThreshold.Value && num > 0.01f);
			if (!PluginConfig.EnableDungeonErgonomics.Value)
			{
				return;
			}
			if (PluginConfig.EnableMinDistanceClamp.Value && num < PluginConfig.MinCameraDistance.Value && num > 0.05f)
			{
				Vector3 val2 = pos - val;
				Vector3 val3 = ((Vector3)(ref val2)).normalized;
				if (val3 == Vector3.zero)
				{
					val3 = -((Component)localPlayer).transform.forward;
				}
				pos = val + val3 * PluginConfig.MinCameraDistance.Value;
				num = PluginConfig.MinCameraDistance.Value;
			}
			if (flag && PluginConfig.EnableCryptShoulderLift.Value)
			{
				float value = PluginConfig.DungeonProximityThreshold.Value;
				float num3 = Mathf.Clamp01(1f - num / value) * PluginConfig.ShoulderLiftAmount.Value;
				pos += Vector3.up * num3;
			}
			if (PluginConfig.DisableShipTilt.Value && __instance.m_shipCameraTilt)
			{
				Vector3 eulerAngles = ((Quaternion)(ref rot)).eulerAngles;
				eulerAngles.z = 0f;
				rot = Quaternion.Euler(eulerAngles);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("UpdateFOV")]
		public static void UpdateFOVPostfix(GameCamera __instance)
		{
			if (!PluginConfig.IsModEnabled.Value || !PluginConfig.EnableDungeonFovBoost.Value)
			{
				StabilizerManager.ResetFov(__instance);
			}
			else if (StabilizerManager.IsTightSpace && PluginConfig.DungeonFovBoost.Value > 0.1f)
			{
				float value = PluginConfig.DungeonFovBoost.Value;
				StabilizerManager.CurrentFovOffset = Mathf.MoveTowards(StabilizerManager.CurrentFovOffset, value, Time.deltaTime * 45f);
				Camera camera = __instance.m_camera;
				camera.fieldOfView += StabilizerManager.CurrentFovOffset;
			}
			else if (StabilizerManager.CurrentFovOffset > 0.01f)
			{
				StabilizerManager.CurrentFovOffset = Mathf.MoveTowards(StabilizerManager.CurrentFovOffset, 0f, Time.deltaTime * 30f);
				Camera camera2 = __instance.m_camera;
				camera2.fieldOfView += StabilizerManager.CurrentFovOffset;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch("UpdateCameraShake")]
		public static void UpdateCameraShakePrefix(GameCamera __instance)
		{
			if (PluginConfig.IsModEnabled.Value)
			{
				float num = Mathf.Clamp01(PluginConfig.CameraShakeScale.Value);
				if (num <= 0.001f)
				{
					__instance.m_shakeIntensity = 0f;
				}
				else if (num < 0.999f)
				{
					__instance.m_shakeIntensity *= num;
				}
			}
		}
	}
}
namespace Unswayed.Core
{
	public static class StabilizerManager
	{
		public static float LastCameraDistance { get; set; } = 4f;

		public static bool IsTightSpace { get; set; } = false;

		public static float OriginalBaseFov { get; set; } = 65f;

		public static float CurrentFovOffset { get; set; } = 0f;

		public static bool IsInDungeonOrTightSpace(GameCamera? camera)
		{
			if ((Object)(object)camera == (Object)null)
			{
				return false;
			}
			if (!IsTightSpace)
			{
				return camera.m_distance < PluginConfig.DungeonProximityThreshold.Value;
			}
			return true;
		}

		public static void ToggleStabilization(out string message)
		{
			PluginConfig.IsModEnabled.Value = !PluginConfig.IsModEnabled.Value;
			message = "[Unswayed] Camera stabilization is now " + (PluginConfig.IsModEnabled.Value ? "ENABLED" : "DISABLED") + ".";
		}

		public static void ResetFov(GameCamera camera)
		{
			if ((Object)(object)camera != (Object)null && (Object)(object)camera.m_camera != (Object)null && CurrentFovOffset > 0.01f)
			{
				camera.m_camera.fieldOfView = OriginalBaseFov;
				CurrentFovOffset = 0f;
			}
		}
	}
}
namespace Unswayed.Configuration
{
	public enum SuppressionMode
	{
		Always,
		RunningOnly,
		DungeonsOnly
	}
	public static class PluginConfig
	{
		public static ConfigEntry<bool> IsModEnabled;

		public static ConfigEntry<KeyCode> ToggleHotkey;

		public static ConfigEntry<bool> EnableBobSuppression;

		public static ConfigEntry<SuppressionMode> Mode;

		public static ConfigEntry<float> StabilizedEyeHeight;

		public static ConfigEntry<float> VerticalDamping;

		public static ConfigEntry<bool> EnableDungeonErgonomics;

		public static ConfigEntry<float> DungeonProximityThreshold;

		public static ConfigEntry<bool> EnableMinDistanceClamp;

		public static ConfigEntry<float> MinCameraDistance;

		public static ConfigEntry<bool> EnableCryptShoulderLift;

		public static ConfigEntry<float> ShoulderLiftAmount;

		public static ConfigEntry<bool> EnableDungeonFovBoost;

		public static ConfigEntry<float> DungeonFovBoost;

		public static ConfigEntry<float> CameraShakeScale;

		public static ConfigEntry<bool> DisableShipTilt;

		public static void BindConfig(ConfigFile config)
		{
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Expected O, but got Unknown
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Expected O, but got Unknown
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Expected O, but got Unknown
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Expected O, but got Unknown
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Expected O, but got Unknown
			IsModEnabled = config.Bind<bool>("1 - General", "Enabled", true, "Master toggle for Unswayed camera stabilization.");
			ToggleHotkey = config.Bind<KeyCode>("1 - General", "ToggleHotkey", (KeyCode)288, "In-game hotkey to quickly toggle camera stabilization on/off.");
			EnableBobSuppression = config.Bind<bool>("2 - Head-Bob Suppression", "EnableBobSuppression", true, "Decouples the camera base offset from the animated head bone, completely eliminating the 1.0 vertical running bounce.");
			Mode = config.Bind<SuppressionMode>("2 - Head-Bob Suppression", "SuppressionMode", SuppressionMode.Always, "When to suppress head-bobbing: Always, RunningOnly (only when sprinting/running), or DungeonsOnly.");
			StabilizedEyeHeight = config.Bind<float>("2 - Head-Bob Suppression", "StabilizedEyeHeight", 1.65f, new ConfigDescription("Stable vertical eye pivot height relative to player root transform.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1.2f, 2.2f), Array.Empty<object>()));
			VerticalDamping = config.Bind<float>("2 - Head-Bob Suppression", "VerticalDamping", 1f, new ConfigDescription("Amount of vertical bobbing suppression (1.0 = completely stable horizon, 0.5 = 50% reduced bounce, 0.0 = vanilla bounce).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			EnableDungeonErgonomics = config.Bind<bool>("3 - Dungeon & Crypt Ergonomics", "EnableDungeonErgonomics", true, "Enables adaptive camera behavior when compressed in tight corridors, burial crypts, and sunken crypts.");
			DungeonProximityThreshold = config.Bind<float>("3 - Dungeon & Crypt Ergonomics", "DungeonProximityThreshold", 1.8f, new ConfigDescription("Camera distance threshold (meters) below which dungeon/tight-space adaptations activate.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 3f), Array.Empty<object>()));
			EnableMinDistanceClamp = config.Bind<bool>("3 - Dungeon & Crypt Ergonomics", "EnableMinDistanceClamp", true, "Prevents the camera collision raycast from crushing point-blank into the player's skull.");
			MinCameraDistance = config.Bind<float>("3 - Dungeon & Crypt Ergonomics", "MinCameraDistance", 0.9f, new ConfigDescription("Minimum camera distance in tight spaces to prevent the Viking mesh from filling the entire screen.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 2f), Array.Empty<object>()));
			EnableCryptShoulderLift = config.Bind<bool>("3 - Dungeon & Crypt Ergonomics", "EnableCryptShoulderLift", true, "Gently elevates the camera over the Viking's shoulders when camera distance drops in tight crypts, preserving forward visibility.");
			ShoulderLiftAmount = config.Bind<float>("3 - Dungeon & Crypt Ergonomics", "ShoulderLiftAmount", 0.35f, new ConfigDescription("Maximum vertical shoulder lift in tight spaces.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 0.8f), Array.Empty<object>()));
			EnableDungeonFovBoost = config.Bind<bool>("3 - Dungeon & Crypt Ergonomics", "EnableDungeonFovBoost", true, "Dynamically expands FOV when navigating tight crypts to widen peripheral vision and reduce nausea.");
			DungeonFovBoost = config.Bind<float>("3 - Dungeon & Crypt Ergonomics", "DungeonFovBoost", 15f, new ConfigDescription("Additional FOV degrees added in tight crypt spaces (e.g. 65° -> 80°).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), Array.Empty<object>()));
			CameraShakeScale = config.Bind<float>("4 - Motion Sickness Toggles", "CameraShakeScale", 0f, new ConfigDescription("Global camera shake multiplier (0.0 = completely off, 0.2 = subtle rumble, 1.0 = vanilla full shake).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			DisableShipTilt = config.Bind<bool>("4 - Motion Sickness Toggles", "DisableShipTilt", false, "Suppresses camera roll/tilt when sailing on boats (prevents seasickness).");
		}
	}
}
namespace Unswayed.Commands
{
	[HarmonyPatch(typeof(Terminal), "InitTerminal")]
	public static class UnswayedCommand
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__0_0;

			internal void <AddTerminalCommands>b__0_0(ConsoleEventArgs args)
			{
				if (args.Length < 2)
				{
					PrintStatus(args.Context);
					return;
				}
				switch (args[1].ToLowerInvariant())
				{
				case "toggle":
				{
					StabilizerManager.ToggleStabilization(out string message);
					args.Context.AddString(message);
					break;
				}
				case "status":
					PrintStatus(args.Context);
					break;
				case "height":
				{
					if (args.Length >= 3 && float.TryParse(args[2], out var result2))
					{
						PluginConfig.StabilizedEyeHeight.Value = Mathf.Clamp(result2, 1.2f, 2.2f);
						args.Context.AddString($"[Unswayed] Stabilized eye height set to: {PluginConfig.StabilizedEyeHeight.Value:F2}m");
					}
					else
					{
						args.Context.AddString($"[Unswayed] Current height: {PluginConfig.StabilizedEyeHeight.Value:F2}m. Usage: unswayed height <1.2 - 2.2>");
					}
					break;
				}
				case "damping":
				{
					if (args.Length >= 3 && float.TryParse(args[2], out var result3))
					{
						PluginConfig.VerticalDamping.Value = Mathf.Clamp01(result3);
						args.Context.AddString($"[Unswayed] Vertical damping set to: {PluginConfig.VerticalDamping.Value:F2} (1.0 = stable, 0.0 = vanilla)");
					}
					else
					{
						args.Context.AddString($"[Unswayed] Current damping: {PluginConfig.VerticalDamping.Value:F2}. Usage: unswayed damping <0.0 - 1.0>");
					}
					break;
				}
				case "shake":
				{
					if (args.Length >= 3 && float.TryParse(args[2], out var result))
					{
						PluginConfig.CameraShakeScale.Value = Mathf.Clamp01(result);
						args.Context.AddString($"[Unswayed] Camera shake scale set to: {PluginConfig.CameraShakeScale.Value:F2}");
					}
					else
					{
						args.Context.AddString($"[Unswayed] Current shake scale: {PluginConfig.CameraShakeScale.Value:F2}. Usage: unswayed shake <0.0 - 1.0>");
					}
					break;
				}
				default:
					args.Context.AddString("[Unswayed] Available commands: toggle, status, height <m>, damping <0-1>, shake <0-1>");
					break;
				}
			}
		}

		[HarmonyPostfix]
		public static void AddTerminalCommands()
		{
			//IL_0033: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			object obj = <>c.<>9__0_0;
			if (obj == null)
			{
				ConsoleEvent val = delegate(ConsoleEventArgs args)
				{
					if (args.Length < 2)
					{
						PrintStatus(args.Context);
					}
					else
					{
						switch (args[1].ToLowerInvariant())
						{
						case "toggle":
						{
							StabilizerManager.ToggleStabilization(out string message);
							args.Context.AddString(message);
							break;
						}
						case "status":
							PrintStatus(args.Context);
							break;
						case "height":
						{
							if (args.Length >= 3 && float.TryParse(args[2], out var result2))
							{
								PluginConfig.StabilizedEyeHeight.Value = Mathf.Clamp(result2, 1.2f, 2.2f);
								args.Context.AddString($"[Unswayed] Stabilized eye height set to: {PluginConfig.StabilizedEyeHeight.Value:F2}m");
							}
							else
							{
								args.Context.AddString($"[Unswayed] Current height: {PluginConfig.StabilizedEyeHeight.Value:F2}m. Usage: unswayed height <1.2 - 2.2>");
							}
							break;
						}
						case "damping":
						{
							if (args.Length >= 3 && float.TryParse(args[2], out var result3))
							{
								PluginConfig.VerticalDamping.Value = Mathf.Clamp01(result3);
								args.Context.AddString($"[Unswayed] Vertical damping set to: {PluginConfig.VerticalDamping.Value:F2} (1.0 = stable, 0.0 = vanilla)");
							}
							else
							{
								args.Context.AddString($"[Unswayed] Current damping: {PluginConfig.VerticalDamping.Value:F2}. Usage: unswayed damping <0.0 - 1.0>");
							}
							break;
						}
						case "shake":
						{
							if (args.Length >= 3 && float.TryParse(args[2], out var result))
							{
								PluginConfig.CameraShakeScale.Value = Mathf.Clamp01(result);
								args.Context.AddString($"[Unswayed] Camera shake scale set to: {PluginConfig.CameraShakeScale.Value:F2}");
							}
							else
							{
								args.Context.AddString($"[Unswayed] Current shake scale: {PluginConfig.CameraShakeScale.Value:F2}. Usage: unswayed shake <0.0 - 1.0>");
							}
							break;
						}
						default:
							args.Context.AddString("[Unswayed] Available commands: toggle, status, height <m>, damping <0-1>, shake <0-1>");
							break;
						}
					}
				};
				<>c.<>9__0_0 = val;
				obj = (object)val;
			}
			new ConsoleCommand("unswayed", "Manage Unswayed camera stabilization (toggle, status, height, damping)", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
		}

		private static void PrintStatus(Terminal terminal)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			terminal.AddString("=== [Unswayed Camera Stabilizer v1.0.0] ===");
			terminal.AddString($"  Enabled: {PluginConfig.IsModEnabled.Value} (Hotkey: [{PluginConfig.ToggleHotkey.Value}])");
			terminal.AddString($"  Mode: {PluginConfig.Mode.Value} | Damping: {PluginConfig.VerticalDamping.Value:F2} | Eye Height: {PluginConfig.StabilizedEyeHeight.Value:F2}m");
			terminal.AddString($"  Dungeon Ergonomics: {PluginConfig.EnableDungeonErgonomics.Value} (MinDist: {PluginConfig.MinCameraDistance.Value:F2}m, ShoulderLift: +{PluginConfig.ShoulderLiftAmount.Value:F2}m, FOV Boost: +{PluginConfig.DungeonFovBoost.Value:F0}°)");
			terminal.AddString($"  Camera Shake Scale: {PluginConfig.CameraShakeScale.Value:F2} | Disable Ship Tilt: {PluginConfig.DisableShipTilt.Value}");
			terminal.AddString($"  Live Camera Distance: {StabilizerManager.LastCameraDistance:F2}m (Tight Space: {StabilizerManager.IsTightSpace})");
		}
	}
}