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<CollisionWeapon> hookedWeapons = new List<CollisionWeapon>();
private readonly List<DataHandler> hitThisBash = new List<DataHandler>();
private void Start()
{
unit = ((Component)this).GetComponentInParent<Unit>();
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<CollisionWeapon>();
if (!((Object)(object)componentInChildren == (Object)null) && !hookedWeapons.Contains(componentInChildren))
{
componentInChildren.AddCollisionAction((Action<Collision, float>)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<Unit>();
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<Rigidbody>();
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<DataHandler>();
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<WeaponBash>() != (Object)null)
{
return;
}
WeaponBash weaponBash = ((Component)__instance).gameObject.AddComponent<WeaponBash>();
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));
}
}
}