Alerts Cleanup and API (#39544)
* alert cleanup and API * I expect update loops to be at the top. * Address review * Address review x 2 * Merg my PR * Fix * Update Content.Shared/Alert/AlertsSystem.cs webedit Co-authored-by: Perry Fraser <perryprog@users.noreply.github.com> * FIX THAT TEST FAIL!!!! * Me when I forget to actually give you alerts * Hammedborgar --------- Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com> Co-authored-by: Perry Fraser <perryprog@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
5e0e5e045a
commit
d488ca96b2
@@ -120,8 +120,8 @@ public sealed class MoverController : SharedMoverController
|
|||||||
base.SetSprinting(entity, subTick, walking);
|
base.SetSprinting(entity, subTick, walking);
|
||||||
|
|
||||||
if (walking && _cfg.GetCVar(CCVars.ToggleWalk))
|
if (walking && _cfg.GetCVar(CCVars.ToggleWalk))
|
||||||
_alerts.ShowAlert(entity, WalkingAlert, showCooldown: false, autoRemove: false);
|
_alerts.ShowAlert(entity.Owner, WalkingAlert, showCooldown: false, autoRemove: false);
|
||||||
else
|
else
|
||||||
_alerts.ClearAlert(entity, WalkingAlert);
|
_alerts.ClearAlert(entity.Owner, WalkingAlert);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public sealed class InternalsSystem : SharedInternalsSystem
|
|||||||
var gasTank = Comp<GasTankComponent>(ent.Comp.GasTankEntity!.Value);
|
var gasTank = Comp<GasTankComponent>(ent.Comp.GasTankEntity!.Value);
|
||||||
args.Gas = _gasTank.RemoveAirVolume((ent.Comp.GasTankEntity.Value, gasTank), args.Respirator.BreathVolume);
|
args.Gas = _gasTank.RemoveAirVolume((ent.Comp.GasTankEntity.Value, gasTank), args.Respirator.BreathVolume);
|
||||||
// TODO: Should listen to gas tank updates instead I guess?
|
// TODO: Should listen to gas tank updates instead I guess?
|
||||||
_alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent));
|
_alerts.ShowAlert(ent.Owner, ent.Comp.InternalsAlert, GetSeverity(ent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -390,7 +390,7 @@ public sealed class RespiratorSystem : EntitySystem
|
|||||||
var organs = _bodySystem.GetBodyOrganEntityComps<LungComponent>((ent, null));
|
var organs = _bodySystem.GetBodyOrganEntityComps<LungComponent>((ent, null));
|
||||||
foreach (var entity in organs)
|
foreach (var entity in organs)
|
||||||
{
|
{
|
||||||
_alertsSystem.ShowAlert(ent, entity.Comp1.Alert);
|
_alertsSystem.ShowAlert(ent.Owner, entity.Comp1.Alert);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,7 +400,7 @@ public sealed class RespiratorSystem : EntitySystem
|
|||||||
var organs = _bodySystem.GetBodyOrganEntityComps<LungComponent>((ent, null));
|
var organs = _bodySystem.GetBodyOrganEntityComps<LungComponent>((ent, null));
|
||||||
foreach (var entity in organs)
|
foreach (var entity in organs)
|
||||||
{
|
{
|
||||||
_alertsSystem.ClearAlert(ent, entity.Comp1.Alert);
|
_alertsSystem.ClearAlert(ent.Owner, entity.Comp1.Alert);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -290,8 +290,8 @@ public sealed partial class BorgSystem : SharedBorgSystem
|
|||||||
{
|
{
|
||||||
if (!_powerCell.TryGetBatteryFromSlot(ent, out var battery, slotComponent))
|
if (!_powerCell.TryGetBatteryFromSlot(ent, out var battery, slotComponent))
|
||||||
{
|
{
|
||||||
_alerts.ClearAlert(ent, ent.Comp.BatteryAlert);
|
_alerts.ClearAlert(ent.Owner, ent.Comp.BatteryAlert);
|
||||||
_alerts.ShowAlert(ent, ent.Comp.NoBatteryAlert);
|
_alerts.ShowAlert(ent.Owner, ent.Comp.NoBatteryAlert);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,8 +304,8 @@ public sealed partial class BorgSystem : SharedBorgSystem
|
|||||||
chargePercent = 1;
|
chargePercent = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
_alerts.ClearAlert(ent, ent.Comp.NoBatteryAlert);
|
_alerts.ClearAlert(ent.Owner, ent.Comp.NoBatteryAlert);
|
||||||
_alerts.ShowAlert(ent, ent.Comp.BatteryAlert, chargePercent);
|
_alerts.ShowAlert(ent.Owner, ent.Comp.BatteryAlert, chargePercent);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryEjectPowerCell(EntityUid uid, BorgChassisComponent component, [NotNullWhen(true)] out List<EntityUid>? ents)
|
public bool TryEjectPowerCell(EntityUid uid, BorgChassisComponent component, [NotNullWhen(true)] out List<EntityUid>? ents)
|
||||||
@@ -315,7 +315,7 @@ public sealed partial class BorgSystem : SharedBorgSystem
|
|||||||
if (!TryComp<PowerCellSlotComponent>(uid, out var slotComp) ||
|
if (!TryComp<PowerCellSlotComponent>(uid, out var slotComp) ||
|
||||||
!Container.TryGetContainer(uid, slotComp.CellSlotId, out var container) ||
|
!Container.TryGetContainer(uid, slotComp.CellSlotId, out var container) ||
|
||||||
!container.ContainedEntities.Any())
|
!container.ContainedEntities.Any())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ents = Container.EmptyContainer(container);
|
ents = Container.EmptyContainer(container);
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public sealed class MimePowersSystem : EntitySystem
|
|||||||
Dirty(ent, illiterateComponent);
|
Dirty(ent, illiterateComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
_alertsSystem.ShowAlert(ent, ent.Comp.VowAlert);
|
_alertsSystem.ShowAlert(ent.Owner, ent.Comp.VowAlert);
|
||||||
_actionsSystem.AddAction(ent, ref ent.Comp.InvisibleWallActionEntity, ent.Comp.InvisibleWallAction);
|
_actionsSystem.AddAction(ent, ref ent.Comp.InvisibleWallActionEntity, ent.Comp.InvisibleWallAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ public sealed partial class AlertAutoRemoveComponent : Component
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[AutoNetworkedField]
|
[AutoNetworkedField]
|
||||||
[DataField]
|
[DataField]
|
||||||
public List<AlertKey> AlertKeys = new();
|
public HashSet<AlertKey> AlertKeys = new();
|
||||||
|
|
||||||
public override bool SendOnlyToOwner => true;
|
public override bool SendOnlyToOwner => true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ using Robust.Shared.Serialization;
|
|||||||
namespace Content.Shared.Alert;
|
namespace Content.Shared.Alert;
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public struct AlertState
|
public record struct AlertState
|
||||||
{
|
{
|
||||||
public short? Severity;
|
public short? Severity;
|
||||||
public (TimeSpan, TimeSpan)? Cooldown;
|
public (TimeSpan startTime, TimeSpan endTime)? Cooldown;
|
||||||
public bool AutoRemove;
|
public bool AutoRemove;
|
||||||
public bool ShowCooldown;
|
public bool ShowCooldown;
|
||||||
public ProtoId<AlertPrototype> Type;
|
public ProtoId<AlertPrototype> Type;
|
||||||
|
|||||||
@@ -11,19 +11,78 @@ public abstract class AlertsSystem : EntitySystem
|
|||||||
[Dependency] private readonly IGameTiming _timing = default!;
|
[Dependency] private readonly IGameTiming _timing = default!;
|
||||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||||
|
|
||||||
|
private EntityQuery<AlertsComponent> _alertsQuery;
|
||||||
private FrozenDictionary<ProtoId<AlertPrototype>, AlertPrototype> _typeToAlert = default!;
|
private FrozenDictionary<ProtoId<AlertPrototype>, AlertPrototype> _typeToAlert = default!;
|
||||||
|
|
||||||
public IReadOnlyDictionary<AlertKey, AlertState>? GetActiveAlerts(EntityUid euid)
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
return TryComp(euid, out AlertsComponent? comp)
|
base.Initialize();
|
||||||
? comp.Alerts
|
|
||||||
|
_alertsQuery = GetEntityQuery<AlertsComponent>();
|
||||||
|
|
||||||
|
SubscribeLocalEvent<AlertsComponent, ComponentStartup>(HandleComponentStartup);
|
||||||
|
SubscribeLocalEvent<AlertsComponent, ComponentShutdown>(HandleComponentShutdown);
|
||||||
|
SubscribeLocalEvent<AlertsComponent, PlayerAttachedEvent>(OnPlayerAttached);
|
||||||
|
|
||||||
|
SubscribeLocalEvent<AlertAutoRemoveComponent, EntityUnpausedEvent>(OnAutoRemoveUnPaused);
|
||||||
|
|
||||||
|
SubscribeAllEvent<ClickAlertEvent>(HandleClickAlert);
|
||||||
|
SubscribeLocalEvent<PrototypesReloadedEventArgs>(HandlePrototypesReloaded);
|
||||||
|
LoadPrototypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Update(float frameTime)
|
||||||
|
{
|
||||||
|
base.Update(frameTime);
|
||||||
|
|
||||||
|
var query = EntityQueryEnumerator<AlertAutoRemoveComponent>();
|
||||||
|
var curTime = _timing.CurTime;
|
||||||
|
while (query.MoveNext(out var uid, out var autoComp))
|
||||||
|
{
|
||||||
|
var removed = false;
|
||||||
|
if (autoComp.AlertKeys.Count <= 0 || !_alertsQuery.TryComp(uid, out var alertComp))
|
||||||
|
{
|
||||||
|
RemCompDeferred(uid, autoComp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var removeList = new List<AlertKey>();
|
||||||
|
foreach (var alertKey in autoComp.AlertKeys)
|
||||||
|
{
|
||||||
|
alertComp.Alerts.TryGetValue(alertKey, out var alertState);
|
||||||
|
|
||||||
|
if (alertState.Cooldown is null || alertState.Cooldown.Value.endTime >= curTime)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
removeList.Add(alertKey);
|
||||||
|
alertComp.Alerts.Remove(alertKey);
|
||||||
|
removed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!removed)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (var alertKey in removeList)
|
||||||
|
{
|
||||||
|
autoComp.AlertKeys.Remove(alertKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
Dirty(uid, alertComp);
|
||||||
|
Dirty(uid, autoComp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IReadOnlyDictionary<AlertKey, AlertState>? GetActiveAlerts(Entity<AlertsComponent?> entity)
|
||||||
|
{
|
||||||
|
return _alertsQuery.Resolve(entity, ref entity.Comp, false)
|
||||||
|
? entity.Comp.Alerts
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public short GetSeverityRange(ProtoId<AlertPrototype> alertType)
|
public short GetSeverityRange(ProtoId<AlertPrototype> alertType)
|
||||||
{
|
{
|
||||||
var minSeverity = _typeToAlert[alertType].MinSeverity;
|
var minSeverity = _typeToAlert[alertType].MinSeverity;
|
||||||
return (short)MathF.Max(minSeverity,_typeToAlert[alertType].MaxSeverity - minSeverity);
|
return (short)MathF.Max(minSeverity, _typeToAlert[alertType].MaxSeverity - minSeverity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public short GetMaxSeverity(ProtoId<AlertPrototype> alertType)
|
public short GetMaxSeverity(ProtoId<AlertPrototype> alertType)
|
||||||
@@ -36,31 +95,29 @@ public abstract class AlertsSystem : EntitySystem
|
|||||||
return _typeToAlert[alertType].MinSeverity;
|
return _typeToAlert[alertType].MinSeverity;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsShowingAlert(EntityUid euid, ProtoId<AlertPrototype> alertType)
|
public bool IsShowingAlert(Entity<AlertsComponent?> entity, ProtoId<AlertPrototype> alertType)
|
||||||
{
|
{
|
||||||
if (!TryComp(euid, out AlertsComponent? alertsComponent))
|
if (!_alertsQuery.Resolve(entity, ref entity.Comp, false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (TryGet(alertType, out var alert))
|
if (TryGet(alertType, out var alert))
|
||||||
{
|
return entity.Comp.Alerts.ContainsKey(alert.AlertKey);
|
||||||
return alertsComponent.Alerts.ContainsKey(alert.AlertKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.Debug("Unknown alert type {0}", alertType);
|
Log.Debug($"Unknown alert type {alertType}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <returns>true iff an alert of the indicated alert category is currently showing</returns>
|
/// <returns>true iff an alert of the indicated alert category is currently showing</returns>
|
||||||
public bool IsShowingAlertCategory(EntityUid euid, ProtoId<AlertCategoryPrototype> alertCategory)
|
public bool IsShowingAlertCategory(Entity<AlertsComponent?> entity, ProtoId<AlertCategoryPrototype> alertCategory)
|
||||||
{
|
{
|
||||||
return TryComp(euid, out AlertsComponent? alertsComponent)
|
return _alertsQuery.Resolve(entity, ref entity.Comp, false)
|
||||||
&& alertsComponent.Alerts.ContainsKey(AlertKey.ForCategory(alertCategory));
|
&& entity.Comp.Alerts.ContainsKey(AlertKey.ForCategory(alertCategory));
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetAlertState(EntityUid euid, AlertKey key, out AlertState alertState)
|
public bool TryGetAlertState(Entity<AlertsComponent?> entity, AlertKey key, out AlertState alertState)
|
||||||
{
|
{
|
||||||
if (TryComp(euid, out AlertsComponent? alertsComponent))
|
if (_alertsQuery.Resolve(entity, ref entity.Comp, false))
|
||||||
return alertsComponent.Alerts.TryGetValue(key, out alertState);
|
return entity.Comp.Alerts.TryGetValue(key, out alertState);
|
||||||
|
|
||||||
alertState = default;
|
alertState = default;
|
||||||
return false;
|
return false;
|
||||||
@@ -71,107 +128,150 @@ public abstract class AlertsSystem : EntitySystem
|
|||||||
/// Shows the alert. If the alert or another alert of the same category is already showing,
|
/// Shows the alert. If the alert or another alert of the same category is already showing,
|
||||||
/// it will be updated / replaced with the specified values.
|
/// it will be updated / replaced with the specified values.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="euid"></param>
|
/// <param name="entity">The entity who we are showing the alert for.</param>
|
||||||
/// <param name="alertType">type of the alert to set</param>
|
/// <param name="alertType">type of the alert to set</param>
|
||||||
/// <param name="severity">severity, if supported by the alert</param>
|
/// <param name="severity">severity, if supported by the alert</param>
|
||||||
/// <param name="cooldown">cooldown start and end, if null there will be no cooldown (and it will
|
/// <param name="cooldown">cooldown start and end, if null there will be no cooldown (and it will
|
||||||
/// be erased if there is currently a cooldown for the alert)</param>
|
/// be erased if there is currently a cooldown for the alert)</param>
|
||||||
/// <param name="autoRemove">if true, the alert will be removed at the end of the cooldown</param>
|
/// <param name="autoRemove">if true, the alert will be removed at the end of the cooldown</param>
|
||||||
/// <param name="showCooldown">if true, the cooldown will be visibly shown over the alert icon</param>
|
/// <param name="showCooldown">if true, the cooldown will be visibly shown over the alert icon</param>
|
||||||
public void ShowAlert(EntityUid euid, ProtoId<AlertPrototype> alertType, short? severity = null, (TimeSpan, TimeSpan)? cooldown = null, bool autoRemove = false, bool showCooldown = true )
|
public void ShowAlert(Entity<AlertsComponent?> entity,
|
||||||
|
ProtoId<AlertPrototype> alertType,
|
||||||
|
short? severity = null,
|
||||||
|
(TimeSpan, TimeSpan)? cooldown = null,
|
||||||
|
bool autoRemove = false,
|
||||||
|
bool showCooldown = true )
|
||||||
|
{
|
||||||
|
ShowAlert(entity, new AlertState { Type = alertType, Severity = severity, Cooldown = cooldown, AutoRemove = autoRemove, ShowCooldown = showCooldown});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ShowAlert(Entity<AlertsComponent?> entity, AlertState state)
|
||||||
{
|
{
|
||||||
// This should be handled as part of networking.
|
// This should be handled as part of networking.
|
||||||
if (_timing.ApplyingState)
|
if (_timing.ApplyingState)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TryComp(euid, out AlertsComponent? alertsComponent))
|
if (!_alertsQuery.Resolve(entity, ref entity.Comp, false))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (TryGet(alertType, out var alert))
|
if (!TryGet(state.Type, out var alert))
|
||||||
{
|
{
|
||||||
// Check whether the alert category we want to show is already being displayed, with the same type,
|
Log.Error($"Unable to show alert {state.Type}, please ensure this alertType has a corresponding YML alert prototype");
|
||||||
// severity, and cooldown.
|
return;
|
||||||
if (alertsComponent.Alerts.TryGetValue(alert.AlertKey, out var alertStateCallback) &&
|
}
|
||||||
alertStateCallback.Type == alertType &&
|
|
||||||
alertStateCallback.Severity == severity &&
|
// Check whether the alert category we want to show is already being displayed, with the same type,
|
||||||
alertStateCallback.Cooldown == cooldown &&
|
// severity, and cooldown.
|
||||||
alertStateCallback.AutoRemove == autoRemove &&
|
if (entity.Comp.Alerts.TryGetValue(alert.AlertKey, out var alertStateCallback))
|
||||||
alertStateCallback.ShowCooldown == showCooldown)
|
{
|
||||||
{
|
if (state == alertStateCallback)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// In the case we're changing the alert type but not the category, we need to remove it first.
|
// If the alert exists and we're updating it, we need to remove it first before adding it back.
|
||||||
alertsComponent.Alerts.Remove(alert.AlertKey);
|
entity.Comp.Alerts.Remove(alert.AlertKey);
|
||||||
|
|
||||||
var state = new AlertState
|
|
||||||
{ Cooldown = cooldown, Severity = severity, Type = alertType, AutoRemove = autoRemove, ShowCooldown = showCooldown};
|
|
||||||
alertsComponent.Alerts[alert.AlertKey] = state;
|
|
||||||
|
|
||||||
// Keeping a list of AutoRemove alerts, so Update() doesn't need to check every alert
|
|
||||||
if (autoRemove)
|
|
||||||
{
|
|
||||||
var autoComp = EnsureComp<AlertAutoRemoveComponent>(euid);
|
|
||||||
if (!autoComp.AlertKeys.Contains(alert.AlertKey))
|
|
||||||
autoComp.AlertKeys.Add(alert.AlertKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
AfterShowAlert((euid, alertsComponent));
|
|
||||||
|
|
||||||
Dirty(euid, alertsComponent);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
entity.Comp.Alerts.Add(alert.AlertKey, state);
|
||||||
|
|
||||||
|
// Keeping a list of AutoRemove alerts, so Update() doesn't need to check every alert
|
||||||
|
if (state.AutoRemove)
|
||||||
{
|
{
|
||||||
Log.Error("Unable to show alert {0}, please ensure this alertType has" +
|
EnsureComp<AlertAutoRemoveComponent>(entity, out var autoComp);
|
||||||
" a corresponding YML alert prototype",
|
|
||||||
alertType);
|
if (autoComp.AlertKeys.Add(alert.AlertKey))
|
||||||
|
Dirty (entity, autoComp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AfterShowAlert((entity, entity.Comp));
|
||||||
|
|
||||||
|
Dirty(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An alternative to show alert with different behavior if an alert already exists.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="entity">Entity whose alert we're updating</param>
|
||||||
|
/// <param name="alertType">Prototype of the alert we're updating</param>
|
||||||
|
/// <param name="severity">Severity we're setting the alert to</param>
|
||||||
|
/// <param name="cooldown">Time left in the alert.</param>
|
||||||
|
/// <param name="autoRemove">Do we want to remove this alert when it expires?</param>
|
||||||
|
/// <param name="showCooldown">Should we show/hide the cooldown?</param>
|
||||||
|
public void UpdateAlert(Entity<AlertsComponent?> entity,
|
||||||
|
ProtoId<AlertPrototype> alertType,
|
||||||
|
short? severity = null,
|
||||||
|
TimeSpan? cooldown = null,
|
||||||
|
bool autoRemove = false,
|
||||||
|
bool showCooldown = true)
|
||||||
|
{
|
||||||
|
if (_timing.ApplyingState)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!_alertsQuery.Resolve(entity, ref entity.Comp, false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!TryGet(alertType, out var alert))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (cooldown == null)
|
||||||
|
{
|
||||||
|
ShowAlert(entity, alertType, severity, null, autoRemove, showCooldown);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep the progress duration the same but only if we're removing time.
|
||||||
|
// If the next cooldown is greater than our previous one we should reset the timer
|
||||||
|
TryGetAlertState(entity, alert.AlertKey, out var alertState);
|
||||||
|
var down = alertState.Cooldown?.endTime < cooldown.Value
|
||||||
|
? (_timing.CurTime, cooldown.Value)
|
||||||
|
: (alertState.Cooldown?.startTime ?? _timing.CurTime, cooldown.Value);
|
||||||
|
|
||||||
|
ShowAlert(entity, alertType, severity, down, autoRemove, showCooldown);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Clear the alert with the given category, if one is currently showing.
|
/// Clear the alert with the given category, if one is currently showing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ClearAlertCategory(EntityUid euid, ProtoId<AlertCategoryPrototype> category)
|
public void ClearAlertCategory(Entity<AlertsComponent?> entity, ProtoId<AlertCategoryPrototype> category)
|
||||||
{
|
{
|
||||||
if(!TryComp(euid, out AlertsComponent? alertsComponent))
|
if(!_alertsQuery.Resolve(entity, ref entity.Comp, false))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var key = AlertKey.ForCategory(category);
|
var key = AlertKey.ForCategory(category);
|
||||||
if (!alertsComponent.Alerts.Remove(key))
|
if (!entity.Comp.Alerts.Remove(key))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AfterClearAlert((euid, alertsComponent));
|
AfterClearAlert((entity, entity.Comp));
|
||||||
|
|
||||||
Dirty(euid, alertsComponent);
|
Dirty(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Clear the alert of the given type if it is currently showing.
|
/// Clear the alert of the given type if it is currently showing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ClearAlert(EntityUid euid, ProtoId<AlertPrototype> alertType)
|
public void ClearAlert(Entity<AlertsComponent?> entity, ProtoId<AlertPrototype> alertType)
|
||||||
{
|
{
|
||||||
if (_timing.ApplyingState)
|
if (_timing.ApplyingState)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TryComp(euid, out AlertsComponent? alertsComponent))
|
if (!_alertsQuery.Resolve(entity, ref entity.Comp, false))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (TryGet(alertType, out var alert))
|
if (TryGet(alertType, out var alert))
|
||||||
{
|
{
|
||||||
if (!alertsComponent.Alerts.Remove(alert.AlertKey))
|
if (!entity.Comp.Alerts.Remove(alert.AlertKey))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AfterClearAlert((euid, alertsComponent));
|
AfterClearAlert((entity, entity.Comp));
|
||||||
|
|
||||||
Dirty(euid, alertsComponent);
|
Dirty(entity);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.Error("Unable to clear alert, unknown alertType {0}", alertType);
|
Log.Error($"Unable to clear alert, unknown alertType {alertType}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,27 +285,10 @@ public abstract class AlertsSystem : EntitySystem
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual void AfterClearAlert(Entity<AlertsComponent> alerts) { }
|
protected virtual void AfterClearAlert(Entity<AlertsComponent> alerts) { }
|
||||||
|
|
||||||
public override void Initialize()
|
private void OnAutoRemoveUnPaused(Entity<AlertAutoRemoveComponent> entity, ref EntityUnpausedEvent args)
|
||||||
{
|
{
|
||||||
base.Initialize();
|
if (!_alertsQuery.TryComp(entity, out var alertComp))
|
||||||
|
|
||||||
SubscribeLocalEvent<AlertsComponent, ComponentStartup>(HandleComponentStartup);
|
|
||||||
SubscribeLocalEvent<AlertsComponent, ComponentShutdown>(HandleComponentShutdown);
|
|
||||||
SubscribeLocalEvent<AlertsComponent, PlayerAttachedEvent>(OnPlayerAttached);
|
|
||||||
|
|
||||||
SubscribeLocalEvent<AlertAutoRemoveComponent, EntityUnpausedEvent>(OnAutoRemoveUnPaused);
|
|
||||||
|
|
||||||
SubscribeAllEvent<ClickAlertEvent>(HandleClickAlert);
|
|
||||||
SubscribeLocalEvent<PrototypesReloadedEventArgs>(HandlePrototypesReloaded);
|
|
||||||
LoadPrototypes();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnAutoRemoveUnPaused(EntityUid uid, AlertAutoRemoveComponent comp, EntityUnpausedEvent args)
|
|
||||||
{
|
|
||||||
if (!TryComp<AlertsComponent>(uid, out var alertComp))
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
var dirty = false;
|
var dirty = false;
|
||||||
|
|
||||||
@@ -214,58 +297,16 @@ public abstract class AlertsSystem : EntitySystem
|
|||||||
if (alert.Value.Cooldown is null)
|
if (alert.Value.Cooldown is null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var cooldown = (alert.Value.Cooldown.Value.Item1, alert.Value.Cooldown.Value.Item2 + args.PausedTime);
|
var (start, end) = alert.Value.Cooldown.Value;
|
||||||
|
var cooldown = (start, end + args.PausedTime);
|
||||||
|
|
||||||
var state = new AlertState
|
var state = alert.Value with { Cooldown = cooldown };
|
||||||
{
|
|
||||||
Severity = alert.Value.Severity,
|
|
||||||
Cooldown = cooldown,
|
|
||||||
ShowCooldown = alert.Value.ShowCooldown,
|
|
||||||
AutoRemove = alert.Value.AutoRemove,
|
|
||||||
Type = alert.Value.Type
|
|
||||||
};
|
|
||||||
alertComp.Alerts[alert.Key] = state;
|
alertComp.Alerts[alert.Key] = state;
|
||||||
dirty = true;
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dirty)
|
if (dirty)
|
||||||
Dirty(uid, comp);
|
Dirty(entity, alertComp);
|
||||||
}
|
|
||||||
|
|
||||||
public override void Update(float frameTime)
|
|
||||||
{
|
|
||||||
base.Update(frameTime);
|
|
||||||
|
|
||||||
var query = EntityQueryEnumerator<AlertAutoRemoveComponent>();
|
|
||||||
while (query.MoveNext(out var uid, out var autoComp))
|
|
||||||
{
|
|
||||||
var dirtyComp = false;
|
|
||||||
if (autoComp.AlertKeys.Count <= 0 || !TryComp<AlertsComponent>(uid, out var alertComp))
|
|
||||||
{
|
|
||||||
RemCompDeferred(uid, autoComp);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var removeList = new List<AlertKey>();
|
|
||||||
foreach (var alertKey in autoComp.AlertKeys)
|
|
||||||
{
|
|
||||||
alertComp.Alerts.TryGetValue(alertKey, out var alertState);
|
|
||||||
|
|
||||||
if (alertState.Cooldown is null || alertState.Cooldown.Value.Item2 >= _timing.CurTime)
|
|
||||||
continue;
|
|
||||||
removeList.Add(alertKey);
|
|
||||||
alertComp.Alerts.Remove(alertKey);
|
|
||||||
dirtyComp = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var alertKey in removeList)
|
|
||||||
{
|
|
||||||
autoComp.AlertKeys.Remove(alertKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dirtyComp)
|
|
||||||
Dirty(uid, alertComp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void HandleComponentShutdown(EntityUid uid, AlertsComponent component, ComponentShutdown args)
|
protected virtual void HandleComponentShutdown(EntityUid uid, AlertsComponent component, ComponentShutdown args)
|
||||||
@@ -290,10 +331,7 @@ public abstract class AlertsSystem : EntitySystem
|
|||||||
foreach (var alert in _prototypeManager.EnumeratePrototypes<AlertPrototype>())
|
foreach (var alert in _prototypeManager.EnumeratePrototypes<AlertPrototype>())
|
||||||
{
|
{
|
||||||
if (!dict.TryAdd(alert.ID, alert))
|
if (!dict.TryAdd(alert.ID, alert))
|
||||||
{
|
Log.Error($"Found alert with duplicate alertType {alert.ID} - all alerts must have a unique alertType, this one will be skipped");
|
||||||
Log.Error("Found alert with duplicate alertType {0} - all alerts must have" +
|
|
||||||
" a unique alertType, this one will be skipped", alert.ID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_typeToAlert = dict.ToFrozenDictionary();
|
_typeToAlert = dict.ToFrozenDictionary();
|
||||||
@@ -316,15 +354,13 @@ public abstract class AlertsSystem : EntitySystem
|
|||||||
|
|
||||||
if (!IsShowingAlert(player.Value, msg.Type))
|
if (!IsShowingAlert(player.Value, msg.Type))
|
||||||
{
|
{
|
||||||
Log.Debug("User {0} attempted to" +
|
Log.Debug($"User {ToPrettyString(player.Value)} attempted to click alert {msg.Type} which is not currently showing for them");
|
||||||
" click alert {1} which is not currently showing for them",
|
|
||||||
Comp<MetaDataComponent>(player.Value).EntityName, msg.Type);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TryGet(msg.Type, out var alert))
|
if (!TryGet(msg.Type, out var alert))
|
||||||
{
|
{
|
||||||
Log.Warning("Unrecognized encoded alert {0}", msg.Type);
|
Log.Warning($"Unrecognized encoded alert {msg.Type}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -413,11 +413,11 @@ public abstract class SharedBloodstreamSystem : EntitySystem
|
|||||||
DirtyField(ent, ent.Comp, nameof(BloodstreamComponent.BleedAmount));
|
DirtyField(ent, ent.Comp, nameof(BloodstreamComponent.BleedAmount));
|
||||||
|
|
||||||
if (ent.Comp.BleedAmount == 0)
|
if (ent.Comp.BleedAmount == 0)
|
||||||
_alertsSystem.ClearAlert(ent, ent.Comp.BleedingAlert);
|
_alertsSystem.ClearAlert(ent.Owner, ent.Comp.BleedingAlert);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var severity = (short)Math.Clamp(Math.Round(ent.Comp.BleedAmount, MidpointRounding.ToZero), 0, 10);
|
var severity = (short)Math.Clamp(Math.Round(ent.Comp.BleedAmount, MidpointRounding.ToZero), 0, 10);
|
||||||
_alertsSystem.ShowAlert(ent, ent.Comp.BleedingAlert, severity);
|
_alertsSystem.ShowAlert(ent.Owner, ent.Comp.BleedingAlert, severity);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -158,12 +158,12 @@ public abstract class SharedInternalsSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnInternalsStartup(Entity<InternalsComponent> ent, ref ComponentStartup args)
|
private void OnInternalsStartup(Entity<InternalsComponent> ent, ref ComponentStartup args)
|
||||||
{
|
{
|
||||||
_alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent));
|
_alerts.ShowAlert(ent.Owner, ent.Comp.InternalsAlert, GetSeverity(ent));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnInternalsShutdown(Entity<InternalsComponent> ent, ref ComponentShutdown args)
|
private void OnInternalsShutdown(Entity<InternalsComponent> ent, ref ComponentShutdown args)
|
||||||
{
|
{
|
||||||
_alerts.ClearAlert(ent, ent.Comp.InternalsAlert);
|
_alerts.ClearAlert(ent.Owner, ent.Comp.InternalsAlert);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConnectBreathTool(Entity<InternalsComponent> ent, EntityUid toolEntity)
|
public void ConnectBreathTool(Entity<InternalsComponent> ent, EntityUid toolEntity)
|
||||||
@@ -178,7 +178,7 @@ public abstract class SharedInternalsSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
Dirty(ent);
|
Dirty(ent);
|
||||||
_alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent));
|
_alerts.ShowAlert(ent.Owner, ent.Comp.InternalsAlert, GetSeverity(ent));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DisconnectBreathTool(Entity<InternalsComponent> ent, EntityUid toolEntity, bool forced = false)
|
public void DisconnectBreathTool(Entity<InternalsComponent> ent, EntityUid toolEntity, bool forced = false)
|
||||||
@@ -199,7 +199,7 @@ public abstract class SharedInternalsSystem : EntitySystem
|
|||||||
DisconnectTank(ent, forced: forced);
|
DisconnectTank(ent, forced: forced);
|
||||||
}
|
}
|
||||||
|
|
||||||
_alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent));
|
_alerts.ShowAlert(ent.Owner, ent.Comp.InternalsAlert, GetSeverity(ent));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DisconnectTank(Entity<InternalsComponent> ent, bool forced = false)
|
public void DisconnectTank(Entity<InternalsComponent> ent, bool forced = false)
|
||||||
@@ -222,7 +222,7 @@ public abstract class SharedInternalsSystem : EntitySystem
|
|||||||
|
|
||||||
ent.Comp.GasTankEntity = tankEntity;
|
ent.Comp.GasTankEntity = tankEntity;
|
||||||
Dirty(ent);
|
Dirty(ent);
|
||||||
_alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent));
|
_alerts.ShowAlert(ent.Owner, ent.Comp.InternalsAlert, GetSeverity(ent));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -196,11 +196,11 @@ public abstract partial class SharedBuckleSystem
|
|||||||
{
|
{
|
||||||
strapEnt.Comp.BuckledEntities.Add(buckle);
|
strapEnt.Comp.BuckledEntities.Add(buckle);
|
||||||
Dirty(strapEnt);
|
Dirty(strapEnt);
|
||||||
_alerts.ShowAlert(buckle, strapEnt.Comp.BuckledAlertType);
|
_alerts.ShowAlert(buckle.Owner, strapEnt.Comp.BuckledAlertType);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_alerts.ClearAlertCategory(buckle, BuckledAlertCategory);
|
_alerts.ClearAlertCategory(buckle.Owner, BuckledAlertCategory);
|
||||||
}
|
}
|
||||||
|
|
||||||
buckle.Comp.BuckledTo = strap;
|
buckle.Comp.BuckledTo = strap;
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ public abstract partial class SharedStaminaSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
RemCompDeferred<ActiveStaminaComponent>(entity);
|
RemCompDeferred<ActiveStaminaComponent>(entity);
|
||||||
}
|
}
|
||||||
_alerts.ClearAlert(entity, entity.Comp.StaminaAlert);
|
_alerts.ClearAlert(entity.Owner, entity.Comp.StaminaAlert);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnStartup(Entity<StaminaComponent> entity, ref ComponentStartup args)
|
private void OnStartup(Entity<StaminaComponent> entity, ref ComponentStartup args)
|
||||||
|
|||||||
@@ -132,9 +132,9 @@ public abstract partial class SharedGravitySystem : EntitySystem
|
|||||||
private void OnWeightlessnessChanged(Entity<AlertsComponent> entity, ref WeightlessnessChangedEvent args)
|
private void OnWeightlessnessChanged(Entity<AlertsComponent> entity, ref WeightlessnessChangedEvent args)
|
||||||
{
|
{
|
||||||
if (args.Weightless)
|
if (args.Weightless)
|
||||||
_alerts.ShowAlert(entity, WeightlessAlert);
|
_alerts.ShowAlert(entity.AsNullable(), WeightlessAlert);
|
||||||
else
|
else
|
||||||
_alerts.ClearAlert(entity, WeightlessAlert);
|
_alerts.ClearAlert(entity.AsNullable(), WeightlessAlert);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnEntParentChanged(Entity<GravityAffectedComponent> entity, ref EntParentChangedMessage args)
|
private void OnEntParentChanged(Entity<GravityAffectedComponent> entity, ref EntParentChangedMessage args)
|
||||||
@@ -202,12 +202,12 @@ public abstract partial class SharedGravitySystem : EntitySystem
|
|||||||
_alerts.ClearAlert(ev.Euid, WeightlessAlert);
|
_alerts.ClearAlert(ev.Euid, WeightlessAlert);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAlertsParentChange(EntityUid uid, AlertsComponent component, ref EntParentChangedMessage args)
|
private void OnAlertsParentChange(Entity<AlertsComponent> entity, ref EntParentChangedMessage args)
|
||||||
{
|
{
|
||||||
if (IsWeightless(uid))
|
if (IsWeightless(entity.Owner))
|
||||||
_alerts.ShowAlert(uid, WeightlessAlert);
|
_alerts.ShowAlert(entity.AsNullable(), WeightlessAlert);
|
||||||
else
|
else
|
||||||
_alerts.ClearAlert(uid, WeightlessAlert);
|
_alerts.ClearAlert(entity.AsNullable(), WeightlessAlert);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGridInit(GridInitializeEvent ev)
|
private void OnGridInit(GridInitializeEvent ev)
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public sealed class WormSystem : EntitySystem
|
|||||||
private void OnMapInit(Entity<WormComponent> ent, ref MapInitEvent args)
|
private void OnMapInit(Entity<WormComponent> ent, ref MapInitEvent args)
|
||||||
{
|
{
|
||||||
EnsureComp<KnockedDownComponent>(ent, out var knocked);
|
EnsureComp<KnockedDownComponent>(ent, out var knocked);
|
||||||
_alerts.ShowAlert(ent, SharedStunSystem.KnockdownAlert);
|
_alerts.ShowAlert(ent.Owner, SharedStunSystem.KnockdownAlert);
|
||||||
_stun.SetAutoStand((ent, knocked));
|
_stun.SetAutoStand((ent, knocked));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ public abstract class SharedRootableSystem : EntitySystem
|
|||||||
|
|
||||||
var actions = new Entity<ActionsComponent?>(entity, comp);
|
var actions = new Entity<ActionsComponent?>(entity, comp);
|
||||||
_actions.RemoveAction(actions, entity.Comp.ActionEntity);
|
_actions.RemoveAction(actions, entity.Comp.ActionEntity);
|
||||||
_alerts.ClearAlert(entity, entity.Comp.RootedAlert);
|
_alerts.ClearAlert(entity.Owner, entity.Comp.RootedAlert);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnRootableToggle(Entity<RootableComponent> entity, ref ToggleActionEvent args)
|
private void OnRootableToggle(Entity<RootableComponent> entity, ref ToggleActionEvent args)
|
||||||
@@ -109,7 +109,7 @@ public abstract class SharedRootableSystem : EntitySystem
|
|||||||
|
|
||||||
if (entity.Comp.Rooted)
|
if (entity.Comp.Rooted)
|
||||||
{
|
{
|
||||||
_alerts.ShowAlert(entity, entity.Comp.RootedAlert);
|
_alerts.ShowAlert(entity.Owner, entity.Comp.RootedAlert);
|
||||||
var curTime = _timing.CurTime;
|
var curTime = _timing.CurTime;
|
||||||
if (curTime > entity.Comp.NextUpdate)
|
if (curTime > entity.Comp.NextUpdate)
|
||||||
{
|
{
|
||||||
@@ -118,7 +118,7 @@ public abstract class SharedRootableSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_alerts.ClearAlert(entity, entity.Comp.RootedAlert);
|
_alerts.ClearAlert(entity.Owner, entity.Comp.RootedAlert);
|
||||||
}
|
}
|
||||||
_audio.PlayPredicted(entity.Comp.RootSound, entity.Owner.ToCoordinates(), entity);
|
_audio.PlayPredicted(entity.Comp.RootSound, entity.Owner.ToCoordinates(), entity);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Content.Shared.Alert;
|
using Content.Shared.Alert;
|
||||||
using Content.Shared.StatusEffectNew.Components;
|
using Content.Shared.StatusEffectNew.Components;
|
||||||
using Robust.Shared.Timing;
|
|
||||||
|
|
||||||
namespace Content.Shared.StatusEffectNew;
|
namespace Content.Shared.StatusEffectNew;
|
||||||
|
|
||||||
@@ -9,7 +8,6 @@ namespace Content.Shared.StatusEffectNew;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class StatusEffectAlertSystem : EntitySystem
|
public sealed class StatusEffectAlertSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IGameTiming _timing = default!;
|
|
||||||
[Dependency] private readonly AlertsSystem _alerts = default!;
|
[Dependency] private readonly AlertsSystem _alerts = default!;
|
||||||
|
|
||||||
private EntityQuery<StatusEffectComponent> _effectQuery;
|
private EntityQuery<StatusEffectComponent> _effectQuery;
|
||||||
@@ -30,7 +28,7 @@ public sealed class StatusEffectAlertSystem : EntitySystem
|
|||||||
if (!_effectQuery.TryComp(ent, out var effectComp))
|
if (!_effectQuery.TryComp(ent, out var effectComp))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
RefreshAlert(ent, args.Target, effectComp.EndEffectTime);
|
_alerts.UpdateAlert(args.Target, ent.Comp.Alert, cooldown: ent.Comp.ShowDuration ? effectComp.EndEffectTime : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnStatusEffectRemoved(Entity<StatusEffectAlertComponent> ent, ref StatusEffectRemovedEvent args)
|
private void OnStatusEffectRemoved(Entity<StatusEffectAlertComponent> ent, ref StatusEffectRemovedEvent args)
|
||||||
@@ -40,23 +38,6 @@ public sealed class StatusEffectAlertSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnEndTimeUpdated(Entity<StatusEffectAlertComponent> ent, ref StatusEffectEndTimeUpdatedEvent args)
|
private void OnEndTimeUpdated(Entity<StatusEffectAlertComponent> ent, ref StatusEffectEndTimeUpdatedEvent args)
|
||||||
{
|
{
|
||||||
RefreshAlert(ent, args.Target, args.EndTime);
|
_alerts.UpdateAlert(args.Target, ent.Comp.Alert, cooldown: ent.Comp.ShowDuration ? args.EndTime : null);
|
||||||
}
|
|
||||||
|
|
||||||
private void RefreshAlert(Entity<StatusEffectAlertComponent> ent, EntityUid target, TimeSpan? endTime)
|
|
||||||
{
|
|
||||||
(TimeSpan Start, TimeSpan End)? cooldown = null;
|
|
||||||
|
|
||||||
// Make sure the start time of the alert cooldown is still accurate
|
|
||||||
// This ensures the progress wheel doesn't "reset" every duration change.
|
|
||||||
if (ent.Comp.ShowDuration
|
|
||||||
&& endTime is not null
|
|
||||||
&& _alerts.TryGet(ent.Comp.Alert, out var alert))
|
|
||||||
{
|
|
||||||
_alerts.TryGetAlertState(target, alert.AlertKey, out var alertState);
|
|
||||||
cooldown = (alertState.Cooldown?.Item1 ?? _timing.CurTime, endTime.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
_alerts.ShowAlert(target, ent.Comp.Alert, cooldown: cooldown);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,12 +32,12 @@ public sealed partial class ThievingSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnCompInit(Entity<ThievingComponent> entity, ref ComponentInit args)
|
private void OnCompInit(Entity<ThievingComponent> entity, ref ComponentInit args)
|
||||||
{
|
{
|
||||||
_alertsSystem.ShowAlert(entity, entity.Comp.StealthyAlertProtoId, 1);
|
_alertsSystem.ShowAlert(entity.Owner, entity.Comp.StealthyAlertProtoId, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnCompRemoved(Entity<ThievingComponent> entity, ref ComponentRemove args)
|
private void OnCompRemoved(Entity<ThievingComponent> entity, ref ComponentRemove args)
|
||||||
{
|
{
|
||||||
_alertsSystem.ClearAlert(entity, entity.Comp.StealthyAlertProtoId);
|
_alertsSystem.ClearAlert(entity.Owner, entity.Comp.StealthyAlertProtoId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnToggleStealthy(Entity<ThievingComponent> ent, ref ToggleThievingEvent args)
|
private void OnToggleStealthy(Entity<ThievingComponent> ent, ref ToggleThievingEvent args)
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ public abstract partial class SharedStunSystem
|
|||||||
entity.Comp.SpeedModifier = 1f;
|
entity.Comp.SpeedModifier = 1f;
|
||||||
|
|
||||||
_standingState.Stand(entity);
|
_standingState.Stand(entity);
|
||||||
Alerts.ClearAlert(entity, KnockdownAlert);
|
Alerts.ClearAlert(entity.Owner, KnockdownAlert);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -179,7 +179,7 @@ public abstract partial class SharedStunSystem
|
|||||||
{
|
{
|
||||||
entity.Comp.NextUpdate = time;
|
entity.Comp.NextUpdate = time;
|
||||||
DirtyField(entity, entity.Comp, nameof(KnockedDownComponent.NextUpdate));
|
DirtyField(entity, entity.Comp, nameof(KnockedDownComponent.NextUpdate));
|
||||||
Alerts.ShowAlert(entity, KnockdownAlert, null, (GameTiming.CurTime, entity.Comp.NextUpdate));
|
Alerts.ShowAlert(entity.Owner, KnockdownAlert, null, (GameTiming.CurTime, entity.Comp.NextUpdate));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -216,7 +216,7 @@ public abstract partial class SharedStunSystem
|
|||||||
|
|
||||||
entity.Comp.NextUpdate += time;
|
entity.Comp.NextUpdate += time;
|
||||||
DirtyField(entity, entity.Comp, nameof(KnockedDownComponent.NextUpdate));
|
DirtyField(entity, entity.Comp, nameof(KnockedDownComponent.NextUpdate));
|
||||||
Alerts.ShowAlert(entity, KnockdownAlert, null, (GameTiming.CurTime, entity.Comp.NextUpdate));
|
Alerts.ShowAlert(entity.Owner, KnockdownAlert, null, (GameTiming.CurTime, entity.Comp.NextUpdate));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
Reference in New Issue
Block a user