Events all over melee (#16997)
This commit is contained in:
@@ -18,7 +18,6 @@ using Content.Shared.Weapons.Melee.Events;
|
||||
using Content.Shared.Weapons.Ranged.Components;
|
||||
using Content.Shared.Weapons.Ranged.Systems;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.Collections;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Physics;
|
||||
@@ -74,6 +73,9 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
SubscribeLocalEvent<MeleeWeaponComponent, HandSelectedEvent>(OnMeleeSelected);
|
||||
SubscribeLocalEvent<MeleeWeaponComponent, GunShotEvent>(OnMeleeShot);
|
||||
SubscribeLocalEvent<BonusMeleeDamageComponent, GetMeleeDamageEvent>(OnGetBonusMeleeDamage);
|
||||
SubscribeLocalEvent<BonusMeleeDamageComponent, GetHeavyDamageModifierEvent>(OnGetBonusHeavyDamageModifier);
|
||||
SubscribeLocalEvent<BonusMeleeAttackRateComponent, GetMeleeAttackRateEvent>(OnGetBonusMeleeAttackRate);
|
||||
SubscribeLocalEvent<BonusMeleeAttackRateComponent, GetHeavyWindupModifierEvent>(OnGetBonusHeavyWindupModifier);
|
||||
|
||||
SubscribeAllEvent<HeavyAttackEvent>(OnHeavyAttack);
|
||||
SubscribeAllEvent<LightAttackEvent>(OnLightAttack);
|
||||
@@ -112,7 +114,8 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
|
||||
private void OnMeleeSelected(EntityUid uid, MeleeWeaponComponent component, HandSelectedEvent args)
|
||||
{
|
||||
if (component.AttackRate.Equals(0f))
|
||||
var attackRate = GetAttackRate(uid, args.User, component);
|
||||
if (attackRate.Equals(0f))
|
||||
return;
|
||||
|
||||
if (!component.ResetOnHandSelected)
|
||||
@@ -123,7 +126,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
|
||||
// If someone swaps to this weapon then reset its cd.
|
||||
var curTime = Timing.CurTime;
|
||||
var minimum = curTime + TimeSpan.FromSeconds(1 / component.AttackRate);
|
||||
var minimum = curTime + TimeSpan.FromSeconds(1 / attackRate);
|
||||
|
||||
if (minimum < component.NextAttack)
|
||||
return;
|
||||
@@ -143,7 +146,28 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
|
||||
private void OnGetBonusMeleeDamage(EntityUid uid, BonusMeleeDamageComponent component, ref GetMeleeDamageEvent args)
|
||||
{
|
||||
args.Damage += component.BonusDamage;
|
||||
if (component.BonusDamage != null)
|
||||
args.Damage += component.BonusDamage;
|
||||
if (component.DamageModifierSet != null)
|
||||
args.Modifiers.Add(component.DamageModifierSet);
|
||||
}
|
||||
|
||||
private void OnGetBonusHeavyDamageModifier(EntityUid uid, BonusMeleeDamageComponent component, ref GetHeavyDamageModifierEvent args)
|
||||
{
|
||||
args.DamageModifier += component.HeavyDamageFlatModifier;
|
||||
args.Multipliers *= component.HeavyDamageMultiplier;
|
||||
}
|
||||
|
||||
private void OnGetBonusMeleeAttackRate(EntityUid uid, BonusMeleeAttackRateComponent component, ref GetMeleeAttackRateEvent args)
|
||||
{
|
||||
args.Rate += component.FlatModifier;
|
||||
args.Multipliers *= component.Multiplier;
|
||||
}
|
||||
|
||||
private void OnGetBonusHeavyWindupModifier(EntityUid uid, BonusMeleeAttackRateComponent component, ref GetHeavyWindupModifierEvent args)
|
||||
{
|
||||
args.WindupModifier += component.HeavyWindupFlatModifier;
|
||||
args.Multipliers *= component.HeavyWindupMultiplier;
|
||||
}
|
||||
|
||||
private void OnStopAttack(StopAttackEvent msg, EntitySessionEventArgs args)
|
||||
@@ -276,15 +300,66 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
component.Range = state.Range;
|
||||
}
|
||||
|
||||
public DamageSpecifier GetDamage(EntityUid uid, MeleeWeaponComponent? component = null)
|
||||
/// <summary>
|
||||
/// Gets the total damage a weapon does, including modifiers like wielding and enablind/disabling
|
||||
/// </summary>
|
||||
public DamageSpecifier GetDamage(EntityUid uid, EntityUid user, MeleeWeaponComponent? component = null)
|
||||
{
|
||||
if (!Resolve(uid, ref component, false))
|
||||
return new DamageSpecifier();
|
||||
|
||||
var ev = new GetMeleeDamageEvent(new (component.Damage));
|
||||
var ev = new GetMeleeDamageEvent(uid, new (component.Damage), new(), user);
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
|
||||
return ev.Damage;
|
||||
return DamageSpecifier.ApplyModifierSets(ev.Damage, ev.Modifiers);
|
||||
}
|
||||
|
||||
public float GetAttackRate(EntityUid uid, EntityUid user, MeleeWeaponComponent? component = null)
|
||||
{
|
||||
if (!Resolve(uid, ref component))
|
||||
return 0;
|
||||
|
||||
var ev = new GetMeleeAttackRateEvent(uid, component.AttackRate, 1, user);
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
|
||||
return ev.Rate * ev.Multipliers;
|
||||
}
|
||||
|
||||
public FixedPoint2 GetHeavyDamageModifier(EntityUid uid, EntityUid user, MeleeWeaponComponent? component = null)
|
||||
{
|
||||
if (!Resolve(uid, ref component))
|
||||
return FixedPoint2.Zero;
|
||||
|
||||
var ev = new GetHeavyDamageModifierEvent(uid, component.HeavyDamageModifier, 1, user);
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
|
||||
return ev.DamageModifier * ev.Multipliers;
|
||||
}
|
||||
|
||||
public float GetHeavyWindupModifier(EntityUid uid, EntityUid user, MeleeWeaponComponent? component = null)
|
||||
{
|
||||
if (!Resolve(uid, ref component))
|
||||
return 0;
|
||||
|
||||
var ev = new GetHeavyWindupModifierEvent(uid, component.HeavyWindupModifier, 1, user);
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
|
||||
return ev.WindupModifier * ev.Multipliers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets how long it takes a heavy attack to windup.
|
||||
/// </summary>
|
||||
public TimeSpan GetWindupTime(EntityUid uid, EntityUid user, MeleeWeaponComponent? component = null)
|
||||
{
|
||||
if (!Resolve(uid, ref component))
|
||||
return TimeSpan.Zero;
|
||||
|
||||
var attackRate = GetAttackRate(uid, user, component);
|
||||
|
||||
return attackRate > 0
|
||||
? TimeSpan.FromSeconds(1 / attackRate * GetHeavyWindupModifier(uid, user, component))
|
||||
: TimeSpan.Zero;
|
||||
}
|
||||
|
||||
public bool TryGetWeapon(EntityUid entity, out EntityUid weaponUid, [NotNullWhen(true)] out MeleeWeaponComponent? melee)
|
||||
@@ -388,7 +463,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
}
|
||||
|
||||
// Windup time checked elsewhere.
|
||||
var fireRate = TimeSpan.FromSeconds(1f / weapon.AttackRate);
|
||||
var fireRate = TimeSpan.FromSeconds(1f / GetAttackRate(weaponUid, user, weapon));
|
||||
var swings = 0;
|
||||
|
||||
// TODO: If we get autoattacks then probably need a shotcounter like guns so we can do timing properly.
|
||||
@@ -451,7 +526,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
/// <summary>
|
||||
/// When an attack is released get the actual modifier for damage done.
|
||||
/// </summary>
|
||||
public float GetModifier(MeleeWeaponComponent component, bool lightAttack)
|
||||
public float GetModifier(EntityUid uid, EntityUid user, MeleeWeaponComponent component, bool lightAttack)
|
||||
{
|
||||
if (lightAttack)
|
||||
return 1f;
|
||||
@@ -461,7 +536,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
return 0f;
|
||||
|
||||
var releaseTime = (Timing.CurTime - windup.Value).TotalSeconds;
|
||||
var windupTime = component.WindupTime.TotalSeconds;
|
||||
var windupTime = GetWindupTime(uid, user, component).TotalSeconds;
|
||||
|
||||
// Wraps around back to 0
|
||||
releaseTime %= (2 * windupTime);
|
||||
@@ -479,14 +554,14 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
fraction = 0;
|
||||
|
||||
DebugTools.Assert(fraction <= 1);
|
||||
return (float) fraction * component.HeavyDamageModifier.Float();
|
||||
return (float) fraction * GetHeavyDamageModifier(uid, user, component).Float();
|
||||
}
|
||||
|
||||
protected abstract bool InRange(EntityUid user, EntityUid target, float range, ICommonSession? session);
|
||||
|
||||
protected virtual void DoLightAttack(EntityUid user, LightAttackEvent ev, EntityUid meleeUid, MeleeWeaponComponent component, ICommonSession? session)
|
||||
{
|
||||
var damage = GetDamage(meleeUid, component) * GetModifier(component, true);
|
||||
var damage = GetDamage(meleeUid, user, component) * GetModifier(meleeUid, user, component, true);
|
||||
|
||||
// For consistency with wide attacks stuff needs damageable.
|
||||
if (Deleted(ev.Target) ||
|
||||
@@ -560,7 +635,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
{
|
||||
Audio.PlayPredicted(hitEvent.HitSoundOverride, meleeUid, user);
|
||||
}
|
||||
else if (GetDamage(meleeUid, component).Total.Equals(FixedPoint2.Zero) && component.HitSound != null)
|
||||
else if (GetDamage(meleeUid, user, component).Total.Equals(FixedPoint2.Zero) && component.HitSound != null)
|
||||
{
|
||||
Audio.PlayPredicted(component.HitSound, meleeUid, user);
|
||||
}
|
||||
@@ -593,7 +668,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem
|
||||
var direction = targetMap.Position - userPos;
|
||||
var distance = Math.Min(component.Range, direction.Length);
|
||||
|
||||
var damage = GetDamage(meleeUid, component) * GetModifier(component, false);
|
||||
var damage = GetDamage(meleeUid, user, component) * GetModifier(meleeUid, user, component, false);
|
||||
var entities = ev.Entities;
|
||||
|
||||
if (entities.Count == 0)
|
||||
|
||||
Reference in New Issue
Block a user