Decompiled source of DynamicWalking v1.1.3

DynamicWalking.dll

Decompiled 3 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.Notifications;
using DynamicWalking;
using HarmonyLib;
using Il2CppSLZ.Marrow;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(Mod), "Dynamic Walking", "1.2.0", "ElectroDynamic", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("DynamicWalking")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DynamicWalking")]
[assembly: AssemblyTitle("DynamicWalking")]
[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 DynamicWalking
{
	public class Mod : MelonMod
	{
		public static MelonPreferences_Category Cat;

		public static MelonPreferences_Entry<bool> Enabled;

		public static MelonPreferences_Entry<bool> AllowRun;

		public static MelonPreferences_Entry<float> Sensitivity;

		public static MelonPreferences_Entry<float> MinStep;

		public static MelonPreferences_Entry<bool> Debug;

		private const float StickDeadzone = 0.15f;

		private const float WalkCap = 0.6f;

		private const float DriftTau = 1.5f;

		private const float MoveFull = 0.22f;

		private const float RunStart = 0.28f;

		private const float RunFull = 0.45f;

		private const float AttackTau = 0.05f;

		private const float ReleaseTau = 0.18f;

		private const float EngageThreshold = 0.02f;

		private const float CrawlFloor = 0.15f;

		private const float WatchdogSeconds = 4f;

		public static float GateMagnitude;

		public static long HookFireCount;

		public static float LastIncomingStickMag;

		public static float LastOutgoingMag;

		public static bool BypassActive;

		private static float _lastHeadY;

		private static bool _hasLastHeadY;

		private static bool _usingHeadset;

		private static float _vDrift;

		private static float _env;

		private static float _lastVY;

		private static float _logAccum;

		public static float FrozenSince = -1f;

		public static Instance Log { get; private set; }

		public override void OnInitializeMelon()
		{
			Log = ((MelonBase)this).LoggerInstance;
			Cat = MelonPreferences.CreateCategory("DynamicWalking");
			Enabled = Cat.CreateEntry<bool>("Enabled", true, "Walk by physically stepping in place", (string)null, false, false, (ValueValidator)null, (string)null);
			AllowRun = Cat.CreateEntry<bool>("AllowRun", true, "Stepping fast enough breaks into a run", (string)null, false, false, (ValueValidator)null, (string)null);
			Sensitivity = Cat.CreateEntry<float>("Sensitivity", 1f, "How easily a head bob becomes movement", (string)null, false, false, (ValueValidator)null, (string)null);
			MinStep = Cat.CreateEntry<float>("MinStep", 0.06f, "Ignore head movement gentler than this (m/s)", (string)null, false, false, (ValueValidator)null, (string)null);
			Debug = Cat.CreateEntry<bool>("Debug", true, "Log step/movement diagnostics to the console", (string)null, false, false, (ValueValidator)null, (string)null);
			Cat.SaveToFile(false);
			BuildMenu();
			Hooking.OnLevelLoaded += delegate
			{
				ResetBob();
			};
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(RemapRig), "ApplyMovement", new Type[3]
				{
					typeof(Vector2),
					typeof(bool),
					typeof(float)
				}, (Type[])null);
				Log.Msg((methodInfo != null) ? "ApplyMovement resolved OK — locomotion hook target found." : "WARNING: ApplyMovement did NOT resolve — the walk hook will not apply!");
			}
			catch (Exception ex)
			{
				Log.Warning("ApplyMovement resolve check failed: " + ex.Message);
			}
			Log.Msg("Dynamic Walking 1.2.0 loaded — step in place to move.");
		}

		public override void OnUpdate()
		{
			if (!Enabled.Value)
			{
				GateMagnitude = 0f;
				return;
			}
			if (!TryGetHeadY(out var y))
			{
				ResetBob();
				return;
			}
			float unscaledDeltaTime = Time.unscaledDeltaTime;
			if (unscaledDeltaTime <= 0f)
			{
				return;
			}
			if (!_hasLastHeadY)
			{
				_lastHeadY = y;
				_hasLastHeadY = true;
				return;
			}
			float num = Mathf.Clamp((y - _lastHeadY) / unscaledDeltaTime, -2f, 2f);
			_lastHeadY = y;
			_lastVY = num;
			_vDrift = Mathf.Lerp(_vDrift, num, 1f - Mathf.Exp((0f - unscaledDeltaTime) / 1.5f));
			float num2 = Mathf.Abs(num - _vDrift);
			float num3 = ((num2 > _env) ? 0.05f : 0.18f);
			_env = Mathf.Lerp(_env, num2, 1f - Mathf.Exp((0f - unscaledDeltaTime) / num3));
			float num4 = Mathf.Max(0.1f, Sensitivity.Value);
			float num5 = Mathf.Max(0.01f, MinStep.Value);
			float num6 = Mathf.Max(num5 + 0.02f, 0.22f / num4);
			float num7 = Mathf.Clamp01((_env - num5) / (num6 - num5));
			float num8 = num7;
			if (AllowRun.Value)
			{
				float num9 = Mathf.Max(num5, 0.28f / num4);
				float num10 = Mathf.Max(num9 + 0.02f, 0.45f / num4);
				float num11 = Mathf.Clamp01((_env - num9) / (num10 - num9));
				num8 = Mathf.Clamp01(num7 + num11 * (1f - num7));
			}
			else
			{
				num8 = Mathf.Min(num8, 0.6f);
			}
			GateMagnitude = num8;
			if (Debug.Value)
			{
				_logAccum += unscaledDeltaTime;
				if (_logAccum >= 1f)
				{
					_logAccum = 0f;
					Log.Msg($"[diag] hookFires={HookFireCount} stickIn={LastIncomingStickMag:F2} out={LastOutgoingMag:F2} gate={GateMagnitude:F2} env={_env:F3} vY={num:F3} src={(_usingHeadset ? "headset" : "physHead")} bypass={BypassActive}");
				}
			}
		}

		private static bool TryGetHeadY(out float y)
		{
			//IL_0028: 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)
			y = 0f;
			try
			{
				OpenControllerRig controllerRig = Player.ControllerRig;
				if ((Object)(object)controllerRig != (Object)null)
				{
					Transform headset = controllerRig.headset;
					if ((Object)(object)headset != (Object)null)
					{
						y = headset.position.y;
						_usingHeadset = true;
						return true;
					}
				}
			}
			catch
			{
			}
			try
			{
				Transform head = Player.Head;
				if ((Object)(object)head != (Object)null)
				{
					y = head.position.y;
					_usingHeadset = false;
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private static void ResetBob()
		{
			_hasLastHeadY = false;
			_vDrift = 0f;
			_env = 0f;
			_lastVY = 0f;
			GateMagnitude = 0f;
			FrozenSince = -1f;
			BypassActive = false;
		}

		private static void BuildMenu()
		{
			//IL_0019: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			Page obj = Page.Root.CreatePage("Dynamic Walking", new Color(0.2f, 0.8f, 1f), 0, true);
			obj.CreateBool("Dynamic Walking", Color.green, Enabled.Value, (Action<bool>)delegate(bool v)
			{
				Enabled.Value = v;
				Cat.SaveToFile(false);
				if (!v)
				{
					ResetBob();
				}
				Notify(v ? "Dynamic Walking on — push the stick to aim, step in place to go." : "Dynamic Walking off — back to normal stick movement.", (NotificationType)0);
			});
			obj.CreateBool("Activate Running", Color.cyan, AllowRun.Value, (Action<bool>)delegate(bool v)
			{
				AllowRun.Value = v;
				Cat.SaveToFile(false);
				Notify(v ? "Running on — step quickly to break into a run." : "Running off — capped at a walk.", (NotificationType)0);
			});
			obj.CreateFloat("Step Sensitivity", Color.yellow, Sensitivity.Value, 0.1f, 0.3f, 3f, (Action<float>)delegate(float v)
			{
				Sensitivity.Value = v;
				Cat.SaveToFile(false);
			});
			obj.CreateFloat("Min Step Strength", new Color(1f, 0.6f, 0.2f), MinStep.Value, 0.01f, 0f, 0.25f, (Action<float>)delegate(float v)
			{
				MinStep.Value = v;
				Cat.SaveToFile(false);
			});
			obj.CreateBool("Debug Logging", new Color(0.6f, 0.6f, 0.6f), Debug.Value, (Action<bool>)delegate(bool v)
			{
				Debug.Value = v;
				Cat.SaveToFile(false);
			});
			obj.CreateFunction("Reset Defaults", Color.red, (Action)delegate
			{
				Sensitivity.Value = 1f;
				MinStep.Value = 0.06f;
				AllowRun.Value = true;
				Cat.SaveToFile(false);
				ResetBob();
				Notify("Settings reset to defaults.", (NotificationType)3);
			});
		}

		internal static void Notify(string message, NotificationType type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//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_0015: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			try
			{
				Notifier.Send(new Notification
				{
					Title = NotificationText.op_Implicit("Dynamic Walking"),
					Message = NotificationText.op_Implicit(message),
					PopupLength = 2.5f,
					Type = type
				});
			}
			catch
			{
			}
		}
	}
	[HarmonyPatch(typeof(RemapRig), "ApplyMovement", new Type[]
	{
		typeof(Vector2),
		typeof(bool),
		typeof(float)
	})]
	public static class ApplyMovement_Patch
	{
		public static void Prefix(ref Vector2 axis, ref bool inputPressed, float deltaTime)
		{
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: 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_012d: 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_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)
			if (!Mod.Enabled.Value)
			{
				return;
			}
			Mod.HookFireCount++;
			float num = (Mod.LastIncomingStickMag = ((Vector2)(ref axis)).magnitude);
			if (Mod.HookFireCount == 1)
			{
				Mod.Log.Msg($"ApplyMovement hook is LIVE (first fire, incoming stick={num:F2}).");
			}
			if (num < 0.15f)
			{
				Mod.FrozenSince = -1f;
				Mod.BypassActive = false;
				Mod.LastOutgoingMag = 0f;
				return;
			}
			float unscaledTime = Time.unscaledTime;
			float gateMagnitude = Mod.GateMagnitude;
			if (gateMagnitude <= 0.02f)
			{
				if (Mod.FrozenSince < 0f)
				{
					Mod.FrozenSince = unscaledTime;
				}
				if (unscaledTime - Mod.FrozenSince >= 4f)
				{
					if (!Mod.BypassActive)
					{
						Mod.BypassActive = true;
						Mod.Notify("No stepping detected — joystick movement re-enabled. Raise Step Sensitivity, then toggle Dynamic Walking off/on.", (NotificationType)1);
					}
					Mod.LastOutgoingMag = num;
				}
				else
				{
					axis = Vector2.zero;
					inputPressed = false;
					Mod.LastOutgoingMag = 0f;
				}
			}
			else
			{
				Mod.FrozenSince = -1f;
				Mod.BypassActive = false;
				Vector2 val = axis / num;
				float num2 = Mathf.Max(gateMagnitude, 0.15f);
				axis = val * num2;
				inputPressed = true;
				Mod.LastOutgoingMag = num2;
			}
		}
	}
}