Decompiled source of SwiftDodge v1.0.0

SwiftDodge.dll

Decompiled 6 hours ago
using System;
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 UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyTitle("SwiftDodge")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SwiftDodge")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("d594ab47-946c-494f-a967-bfe78b32d002")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SwiftDodge
{
	[BepInPlugin("hoskope.valheim.swiftdodge", "SwiftDodge", "1.0.0")]
	public class SwiftDodgePlugin : BaseUnityPlugin
	{
		internal enum DodgeInputMode
		{
			DoubleTap,
			DodgeKey,
			Both
		}

		public const string PluginGuid = "hoskope.valheim.swiftdodge";

		public const string PluginName = "SwiftDodge";

		public const string PluginVersion = "1.0.0";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> ModEnabled;

		internal static ConfigEntry<bool> DebugEnabled;

		internal static ConfigEntry<DodgeInputMode> DodgeMode;

		internal static ConfigEntry<float> DoubleTapWindow;

		internal static ConfigEntry<float> DodgeCooldownGuard;

		internal static ConfigEntry<KeyboardShortcut> DodgeKey;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected O, but got Unknown
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Mod enabled", true, "Enable SwiftDodge.");
			DebugEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Debug enabled", false, "Enable debug logging.");
			DodgeMode = ((BaseUnityPlugin)this).Config.Bind<DodgeInputMode>("General", "Dodge mode", DodgeInputMode.DoubleTap, "How SwiftDodge should trigger dodge rolls.");
			DoubleTapWindow = ((BaseUnityPlugin)this).Config.Bind<float>("Double Tap", "Double-tap window", 0.3f, new ConfigDescription("Maximum time in seconds between two direction taps.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 0.75f), Array.Empty<object>()));
			DodgeCooldownGuard = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Dodge cooldown guard", 0.45f, new ConfigDescription("Minimum time in seconds between SwiftDodge-triggered dodge attempts.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1.5f), Array.Empty<object>()));
			DodgeKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Dodge Key", "Dodge key", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), "Dedicated dodge key. Dodge direction uses current movement direction, or backward if standing still.");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"SwiftDodge config initialized.");
			_harmony = new Harmony("hoskope.valheim.swiftdodge");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"SwiftDodge 1.0.0 loaded.");
		}

		private void OnDestroy()
		{
			if (_harmony != null)
			{
				_harmony.UnpatchSelf();
			}
		}
	}
}
namespace SwiftDodge.Patch
{
	[HarmonyPatch(typeof(Player), "SetControls")]
	public static class PlayerSetControlsPatch
	{
		private enum DodgeDirection
		{
			None,
			Forward,
			Backward,
			Left,
			Right
		}

		private static readonly MethodInfo DodgeMethod = AccessTools.Method(typeof(Player), "Dodge", new Type[1] { typeof(Vector3) }, (Type[])null);

		private static readonly FieldInfo LookDirField = AccessTools.Field(typeof(Player), "m_lookDir");

		private static DodgeDirection _lastTapDirection = DodgeDirection.None;

		private static float _lastTapTime;

		private static float _lastDodgeTime;

		private static bool _wasForwardPressed;

		private static bool _wasBackwardPressed;

		private static bool _wasLeftPressed;

		private static bool _wasRightPressed;

		private const float DirectionThreshold = 0.5f;

		private static void Prefix(Player __instance, Vector3 movedir)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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 ((SwiftDodgePlugin.ModEnabled != null && !SwiftDodgePlugin.ModEnabled.Value) || (Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			if (!CanAttemptDodge(__instance))
			{
				ResetInputState();
				return;
			}
			SwiftDodgePlugin.DodgeInputMode value = SwiftDodgePlugin.DodgeMode.Value;
			bool flag = value == SwiftDodgePlugin.DodgeInputMode.DoubleTap || value == SwiftDodgePlugin.DodgeInputMode.Both;
			if ((value == SwiftDodgePlugin.DodgeInputMode.DodgeKey || value == SwiftDodgePlugin.DodgeInputMode.Both) && IsDodgeKeyDownRelaxed() && TryDodgeFromKey(__instance, movedir))
			{
				return;
			}
			if (!flag)
			{
				ResetInputState();
				return;
			}
			bool flag2 = movedir.z > 0.5f;
			bool flag3 = movedir.z < -0.5f;
			bool flag4 = movedir.x < -0.5f;
			bool flag5 = movedir.x > 0.5f;
			if (flag2 && !_wasForwardPressed)
			{
				RegisterTap(__instance, DodgeDirection.Forward);
			}
			if (flag3 && !_wasBackwardPressed)
			{
				RegisterTap(__instance, DodgeDirection.Backward);
			}
			if (flag4 && !_wasLeftPressed)
			{
				RegisterTap(__instance, DodgeDirection.Left);
			}
			if (flag5 && !_wasRightPressed)
			{
				RegisterTap(__instance, DodgeDirection.Right);
			}
			_wasForwardPressed = flag2;
			_wasBackwardPressed = flag3;
			_wasLeftPressed = flag4;
			_wasRightPressed = flag5;
		}

		private static bool IsDodgeKeyDownRelaxed()
		{
			//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_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_003b: Invalid comparison between Unknown and I4
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = SwiftDodgePlugin.DodgeKey.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey == 0)
			{
				return false;
			}
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers)
			{
				if ((int)modifier == 0 || Input.GetKey(modifier))
				{
					continue;
				}
				return false;
			}
			return Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey);
		}

		private static bool CanAttemptDodge(Player player)
		{
			if (((Character)player).IsDead())
			{
				return false;
			}
			if (((Character)player).InDodge())
			{
				return false;
			}
			if (((Character)player).IsEncumbered())
			{
				return false;
			}
			if (InventoryGui.IsVisible())
			{
				return false;
			}
			if (Menu.IsVisible())
			{
				return false;
			}
			if (Hud.InRadial())
			{
				return false;
			}
			if (Hud.IsPieceSelectionVisible())
			{
				return false;
			}
			if (((Character)player).InPlaceMode())
			{
				return false;
			}
			return true;
		}

		private static void RegisterTap(Player player, DodgeDirection direction)
		{
			//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_004b: Unknown result type (might be due to invalid IL or missing references)
			float time = Time.time;
			if (_lastTapDirection == direction && time - _lastTapTime <= SwiftDodgePlugin.DoubleTapWindow.Value && time - _lastDodgeTime >= SwiftDodgePlugin.DodgeCooldownGuard.Value)
			{
				Vector3 worldDodgeDirection = GetWorldDodgeDirection(player, direction);
				if (InvokeDodge(player, worldDodgeDirection))
				{
					_lastDodgeTime = time;
				}
				_lastTapDirection = DodgeDirection.None;
				_lastTapTime = 0f;
			}
			else
			{
				_lastTapDirection = direction;
				_lastTapTime = time;
			}
		}

		private static Vector3 GetWorldDodgeDirection(Player player, DodgeDirection direction)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_004d: 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_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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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)
			Vector3 val = GetLookDir(player);
			val.y = 0f;
			if (((Vector3)(ref val)).sqrMagnitude < 0.001f)
			{
				val = ((Component)player).transform.forward;
				val.y = 0f;
			}
			((Vector3)(ref val)).Normalize();
			Vector3 val2 = Vector3.Cross(Vector3.up, val);
			val2.y = 0f;
			((Vector3)(ref val2)).Normalize();
			Vector3 result = (Vector3)(direction switch
			{
				DodgeDirection.Forward => val, 
				DodgeDirection.Backward => -val, 
				DodgeDirection.Left => -val2, 
				DodgeDirection.Right => val2, 
				_ => -val, 
			});
			result.y = 0f;
			((Vector3)(ref result)).Normalize();
			return result;
		}

		private static Vector3 GetLookDir(Player player)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0044: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			if (LookDirField == null)
			{
				return ((Component)player).transform.forward;
			}
			try
			{
				return (Vector3)LookDirField.GetValue(player);
			}
			catch
			{
				return ((Component)player).transform.forward;
			}
		}

		private static bool InvokeDodge(Player player, Vector3 dodgeDir)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (DodgeMethod == null)
			{
				SwiftDodgePlugin.Log.LogWarning((object)"Failed to invoke vanilla dodge: Player.Dodge method was not found.");
				return false;
			}
			try
			{
				DodgeMethod.Invoke(player, new object[1] { dodgeDir });
				return true;
			}
			catch (Exception ex)
			{
				SwiftDodgePlugin.Log.LogWarning((object)("Failed to invoke vanilla dodge: " + ex.Message));
				return false;
			}
		}

		private static void ResetInputState()
		{
			_wasForwardPressed = false;
			_wasBackwardPressed = false;
			_wasLeftPressed = false;
			_wasRightPressed = false;
			_lastTapDirection = DodgeDirection.None;
			_lastTapTime = 0f;
		}

		private static bool TryDodgeFromKey(Player player, Vector3 movedir)
		{
			//IL_0024: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			float time = Time.time;
			if (time - _lastDodgeTime < SwiftDodgePlugin.DodgeCooldownGuard.Value)
			{
				return false;
			}
			DodgeDirection dodgeDirection = GetDirectionFromMoveInput(movedir);
			if (dodgeDirection == DodgeDirection.None)
			{
				dodgeDirection = DodgeDirection.Backward;
			}
			Vector3 worldDodgeDirection = GetWorldDodgeDirection(player, dodgeDirection);
			if (!InvokeDodge(player, worldDodgeDirection))
			{
				return false;
			}
			_lastDodgeTime = time;
			_lastTapDirection = DodgeDirection.None;
			_lastTapTime = 0f;
			return true;
		}

		private static DodgeDirection GetDirectionFromMoveInput(Vector3 movedir)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: 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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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)
			if (Mathf.Abs(movedir.x) > Mathf.Abs(movedir.z))
			{
				if (movedir.x < -0.5f)
				{
					return DodgeDirection.Left;
				}
				if (movedir.x > 0.5f)
				{
					return DodgeDirection.Right;
				}
			}
			else
			{
				if (movedir.z > 0.5f)
				{
					return DodgeDirection.Forward;
				}
				if (movedir.z < -0.5f)
				{
					return DodgeDirection.Backward;
				}
			}
			return DodgeDirection.None;
		}
	}
}