fix: dirty SSD indicator comp on mapinit (#38891)

This commit is contained in:
Perry Fraser
2025-07-22 11:40:15 -04:00
committed by GitHub
parent 4033089c46
commit f16175a6e3
2 changed files with 41 additions and 17 deletions

View File

@@ -1,29 +1,49 @@
using Content.Shared.CCVar;
using Content.Shared.StatusIcon; using Content.Shared.StatusIcon;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
namespace Content.Shared.SSDIndicator; namespace Content.Shared.SSDIndicator;
/// <summary> /// <summary>
/// Shows status icon when player in SSD /// Shows status icon when an entity is SSD, based on if a player is attached or not.
/// </summary> /// </summary>
[RegisterComponent, NetworkedComponent] [RegisterComponent, NetworkedComponent]
[AutoGenerateComponentState, AutoGenerateComponentPause] [AutoGenerateComponentState, AutoGenerateComponentPause]
public sealed partial class SSDIndicatorComponent : Component public sealed partial class SSDIndicatorComponent : Component
{ {
[DataField, ViewVariables(VVAccess.ReadOnly)] /// <summary>
/// Whether or not the entity is SSD.
/// </summary>
[AutoNetworkedField] [AutoNetworkedField]
[DataField, ViewVariables(VVAccess.ReadOnly)]
public bool IsSSD = true; public bool IsSSD = true;
/// <summary>
/// The icon displayed next to the associated entity when it is SSD.
/// </summary>
[DataField] [DataField]
public ProtoId<SsdIconPrototype> Icon = "SSDIcon"; public ProtoId<SsdIconPrototype> Icon = "SSDIcon";
/// <summary> /// <summary>
/// When the entity should fall asleep /// The time at which the entity will fall asleep, if <see cref="CCVars.ICSSDSleep"/> is true.
/// </summary> /// </summary>
[DataField]
[AutoNetworkedField, AutoPausedField] [AutoNetworkedField, AutoPausedField]
[Access(typeof(SSDIndicatorSystem))] [Access(typeof(SSDIndicatorSystem))]
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan FallAsleepTime = TimeSpan.Zero; public TimeSpan FallAsleepTime = TimeSpan.Zero;
/// <summary>
/// The next time this component will be updated.
/// </summary>
[AutoNetworkedField, AutoPausedField]
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer))]
public TimeSpan NextUpdate = TimeSpan.Zero;
/// <summary>
/// The time between updates checking if the entity should be force slept.
/// </summary>
[DataField]
public TimeSpan UpdateInterval = TimeSpan.FromSeconds(1);
} }

View File

@@ -61,12 +61,12 @@ public sealed class SSDIndicatorSystem : EntitySystem
// Prevents mapped mobs to go to sleep immediately // Prevents mapped mobs to go to sleep immediately
private void OnMapInit(EntityUid uid, SSDIndicatorComponent component, MapInitEvent args) private void OnMapInit(EntityUid uid, SSDIndicatorComponent component, MapInitEvent args)
{ {
if (_icSsdSleep && if (!_icSsdSleep || !component.IsSSD)
component.IsSSD && return;
component.FallAsleepTime == TimeSpan.Zero)
{
component.FallAsleepTime = _timing.CurTime + TimeSpan.FromSeconds(_icSsdSleepTime); component.FallAsleepTime = _timing.CurTime + TimeSpan.FromSeconds(_icSsdSleepTime);
} component.NextUpdate = _timing.CurTime + component.UpdateInterval;
Dirty(uid, component);
} }
public override void Update(float frameTime) public override void Update(float frameTime)
@@ -76,17 +76,21 @@ public sealed class SSDIndicatorSystem : EntitySystem
if (!_icSsdSleep) if (!_icSsdSleep)
return; return;
var curTime = _timing.CurTime;
var query = EntityQueryEnumerator<SSDIndicatorComponent>(); var query = EntityQueryEnumerator<SSDIndicatorComponent>();
while (query.MoveNext(out var uid, out var ssd)) while (query.MoveNext(out var uid, out var ssd))
{ {
// Forces the entity to sleep when the time has come // Forces the entity to sleep when the time has come
if (ssd.IsSSD && if (!ssd.IsSSD
ssd.FallAsleepTime <= _timing.CurTime && || ssd.NextUpdate > curTime
!TerminatingOrDeleted(uid)) || ssd.FallAsleepTime > curTime
{ || TerminatingOrDeleted(uid))
_statusEffects.TrySetStatusEffectDuration(uid, StatusEffectSSDSleeping, null); continue;
}
_statusEffects.TryUpdateStatusEffectDuration(uid, StatusEffectSSDSleeping);
ssd.NextUpdate += ssd.UpdateInterval;
Dirty(uid, ssd);
} }
} }
} }