diff --git a/Content.Shared/Damage/Components/StaminaDamageOnEmbedComponent.cs b/Content.Shared/Damage/Components/StaminaDamageOnEmbedComponent.cs new file mode 100644 index 0000000000..4ad4906246 --- /dev/null +++ b/Content.Shared/Damage/Components/StaminaDamageOnEmbedComponent.cs @@ -0,0 +1,17 @@ +using Content.Shared.Damage.Systems; +using Robust.Shared.GameStates; + +namespace Content.Shared.Damage.Components; + +/// +/// Applies stamina damage when embeds in an entity. +/// +[RegisterComponent] +[NetworkedComponent] +[AutoGenerateComponentState] +[Access(typeof(StaminaSystem))] +public sealed partial class StaminaDamageOnEmbedComponent : Component +{ + [ViewVariables(VVAccess.ReadWrite), DataField, AutoNetworkedField] + public float Damage = 10f; +} diff --git a/Content.Shared/Damage/Systems/StaminaSystem.cs b/Content.Shared/Damage/Systems/StaminaSystem.cs index 33f1b0375b..2587d4e05f 100644 --- a/Content.Shared/Damage/Systems/StaminaSystem.cs +++ b/Content.Shared/Damage/Systems/StaminaSystem.cs @@ -55,8 +55,11 @@ public sealed partial class StaminaSystem : EntitySystem SubscribeLocalEvent(OnDisarmed); SubscribeLocalEvent(OnRejuvenate); + SubscribeLocalEvent(OnProjectileEmbed); + SubscribeLocalEvent(OnProjectileHit); SubscribeLocalEvent(OnThrowHit); + SubscribeLocalEvent(OnMeleeHit); } @@ -114,7 +117,7 @@ public sealed partial class StaminaSystem : EntitySystem component.StaminaDamage = 0; RemComp(uid); SetStaminaAlert(uid, component); - Dirty(component); + Dirty(uid, component); } private void OnDisarmed(EntityUid uid, StaminaComponent component, DisarmedEvent args) @@ -192,6 +195,14 @@ public sealed partial class StaminaSystem : EntitySystem OnCollide(uid, component, args.Target); } + private void OnProjectileEmbed(EntityUid uid, StaminaDamageOnEmbedComponent component, ref EmbedEvent args) + { + if (!TryComp(args.Embedded, out var stamina)) + return; + + TakeStaminaDamage(args.Embedded, component.Damage, stamina, source: uid); + } + private void OnThrowHit(EntityUid uid, StaminaDamageOnCollideComponent component, ThrowDoHitEvent args) { OnCollide(uid, component, args.Target); diff --git a/Content.Shared/Projectiles/EmbedEvent.cs b/Content.Shared/Projectiles/EmbedEvent.cs new file mode 100644 index 0000000000..521a691f45 --- /dev/null +++ b/Content.Shared/Projectiles/EmbedEvent.cs @@ -0,0 +1,15 @@ +namespace Content.Shared.Projectiles; + +/// +/// Raised directed on an entity when it embeds in another entity. +/// +[ByRefEvent] +public readonly record struct EmbedEvent(EntityUid? Shooter, EntityUid Embedded) +{ + public readonly EntityUid? Shooter = Shooter; + + /// + /// Entity that is embedded in. + /// + public readonly EntityUid Embedded = Embedded; +} diff --git a/Content.Shared/Projectiles/ProjectileEmbedEvent.cs b/Content.Shared/Projectiles/ProjectileEmbedEvent.cs index 4dc9b9841c..e7dd6df8e2 100644 --- a/Content.Shared/Projectiles/ProjectileEmbedEvent.cs +++ b/Content.Shared/Projectiles/ProjectileEmbedEvent.cs @@ -4,4 +4,4 @@ namespace Content.Shared.Projectiles; /// Raised directed on an entity when it embeds into something. /// [ByRefEvent] -public readonly record struct ProjectileEmbedEvent(EntityUid Shooter, EntityUid Weapon, EntityUid Embedded); +public readonly record struct ProjectileEmbedEvent(EntityUid? Shooter, EntityUid Weapon, EntityUid Embedded); diff --git a/Content.Shared/Projectiles/SharedProjectileSystem.cs b/Content.Shared/Projectiles/SharedProjectileSystem.cs index e003764f92..2db497f94c 100644 --- a/Content.Shared/Projectiles/SharedProjectileSystem.cs +++ b/Content.Shared/Projectiles/SharedProjectileSystem.cs @@ -96,22 +96,22 @@ public abstract partial class SharedProjectileSystem : EntitySystem if (!component.EmbedOnThrow) return; - Embed(uid, args.Target, component); + Embed(uid, args.Target, null, component); } private void OnEmbedProjectileHit(EntityUid uid, EmbeddableProjectileComponent component, ref ProjectileHitEvent args) { - Embed(uid, args.Target, component); + Embed(uid, args.Target, args.Shooter, component); // Raise a specific event for projectiles. - if (TryComp(uid, out var projectile)) + if (TryComp(uid, out ProjectileComponent? projectile)) { var ev = new ProjectileEmbedEvent(projectile.Shooter!.Value, projectile.Weapon!.Value, args.Target); RaiseLocalEvent(uid, ref ev); } } - private void Embed(EntityUid uid, EntityUid target, EmbeddableProjectileComponent component) + private void Embed(EntityUid uid, EntityUid target, EntityUid? user, EmbeddableProjectileComponent component) { TryComp(uid, out var physics); _physics.SetLinearVelocity(uid, Vector2.Zero, body: physics); @@ -121,13 +121,13 @@ public abstract partial class SharedProjectileSystem : EntitySystem if (component.Offset != Vector2.Zero) { - _transform.SetLocalPosition(xform, xform.LocalPosition + xform.LocalRotation.RotateVec(component.Offset)); + _transform.SetLocalPosition(uid, xform.LocalPosition + xform.LocalRotation.RotateVec(component.Offset), + xform); } - if (component.Sound != null) - { - _audio.PlayPredicted(component.Sound, uid, null); - } + _audio.PlayPredicted(component.Sound, uid, null); + var ev = new EmbedEvent(user, target); + RaiseLocalEvent(uid, ref ev); } private void PreventCollision(EntityUid uid, ProjectileComponent component, ref PreventCollideEvent args) diff --git a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/throwing_stars.yml b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/throwing_stars.yml index 48138452b2..c68feff0b5 100644 --- a/Resources/Prototypes/Entities/Objects/Weapons/Throwable/throwing_stars.yml +++ b/Resources/Prototypes/Entities/Objects/Weapons/Throwable/throwing_stars.yml @@ -36,6 +36,10 @@ types: Slash: 8 Piercing: 10 + - type: StaminaDamageOnCollide + damage: 45 + - type: StaminaDamageOnEmbed + damage: 10 - type: entity parent: ThrowingStar