From dd044f4a91effc6cf9b0100db27221768cf72e11 Mon Sep 17 00:00:00 2001 From: Nemanja <98561806+EmoGarbage404@users.noreply.github.com> Date: Sun, 28 May 2023 03:03:25 -0400 Subject: [PATCH] Make melee damage not go through MeleeHitEvent.cs (#16881) Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> --- .../Electrocution/ElectrocutionSystem.cs | 16 ++++++------- .../Stunnable/Systems/StunbatonSystem.cs | 10 ++++---- Content.Server/Tools/ToolSystem.Welder.cs | 8 +++---- .../Melee/EnergySword/EnergySwordSystem.cs | 10 ++++---- .../Weapons/Melee/MeleeWeaponSystem.cs | 15 +----------- .../Components/BonusMeleeDamageComponent.cs | 17 ++++++++++++++ .../Weapons/Melee/Events/MeleeHitEvent.cs | 7 ++++++ .../Weapons/Melee/SharedMeleeWeaponSystem.cs | 23 ++++++++++++++++--- Content.Shared/Wieldable/WieldableSystem.cs | 15 +++++------- 9 files changed, 73 insertions(+), 48 deletions(-) create mode 100644 Content.Shared/Weapons/Melee/Components/BonusMeleeDamageComponent.cs diff --git a/Content.Server/Electrocution/ElectrocutionSystem.cs b/Content.Server/Electrocution/ElectrocutionSystem.cs index bb53b7a374..487c556873 100644 --- a/Content.Server/Electrocution/ElectrocutionSystem.cs +++ b/Content.Server/Electrocution/ElectrocutionSystem.cs @@ -6,6 +6,7 @@ using Content.Server.NodeContainer.Nodes; using Content.Server.Power.Components; using Content.Server.Power.EntitySystems; using Content.Server.Power.NodeGroups; +using Content.Server.Weapons.Melee; using Content.Shared.Damage; using Content.Shared.Damage.Prototypes; using Content.Shared.Database; @@ -37,6 +38,7 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly StatusEffectsSystem _statusEffects = default!; [Dependency] private readonly SharedJitteringSystem _jittering = default!; + [Dependency] private readonly MeleeWeaponSystem _meleeWeapon = default!; [Dependency] private readonly SharedStunSystem _stun = default!; [Dependency] private readonly SharedStutteringSystem _stuttering = default!; [Dependency] private readonly SharedPopupSystem _popup = default!; @@ -161,12 +163,8 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem if (!electrified.OnAttacked) return; - //Dont shock if the attacker used a toy - if (EntityManager.TryGetComponent(args.Used, out var meleeWeaponComponent)) - { - if (meleeWeaponComponent.Damage.Total == 0) - return; - } + if (_meleeWeapon.GetDamage(args.Used).Total == 0) + return; TryDoElectrifiedAct(uid, args.User, 1, electrified); } @@ -220,7 +218,7 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem entity, uid, (int) (electrified.ShockDamage * MathF.Pow(RecursiveDamageMultiplier, depth)), - TimeSpan.FromSeconds(electrified.ShockTime * MathF.Pow(RecursiveTimeMultiplier, depth)), + TimeSpan.FromSeconds(electrified.ShockTime * MathF.Pow(RecursiveTimeMultiplier, depth)), true, electrified.SiemensCoefficient ); @@ -249,7 +247,7 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem uid, node, (int) (electrified.ShockDamage * MathF.Pow(RecursiveDamageMultiplier, depth) * damageMult), - TimeSpan.FromSeconds(electrified.ShockTime * MathF.Pow(RecursiveTimeMultiplier, depth) * timeMult), + TimeSpan.FromSeconds(electrified.ShockTime * MathF.Pow(RecursiveTimeMultiplier, depth) * timeMult), true, electrified.SiemensCoefficient); } @@ -374,7 +372,7 @@ public sealed class ElectrocutionSystem : SharedElectrocutionSystem { return false; } - + if (!_statusEffects.TryAddStatusEffect(uid, StatusEffectKey, time, refresh, statusEffects)) return false; diff --git a/Content.Server/Stunnable/Systems/StunbatonSystem.cs b/Content.Server/Stunnable/Systems/StunbatonSystem.cs index 61daf523c6..97faac5b28 100644 --- a/Content.Server/Stunnable/Systems/StunbatonSystem.cs +++ b/Content.Server/Stunnable/Systems/StunbatonSystem.cs @@ -2,6 +2,7 @@ using Content.Server.Power.Components; using Content.Server.Power.Events; using Content.Server.Stunnable.Components; using Content.Shared.Audio; +using Content.Shared.Damage; using Content.Shared.Damage.Events; using Content.Shared.Examine; using Content.Shared.Interaction.Events; @@ -27,15 +28,16 @@ namespace Content.Server.Stunnable.Systems SubscribeLocalEvent(OnUseInHand); SubscribeLocalEvent(OnExamined); SubscribeLocalEvent(OnStaminaHitAttempt); - SubscribeLocalEvent(OnMeleeHit); + SubscribeLocalEvent(OnGetMeleeDamage); } - private void OnMeleeHit(EntityUid uid, StunbatonComponent component, MeleeHitEvent args) + private void OnGetMeleeDamage(EntityUid uid, StunbatonComponent component, ref GetMeleeDamageEvent args) { - if (!component.Activated) return; + if (!component.Activated) + return; // Don't apply damage if it's activated; just do stamina damage. - args.BonusDamage -= args.BaseDamage; + args.Damage = new DamageSpecifier(); } private void OnStaminaHitAttempt(EntityUid uid, StunbatonComponent component, ref StaminaDamageOnHitAttemptEvent args) diff --git a/Content.Server/Tools/ToolSystem.Welder.cs b/Content.Server/Tools/ToolSystem.Welder.cs index 43f43dc9d4..47c7a965e6 100644 --- a/Content.Server/Tools/ToolSystem.Welder.cs +++ b/Content.Server/Tools/ToolSystem.Welder.cs @@ -44,13 +44,13 @@ namespace Content.Server.Tools SubscribeLocalEvent(OnWelderDoAfter); SubscribeLocalEvent(OnWelderShutdown); SubscribeLocalEvent(OnWelderGetState); - SubscribeLocalEvent(OnMeleeHit); + SubscribeLocalEvent(OnGetMeleeDamage); } - private void OnMeleeHit(EntityUid uid, WelderComponent component, MeleeHitEvent args) + private void OnGetMeleeDamage(EntityUid uid, WelderComponent component, ref GetMeleeDamageEvent args) { - if (!args.Handled && component.Lit) - args.BonusDamage += component.LitMeleeDamageBonus; + if (component.Lit) + args.Damage += component.LitMeleeDamageBonus; } public (FixedPoint2 fuel, FixedPoint2 capacity) GetWelderFuelAndCapacity(EntityUid uid, WelderComponent? welder = null, SolutionContainerManagerComponent? solutionContainer = null) diff --git a/Content.Server/Weapons/Melee/EnergySword/EnergySwordSystem.cs b/Content.Server/Weapons/Melee/EnergySword/EnergySwordSystem.cs index 823ee642cf..5251befeb4 100644 --- a/Content.Server/Weapons/Melee/EnergySword/EnergySwordSystem.cs +++ b/Content.Server/Weapons/Melee/EnergySword/EnergySwordSystem.cs @@ -28,7 +28,7 @@ public sealed class EnergySwordSystem : EntitySystem base.Initialize(); SubscribeLocalEvent(OnMapInit); - SubscribeLocalEvent(OnMeleeHit); + SubscribeLocalEvent(OnGetMeleeDamage); SubscribeLocalEvent(OnUseInHand); SubscribeLocalEvent(OnInteractUsing); SubscribeLocalEvent(OnIsHotEvent); @@ -42,13 +42,13 @@ public sealed class EnergySwordSystem : EntitySystem comp.BladeColor = _random.Pick(comp.ColorOptions); } - private void OnMeleeHit(EntityUid uid, EnergySwordComponent comp, MeleeHitEvent args) + private void OnGetMeleeDamage(EntityUid uid, EnergySwordComponent comp, ref GetMeleeDamageEvent args) { if (!comp.Activated) return; // Overrides basic blunt damage with burn+slash as set in yaml - args.BonusDamage = comp.LitDamageBonus; + args.Damage = comp.LitDamageBonus; } private void OnUseInHand(EntityUid uid, EnergySwordComponent comp, UseInHandEvent args) @@ -57,7 +57,7 @@ public sealed class EnergySwordSystem : EntitySystem return; args.Handled = true; - + if (comp.Activated) { var ev = new EnergySwordDeactivatedEvent(); @@ -120,7 +120,7 @@ public sealed class EnergySwordSystem : EntitySystem { malus.Malus += comp.LitDisarmMalus; } - + _audio.Play(comp.ActivateSound, Filter.Pvs(uid, entityManager: EntityManager), uid, true, comp.ActivateSound.Params); comp.Activated = true; diff --git a/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs b/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs index 39c40854ea..c67f8079a7 100644 --- a/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs +++ b/Content.Server/Weapons/Melee/MeleeWeaponSystem.cs @@ -62,16 +62,7 @@ public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem if (!args.CanInteract || !args.CanAccess || component.HideFromExamine) return; - var getDamage = new MeleeHitEvent(new List(), args.User, uid, component.Damage); - getDamage.IsHit = false; - RaiseLocalEvent(uid, getDamage); - - var damageSpec = GetDamage(component); - - if (damageSpec == null) - damageSpec = new DamageSpecifier(); - - damageSpec += getDamage.BonusDamage; + var damageSpec = GetDamage(uid, component); if (damageSpec.Total == FixedPoint2.Zero) return; @@ -115,10 +106,6 @@ public sealed class MeleeWeaponSystem : SharedMeleeWeaponSystem return true; } - private DamageSpecifier? GetDamage(MeleeWeaponComponent component) - { - return component.Damage.Total > FixedPoint2.Zero ? component.Damage : null; - } protected override void Popup(string message, EntityUid? uid, EntityUid? user) { diff --git a/Content.Shared/Weapons/Melee/Components/BonusMeleeDamageComponent.cs b/Content.Shared/Weapons/Melee/Components/BonusMeleeDamageComponent.cs new file mode 100644 index 0000000000..5ed6a26531 --- /dev/null +++ b/Content.Shared/Weapons/Melee/Components/BonusMeleeDamageComponent.cs @@ -0,0 +1,17 @@ +using Content.Shared.Damage; + +namespace Content.Shared.Weapons.Melee.Components; + +/// +/// This is used for adding in bonus damage via +/// This exists only for event relays and doing entity shenanigans. +/// +[RegisterComponent, NetworkedComponent] +public sealed class BonusMeleeDamageComponent : Component +{ + /// + /// The damage that will be applied. + /// + [DataField("bonusDamage", required: true)] + public DamageSpecifier BonusDamage = default!; +} diff --git a/Content.Shared/Weapons/Melee/Events/MeleeHitEvent.cs b/Content.Shared/Weapons/Melee/Events/MeleeHitEvent.cs index 5ba2f4f0bf..cb7e28890b 100644 --- a/Content.Shared/Weapons/Melee/Events/MeleeHitEvent.cs +++ b/Content.Shared/Weapons/Melee/Events/MeleeHitEvent.cs @@ -66,3 +66,10 @@ public sealed class MeleeHitEvent : HandledEntityEventArgs BaseDamage = baseDamage; } } + +/// +/// Raised on a melee weapon to calculate potential damage bonuses or decreases. +/// +/// +[ByRefEvent] +public record struct GetMeleeDamageEvent(DamageSpecifier Damage); diff --git a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs index 124023dc13..f1a4ae111c 100644 --- a/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs +++ b/Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs @@ -73,6 +73,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem SubscribeLocalEvent(OnMeleeDropped); SubscribeLocalEvent(OnMeleeSelected); SubscribeLocalEvent(OnMeleeShot); + SubscribeLocalEvent(OnGetBonusMeleeDamage); SubscribeAllEvent(OnHeavyAttack); SubscribeAllEvent(OnLightAttack); @@ -140,6 +141,11 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem Dirty(component); } + private void OnGetBonusMeleeDamage(EntityUid uid, BonusMeleeDamageComponent component, ref GetMeleeDamageEvent args) + { + args.Damage += component.BonusDamage; + } + private void OnStopAttack(StopAttackEvent msg, EntitySessionEventArgs args) { var user = args.SenderSession.AttachedEntity; @@ -270,6 +276,17 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem component.Range = state.Range; } + public DamageSpecifier GetDamage(EntityUid uid, MeleeWeaponComponent? component = null) + { + if (!Resolve(uid, ref component, false)) + return new DamageSpecifier(); + + var ev = new GetMeleeDamageEvent(new (component.Damage)); + RaiseLocalEvent(uid, ref ev); + + return ev.Damage; + } + public bool TryGetWeapon(EntityUid entity, out EntityUid weaponUid, [NotNullWhen(true)] out MeleeWeaponComponent? melee) { weaponUid = default; @@ -469,7 +486,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem protected virtual void DoLightAttack(EntityUid user, LightAttackEvent ev, EntityUid meleeUid, MeleeWeaponComponent component, ICommonSession? session) { - var damage = component.Damage * GetModifier(component, true); + var damage = GetDamage(meleeUid, component) * GetModifier(component, true); // For consistency with wide attacks stuff needs damageable. if (Deleted(ev.Target) || @@ -543,7 +560,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem { Audio.PlayPredicted(hitEvent.HitSoundOverride, meleeUid, user); } - else if (component.Damage.Total.Equals(FixedPoint2.Zero) && component.HitSound != null) + else if (GetDamage(meleeUid, component).Total.Equals(FixedPoint2.Zero) && component.HitSound != null) { Audio.PlayPredicted(component.HitSound, meleeUid, user); } @@ -576,7 +593,7 @@ public abstract class SharedMeleeWeaponSystem : EntitySystem var direction = targetMap.Position - userPos; var distance = Math.Min(component.Range, direction.Length); - var damage = component.Damage * GetModifier(component, false); + var damage = GetDamage(meleeUid, component) * GetModifier(component, false); var entities = ev.Entities; if (entities.Count == 0) diff --git a/Content.Shared/Wieldable/WieldableSystem.cs b/Content.Shared/Wieldable/WieldableSystem.cs index 61c167fda7..df73ff636c 100644 --- a/Content.Shared/Wieldable/WieldableSystem.cs +++ b/Content.Shared/Wieldable/WieldableSystem.cs @@ -40,7 +40,7 @@ public sealed class WieldableSystem : EntitySystem SubscribeLocalEvent(OnMeleeAttempt); SubscribeLocalEvent(OnShootAttempt); - SubscribeLocalEvent(OnMeleeHit); + SubscribeLocalEvent(OnGetMeleeDamage); } private void OnMeleeAttempt(EntityUid uid, MeleeRequiresWieldComponent component, ref AttemptMeleeEvent args) @@ -243,16 +243,13 @@ public sealed class WieldableSystem : EntitySystem AttemptUnwield(args.BlockingEntity, component, args.User); } - private void OnMeleeHit(EntityUid uid, IncreaseDamageOnWieldComponent component, MeleeHitEvent args) + private void OnGetMeleeDamage(EntityUid uid, IncreaseDamageOnWieldComponent component, ref GetMeleeDamageEvent args) { - if (EntityManager.TryGetComponent(uid, out var wield)) - { - if (!wield.Wielded) - return; - } - if (args.Handled) + if (!TryComp(uid, out var wield)) + return; + if (!wield.Wielded) return; - args.BonusDamage += component.BonusDamage; + args.Damage += component.BonusDamage; } }