From 4b23521af519b561734609c918b5f715dbdfda3f Mon Sep 17 00:00:00 2001 From: rolfero <45628623+rolfero@users.noreply.github.com> Date: Sun, 11 Sep 2022 08:39:36 +0200 Subject: [PATCH] Melee special examine (#11168) Co-authored-by: CommieFlowers --- .../Abilities/Boxer/BoxingSystem.cs | 4 +- .../Stunnable/Systems/StunbatonSystem.cs | 4 +- Content.Server/Tools/ToolSystem.Welder.cs | 4 +- .../Melee/Components/MeleeWeaponComponent.cs | 4 ++ .../Components/EnergySwordComponent.cs | 6 ++ .../Melee/EnergySword/EnergySwordSystem.cs | 12 +++- .../Weapon/Melee/MeleeWeaponSystem.cs | 57 +++++++++++++++++-- .../IncreaseDamageOnWieldComponent.cs | 4 +- Content.Server/Wieldable/WieldableSystem.cs | 6 +- .../Damage/Systems/DamageableSystem.cs | 7 ++- .../Fun/Instruments/instruments_string.yml | 8 +-- .../Objects/Weapons/Melee/e_sword.yml | 2 + .../Objects/Weapons/Melee/fireaxe.yml | 10 ++-- .../Entities/Objects/Weapons/Melee/spear.yml | 6 +- 14 files changed, 101 insertions(+), 33 deletions(-) diff --git a/Content.Server/Abilities/Boxer/BoxingSystem.cs b/Content.Server/Abilities/Boxer/BoxingSystem.cs index 22389ea309..44f5ebe64e 100644 --- a/Content.Server/Abilities/Boxer/BoxingSystem.cs +++ b/Content.Server/Abilities/Boxer/BoxingSystem.cs @@ -20,7 +20,7 @@ namespace Content.Server.Abilities.Boxer { base.Initialize(); SubscribeLocalEvent(OnInit); - SubscribeLocalEvent(ApplyBoxerModifiers); + SubscribeLocalEvent(GetDamageModifiers); SubscribeLocalEvent(OnStamHit); } @@ -29,7 +29,7 @@ namespace Content.Server.Abilities.Boxer if (TryComp(uid, out var meleeComp)) meleeComp.Range *= boxer.RangeBonus; } - private void ApplyBoxerModifiers(EntityUid uid, BoxerComponent component, MeleeHitEvent args) + private void GetDamageModifiers(EntityUid uid, BoxerComponent component, ItemMeleeDamageEvent args) { if (component.UnarmedModifiers == default!) { diff --git a/Content.Server/Stunnable/Systems/StunbatonSystem.cs b/Content.Server/Stunnable/Systems/StunbatonSystem.cs index daee202c6a..5d1ec5897d 100644 --- a/Content.Server/Stunnable/Systems/StunbatonSystem.cs +++ b/Content.Server/Stunnable/Systems/StunbatonSystem.cs @@ -33,10 +33,10 @@ namespace Content.Server.Stunnable.Systems SubscribeLocalEvent(OnUseInHand); SubscribeLocalEvent(OnExamined); SubscribeLocalEvent(OnStaminaHitAttempt); - SubscribeLocalEvent(OnMeleeHit); + SubscribeLocalEvent(OnMeleeHit); } - private void OnMeleeHit(EntityUid uid, StunbatonComponent component, MeleeHitEvent args) + private void OnMeleeHit(EntityUid uid, StunbatonComponent component, ItemMeleeDamageEvent args) { if (!component.Activated) return; diff --git a/Content.Server/Tools/ToolSystem.Welder.cs b/Content.Server/Tools/ToolSystem.Welder.cs index 87e13a049d..805c0bc948 100644 --- a/Content.Server/Tools/ToolSystem.Welder.cs +++ b/Content.Server/Tools/ToolSystem.Welder.cs @@ -37,10 +37,10 @@ namespace Content.Server.Tools SubscribeLocalEvent(OnWelderToolUseFinishAttempt); SubscribeLocalEvent(OnWelderShutdown); SubscribeLocalEvent(OnWelderGetState); - SubscribeLocalEvent(OnMeleeHit); + SubscribeLocalEvent(OnMeleeHit); } - private void OnMeleeHit(EntityUid uid, WelderComponent component, MeleeHitEvent args) + private void OnMeleeHit(EntityUid uid, WelderComponent component, ItemMeleeDamageEvent args) { if (!args.Handled && component.Lit) args.BonusDamage += component.LitMeleeDamageBonus; diff --git a/Content.Server/Weapon/Melee/Components/MeleeWeaponComponent.cs b/Content.Server/Weapon/Melee/Components/MeleeWeaponComponent.cs index 5e62e1d2f7..4cf6b14df9 100644 --- a/Content.Server/Weapon/Melee/Components/MeleeWeaponComponent.cs +++ b/Content.Server/Weapon/Melee/Components/MeleeWeaponComponent.cs @@ -47,6 +47,10 @@ namespace Content.Server.Weapon.Melee.Components [DataField("clickAttackEffect")] public bool ClickAttackEffect { get; set; } = true; + [ViewVariables(VVAccess.ReadWrite)] + [DataField("hidden")] + public bool HideFromExamine { get; set; } = false; + public TimeSpan LastAttackTime; public TimeSpan CooldownEnd; diff --git a/Content.Server/Weapon/Melee/EnergySword/Components/EnergySwordComponent.cs b/Content.Server/Weapon/Melee/EnergySword/Components/EnergySwordComponent.cs index 532a2b206e..9de9c6449a 100644 --- a/Content.Server/Weapon/Melee/EnergySword/Components/EnergySwordComponent.cs +++ b/Content.Server/Weapon/Melee/EnergySword/Components/EnergySwordComponent.cs @@ -15,6 +15,12 @@ namespace Content.Server.Weapon.Melee.EnergySword [DataField("isSharp")] public bool IsSharp = true; + /// + /// Does this become hidden when deactivated + /// + [DataField("secret")] + public bool Secret { get; set; } = false; + /// /// RGB cycle rate for hacked e-swords. /// diff --git a/Content.Server/Weapon/Melee/EnergySword/EnergySwordSystem.cs b/Content.Server/Weapon/Melee/EnergySword/EnergySwordSystem.cs index 0699c3b334..0db06cd01e 100644 --- a/Content.Server/Weapon/Melee/EnergySword/EnergySwordSystem.cs +++ b/Content.Server/Weapon/Melee/EnergySword/EnergySwordSystem.cs @@ -26,7 +26,7 @@ namespace Content.Server.Weapon.Melee.EnergySword base.Initialize(); SubscribeLocalEvent(OnMapInit); - SubscribeLocalEvent(OnMeleeHit); + SubscribeLocalEvent(OnMeleeHit); SubscribeLocalEvent(OnUseInHand); SubscribeLocalEvent(OnInteractUsing); SubscribeLocalEvent(OnIsHotEvent); @@ -38,7 +38,7 @@ namespace Content.Server.Weapon.Melee.EnergySword comp.BladeColor = _random.Pick(comp.ColorOptions); } - private void OnMeleeHit(EntityUid uid, EnergySwordComponent comp, MeleeHitEvent args) + private void OnMeleeHit(EntityUid uid, EnergySwordComponent comp, ItemMeleeDamageEvent args) { if (!comp.Activated) return; @@ -80,7 +80,11 @@ namespace Content.Server.Weapon.Melee.EnergySword } if(TryComp(comp.Owner, out var weaponComp)) + { weaponComp.HitSound = comp.OnHitOff; + if (comp.Secret) + weaponComp.HideFromExamine = true; + } if (comp.IsSharp) RemComp(comp.Owner); @@ -104,7 +108,11 @@ namespace Content.Server.Weapon.Melee.EnergySword EnsureComp(comp.Owner); if(TryComp(comp.Owner, out var weaponComp)) + { weaponComp.HitSound = comp.OnHitOn; + if (comp.Secret) + weaponComp.HideFromExamine = false; + } SoundSystem.Play(comp.ActivateSound.GetSound(), Filter.Pvs(comp.Owner, entityManager: EntityManager), comp.Owner); diff --git a/Content.Server/Weapon/Melee/MeleeWeaponSystem.cs b/Content.Server/Weapon/Melee/MeleeWeaponSystem.cs index 017d1f008a..3b7589941c 100644 --- a/Content.Server/Weapon/Melee/MeleeWeaponSystem.cs +++ b/Content.Server/Weapon/Melee/MeleeWeaponSystem.cs @@ -55,12 +55,20 @@ namespace Content.Server.Weapon.Melee private void OnMeleeExaminableVerb(EntityUid uid, MeleeWeaponComponent component, GetVerbsEvent args) { - if (!args.CanInteract || !args.CanAccess) + if (!args.CanInteract || !args.CanAccess || component.HideFromExamine) return; + var getDamage = new ItemMeleeDamageEvent(component.Damage); + RaiseLocalEvent(uid, getDamage, false); + var damageSpec = GetDamage(component); if (damageSpec == null) + damageSpec = new DamageSpecifier(); + + damageSpec += getDamage.BonusDamage; + + if (damageSpec.Total == FixedPoint2.Zero) return; var verb = new ExamineVerb() @@ -125,7 +133,7 @@ namespace Content.Server.Weapon.Melee if (args.Target is {Valid: true} target) { - // Raise event before doing damage so we can cancel damage if the event is handled + // Raising a melee hit event which may handle combat for us var hitEvent = new MeleeHitEvent(new List() { target }, args.User, comp.Damage); RaiseLocalEvent(owner, hitEvent, false); @@ -134,9 +142,15 @@ namespace Content.Server.Weapon.Melee var targets = new[] { target }; SendAnimation(comp.ClickArc, angle, args.User, owner, targets, comp.ClickAttackEffect, false); + // Raising a GetMeleeDamage event which gets our damage + var getDamageEvent = new ItemMeleeDamageEvent(comp.Damage); + RaiseLocalEvent(owner, getDamageEvent, false); + RaiseLocalEvent(target, new AttackedEvent(args.Used, args.User, args.ClickLocation), true); - var modifiedDamage = DamageSpecifier.ApplyModifierSets(comp.Damage + hitEvent.BonusDamage, hitEvent.ModifiersList); + var modifiersList = getDamageEvent.ModifiersList; + modifiersList.AddRange(hitEvent.ModifiersList); + var modifiedDamage = DamageSpecifier.ApplyModifierSets(comp.Damage + hitEvent.BonusDamage + getDamageEvent.BonusDamage, modifiersList); var damageResult = _damageable.TryChangeDamage(target, modifiedDamage); if (damageResult != null && damageResult.Total > FixedPoint2.Zero) @@ -218,15 +232,19 @@ namespace Content.Server.Weapon.Melee hitEntities.Add(entity); } } - - // Raise event before doing damage so we can cancel damage if handled + // Raising a melee hit event which may handle combat for us var hitEvent = new MeleeHitEvent(hitEntities, args.User, comp.Damage); RaiseLocalEvent(owner, hitEvent, false); SendAnimation(comp.Arc, angle, args.User, owner, hitEntities); if (!hitEvent.Handled) { - var modifiedDamage = DamageSpecifier.ApplyModifierSets(comp.Damage + hitEvent.BonusDamage, hitEvent.ModifiersList); + var getDamageEvent = new ItemMeleeDamageEvent(comp.Damage); + RaiseLocalEvent(owner, getDamageEvent, false); + + var modifiersList = getDamageEvent.ModifiersList; + modifiersList.AddRange(hitEvent.ModifiersList); + var modifiedDamage = DamageSpecifier.ApplyModifierSets(comp.Damage + hitEvent.BonusDamage + getDamageEvent.BonusDamage, modifiersList); var appliedDamage = new DamageSpecifier(); foreach (var entity in hitEntities) @@ -423,6 +441,33 @@ namespace Content.Server.Weapon.Melee } } + public sealed class ItemMeleeDamageEvent : HandledEntityEventArgs + { + /// + /// The base amount of damage dealt by the melee hit. + /// + public readonly DamageSpecifier BaseDamage = new(); + + /// + /// Modifier sets to apply to the damage when it's all said and done. + /// This should be modified by adding a new entry to the list. + /// + public List ModifiersList = new(); + + /// + /// Damage to add to the default melee weapon damage. Applied before modifiers. + /// + /// + /// This might be required as damage modifier sets cannot add a new damage type to a DamageSpecifier. + /// + public DamageSpecifier BonusDamage = new(); + + public ItemMeleeDamageEvent(DamageSpecifier baseDamage) + { + BaseDamage = baseDamage; + } + } + /// /// Raised directed on the melee weapon entity used to attack something in combat mode, /// whether through a click attack or wide attack. diff --git a/Content.Server/Wieldable/Components/IncreaseDamageOnWieldComponent.cs b/Content.Server/Wieldable/Components/IncreaseDamageOnWieldComponent.cs index 301893a29a..083bd514b8 100644 --- a/Content.Server/Wieldable/Components/IncreaseDamageOnWieldComponent.cs +++ b/Content.Server/Wieldable/Components/IncreaseDamageOnWieldComponent.cs @@ -5,7 +5,7 @@ namespace Content.Server.Wieldable.Components [RegisterComponent, Access(typeof(WieldableSystem))] public sealed class IncreaseDamageOnWieldComponent : Component { - [DataField("modifiers", required: true)] - public DamageModifierSet Modifiers = default!; + [DataField("damage", required: true)] + public DamageSpecifier BonusDamage = default!; } } diff --git a/Content.Server/Wieldable/WieldableSystem.cs b/Content.Server/Wieldable/WieldableSystem.cs index 1aaa9c8fca..fa4131a139 100644 --- a/Content.Server/Wieldable/WieldableSystem.cs +++ b/Content.Server/Wieldable/WieldableSystem.cs @@ -37,7 +37,7 @@ namespace Content.Server.Wieldable SubscribeLocalEvent>(AddToggleWieldVerb); SubscribeLocalEvent(OnDisarmAttemptEvent); - SubscribeLocalEvent(OnMeleeHit); + SubscribeLocalEvent(OnMeleeHit); } private void OnDisarmAttemptEvent(EntityUid uid, WieldableComponent component, DisarmAttemptEvent args) @@ -233,7 +233,7 @@ namespace Content.Server.Wieldable AttemptUnwield(args.BlockingEntity, component, args.User); } - private void OnMeleeHit(EntityUid uid, IncreaseDamageOnWieldComponent component, MeleeHitEvent args) + private void OnMeleeHit(EntityUid uid, IncreaseDamageOnWieldComponent component, ItemMeleeDamageEvent args) { if (EntityManager.TryGetComponent(uid, out var wield)) { @@ -243,7 +243,7 @@ namespace Content.Server.Wieldable if (args.Handled) return; - args.ModifiersList.Add(component.Modifiers); + args.BonusDamage += component.BonusDamage; } } diff --git a/Content.Shared/Damage/Systems/DamageableSystem.cs b/Content.Shared/Damage/Systems/DamageableSystem.cs index cea2f2f541..92453e9dc9 100644 --- a/Content.Shared/Damage/Systems/DamageableSystem.cs +++ b/Content.Shared/Damage/Systems/DamageableSystem.cs @@ -41,8 +41,11 @@ namespace Content.Shared.Damage foreach (var damage in damageSpecifier.DamageDict) { - msg.PushNewline(); - msg.AddMarkup(Loc.GetString("damage-value", ("type", damage.Key), ("amount", damage.Value))); + if (damage.Value != FixedPoint2.Zero) + { + msg.PushNewline(); + msg.AddMarkup(Loc.GetString("damage-value", ("type", damage.Key), ("amount", damage.Value))); + } } return msg; diff --git a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_string.yml b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_string.yml index 88a39b00f9..09c6fab74b 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_string.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/Instruments/instruments_string.yml @@ -74,10 +74,10 @@ Slash: 8 - type: Wieldable - type: IncreaseDamageOnWield #they don't call it an axe for nothing - modifiers: - flatReductions: - Blunt: -2 - Slash: -6 + damage: + types: + Blunt: 2 + Slash: 6 - type: entity parent: BaseHandheldInstrument diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml index 3c5a12ef66..9025bc1a1f 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/e_sword.yml @@ -58,6 +58,7 @@ description: 'A dark ink pen.' components: - type: EnergySword + secret: true litDamageBonus: types: Slash: 7.5 @@ -74,6 +75,7 @@ shader: unshaded map: [ "blade" ] - type: MeleeWeapon + hidden: true damage: types: Blunt: 1 diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml index b8651590d9..2fe49d5513 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/fireaxe.yml @@ -20,11 +20,11 @@ Structural: 5 - type: Wieldable - type: IncreaseDamageOnWield - modifiers: - flatReductions: - Blunt: -2 # negative reductions = increases - Slash: -8 - Structural: -45 + damage: + types: + Blunt: 2 + Slash: 8 + Structural: 45 - type: Item size: 150 - type: Clothing diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml index 30b050a553..3b6e7b46c3 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Melee/spear.yml @@ -45,9 +45,9 @@ maxTransferAmount: 5 - type: Wieldable - type: IncreaseDamageOnWield - modifiers: - flatReductions: - Piercing: -7 + damage: + types: + Piercing: 7 - type: Damageable damageContainer: Inorganic - type: Destructible