Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ToggleMovementMod v1.4.3
ToggleMovementMod.dll
Decompiled 2 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; 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: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace ValheimMovementMods; [BepInPlugin("afilbert.ValheimToggleMovementMod", "Valheim - Toggle Movement Mod", "1.4.3")] [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 attack, 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_03f4: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_03be: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03ca: Unknown result type (might be due to invalid IL or missing references) //IL_03cf: Unknown result type (might be due to invalid IL or missing references) //IL_03d4: Unknown result type (might be due to invalid IL or missing references) _plugin.PrivateUpdate(); if (!EnableToggle.Value) { return; } if (!Object.op_Implicit((Object)(object)__instance) || _plugin.IsInMenu() || ((Character)__instance).InPlaceMode() || __instance.InRepairMode() || (!AllowAutorunInInventory.Value && _plugin.IsInInventory())) { ___m_autoRun = false; AutorunSet = false; return; } if (!Started) { Started = true; } if (!SprintSet && !Crouching) { StaminaRefilling = false; } _plugin.MaybeUpdateConfigurableInput(); if ((SprintToggle.Value || SprintToggleOnAutorun.Value) && !_plugin.IsInChat() && !_plugin.IsInInventory()) { run = ZInput.GetButton("Run") || ZInput.GetButton("JoyRun"); if (SprintToggleAlternate.Value && !run) { run = ZInput.GetButtonUp("Sprint"); } } 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 = ZInput.GetButton("Attack") || ZInput.GetButton("JoyAttack"); bool flag6 = 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(); if (!_plugin.IsInChat() && !_plugin.IsInInventory()) { flag6 = ((!AutorunStrafe.Value) ? (flag || flag2 || flag3 || flag4) : (flag2 || (AutorunStrafeForwardDisables.Value && flag))); } if (ZInput.ToggleRun && !SprintTogglePersistsOnHalt.Value && ((Vector3)(ref ___m_moveDir)).magnitude == 0f) { SprintSet = false; } if (!ZInput.ToggleRun && (SprintToggle.Value || SprintToggleOnAutorun.Value) && !SprintTogglePersistsOnHalt.Value && ((Vector3)(ref ___m_moveDir)).magnitude == 0f) { SprintSet = false; } bool flag7 = true; if (AutorunOverride.Value) { ___m_autoRun = false; } bool flag8 = ___m_actionAnimation != null; if (___m_actionQueue.Exists((MinorActionData item) => (int)item.m_type == 0 || (int)item.m_type == 1)) { flag8 = true; } if (AutorunSet && AutorunOverride.Value && flag6) { AutorunSet = false; } if (DisableStamLimitOnManualCntrl.Value && flag6 && StaminaRefilling) { StaminaRefilling = false; } if (((Humanoid)__instance).GetCurrentWeapon() != null && ((Humanoid)__instance).GetCurrentWeapon().m_shared.m_name == "$item_crossbow_arbalest") { flag7 = ((Humanoid)__instance).IsWeaponLoaded(); } if (AutorunSet && !___m_autoRun && !flag8) { ___m_autoRun = true; } if (___m_autoRun && AutorunOverride.Value && !ZInput.GetButton("FreeLook")) { 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 (AutorunSafeguardStamina.Value && ((Character)__instance).GetStaminaPercentage() < StamRefillThreshold && !flag6) { StaminaRefilling = true; } if (AutoJump.Value && AutoJumpSet && ((Character)__instance).GetStaminaPercentage() == 0f) { JumpStamRefilling = true; } if (AutoPrimaryAttack.Value && AutoPrimaryAttackSet && (double)((Character)__instance).GetStaminaPercentage() <= 0.01) { AttackStamRefilling = true; } if (((Character)__instance).GetStaminaPercentage() >= 1f) { StaminaRefilling = false; JumpStamRefilling = false; AttackStamRefilling = 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 (!SprintToggle.Value && !SprintToggleOnAutorun.Value && ZInput.ToggleRun && StaminaRefilling) { run = false; } if (SprintSet && (!StaminaRefilling || (flag && DisableStamLimitOnManualCntrl.Value)) && flag7 && !flag8) { run = true; crouch = false; } if (AutoJump.Value && AutoJumpSet && !JumpStamRefilling) { ((Character)__instance).Jump(false); } if (AutoPrimaryAttack.Value && AutoPrimaryAttackSet && !AttackStamRefilling) { attack = true; } } if (SprintSet && ((Character)__instance).GetStaminaPercentage() == 0f) { ElapsedTimeAtZeroStam += Time.deltaTime; } else { ElapsedTimeAtZeroStam = 0f; } if (TrackElapsedZeroStamToggle.Value && SprintSet && ElapsedTimeAtZeroStam > TrackElapsedZeroStamTime.Value) { SprintSet = false; } if (DetoggleSprintAtLowStamWhenAttacking.Value && SprintSet && ((Character)__instance).GetStaminaPercentage() <= DetoggleSprintAtLowStamWhenAttackingThreshold.Value && flag5) { SprintSet = false; } } } [HarmonyPatch(typeof(ZInput), "Load")] private class ZInput_PatchLoad { private static void Postfix(ZInput __instance, Dictionary<string, ButtonDef> ___m_buttons) { //IL_0020: 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_0030: Unknown result type (might be due to invalid IL or missing references) _inputInstance = __instance; _buttonsDict = ___m_buttons; Key val = (Key)Enum.Parse(typeof(Key), "Escape"); _inputInstance.AddButton("Esc", ZInput.KeyToPath(val), false, true, false, 0f, 0f); _plugin.UpdateBindings(); } } [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_0065: 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_0045: Unknown result type (might be due to invalid IL or missing references) if (EnableToggle.Value && VisuallyIndicateSprintState.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.4.3"; private const string freeLookKey = "FreeLook"; private const string sprintKey = "Sprint"; public static ManualLogSource logger; private readonly Harmony _harmony = new Harmony("afilbert.ValheimToggleMovementMod"); public static ToggleMovementMod _plugin; public static ZInput _inputInstance; public static Dictionary<string, ButtonDef> _buttonsDict; 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> SprintToggleOnAutorun; public static ConfigEntry<bool> SprintTogglePersistsOnHalt; 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> AutorunDisableOnEsc; public static ConfigEntry<bool> AutorunSafeguardStamina; public static ConfigEntry<bool> AutoJump; public static ConfigEntry<bool> AutoPrimaryAttack; 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> AllowAutorunWhileInMap; public static ConfigEntry<bool> VisuallyIndicateSprintState; public static ConfigEntry<bool> AllowAutorunInInventory; public static ConfigEntry<bool> DetoggleSprintAtLowStamWhenAttacking; public static ConfigEntry<float> DetoggleSprintAtLowStamWhenAttackingThreshold; public static string InitialSprintToggleAlternateKey; public static string InitialAutorunFreelookKey; public static bool StaminaRefilling; public static bool JumpStamRefilling; public static bool SprintSet; public static bool AutorunSet; public static bool RunToCrouch; public static bool Crouching; public static bool GameplaySettingAutorun; public static bool AutoJumpSet; public static bool AttackStamRefilling; public static bool AutoPrimaryAttackSet; 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"); 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"); SprintTogglePersistsOnHalt = ((BaseUnityPlugin)this).Config.Bind<bool>("Sprint", "SprintTogglePersistsOnHalt", false, "Sprint stays toggled even after character halts"); SprintToggleAlternate = ((BaseUnityPlugin)this).Config.Bind<bool>("Sprint", "SprintToggleAlternate", false, "Sprint is toggled through use of another key/button"); SprintToggleAlternateKey = ((BaseUnityPlugin)this).Config.Bind<string>("Sprint", "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"); AutorunDisableOnEsc = ((BaseUnityPlugin)this).Config.Bind<bool>("Auto-run", "AutorunDisableOnEsc", true, "Disable autorun if Esc key pressed"); AutorunSafeguardStamina = ((BaseUnityPlugin)this).Config.Bind<bool>("Auto-run", "AutorunSafeguardStamina", true, "Enables stam safeguards that prevent stamina from running to zero"); AutoJump = ((BaseUnityPlugin)this).Config.Bind<bool>("Auto-jump", "AutoJumpToggle", false, "Enables character jump input to function as a toggle with stamina safeguards"); 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"); AutoPrimaryAttack = ((BaseUnityPlugin)this).Config.Bind<bool>("Auto-attack", "AutoPrimaryAttackToggle", false, "Enables character primary attack input to function as a toggle with stamina safeguards"); 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"); DetoggleSprintAtLowStamWhenAttacking = ((BaseUnityPlugin)this).Config.Bind<bool>("Stamina", "DetoggleSprintAtLowStamWhenAttacking", true, "Detoggles sprint if attacking at low stamina"); DetoggleSprintAtLowStamWhenAttackingThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "DetoggleSprintAtLowStamWhenAttackingThreshold", 0.04f, "Threshold at which stamina will detoggle sprint if also attacking"); InitialSprintToggleAlternateKey = SprintToggleAlternateKey.Value; InitialAutorunFreelookKey = AutorunFreelookKey.Value; _harmony.PatchAll(); } private void MaybeUpdateConfigurableInput() { if (InitialSprintToggleAlternateKey != SprintToggleAlternateKey.Value || InitialAutorunFreelookKey != AutorunFreelookKey.Value) { _buttonsDict.Remove("Sprint"); _buttonsDict.Remove("FreeLook"); if (UpdateBindings()) { InitialSprintToggleAlternateKey = SprintToggleAlternateKey.Value; InitialAutorunFreelookKey = AutorunFreelookKey.Value; } } } private bool UpdateBindings() { //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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) try { Key val = (Key)Enum.Parse(typeof(Key), AutorunFreelookKey.Value); _inputInstance.AddButton("FreeLook", ZInput.KeyToPath(val), false, true, false, 0f, 0f); val = (Key)Enum.Parse(typeof(Key), SprintToggleAlternateKey.Value); _inputInstance.AddButton("Sprint", ZInput.KeyToPath(val), false, true, false, 0f, 0f); logger.LogInfo((object)("Bindings - Free look: " + AutorunFreelookKey.Value + ". Toggle alternate: " + SprintToggleAlternateKey.Value)); return true; } catch (ArgumentException ex) { logger.LogError((object)("Error binding input buttons: " + ex.Message)); return false; } } private void OnDestroy() { _harmony.UnpatchSelf(); } private bool IsInMenu() { if ((!AutorunDisableOnEsc.Value || !ZInput.GetButtonDown("Esc")) && !ZInput.GetButtonDown("JoyMenu") && (AllowAutorunWhileInMap.Value || !Minimap.IsOpen()) && !Console.IsVisible() && !TextInput.IsVisible() && !ZNet.instance.InPasswordDialog() && !StoreGui.IsVisible() && !Hud.IsPieceSelectionVisible() && !UnifiedPopup.IsVisible() && !GameCamera.InFreeFly()) { return PlayerCustomizaton.IsBarberGuiVisible(); } return true; } private bool IsInInventory() { return InventoryGui.IsVisible(); } private bool IsInChat() { if (Object.op_Implicit((Object)(object)Chat.instance)) { return Chat.instance.HasFocus(); } return false; } private void PrivateUpdate() { if (!Started || !EnableToggle.Value || IsInMenu() || IsInChat() || IsInInventory()) { return; } bool flag = false; if (SprintToggle.Value || SprintToggleOnAutorun.Value || ZInput.ToggleRun) { flag = ZInput.GetButtonUp("Run") || ZInput.GetButtonUp("JoyRun"); if (SprintToggleAlternate.Value) { flag = ZInput.GetButtonUp("Sprint"); } } bool buttonDown = ZInput.GetButtonDown("Attack"); bool num = ZInput.GetButtonDown("Crouch") || ZInput.GetButtonDown("JoyCrouch"); bool buttonDown2 = ZInput.GetButtonDown("AutoRun"); bool buttonDown3 = ZInput.GetButtonDown("Jump"); bool flag2 = ZInput.GetButton("Backward") || ZInput.GetButton("JoyBackward"); if (!AutorunOverride.Value) { AutorunSet = false; } if (!RunToCrouchToggle.Value) { RunToCrouch = false; } if (!SprintToggle.Value && !SprintToggleOnAutorun.Value && !ZInput.ToggleRun) { SprintSet = false; } if (buttonDown2 && AutorunOverride.Value) { AutorunSet = !AutorunSet; } if (!AutorunSet && SprintToggleOnAutorun.Value) { SprintSet = false; } if (flag && (SprintToggle.Value || SprintToggleOnAutorun.Value || ZInput.ToggleRun)) { if (!SprintToggleOnAutorun.Value || ZInput.ToggleRun) { SprintSet = !SprintSet; } if (SprintToggleOnAutorun.Value && AutorunSet) { SprintSet = !SprintSet; } } if (num && RunToCrouchToggle.Value) { Crouching = !Crouching; } if (buttonDown3 && AutoJump.Value) { AutoJumpSet = !AutoJumpSet; } if (buttonDown && AutoPrimaryAttack.Value) { AutoPrimaryAttackSet = !AutoPrimaryAttackSet; } if (AutorunSet && flag2) { AutorunSet = false; } } }