using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("HarderFeatherFallMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("HarderFeatherFallMod")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("7ac73af1-150f-446c-a73b-468543ca8ccc")]
[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.ValheimHarderFeatherFallMod", "Valheim - Harder Feather Fall Mod", "0.2.2")]
[BepInProcess("valheim.exe")]
public class HarderFeatherFallMod : BaseUnityPlugin
{
[HarmonyPatch(typeof(SEMan), "ModifyFallDamage")]
private class ModifyFallDamageSEManPatch
{
private static void Prefix(ref List<StatusEffect> ___m_statusEffects)
{
FeatherFallStatusIndex = ___m_statusEffects.FindIndex((StatusEffect se) => se.m_name == FeatherFallName);
AppliedDamageIndex = 0;
}
}
[HarmonyPatch(typeof(SE_Stats), "ModifyFallDamage")]
private class ModifyFallDamagePatch
{
private static void Prefix(ref float baseDamage, ref float damage, ref float ___m_fallDamageModifier)
{
if (FeatherFallStatusIndex != AppliedDamageIndex)
{
AppliedDamageIndex++;
return;
}
FeatherFallStatusIndex = -1;
AppliedDamageIndex = 0;
float fullFallVelocity = FullFallVelocity;
if (!EnableToggle.Value || !FeatherFallEnabled)
{
___m_fallDamageModifier = (FeatherFallEnabled ? (-1) : 0);
return;
}
if (AltMode.Value && !HardcoreMode.Value)
{
setDamageModifier(ref damage, ref ___m_fallDamageModifier, fullFallVelocity);
return;
}
___m_fallDamageModifier = -1f;
if (!WispLightEnabled || EnableEverywhere.Value || HardcoreMode.Value)
{
setStamDerivedDamage(ref damage, ref ___m_fallDamageModifier);
}
}
private static void setDamageModifier(ref float damage, ref float damageModifier, float vel)
{
if (StaminaPercentage == 0f)
{
if (FullFallVelocity > 5.4f)
{
CapturedFallVel = Mathf.Clamp(vel * 2.9f, 0f, 100f);
damage = CapturedFallVel;
damageModifier = 0f;
CapturedFallVel = 0f;
FullFallVelocity = 0f;
}
else
{
setFinalDamageModifier(ref damage, ref damageModifier);
}
}
else
{
setFinalDamageModifier(ref damage, ref damageModifier);
}
}
private static void setStamDerivedDamage(ref float damage, ref float damageModifier)
{
float num = 1f - StaminaPercentage;
damage = 0f;
damageModifier = num;
}
private static void setFinalDamageModifier(ref float damage, ref float damageModifier)
{
if (HardcoreMode.Value)
{
setStamDerivedDamage(ref damage, ref damageModifier);
}
else
{
damageModifier = -1f;
}
}
}
[HarmonyPatch(typeof(Player), "SetControls")]
private class SetControlsPatch
{
private static void Prefix(ref Player __instance, ref bool ___m_groundContact, ref float ___m_fallTimer)
{
//IL_0009: 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_009a: Unknown result type (might be due to invalid IL or missing references)
Vector3 vel = ((Character)__instance).GetVelocity();
StatusEffect val = ((Character)__instance).GetSEMan().GetStatusEffects().Find((StatusEffect effect) => effect.m_name == FeatherFallName);
StatusEffect? obj = ((Character)__instance).GetSEMan().GetStatusEffects().Find((StatusEffect effect) => effect.m_name == WispLightName);
FeatherFallEnabled = (Object)(object)val != (Object)null;
WispLightEnabled = (Object)(object)obj != (Object)null;
if (!EnableToggle.Value)
{
return;
}
PlayerFalling = ((Character)__instance).GetVelocity().y < 0f && !___m_groundContact;
if (AltMode.Value && FeatherFallEnabled && PlayerFalling && (!WispLightEnabled || HardcoreMode.Value))
{
((Character)__instance).UseStamina((float)AltStamDrain.Value / 100f);
}
StaminaPercentage = ((Character)__instance).GetStaminaPercentage();
if (AltMode.Value && PlayerFalling && FeatherFallEnabled && !((Character)__instance).IsFlying() && StaminaPercentage == 0f)
{
ElapsedFreeFallTime += Time.deltaTime;
}
else
{
ElapsedFreeFallTime = 0f;
}
if (AltMode.Value && FeatherFallEnabled && PlayerFalling && ElapsedFreeFallTime > 0f && ___m_fallTimer > 0f)
{
Task.Delay((Mathf.Abs(vel.y) > 50f) ? 200 : 100).ContinueWith(delegate
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
setVelocity(vel);
});
}
}
private static void setVelocity(Vector3 vel)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
FullFallVelocity = Mathf.Abs(vel.y);
}
}
[HarmonyPatch(typeof(SE_Stats), "ModifyWalkVelocity")]
private class ModifyWalkVelocityPatch
{
private static void Prefix(ref Vector3 vel, ref float ___m_maxMaxFallSpeed)
{
if (!EnableToggle.Value || !FeatherFallEnabled)
{
___m_maxMaxFallSpeed = (FeatherFallEnabled ? 5 : 0);
return;
}
if (WispLightEnabled)
{
___m_maxMaxFallSpeed = 5f;
}
if (AltMode.Value && !HardcoreMode.Value)
{
if (StaminaPercentage <= 0f)
{
___m_maxMaxFallSpeed = 0f;
}
else
{
___m_maxMaxFallSpeed = 5f;
}
return;
}
if ((!WispLightEnabled || EnableEverywhere.Value || (AltMode.Value && HardcoreMode.Value)) && StaminaPercentage != 0f)
{
___m_maxMaxFallSpeed = InitialMaxFallSpeed / StaminaPercentage;
}
if (AltMode.Value && StaminaPercentage <= 0f)
{
___m_maxMaxFallSpeed = 0f;
}
}
}
private const string pluginGUID = "afilbert.ValheimHarderFeatherFallMod";
private const string pluginName = "Valheim - Harder Feather Fall Mod";
private const string pluginVersion = "0.2.2";
public static ManualLogSource logger;
public static HarderFeatherFallMod plugin;
private readonly Harmony _harmony = new Harmony("afilbert.ValheimHarderFeatherFallMod");
public static bool Started = false;
public static int FeatherFallStatusIndex = -1;
public static int AppliedDamageIndex = -1;
private static string FeatherFallName = "$se_slowfall_name";
private static string WispLightName = "$item_demister";
private static bool FeatherFallEnabled = false;
private static bool WispLightEnabled = false;
private static bool PlayerFalling = false;
private static float StaminaPercentage = 0f;
private static float InitialMaxFallSpeed = 5f;
public static float ElapsedFreeFallTime = 0f;
public static float FullFallVelocity = 0f;
public static float CapturedFallVel = 0f;
public static ConfigEntry<bool> EnableToggle;
public static ConfigEntry<bool> EnableEverywhere;
public static ConfigEntry<bool> AltMode;
public static ConfigEntry<int> AltStamDrain;
public static ConfigEntry<bool> HardcoreMode;
private void Awake()
{
plugin = this;
logger = ((BaseUnityPlugin)this).Logger;
_harmony.PatchAll();
EnableToggle = ((BaseUnityPlugin)this).Config.Bind<bool>("Mod", "Enable Mod", true, "Enable this mod");
EnableEverywhere = ((BaseUnityPlugin)this).Config.Bind<bool>("Mod", "Hard mode: Enabled even when Wisplight equipped", false, "Stamina affects fall speed/damage even when Wisplight equipped");
AltMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Stamina Mode Override", "Drains stamina while aloft when Wisplight unequipped", false, "Uses stamina to stay aloft without Wisplight");
AltStamDrain = ((BaseUnityPlugin)this).Config.Bind<int>("Stamina Mode Override", "Stamina drain unit (larger drains faster)", 10, "Stamina drain unit");
HardcoreMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Stamina Mode Override", "Hardcore mode: Drains stamina & affects fall speed/damage (only works if Stamina Mode Override enabled)", false, "Uses stamina while aloft, regardless of Wisplight, & affects fall speed/damage");
}
}