diff --git a/Content.Server/Bed/Sleep/SleepingSystem.cs b/Content.Server/Bed/Sleep/SleepingSystem.cs index 6a94a834ba..1a774db397 100644 --- a/Content.Server/Bed/Sleep/SleepingSystem.cs +++ b/Content.Server/Bed/Sleep/SleepingSystem.cs @@ -178,6 +178,10 @@ namespace Content.Server.Bed.Sleep if (!HasComp(uid)) return false; + var tryingToSleepEvent = new TryingToSleepEvent(uid); + RaiseLocalEvent(uid, ref tryingToSleepEvent); + if (tryingToSleepEvent.Cancelled) return false; + if (_prototypeManager.TryIndex("Sleep", out var sleepAction)) _actionsSystem.RemoveAction(uid, sleepAction); diff --git a/Content.Server/Zombies/ZombieSystem.cs b/Content.Server/Zombies/ZombieSystem.cs index a27abd7817..d31ee28067 100644 --- a/Content.Server/Zombies/ZombieSystem.cs +++ b/Content.Server/Zombies/ZombieSystem.cs @@ -12,7 +12,7 @@ using Content.Server.Inventory; using Robust.Shared.Prototypes; using Content.Server.Speech; using Content.Server.Chat.Systems; -using Content.Shared.Movement.Systems; +using Content.Shared.Bed.Sleep; using Content.Shared.Damage; using Content.Shared.Weapons.Melee.Events; using Content.Shared.Zombies; @@ -37,9 +37,15 @@ namespace Content.Server.Zombies SubscribeLocalEvent(OnMeleeHit); SubscribeLocalEvent(OnMobState); SubscribeLocalEvent(OnDamage); + SubscribeLocalEvent(OnSleepAttempt); } + private void OnSleepAttempt(EntityUid uid, ActiveZombieComponent component, ref TryingToSleepEvent args) + { + args.Cancelled = true; + } + private void OnMobState(EntityUid uid, ZombieComponent component, MobStateChangedEvent args) { if (args.CurrentMobState == DamageState.Alive) diff --git a/Content.Shared/Bed/Sleep/TryingToSleepEvent.cs b/Content.Shared/Bed/Sleep/TryingToSleepEvent.cs new file mode 100644 index 0000000000..f978b12082 --- /dev/null +++ b/Content.Shared/Bed/Sleep/TryingToSleepEvent.cs @@ -0,0 +1,8 @@ +namespace Content.Shared.Bed.Sleep; + +/// +/// Raised by an entity about to fall asleep. +/// Set Cancelled to true on event handling to interrupt +/// +[ByRefEvent] +public record struct TryingToSleepEvent(EntityUid uid, bool Cancelled = false); diff --git a/Content.Shared/MobState/EntitySystems/SharedMobStateSystem.cs b/Content.Shared/MobState/EntitySystems/SharedMobStateSystem.cs index 1dd79375d1..f7e62bc29d 100644 --- a/Content.Shared/MobState/EntitySystems/SharedMobStateSystem.cs +++ b/Content.Shared/MobState/EntitySystems/SharedMobStateSystem.cs @@ -2,6 +2,7 @@ using System.Diagnostics.CodeAnalysis; using Content.Shared.ActionBlocker; using Content.Shared.Administration.Logs; using Content.Shared.Alert; +using Content.Shared.Bed.Sleep; using Content.Shared.Damage; using Content.Shared.Database; using Content.Shared.DragDrop; @@ -56,10 +57,17 @@ namespace Content.Shared.MobState.EntitySystems SubscribeLocalEvent(UpdateState); SubscribeLocalEvent(OnMoveAttempt); SubscribeLocalEvent(OnStandAttempt); + SubscribeLocalEvent(OnSleepAttempt); SubscribeLocalEvent(OnStateChanged); // Note that there's no check for Down attempts because if a mob's in crit or dead, they can be downed... } + private void OnSleepAttempt(EntityUid uid, MobStateComponent component, ref TryingToSleepEvent args) + { + if(IsDead(uid, component)) + args.Cancelled = true; + } + private void OnGettingStripped(EntityUid uid, MobStateComponent component, BeforeGettingStrippedEvent args) { // Incapacitated or dead targets get stripped two or three times as fast. Makes stripping corpses less tedious.