Decompiled source of WeaponBash v1.0.0

bin/WeaponBash.dll

Decompiled 2 days ago
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));
		}
	}
}