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<ProjectileBaseline>();
if ((Object)(object)projectileBaseline == (Object)null)
{
projectileBaseline = ((Component)__instance).gameObject.AddComponent<ProjectileBaseline>();
}
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<ProjectileBaseline>();
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<MoveTransform>();
if ((Object)(object)val == (Object)null)
{
val = ((Component)__instance).GetComponentInChildren<MoveTransform>();
}
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<ProjectileBaseline>();
if ((Object)(object)projectileBaseline == (Object)null)
{
projectileBaseline = ((Component)__instance).GetComponentInChildren<ProjectileBaseline>();
}
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<DamageScaleTag>();
if ((Object)(object)damageScaleTag == (Object)null)
{
damageScaleTag = ((Component)__instance).gameObject.AddComponent<DamageScaleTag>();
}
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<DamageScaleTag>();
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<Rigidbody>();
if ((Object)(object)val == (Object)null)
{
val = ((Component)__instance).GetComponentInParent<Rigidbody>();
}
if ((Object)(object)val == (Object)null)
{
return;
}
MeleeWeapon component = ((Component)__instance).GetComponent<MeleeWeapon>();
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<DamageScaleTag>();
if ((Object)(object)damageScaleTag == (Object)null)
{
damageScaleTag = ((Component)__instance).gameObject.AddComponent<DamageScaleTag>();
}
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<DamageScaleTag>();
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<bool> Enabled;
public static ConfigEntry<float> MeleeBaselineSpeed;
public static ConfigEntry<float> ProjectileFallbackBaseline;
public static ConfigEntry<float> MinMultiplier;
public static ConfigEntry<float> MaxMultiplier;
public static ConfigEntry<bool> AffectMelee;
public static ConfigEntry<bool> AffectProjectiles;
public static ConfigEntry<bool> 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<bool>("General", "Enabled", true, "Scale damage by relative speed vs baseline (mult=1 at baseline).");
DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DebugLog", false, "Log multiplier calculations.");
AffectMelee = ((BaseUnityPlugin)this).Config.Bind<bool>("Scope", "AffectMelee", true, "Apply to melee CollisionWeapon hits.");
AffectProjectiles = ((BaseUnityPlugin)this).Config.Bind<bool>("Scope", "AffectProjectiles", true, "Apply to projectile hits.");
MeleeBaselineSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("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<float>("Baseline", "ProjectileFallbackBaseline", 40f, "Used if a projectile has no recorded initial speed.");
MinMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Clamp", "MinMultiplier", 0.15f, "Floor for damage multiplier.");
MaxMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("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;
}
}
}
}