Events all over melee (#16997)

This commit is contained in:
Nemanja
2023-06-07 16:26:45 -04:00
committed by GitHub
parent 937aae14ff
commit 37d3056809
9 changed files with 170 additions and 34 deletions

View File

@@ -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)