using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("VelocityDamage")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("VelocityDamage")] [assembly: AssemblyTitle("VelocityDamage")] [assembly: AssemblyVersion("1.0.0.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 VelocityDamage { [HarmonyPatch(typeof(MoveTransform), "InitializeVelocity")] internal static class MoveTransformInitPatch { private static void Postfix(MoveTransform __instance) { if (!Plugin.Enabled.Value || (Object)(object)__instance == (Object)null) { return; } float magnitude = ((Vector3)(ref __instance.velocity)).magnitude; if (!(magnitude < 0.01f)) { ProjectileBaseline projectileBaseline = ((Component)__instance).GetComponent(); if ((Object)(object)projectileBaseline == (Object)null) { projectileBaseline = ((Component)__instance).gameObject.AddComponent(); } projectileBaseline.Capture(magnitude); Plugin.Dbg("[VelocityDamage] projectile baseline=" + magnitude.ToString("0.##") + " on " + ((Object)((Component)__instance).gameObject).name); } } } [HarmonyPatch(typeof(MoveTransform), "Reset")] internal static class MoveTransformResetPatch { private static void Postfix(MoveTransform __instance) { if (!((Object)(object)__instance == (Object)null)) { ProjectileBaseline component = ((Component)__instance).GetComponent(); if ((Object)(object)component != (Object)null) { component.baselineSpeed = -1f; } } } } [HarmonyPatch(typeof(ProjectileHit), "DoGameplayEffects")] internal static class ProjectileHitVelocityPatch { [HarmonyPriority(0)] private static void Prefix(ProjectileHit __instance, HitData hit) { //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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Enabled.Value || !Plugin.AffectProjectiles.Value || (Object)(object)__instance == (Object)null || hit == null) { return; } MoveTransform val = ((Component)__instance).GetComponent(); if ((Object)(object)val == (Object)null) { val = ((Component)__instance).GetComponentInChildren(); } if (!((Object)(object)val == (Object)null)) { Vector3 velocity = val.velocity; Vector3 val2 = Vector3.zero; if ((Object)(object)hit.rigidbody != (Object)null) { val2 = hit.rigidbody.velocity; } Vector3 val3 = velocity - val2; float magnitude = ((Vector3)(ref val3)).magnitude; float baseline = Plugin.ProjectileFallbackBaseline.Value; ProjectileBaseline projectileBaseline = ((Component)__instance).GetComponent(); if ((Object)(object)projectileBaseline == (Object)null) { projectileBaseline = ((Component)__instance).GetComponentInChildren(); } if ((Object)(object)projectileBaseline != (Object)null && projectileBaseline.baselineSpeed > 0.01f) { baseline = projectileBaseline.baselineSpeed; } float num = Plugin.ComputeMultiplier(magnitude, baseline, squareCurve: true); DamageScaleTag damageScaleTag = ((Component)__instance).GetComponent(); if ((Object)(object)damageScaleTag == (Object)null) { damageScaleTag = ((Component)__instance).gameObject.AddComponent(); } if (!damageScaleTag.active) { damageScaleTag.originalDamage = __instance.damage; damageScaleTag.active = true; } __instance.damage = damageScaleTag.originalDamage * num; Plugin.Dbg("[VelocityDamage] proj rel=" + magnitude.ToString("0.##") + " base=" + baseline.ToString("0.##") + " mult=" + num.ToString("0.###") + " dmg=" + __instance.damage.ToString("0.#")); } } [HarmonyPriority(800)] private static void Postfix(ProjectileHit __instance) { if (!((Object)(object)__instance == (Object)null)) { DamageScaleTag component = ((Component)__instance).GetComponent(); if ((Object)(object)component != (Object)null && component.active) { __instance.damage = component.originalDamage; component.active = false; } } } } [HarmonyPatch(typeof(CollisionWeapon), "OnCollisionEnter")] internal static class CollisionWeaponVelocityPatch { [HarmonyPriority(0)] private static void Prefix(CollisionWeapon __instance, Collision collision) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Enabled.Value || !Plugin.AffectMelee.Value || (Object)(object)__instance == (Object)null || collision == null || (Object)(object)collision.rigidbody == (Object)null) { return; } Rigidbody val = ((Component)__instance).GetComponent(); if ((Object)(object)val == (Object)null) { val = ((Component)__instance).GetComponentInParent(); } if ((Object)(object)val == (Object)null) { return; } MeleeWeapon component = ((Component)__instance).GetComponent(); if (!((Object)(object)component != (Object)null) || component.canDealDamage) { Vector3 velocity = val.velocity; Vector3 velocity2 = collision.rigidbody.velocity; Vector3 val2 = velocity - velocity2; float magnitude = ((Vector3)(ref val2)).magnitude; float baseline = Mathf.Max(0.01f, Plugin.MeleeBaselineSpeed.Value); float num = Plugin.ComputeMultiplier(magnitude, baseline, squareCurve: false); DamageScaleTag damageScaleTag = ((Component)__instance).GetComponent(); if ((Object)(object)damageScaleTag == (Object)null) { damageScaleTag = ((Component)__instance).gameObject.AddComponent(); } if (!damageScaleTag.active) { damageScaleTag.originalDamage = __instance.damage; damageScaleTag.active = true; } __instance.damage = damageScaleTag.originalDamage * num; Plugin.Dbg("[VelocityDamage] melee rel=" + magnitude.ToString("0.##") + " base=" + baseline.ToString("0.##") + " mult=" + num.ToString("0.###") + " dmg=" + __instance.damage.ToString("0.#")); } } [HarmonyPriority(800)] private static void Postfix(CollisionWeapon __instance) { if (!((Object)(object)__instance == (Object)null)) { DamageScaleTag component = ((Component)__instance).GetComponent(); if ((Object)(object)component != (Object)null && component.active) { __instance.damage = component.originalDamage; component.active = false; } } } } public class DamageScaleTag : MonoBehaviour { public float originalDamage; public bool active; } [BepInPlugin("local.velocitydamage", "VelocityDamage", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string GUID = "local.velocitydamage"; public const string Name = "VelocityDamage"; public const string Version = "1.0.0"; public static ManualLogSource Log; public static ConfigEntry Enabled; public static ConfigEntry MeleeBaselineSpeed; public static ConfigEntry ProjectileFallbackBaseline; public static ConfigEntry MinMultiplier; public static ConfigEntry MaxMultiplier; public static ConfigEntry AffectMelee; public static ConfigEntry AffectProjectiles; public static ConfigEntry DebugLog; private void Awake() { //IL_0120: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Scale damage by relative speed vs baseline (mult=1 at baseline)."); DebugLog = ((BaseUnityPlugin)this).Config.Bind("General", "DebugLog", false, "Log multiplier calculations."); AffectMelee = ((BaseUnityPlugin)this).Config.Bind("Scope", "AffectMelee", true, "Apply to melee CollisionWeapon hits."); AffectProjectiles = ((BaseUnityPlugin)this).Config.Bind("Scope", "AffectProjectiles", true, "Apply to projectile hits."); MeleeBaselineSpeed = ((BaseUnityPlugin)this).Config.Bind("Baseline", "MeleeBaselineSpeed", 10f, "Relative speed (m/s) at which melee damage multiplier is 1. Typical TABS swings land around 6–15."); ProjectileFallbackBaseline = ((BaseUnityPlugin)this).Config.Bind("Baseline", "ProjectileFallbackBaseline", 40f, "Used if a projectile has no recorded initial speed."); MinMultiplier = ((BaseUnityPlugin)this).Config.Bind("Clamp", "MinMultiplier", 0.15f, "Floor for damage multiplier."); MaxMultiplier = ((BaseUnityPlugin)this).Config.Bind("Clamp", "MaxMultiplier", 3f, "Ceiling for damage multiplier."); new Harmony("local.velocitydamage").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"VelocityDamage 1.0.0 loaded."); } public static float ComputeMultiplier(float relativeSpeed, float baseline, bool squareCurve) { if (baseline < 0.01f) { baseline = 0.01f; } float num = relativeSpeed / baseline; return Mathf.Clamp(squareCurve ? (num * num) : Mathf.Sqrt(Mathf.Max(0f, num)), MinMultiplier.Value, MaxMultiplier.Value); } public static void Dbg(string msg) { if (DebugLog != null && DebugLog.Value) { Log.LogInfo((object)msg); } } } public class ProjectileBaseline : MonoBehaviour { public float baselineSpeed = -1f; public void Capture(float speed) { if (speed > 0.01f) { baselineSpeed = speed; } } } }