Decompiled source of FlyWithHammer v1.1.1

FlyWithHammer.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
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: AssemblyCompany("FlyWithHammer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.1.1.0")]
[assembly: AssemblyInformationalVersion("1.1.1")]
[assembly: AssemblyProduct("FlyWithHammer")]
[assembly: AssemblyTitle("FlyWithHammer")]
[assembly: AssemblyVersion("1.1.1.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 FlyWithHammer
{
	[BepInPlugin("Moopfam.FlyWithHammer", "Fly With Hammer", "1.1.1")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "Moopfam.FlyWithHammer";

		public const string PluginName = "Fly With Hammer";

		public const string PluginVersion = "1.1.1";

		internal static Plugin Instance;

		private bool _flyApplied;

		private bool _featherFalling;

		private bool _protectThisDrop;

		private bool _floating;

		private float _floatUntil;

		private float _featherFallStartedAt;

		private ConfigEntry<bool> _modEnabled;

		private ConfigEntry<KeyCode> _toggleKey;

		private ConfigEntry<float> _flySpeedMultiplier;

		private ConfigEntry<bool> _enableFloatAfterHammer;

		private ConfigEntry<float> _floatSeconds;

		private Vector3 _floatAnchorPosition;

		private Quaternion _floatAnchorRotation;

		private Vector3 _lastFlyPosition;

		private bool _haveLastFlyPosition;

		private Player _trackedPlayer;

		private const float DefaultFlySpeedMultiplier = 0.1f;

		private const float FeatherFallSpeed = 1.5f;

		private Harmony _harmony;

		private static readonly MethodInfo GetRightItemMethod = AccessTools.Method(typeof(Humanoid), "GetRightItem", (Type[])null, (Type[])null) ?? AccessTools.Method(typeof(Player), "GetRightItem", (Type[])null, (Type[])null);

		private static readonly MethodInfo ToggleDebugFlyMethod = AccessTools.Method(typeof(Player), "ToggleDebugFly", (Type[])null, (Type[])null);

		private static readonly MethodInfo IsOnGroundMethod = AccessTools.Method(typeof(Character), "IsOnGround", (Type[])null, (Type[])null) ?? AccessTools.Method(typeof(Player), "IsOnGround", (Type[])null, (Type[])null);

		private static readonly FieldInfo BodyField = AccessTools.Field(typeof(Character), "m_body") ?? AccessTools.Field(typeof(Player), "m_body");

		private static readonly FieldInfo FallSpeedField = AccessTools.Field(typeof(Character), "m_fallSpeed") ?? AccessTools.Field(typeof(Player), "m_fallSpeed");

		private void Awake()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			Instance = this;
			_modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable or disable Fly With Hammer.");
			_toggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ToggleKey", (KeyCode)287, "Key used to toggle Fly With Hammer on or off.");
			_flySpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "FlySpeed", 0.1f, new ConfigDescription("Fly speed multiplier. 0 = stationary, 1 = normal Valheim debug-fly speed.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			_enableFloatAfterHammer = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "FloatingEnabled", false, "Float in place after deselecting the Hammer before Feather Fall begins.");
			_floatSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "FloatingSeconds", 5f, new ConfigDescription("How many seconds to float after deselecting the Hammer. 0 starts Feather Fall immediately.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>()));
			_harmony = new Harmony("Moopfam.FlyWithHammer");
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Fly With Hammer 1.1.1 loaded.");
		}

		private void Update()
		{
			//IL_000f: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: 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_02ad: Unknown result type (might be due to invalid IL or missing references)
			if (_toggleKey != null && (int)_toggleKey.Value != 0 && Input.GetKeyDown(_toggleKey.Value))
			{
				_modEnabled.Value = !_modEnabled.Value;
				((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("Fly With Hammer: mod {0} via {1}.", _modEnabled.Value ? "ENABLED" : "DISABLED", _toggleKey.Value));
				if (!_modEnabled.Value && (Object)(object)Player.m_localPlayer != (Object)null)
				{
					DisableModEffects(Player.m_localPlayer);
				}
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				ResetRuntimeState();
				return;
			}
			if (!_modEnabled.Value)
			{
				DisableModEffects(localPlayer);
				return;
			}
			if ((Object)(object)_trackedPlayer != (Object)(object)localPlayer)
			{
				_trackedPlayer = localPlayer;
			}
			if (IsHammerEquipped(localPlayer))
			{
				Rigidbody body = GetBody(localPlayer);
				if ((Object)(object)body != (Object)null)
				{
					body.useGravity = true;
				}
				if (!_flyApplied)
				{
					SetFly(localPlayer, enabled: true);
					_flyApplied = true;
					Rigidbody body2 = GetBody(localPlayer);
					if ((Object)(object)body2 != (Object)null)
					{
						_lastFlyPosition = body2.position;
						_haveLastFlyPosition = true;
					}
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Fly With Hammer: hammer equipped - fly ON.");
				}
				if (!localPlayer.InDebugFlyMode())
				{
					SetFly(localPlayer, enabled: true);
				}
			}
			else if (_flyApplied)
			{
				SetFly(localPlayer, enabled: false);
				_flyApplied = false;
				_haveLastFlyPosition = false;
				_protectThisDrop = true;
				float num = (_enableFloatAfterHammer.Value ? Mathf.Clamp(_floatSeconds.Value, 0f, 60f) : 0f);
				_floating = num > 0f;
				_floatUntil = Time.time + num;
				_featherFalling = !_floating;
				_featherFallStartedAt = (_floating ? _floatUntil : Time.time);
				Rigidbody body3 = GetBody(localPlayer);
				if (_floating && (Object)(object)body3 != (Object)null)
				{
					_floatAnchorPosition = body3.position;
					_floatAnchorRotation = body3.rotation;
					body3.velocity = Vector3.zero;
					body3.angularVelocity = Vector3.zero;
				}
				ClearFallSpeed(localPlayer);
				if (_floating)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)$"Fly With Hammer: hammer deselected - floating for {num:0.##} seconds.");
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Fly With Hammer: hammer deselected - feather fall ON.");
				}
			}
			if (_floating && Time.time >= _floatUntil)
			{
				_floating = false;
				_featherFalling = true;
				_featherFallStartedAt = Time.time;
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Fly With Hammer: float finished - feather fall ON.");
			}
			if (_protectThisDrop)
			{
				ClearFallSpeed(localPlayer);
				if (Time.time - _featherFallStartedAt > 0.35f && IsGrounded(localPlayer))
				{
					_protectThisDrop = false;
					_floating = false;
					_featherFalling = false;
					ClearFallSpeed(localPlayer);
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Fly With Hammer: protected landing complete.");
				}
			}
		}

		private void FixedUpdate()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			Rigidbody body = GetBody(localPlayer);
			if (!((Object)(object)body == (Object)null))
			{
				if (_floating && !_flyApplied)
				{
					body.useGravity = false;
					body.velocity = Vector3.zero;
					body.angularVelocity = Vector3.zero;
					body.position = _floatAnchorPosition;
					body.rotation = _floatAnchorRotation;
					ClearFallSpeed(localPlayer);
				}
				else if (_featherFalling && !_flyApplied)
				{
					body.useGravity = false;
					Vector3 velocity = body.velocity;
					velocity.y = -1.5f;
					body.velocity = velocity;
					ClearFallSpeed(localPlayer);
				}
				else if (!_flyApplied)
				{
					body.useGravity = true;
				}
			}
		}

		private void LateUpdate()
		{
			//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_0095: 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_009c: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null || _modEnabled == null || !_modEnabled.Value || !_flyApplied || !localPlayer.InDebugFlyMode())
				{
					_haveLastFlyPosition = false;
					return;
				}
				Rigidbody body = GetBody(localPlayer);
				if ((Object)(object)body == (Object)null)
				{
					return;
				}
				if (!_haveLastFlyPosition)
				{
					_lastFlyPosition = body.position;
					_haveLastFlyPosition = true;
					return;
				}
				Vector3 position = body.position;
				Vector3 val = position - _lastFlyPosition;
				if (((Vector3)(ref val)).sqrMagnitude > 1E-07f)
				{
					float num = ((_flySpeedMultiplier != null) ? Mathf.Clamp01(_flySpeedMultiplier.Value) : 0.1f);
					Vector3 val2 = (body.position = _lastFlyPosition + val * num);
					((Component)localPlayer).transform.position = val2;
					_lastFlyPosition = val2;
				}
				else
				{
					_lastFlyPosition = position;
				}
				float num2 = ((_flySpeedMultiplier != null) ? Mathf.Clamp01(_flySpeedMultiplier.Value) : 0.1f);
				body.velocity *= num2;
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Fly With Hammer: fly speed limiter skipped this frame: " + ex.Message));
			}
		}

		private static Rigidbody GetBody(Player player)
		{
			try
			{
				object? obj = BodyField?.GetValue(player);
				return (Rigidbody)((obj is Rigidbody) ? obj : null);
			}
			catch
			{
				return null;
			}
		}

		private static bool IsGrounded(Player player)
		{
			try
			{
				if (IsOnGroundMethod != null && IsOnGroundMethod.ReturnType == typeof(bool))
				{
					return (bool)IsOnGroundMethod.Invoke(player, null);
				}
			}
			catch
			{
			}
			return false;
		}

		private static void ClearFallSpeed(Player player)
		{
			try
			{
				if (FallSpeedField != null)
				{
					FallSpeedField.SetValue(player, 0f);
				}
			}
			catch
			{
			}
		}

		private static bool IsHammerEquipped(Player player)
		{
			try
			{
				object obj = GetRightItemMethod?.Invoke(player, null);
				if (obj == null)
				{
					return false;
				}
				object obj2 = AccessTools.Field(obj.GetType(), "m_shared")?.GetValue(obj);
				if (obj2 != null)
				{
					string text = AccessTools.Field(obj2.GetType(), "m_name")?.GetValue(obj2) as string;
					if (!string.IsNullOrEmpty(text) && text.IndexOf("hammer", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return true;
					}
				}
				object? obj3 = AccessTools.Field(obj.GetType(), "m_dropPrefab")?.GetValue(obj);
				GameObject val = (GameObject)((obj3 is GameObject) ? obj3 : null);
				return (Object)(object)val != (Object)null && ((Object)val).name.IndexOf("hammer", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			catch
			{
				return false;
			}
		}

		private static void SetFly(Player player, bool enabled)
		{
			try
			{
				if (!((Object)(object)player == (Object)null) && player.InDebugFlyMode() != enabled)
				{
					ToggleDebugFlyMethod?.Invoke(player, null);
				}
			}
			catch
			{
			}
		}

		private void DisableModEffects(Player player)
		{
			if (!((Object)(object)player == (Object)null))
			{
				if (_flyApplied && player.InDebugFlyMode())
				{
					SetFly(player, enabled: false);
				}
				Rigidbody body = GetBody(player);
				if ((Object)(object)body != (Object)null)
				{
					body.useGravity = true;
				}
				_flyApplied = false;
				_haveLastFlyPosition = false;
				_floating = false;
				_featherFalling = false;
				_protectThisDrop = false;
			}
		}

		private void ResetRuntimeState()
		{
			Player trackedPlayer = _trackedPlayer;
			_trackedPlayer = null;
			_flyApplied = false;
			_haveLastFlyPosition = false;
			_floating = false;
			_featherFalling = false;
			_protectThisDrop = false;
			if ((Object)(object)trackedPlayer != (Object)null)
			{
				Rigidbody body = GetBody(trackedPlayer);
				if ((Object)(object)body != (Object)null)
				{
					body.useGravity = true;
				}
			}
		}

		internal bool ProtectingCurrentDrop(Player player)
		{
			return _protectThisDrop && (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)Player.m_localPlayer;
		}

		private void OnDestroy()
		{
			Player localPlayer = Player.m_localPlayer;
			Rigidbody body = GetBody(localPlayer);
			if ((Object)(object)body != (Object)null)
			{
				body.useGravity = true;
			}
			if ((Object)(object)localPlayer != (Object)null && _flyApplied)
			{
				SetFly(localPlayer, enabled: false);
			}
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}
	}
	[HarmonyPatch(typeof(Character), "Damage")]
	internal static class ProtectedDropDamagePatch
	{
		private static bool Prefix(Character __instance, HitData hit)
		{
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			Plugin instance = Plugin.Instance;
			if ((Object)(object)instance == (Object)null || !instance.ProtectingCurrentDrop(val) || hit == null)
			{
				return true;
			}
			try
			{
				if ((Object)(object)hit.GetAttacker() == (Object)null)
				{
					object? obj = (AccessTools.Field(typeof(Character), "m_body") ?? AccessTools.Field(typeof(Player), "m_body"))?.GetValue(val);
					Rigidbody val2 = (Rigidbody)((obj is Rigidbody) ? obj : null);
					if ((Object)(object)val2 == (Object)null || val2.velocity.y <= 0.5f)
					{
						return false;
					}
				}
			}
			catch
			{
			}
			return true;
		}
	}
}