using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using HarmonyLib; using Landfall.TABS; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyVersion("0.0.0.0")] namespace WeaponBashMod; [BepInPlugin("joshu.weaponbash", "Weapon Bash", "1.0.0")] public class Plugin : BaseUnityPlugin { private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) Debug.Log((object)"[WeaponBash] Weapon Bash loaded"); new Harmony("joshu.weaponbash").PatchAll(); } } public class WeaponBash : MonoBehaviour { public float Radius = 1.75f; public float Damage = 5f; public float Knockback = 0f; public float WeaponShove = 18f; public float SwingBoost = 6f; public float Cooldown = 3f; public float UpwardsRatio = 0.35f; public float BashWindow = 0.8f; public float MinContactSpeed = 2f; public bool StartReady = true; public bool RangedOnly = true; private const float SCAN_INTERVAL = 0.2f; private const int MAX_SCAN_HITS = 128; private static readonly Collider[] scanBuffer = (Collider[])(object)new Collider[128]; private Unit unit; private DataHandler data; private float cooldownCounter; private float scanCounter; private float armedUntil; private readonly List hookedWeapons = new List(); private readonly List hitThisBash = new List(); private void Start() { unit = ((Component)this).GetComponentInParent(); if ((Object)(object)unit == (Object)null || (Object)(object)unit.data == (Object)null) { ((Behaviour)this).enabled = false; return; } data = unit.data; cooldownCounter = (StartReady ? Cooldown : 0f); scanCounter = Random.Range(0f, 0.2f); } private void Update() { //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) if (data.Dead || (Object)(object)data.mainRig == (Object)null || (Object)(object)data.targetData == (Object)null) { return; } cooldownCounter += Time.deltaTime; scanCounter += Time.deltaTime; if (cooldownCounter < Cooldown || scanCounter < 0.2f) { return; } scanCounter = 0f; if (RangedOnly && !HoldsRangedWeapon()) { return; } HookHeldWeapons(); Vector3 position = data.mainRig.position; Unit val = FindNearestEnemy(position); if ((Object)(object)val == (Object)null) { return; } cooldownCounter = 0f; if (WeaponBashConfig.DebugLogs) { UnitBlueprint unitBlueprint = unit.unitBlueprint; object obj; if (unitBlueprint == null) { obj = null; } else { DatabaseEntity entity = unitBlueprint.Entity; obj = ((entity != null) ? entity.Name : null); } UnitBlueprint unitBlueprint2 = val.unitBlueprint; object obj2; if (unitBlueprint2 == null) { obj2 = null; } else { DatabaseEntity entity2 = unitBlueprint2.Entity; obj2 = ((entity2 != null) ? entity2.Name : null); } Debug.Log((object)("[WeaponBash] " + (string?)obj + " bashing at " + (string?)obj2)); } Bash(position, val); } private bool HoldsRangedWeapon() { if ((Object)(object)unit.WeaponHandler == (Object)null) { return false; } Weapon rightWeapon = unit.WeaponHandler.rightWeapon; Weapon leftWeapon = unit.WeaponHandler.leftWeapon; return ((Object)(object)rightWeapon != (Object)null && rightWeapon.isRange) || ((Object)(object)leftWeapon != (Object)null && leftWeapon.isRange); } private void HookHeldWeapons() { if (!((Object)(object)unit.WeaponHandler == (Object)null)) { HookWeapon(unit.WeaponHandler.rightWeapon); HookWeapon(unit.WeaponHandler.leftWeapon); } } private void HookWeapon(Weapon weapon) { if ((Object)(object)weapon == (Object)null) { return; } CollisionWeapon componentInChildren = ((Component)weapon).GetComponentInChildren(); if (!((Object)(object)componentInChildren == (Object)null) && !hookedWeapons.Contains(componentInChildren)) { componentInChildren.AddCollisionAction((Action)delegate(Collision collision, float impact) { OnWeaponContact(collision); }); hookedWeapons.Add(componentInChildren); } } private Unit FindNearestEnemy(Vector3 origin) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) Unit result = null; float num = float.MaxValue; int num2 = Physics.OverlapSphereNonAlloc(origin, Radius, scanBuffer); for (int i = 0; i < num2; i++) { Rigidbody attachedRigidbody = scanBuffer[i].attachedRigidbody; if ((Object)(object)attachedRigidbody == (Object)null) { continue; } Unit componentInParent = ((Component)attachedRigidbody).GetComponentInParent(); if (!((Object)(object)componentInParent == (Object)null) && !((Object)(object)componentInParent == (Object)(object)unit) && componentInParent.Team != unit.Team && !((Object)(object)componentInParent.data == (Object)null) && !componentInParent.data.Dead && !((Object)(object)componentInParent.data.mainRig == (Object)null)) { Vector3 val = componentInParent.data.mainRig.position - origin; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = componentInParent; } } } return result; } private void Bash(Vector3 origin, Unit nearest) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: 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) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0065: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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_00a8: Unknown result type (might be due to invalid IL or missing references) hitThisBash.Clear(); armedUntil = Time.time + BashWindow; Vector3 position = nearest.data.mainRig.position; Vector3 val = KnockbackDirection(position, origin); bool flag = false; if ((Object)(object)unit.WeaponHandler != (Object)null) { flag |= SwingWeapon(unit.WeaponHandler.rightWeapon, position, nearest, val); flag |= SwingWeapon(unit.WeaponHandler.leftWeapon, position, nearest, val); } if (!flag) { unit.Attack(position, nearest.data.mainRig, val); } ShoveRig(data.rightHand, val, WeaponShove * 0.6f); ShoveRig(data.leftHand, val, WeaponShove * 0.6f); Vector3 val2 = val; val2.y = 0f; data.mainRig.AddForce(val2 * (WeaponShove * 0.25f), (ForceMode)2); } private void ShoveRig(Transform limb, Vector3 direction, float speed) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)limb == (Object)null)) { Rigidbody component = ((Component)limb).GetComponent(); if (!((Object)(object)component == (Object)null)) { component.AddForce(direction * speed, (ForceMode)2); } } } private bool SwingWeapon(Weapon weapon, Vector3 aim, Unit nearest, Vector3 swingDirection) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_009f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)weapon == (Object)null) { return false; } if (weapon.isRange) { ShoveWeapon(weapon, swingDirection, WeaponShove * 2f); return false; } MeleeWeapon val = (MeleeWeapon)(object)((weapon is MeleeWeapon) ? weapon : null); if ((Object)(object)val != (Object)null && SwingBoost > 1f) { float curveForce = val.curveForce; val.curveForce = curveForce * SwingBoost; ((MonoBehaviour)this).StartCoroutine(RestoreSwingForce(val, curveForce)); } weapon.Attack(aim, nearest.data.mainRig, swingDirection, true); ShoveWeapon(weapon, swingDirection, WeaponShove); return true; } private IEnumerator RestoreSwingForce(MeleeWeapon melee, float original) { yield return (object)new WaitForSeconds(BashWindow); if ((Object)(object)melee != (Object)null) { melee.curveForce = original; } } private void OnWeaponContact(Collision collision) { //IL_0033: 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_008c: 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_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) if (Time.time > armedUntil || collision == null || (Object)(object)collision.rigidbody == (Object)null) { return; } Vector3 relativeVelocity = collision.relativeVelocity; if (((Vector3)(ref relativeVelocity)).magnitude < MinContactSpeed) { return; } DataHandler componentInParent = ((Component)collision.rigidbody).GetComponentInParent(); if ((Object)(object)componentInParent == (Object)null || (Object)(object)componentInParent == (Object)(object)data || componentInParent.Dead || componentInParent.team == data.team || (Object)(object)componentInParent.mainRig == (Object)null || hitThisBash.Contains(componentInParent)) { return; } hitThisBash.Add(componentInParent); if (WeaponBashConfig.DebugLogs) { UnitBlueprint unitBlueprint = unit.unitBlueprint; object obj; if (unitBlueprint == null) { obj = null; } else { DatabaseEntity entity = unitBlueprint.Entity; obj = ((entity != null) ? entity.Name : null); } Unit obj2 = componentInParent.unit; object obj3; if (obj2 == null) { obj3 = null; } else { UnitBlueprint unitBlueprint2 = obj2.unitBlueprint; if (unitBlueprint2 == null) { obj3 = null; } else { DatabaseEntity entity2 = unitBlueprint2.Entity; obj3 = ((entity2 != null) ? entity2.Name : null); } } Debug.Log((object)("[WeaponBash] " + (string?)obj + " bash connected with " + (string?)obj3)); } Vector3 val = KnockbackDirection(componentInParent.mainRig.position, data.mainRig.position); if ((Object)(object)componentInParent.healthHandler != (Object)null) { ((Damagable)componentInParent.healthHandler).TakeDamage(Damage, val, unit, (DamageType)2); } if (Knockback > 0f) { componentInParent.mainRig.AddForce(val * Knockback, (ForceMode)2); if ((Object)(object)componentInParent.hip != (Object)null) { componentInParent.hip.AddForce(val * Knockback * 0.5f, (ForceMode)2); } } } private void ShoveWeapon(Weapon weapon, Vector3 direction, float force) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)weapon == (Object)null) && !((Object)(object)weapon.rigidbody == (Object)null)) { weapon.rigidbody.AddForce(direction * force, (ForceMode)2); } } private Vector3 KnockbackDirection(Vector3 target, Vector3 origin) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) Vector3 val = target - origin; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.001f) { val = ((Component)data.mainRig).transform.forward; } Vector3 val2 = ((Vector3)(ref val)).normalized + Vector3.up * UpwardsRatio; return ((Vector3)(ref val2)).normalized; } } public static class WeaponBashConfig { public static bool Enabled = true; public static bool DebugLogs = false; public static float Radius = 1.75f; public static float Damage = 5f; public static float Knockback = 0f; public static float Cooldown = 3f; public static bool RangedOnly = true; } [HarmonyPatch(typeof(Unit), "InitializeUnit")] public static class WeaponBashUnitPatch { private static void Postfix(Unit __instance) { if (!WeaponBashConfig.Enabled || (Object)(object)((Component)__instance).GetComponentInChildren() != (Object)null) { return; } WeaponBash weaponBash = ((Component)__instance).gameObject.AddComponent(); weaponBash.Radius = WeaponBashConfig.Radius; weaponBash.Damage = WeaponBashConfig.Damage; weaponBash.Knockback = WeaponBashConfig.Knockback; weaponBash.Cooldown = WeaponBashConfig.Cooldown; weaponBash.RangedOnly = WeaponBashConfig.RangedOnly; if (WeaponBashConfig.DebugLogs) { UnitBlueprint unitBlueprint = __instance.unitBlueprint; object obj; if (unitBlueprint == null) { obj = null; } else { DatabaseEntity entity = unitBlueprint.Entity; obj = ((entity != null) ? entity.Name : null); } Debug.Log((object)("[WeaponBash] attached to " + (string?)obj)); } } }