using Content.Shared.Bed.Sleep; using Content.Shared.CCVar; using Robust.Shared.Configuration; using Robust.Shared.Player; using Robust.Shared.Timing; namespace Content.Shared.SSDIndicator; /// /// Handle changing player SSD indicator status /// public sealed class SSDIndicatorSystem : EntitySystem { [Dependency] private readonly IConfigurationManager _cfg = default!; [Dependency] private readonly IGameTiming _timing = default!; private bool _icSsdSleep; private float _icSsdSleepTime; public override void Initialize() { SubscribeLocalEvent(OnPlayerAttached); SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(OnMapInit); _cfg.OnValueChanged(CCVars.ICSSDSleep, obj => _icSsdSleep = obj, true); _cfg.OnValueChanged(CCVars.ICSSDSleepTime, obj => _icSsdSleepTime = obj, true); } private void OnPlayerAttached(EntityUid uid, SSDIndicatorComponent component, PlayerAttachedEvent args) { component.IsSSD = false; // Removes force sleep and resets the time to zero if (_icSsdSleep) { component.FallAsleepTime = TimeSpan.Zero; if (component.ForcedSleepAdded) // Remove component only if it has been added by this system { EntityManager.RemoveComponent(uid); component.ForcedSleepAdded = false; } } Dirty(uid, component); } private void OnPlayerDetached(EntityUid uid, SSDIndicatorComponent component, PlayerDetachedEvent args) { component.IsSSD = true; // Sets the time when the entity should fall asleep if (_icSsdSleep) { component.FallAsleepTime = _timing.CurTime + TimeSpan.FromSeconds(_icSsdSleepTime); } Dirty(uid, component); } // Prevents mapped mobs to go to sleep immediately private void OnMapInit(EntityUid uid, SSDIndicatorComponent component, MapInitEvent args) { if (_icSsdSleep && component.IsSSD && component.FallAsleepTime == TimeSpan.Zero) { component.FallAsleepTime = _timing.CurTime + TimeSpan.FromSeconds(_icSsdSleepTime); } } public override void Update(float frameTime) { base.Update(frameTime); if (!_icSsdSleep) return; var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var ssd)) { // Forces the entity to sleep when the time has come if(ssd.IsSSD && ssd.FallAsleepTime <= _timing.CurTime && !TerminatingOrDeleted(uid) && !HasComp(uid)) // Don't add the component if the entity has it from another sources { EnsureComp(uid); ssd.ForcedSleepAdded = true; } } } }