Decompiled source of ToggleMovementMod v1.1.0

ToggleMovementMod.dll

Decompiled 3 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ToggleMovementMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ToggleMovementMod")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("f1b958a9-3b6f-4a6a-b27f-71f24ecff0c8")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ValheimMovementMods;

[BepInPlugin("afilbert.ValheimToggleMovementMod", "Valheim - Toggle Movement Mod", "1.1.0")]
[BepInProcess("valheim.exe")]
public class ToggleMovementMod : BaseUnityPlugin
{
	[HarmonyPatch(typeof(Player), "SetControls")]
	private class ToggleMovement
	{
		private static void Prefix(ref Player __instance, ref Vector3 movedir, ref bool run, ref bool crouch, ref Vector3 ___m_lookDir, ref Vector3 ___m_moveDir, ref bool ___m_autoRun, ref bool ___m_crouchToggled, ref string ___m_actionAnimation, ref List<MinorActionData> ___m_actionQueue)
		{
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: 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)
			//IL_0281: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			if (!EnableToggle.Value)
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)__instance) || _plugin.IsInMenu())
			{
				___m_autoRun = false;
				AutorunSet = false;
				return;
			}
			if (!Started)
			{
				Started = true;
			}
			if (!SprintSet)
			{
				StaminaRefilling = false;
			}
			if (OverrideAutorunSetting.Value)
			{
				run = ZInput.GetButton("Run") || ZInput.GetButton("JoyRun");
			}
			bool flag = ZInput.GetButton("Forward") || ZInput.GetButton("JoyForward");
			bool flag2 = ZInput.GetButton("Backward") || ZInput.GetButton("JoyBackward");
			bool flag3 = ZInput.GetButton("Left") || ZInput.GetButton("JoyLeft");
			bool flag4 = ZInput.GetButton("Right") || ZInput.GetButton("JoyRight");
			bool flag5 = false;
			if (ReequipWeaponAfterSwimming.Value && EquippedItem != null && EquippedItem.m_shared.m_name != "Unarmed" && ((Character)__instance).IsSwimming())
			{
				ReequipItem = EquippedItem;
			}
			else if (ReequipWeaponAfterSwimming.Value && ReequipItem != null && !((Character)__instance).IsSwimming())
			{
				((Humanoid)__instance).EquipItem(ReequipItem, true);
				ReequipItem = null;
			}
			EquippedItem = ((Humanoid)__instance).GetCurrentWeapon();
			flag5 = ((!AutorunStrafe.Value) ? (flag || flag2 || flag3 || flag4) : (flag2 || (AutorunStrafeForwardDisables.Value && flag)));
			bool flag6 = true;
			if (AutorunOverride.Value)
			{
				___m_autoRun = false;
			}
			bool flag7 = ___m_actionAnimation != null;
			if (___m_actionQueue.Exists((MinorActionData item) => (int)item.m_type == 0 || (int)item.m_type == 1))
			{
				flag7 = true;
			}
			if (AutorunSet && AutorunOverride.Value && flag5)
			{
				AutorunSet = false;
			}
			if (DisableStamLimitOnManualCntrl.Value && flag5 && StaminaRefilling)
			{
				StaminaRefilling = false;
			}
			if (((Humanoid)__instance).GetCurrentWeapon() != null && ((Humanoid)__instance).GetCurrentWeapon().m_shared.m_name == "$item_crossbow_arbalest")
			{
				flag6 = ((Humanoid)__instance).IsWeaponLoaded();
			}
			if (AutorunSet && !___m_autoRun && !flag7)
			{
				___m_autoRun = true;
			}
			if (___m_autoRun && AutorunOverride.Value && !ZInput.GetButton("Caps"))
			{
				if (AutorunStrafe.Value)
				{
					Vector3 val = ___m_lookDir;
					val.y = 0f;
					((Vector3)(ref val)).Normalize();
					___m_moveDir = val + movedir.x * Vector3.Cross(Vector3.up, val);
					if (((Vector3)(ref ___m_moveDir)).magnitude > 1f)
					{
						((Vector3)(ref ___m_moveDir)).Normalize();
					}
				}
				else
				{
					___m_moveDir = ___m_lookDir;
					___m_moveDir.y = 0f;
					((Vector3)(ref ___m_moveDir)).Normalize();
				}
			}
			if (((Character)__instance).GetStaminaPercentage() < StamRefillThreshold && !flag5)
			{
				StaminaRefilling = true;
			}
			if (((Character)__instance).GetStaminaPercentage() == 1f)
			{
				StaminaRefilling = false;
			}
			if (Crouching)
			{
				run = false;
				___m_crouchToggled = true;
				crouch = false;
				if (StaminaRefilling && AutorunSet && StopSneakMovementToggle.Value)
				{
					___m_autoRun = false;
				}
			}
			else
			{
				if (((Character)__instance).GetHealthPercentage() < SprintHealthThreshold && SafeguardStaminaOnLowHealth.Value)
				{
					SprintSet = false;
				}
				if (SprintSet && (!StaminaRefilling || (flag && DisableStamLimitOnManualCntrl.Value)) && flag6 && !flag7)
				{
					run = true;
					crouch = false;
				}
			}
			if (SprintSet && ((Character)__instance).GetStaminaPercentage() == 0f)
			{
				ElapsedTimeAtZeroStam += Time.deltaTime;
			}
			else
			{
				ElapsedTimeAtZeroStam = 0f;
			}
			if (TrackElapsedZeroStamToggle.Value && SprintSet && ElapsedTimeAtZeroStam > TrackElapsedZeroStamTime.Value)
			{
				SprintSet = false;
			}
		}
	}

	[HarmonyPatch(typeof(ZInput), "Reset")]
	private class ZInput_PatchReset
	{
		private static void Postfix(ZInput __instance)
		{
			//IL_0019: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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)
			Key val = (Key)Enum.Parse(typeof(Key), AutorunFreelookKey.Value);
			__instance.AddButton("Caps", val, 0f, 0f, true, false);
			val = (Key)Enum.Parse(typeof(Key), "Escape");
			__instance.AddButton("Esc", val, 0f, 0f, true, false);
			val = (Key)Enum.Parse(typeof(Key), SprintToggleAlternateKey.Value);
			__instance.AddButton("Sprint", val, 0f, 0f, true, false);
		}
	}

	[HarmonyPatch(typeof(Game), "Logout")]
	private class Game_PatchLogout
	{
		private static void Postfix()
		{
			Started = false;
		}
	}

	[HarmonyPatch(typeof(Hud), "UpdateStamina")]
	private class Hud_UpdateStamina
	{
		private static void Postfix(Hud __instance, ref Player player, ref TMP_Text ___m_staminaText, ref RectTransform ___m_staminaBar2Root, ref GuiBar ___m_staminaBar2Slow, ref GuiBar ___m_staminaBar2Fast)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			if (EnableToggle.Value && VisuallyIndicateSprintState.Value && SprintToggle.Value && SprintSet)
			{
				___m_staminaBar2Fast.SetColor(new Color(1f, 0.64f, 0f));
				if (StaminaRefilling)
				{
					___m_staminaBar2Fast.SetColor(Color.blue);
				}
				if (ElapsedTimeAtZeroStam > 1f)
				{
					__instance.StaminaBarEmptyFlash();
				}
			}
			else
			{
				___m_staminaBar2Fast.SetColor(Color.yellow);
			}
		}
	}

	private const string pluginGUID = "afilbert.ValheimToggleMovementMod";

	private const string pluginName = "Valheim - Toggle Movement Mod";

	private const string pluginVersion = "1.1.0";

	public static ManualLogSource logger;

	private readonly Harmony _harmony = new Harmony("afilbert.ValheimToggleMovementMod");

	public static ToggleMovementMod _plugin;

	public static bool Started;

	public static ConfigEntry<bool> EnableToggle;

	public static ConfigEntry<bool> SprintToggle;

	public static ConfigEntry<bool> SprintToggleAlternate;

	public static ConfigEntry<string> SprintToggleAlternateKey;

	public static ConfigEntry<bool> DisableStamLimitOnManualCntrl;

	public static ConfigEntry<bool> AutorunOverride;

	public static ConfigEntry<string> AutorunFreelookKey;

	public static ConfigEntry<bool> AutorunStrafe;

	public static ConfigEntry<bool> AutorunStrafeForwardDisables;

	public static ConfigEntry<bool> ReequipWeaponAfterSwimming;

	public static ConfigEntry<bool> RunToCrouchToggle;

	public static ConfigEntry<bool> StopSneakMovementToggle;

	public static ConfigEntry<float> MinStamRefillPercent;

	public static ConfigEntry<bool> SafeguardStaminaOnLowHealth;

	public static ConfigEntry<float> SprintHealthOverride;

	public static ConfigEntry<bool> TrackElapsedZeroStamToggle;

	public static ConfigEntry<float> TrackElapsedZeroStamTime;

	public static ConfigEntry<bool> OverrideAutorunSetting;

	public static ConfigEntry<bool> AllowAutorunWhileInMap;

	public static ConfigEntry<bool> VisuallyIndicateSprintState;

	public static ConfigEntry<bool> SprintToggleOnAutorun;

	public static ConfigEntry<bool> AllowAutorunInInventory;

	public static bool StaminaRefilling;

	public static bool SprintSet;

	public static bool AutorunSet;

	public static bool RunToCrouch;

	public static bool Crouching;

	public static float ElapsedTimeAtZeroStam;

	public static float StamRefillThreshold;

	public static float SprintHealthThreshold;

	public static ItemData EquippedItem;

	public static ItemData ReequipItem;

	private void Awake()
	{
		_plugin = this;
		logger = ((BaseUnityPlugin)this).Logger;
		EnableToggle = ((BaseUnityPlugin)this).Config.Bind<bool>("Mod Config", "Enable", true, "Enable this mod");
		OverrideAutorunSetting = ((BaseUnityPlugin)this).Config.Bind<bool>("Mod Config", "OverrideGameAutorun", true, "This overrides the new auto-run config setting that functions as a sprint toggle");
		SprintToggle = ((BaseUnityPlugin)this).Config.Bind<bool>("Sprint", "SprintToggle", true, "Sprint works like a toggle when true");
		SprintToggleOnAutorun = ((BaseUnityPlugin)this).Config.Bind<bool>("Sprint", "OnlyToggleWhenAutorunning", false, "Sprint only works like a toggle when auto-running");
		SprintToggleAlternate = ((BaseUnityPlugin)this).Config.Bind<bool>("SprintAlternate", "SprintToggleAlternate", false, "Sprint is toggled through use of another key/button");
		SprintToggleAlternateKey = ((BaseUnityPlugin)this).Config.Bind<string>("SprintAlternate", "SprintToggleAlternateKey", "T", "Used in conjunction with SprintToggleAlternate. This is the key used to toggle sprint on/off");
		AutorunOverride = ((BaseUnityPlugin)this).Config.Bind<bool>("Auto-run", "AutorunToggle", true, "Fixes auto-run to follow look direction");
		AutorunFreelookKey = ((BaseUnityPlugin)this).Config.Bind<string>("Auto-run", "AutorunFreelookKey", "CapsLock", "Overrides look direction in auto-run while pressed");
		AutorunStrafe = ((BaseUnityPlugin)this).Config.Bind<bool>("Auto-run", "AutorunStrafe", true, "Enable strafing while in auto-run/crouch");
		AutorunStrafeForwardDisables = ((BaseUnityPlugin)this).Config.Bind<bool>("Auto-run", "AutorunStrafeForwardDisables", false, "Disable autorun if Forward key/button pressed while AutorunStrafe enabled");
		AllowAutorunWhileInMap = ((BaseUnityPlugin)this).Config.Bind<bool>("Auto-run", "AutorunInMap", true, "Keep running while viewing map");
		AllowAutorunInInventory = ((BaseUnityPlugin)this).Config.Bind<bool>("Auto-run", "AutorunInInventory", false, "Keep running while viewing inventory");
		ReequipWeaponAfterSwimming = ((BaseUnityPlugin)this).Config.Bind<bool>("Swim", "ReequipWeaponAfterSwimming", true, "Any weapon stowed in order to swim will reequip once out of swimming state");
		RunToCrouchToggle = ((BaseUnityPlugin)this).Config.Bind<bool>("Auto-sneak", "RunToCrouchToggle", true, "Allows going from full run to crouch with a click of the crouch button (and vice versa)");
		StopSneakMovementToggle = ((BaseUnityPlugin)this).Config.Bind<bool>("Auto-sneak", "StopSneakOnNoStam", true, "Stops sneak movement if no stamina available. Stock behavior is to pop out of sneak into walk");
		MinStamRefillPercent = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "MinStamRefillPercentValue", 20f, "Percentage to stop running and let stamina refill");
		DisableStamLimitOnManualCntrl = ((BaseUnityPlugin)this).Config.Bind<bool>("Stamina", "StopStamLimitOnManualInputToggle", true, "Stops the wait for 100% stam fill to resume sprinting on manual Forward input");
		StamRefillThreshold = MinStamRefillPercent.Value / 100f;
		SafeguardStaminaOnLowHealth = ((BaseUnityPlugin)this).Config.Bind<bool>("Stamina", "SafeguardStaminaOnLowHealthToggle", true, "Allow stamina to recover on low health by automatically detoggling sprint");
		SprintHealthOverride = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "SprintHealthOverridePercentValue", 30f, "Percentage of health to detoggle sprint so stamina can start to recover");
		SprintHealthThreshold = SprintHealthOverride.Value / 100f;
		TrackElapsedZeroStamToggle = ((BaseUnityPlugin)this).Config.Bind<bool>("Stamina", "TrackElapsedZeroStamToggle", true, "Automatically toggle off sprint after elapsed time spent at zero stamina");
		TrackElapsedZeroStamTime = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "TrackElapsedZeroStamTime", 5f, "Seconds to wait at zero stamina before toggling off sprint");
		VisuallyIndicateSprintState = ((BaseUnityPlugin)this).Config.Bind<bool>("Stamina", "ChangeStamColorOnSprint", true, "Changes stamina bar color to orange when draining and sprint enabled, and blue when stam regenerating. Flashes empty bar if stam drained fully while sprinting");
		_harmony.PatchAll();
	}

	private void OnDestroy()
	{
		_harmony.UnpatchSelf();
	}

	private bool IsInMenu()
	{
		if (!ZInput.GetButtonDown("Esc") && !ZInput.GetButtonDown("JoyMenu") && (AllowAutorunInInventory.Value || !InventoryGui.IsVisible()) && (AllowAutorunWhileInMap.Value || !Minimap.IsOpen()) && !Console.IsVisible() && !TextInput.IsVisible() && !ZNet.instance.InPasswordDialog() && !StoreGui.IsVisible() && !Hud.IsPieceSelectionVisible())
		{
			return UnifiedPopup.IsVisible();
		}
		return true;
	}

	private void Update()
	{
		if (!Started || !EnableToggle.Value || IsInMenu())
		{
			return;
		}
		bool flag = false;
		if (SprintToggleAlternate.Value)
		{
			flag = ZInput.GetButtonUp("Sprint");
		}
		else if (SprintToggle.Value)
		{
			flag = ZInput.GetButtonUp("Run") || ZInput.GetButtonUp("JoyRun");
		}
		bool num = ZInput.GetButtonDown("Crouch") || ZInput.GetButtonDown("JoyCrouch");
		bool buttonDown = ZInput.GetButtonDown("AutoRun");
		bool flag2 = ZInput.GetButton("Backward") || ZInput.GetButton("JoyBackward");
		if (!AutorunOverride.Value)
		{
			AutorunSet = false;
		}
		if (!RunToCrouchToggle.Value)
		{
			RunToCrouch = false;
		}
		if (!SprintToggle.Value)
		{
			SprintSet = false;
		}
		if (buttonDown && AutorunOverride.Value)
		{
			AutorunSet = !AutorunSet;
		}
		if (!AutorunSet && SprintToggleOnAutorun.Value)
		{
			SprintSet = false;
		}
		if (flag && SprintToggle.Value)
		{
			if (!SprintToggleOnAutorun.Value)
			{
				SprintSet = !SprintSet;
			}
			if (SprintToggleOnAutorun.Value && AutorunSet)
			{
				SprintSet = !SprintSet;
			}
		}
		if (num && RunToCrouchToggle.Value)
		{
			Crouching = !Crouching;
		}
		if (AutorunSet && flag2)
		{
			AutorunSet = false;
		}
	}
}