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