diff --git a/Content.Client/Bed/SleepingSystem.cs b/Content.Client/Bed/SleepingSystem.cs new file mode 100644 index 0000000000..addf855bf3 --- /dev/null +++ b/Content.Client/Bed/SleepingSystem.cs @@ -0,0 +1,8 @@ +using Content.Server.Bed.Sleep; + +namespace Content.Client.Bed; + +public sealed class SleepingSystem : SharedSleepingSystem +{ + +} diff --git a/Content.Server/Bed/Sleep/SleepingSystem.cs b/Content.Server/Bed/Sleep/SleepingSystem.cs index b3f3efcb92..2f44bee1f8 100644 --- a/Content.Server/Bed/Sleep/SleepingSystem.cs +++ b/Content.Server/Bed/Sleep/SleepingSystem.cs @@ -21,14 +21,15 @@ using Robust.Shared.Timing; namespace Content.Server.Bed.Sleep { - public sealed class SleepingSystem : EntitySystem + public sealed class SleepingSystem : SharedSleepingSystem { - [Dependency] private readonly IPrototypeManager _prototypeManager = default!; - [Dependency] private readonly ActionsSystem _actionsSystem = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly PopupSystem _popupSystem = default!; - + [Dependency] private readonly IPrototypeManager _prototypeManager = default!; [Dependency] private readonly IRobustRandom _robustRandom = default!; + [Dependency] private readonly ActionsSystem _actionsSystem = default!; + [Dependency] private readonly PopupSystem _popupSystem = default!; + [Dependency] private readonly SharedAudioSystem _audio = default!; + public override void Initialize() { base.Initialize(); @@ -88,7 +89,7 @@ namespace Content.Server.Bed.Sleep return; if (args.DamageDelta.Total >= component.WakeThreshold) - TryWaking(uid); + TryWaking(uid, component); } private void OnSleepAction(EntityUid uid, MobStateComponent component, SleepActionEvent args) @@ -98,7 +99,11 @@ namespace Content.Server.Bed.Sleep private void OnWakeAction(EntityUid uid, MobStateComponent component, WakeActionEvent args) { - TryWaking(uid); + if (!TryWakeCooldown(uid)) + return; + + if (TryWaking(uid)) + args.Handled = true; } /// @@ -126,7 +131,10 @@ namespace Content.Server.Bed.Sleep { Act = () => { - TryWaking(args.Target, user: args.User); + if (!TryWakeCooldown(uid)) + return; + + TryWaking(args.Target, user: args.User); }, Text = Loc.GetString("action-name-wake"), Priority = 2 @@ -140,16 +148,11 @@ namespace Content.Server.Bed.Sleep /// private void OnInteractHand(EntityUid uid, SleepingComponent component, InteractHandEvent args) { - args.Handled = true; - - var curTime = _gameTiming.CurTime; - if (curTime < component.CoolDownEnd) - { + if (!TryWakeCooldown(uid)) return; - } + args.Handled = true; TryWaking(args.Target, user: args.User); - component.CoolDownEnd = curTime + component.Cooldown; } private void OnExamined(EntityUid uid, SleepingComponent component, ExaminedEvent args) @@ -189,25 +192,44 @@ namespace Content.Server.Bed.Sleep return true; } + private bool TryWakeCooldown(EntityUid uid, SleepingComponent? component = null) + { + if (!Resolve(uid, ref component, false)) + return false; + + var curTime = _gameTiming.CurTime; + + if (curTime < component.CoolDownEnd) + { + return false; + } + + component.CoolDownEnd = curTime + component.Cooldown; + return true; + } + /// /// Try to wake up. /// - public bool TryWaking(EntityUid uid, bool force = false, EntityUid? user = null) + public bool TryWaking(EntityUid uid, SleepingComponent? component = null, bool force = false, EntityUid? user = null) { + if (!Resolve(uid, ref component)) + return false; + if (!force && HasComp(uid)) { if (user != null) { - SoundSystem.Play("/Audio/Effects/thudswoosh.ogg", Filter.Pvs(uid), uid, AudioHelpers.WithVariation(0.05f, _robustRandom)); - _popupSystem.PopupEntity(Loc.GetString("wake-other-failure", ("target", Identity.Entity(uid, EntityManager))), uid, user.Value, Shared.Popups.PopupType.SmallCaution); + _audio.PlayPvs("/Audio/Effects/thudswoosh.ogg", uid, AudioHelpers.WithVariation(0.05f, _robustRandom)); + _popupSystem.PopupEntity(Loc.GetString("wake-other-failure", ("target", Identity.Entity(uid, EntityManager))), uid, Filter.Entities(user.Value), true, Shared.Popups.PopupType.SmallCaution); } return false; } if (user != null) { - SoundSystem.Play("/Audio/Effects/thudswoosh.ogg", Filter.Pvs(uid), uid, AudioHelpers.WithVariation(0.05f, _robustRandom)); - _popupSystem.PopupEntity(Loc.GetString("wake-other-success", ("target", Identity.Entity(uid, EntityManager))), uid, user.Value); + _audio.PlayPvs("/Audio/Effects/thudswoosh.ogg", uid, AudioHelpers.WithVariation(0.05f, _robustRandom)); + _popupSystem.PopupEntity(Loc.GetString("wake-other-success", ("target", Identity.Entity(uid, EntityManager))), uid, Filter.Entities(user.Value), true); } RemComp(uid); return true; diff --git a/Content.Shared/Bed/Sleep/SharedSleepingSystem.cs b/Content.Shared/Bed/Sleep/SharedSleepingSystem.cs index 855aafff9c..2435711c71 100644 --- a/Content.Shared/Bed/Sleep/SharedSleepingSystem.cs +++ b/Content.Shared/Bed/Sleep/SharedSleepingSystem.cs @@ -5,15 +5,23 @@ using Content.Shared.Bed.Sleep; namespace Content.Server.Bed.Sleep { - public sealed class SharedSleepingSystem : EntitySystem + public abstract class SharedSleepingSystem : EntitySystem { [Dependency] private readonly SharedBlindingSystem _blindingSystem = default!; + public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnInit); SubscribeLocalEvent(OnShutdown); SubscribeLocalEvent(OnSpeakAttempt); + SubscribeLocalEvent(OnSleepUnpaused); + } + + private void OnSleepUnpaused(EntityUid uid, SleepingComponent component, ref EntityUnpausedEvent args) + { + component.CoolDownEnd += args.PausedTime; + Dirty(component); } private void OnInit(EntityUid uid, SleepingComponent component, ComponentInit args) diff --git a/Content.Shared/Bed/Sleep/SleepingComponent.cs b/Content.Shared/Bed/Sleep/SleepingComponent.cs index 76ced65b89..4ea419c65a 100644 --- a/Content.Shared/Bed/Sleep/SleepingComponent.cs +++ b/Content.Shared/Bed/Sleep/SleepingComponent.cs @@ -1,4 +1,6 @@ +using Content.Shared.FixedPoint; using Robust.Shared.GameStates; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom; namespace Content.Shared.Bed.Sleep; @@ -8,9 +10,11 @@ namespace Content.Shared.Bed.Sleep; [NetworkedComponent, RegisterComponent] public sealed class SleepingComponent : Component { - // How much damage of any type it takes to wake this entity. + /// + /// How much damage of any type it takes to wake this entity. + /// [DataField("wakeThreshold")] - public float WakeThreshold = 2; + public FixedPoint2 WakeThreshold = FixedPoint2.New(2); /// /// Cooldown time between users hand interaction. @@ -19,5 +23,6 @@ public sealed class SleepingComponent : Component [ViewVariables(VVAccess.ReadWrite)] public TimeSpan Cooldown = TimeSpan.FromSeconds(1f); + [DataField("cooldownEnd", customTypeSerializer:typeof(TimeOffsetSerializer))] public TimeSpan CoolDownEnd; }