Remove AlertType and AlertCategory (#27933)
This commit is contained in:
@@ -91,7 +91,7 @@ public sealed class ClientAlertsSystem : AlertsSystem
|
||||
ClearAlerts?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public void AlertClicked(AlertType alertType)
|
||||
public void AlertClicked(ProtoId<AlertPrototype> alertType)
|
||||
{
|
||||
RaiseNetworkEvent(new ClickAlertEvent(alertType));
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Client.Alerts;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Revenant;
|
||||
using Content.Shared.Revenant.Components;
|
||||
using Robust.Client.GameObjects;
|
||||
@@ -42,7 +41,7 @@ public sealed class RevenantSystem : EntitySystem
|
||||
|
||||
private void OnUpdateAlert(Entity<RevenantComponent> ent, ref UpdateAlertSpriteEvent args)
|
||||
{
|
||||
if (args.Alert.AlertType != AlertType.Essence)
|
||||
if (args.Alert.ID != ent.Comp.EssenceAlert)
|
||||
return;
|
||||
|
||||
var sprite = args.SpriteViewEnt.Comp;
|
||||
|
||||
@@ -7,6 +7,7 @@ using Robust.Client.GameObjects;
|
||||
using Robust.Client.Player;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Client.UserInterface.Controllers;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.UserInterface.Systems.Alerts;
|
||||
|
||||
@@ -43,7 +44,7 @@ public sealed class AlertsUIController : UIController, IOnStateEntered<GameplayS
|
||||
SyncAlerts();
|
||||
}
|
||||
|
||||
private void OnAlertPressed(object? sender, AlertType e)
|
||||
private void OnAlertPressed(object? sender, ProtoId<AlertPrototype> e)
|
||||
{
|
||||
_alertsSystem?.AlertClicked(e);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using Robust.Client.AutoGenerated;
|
||||
using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.XAML;
|
||||
using Robust.Shared.Input;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Client.UserInterface.Systems.Alerts.Widgets;
|
||||
|
||||
@@ -21,8 +22,10 @@ public sealed partial class AlertsUI : UIWidget
|
||||
RobustXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public void SyncControls(AlertsSystem alertsSystem, AlertOrderPrototype? alertOrderPrototype,
|
||||
IReadOnlyDictionary<AlertKey, AlertState> alertStates)
|
||||
public void SyncControls(AlertsSystem alertsSystem,
|
||||
AlertOrderPrototype? alertOrderPrototype,
|
||||
IReadOnlyDictionary<AlertKey,
|
||||
AlertState> alertStates)
|
||||
{
|
||||
// remove any controls with keys no longer present
|
||||
if (SyncRemoveControls(alertStates))
|
||||
@@ -46,7 +49,7 @@ public sealed partial class AlertsUI : UIWidget
|
||||
_alertControls.Clear();
|
||||
}
|
||||
|
||||
public event EventHandler<AlertType>? AlertPressed;
|
||||
public event EventHandler<ProtoId<AlertPrototype>>? AlertPressed;
|
||||
|
||||
private bool SyncRemoveControls(IReadOnlyDictionary<AlertKey, AlertState> alertStates)
|
||||
{
|
||||
@@ -88,7 +91,7 @@ public sealed partial class AlertsUI : UIWidget
|
||||
}
|
||||
|
||||
if (_alertControls.TryGetValue(newAlert.AlertKey, out var existingAlertControl) &&
|
||||
existingAlertControl.Alert.AlertType == newAlert.AlertType)
|
||||
existingAlertControl.Alert.ID == newAlert.ID)
|
||||
{
|
||||
// key is the same, simply update the existing control severity / cooldown
|
||||
existingAlertControl.SetSeverity(alertState.Severity);
|
||||
@@ -155,6 +158,6 @@ public sealed partial class AlertsUI : UIWidget
|
||||
if (args.Event.Function != EngineKeyFunctions.UIClick)
|
||||
return;
|
||||
|
||||
AlertPressed?.Invoke(this, control.Alert.AlertType);
|
||||
AlertPressed?.Invoke(this, control.Alert.ID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ using Content.Shared.Alert;
|
||||
using Robust.Client.UserInterface;
|
||||
using Robust.Server.Player;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.IntegrationTests.Tests.GameObjects.Components.Mobs
|
||||
{
|
||||
@@ -45,8 +44,8 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.Mobs
|
||||
Assert.That(alerts, Is.Not.Null);
|
||||
var alertCount = alerts.Count;
|
||||
|
||||
alertsSystem.ShowAlert(playerUid, AlertType.Debug1);
|
||||
alertsSystem.ShowAlert(playerUid, AlertType.Debug2);
|
||||
alertsSystem.ShowAlert(playerUid, "Debug1");
|
||||
alertsSystem.ShowAlert(playerUid, "Debug2");
|
||||
|
||||
Assert.That(alerts, Has.Count.EqualTo(alertCount + 2));
|
||||
});
|
||||
@@ -87,14 +86,14 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.Mobs
|
||||
// we should be seeing 3 alerts - our health, and the 2 debug alerts, in a specific order.
|
||||
Assert.That(clientAlertsUI.AlertContainer.ChildCount, Is.GreaterThanOrEqualTo(3));
|
||||
var alertControls = clientAlertsUI.AlertContainer.Children.Select(c => (AlertControl) c);
|
||||
var alertIDs = alertControls.Select(ac => ac.Alert.AlertType).ToArray();
|
||||
var expectedIDs = new[] { AlertType.HumanHealth, AlertType.Debug1, AlertType.Debug2 };
|
||||
var alertIDs = alertControls.Select(ac => ac.Alert.ID).ToArray();
|
||||
var expectedIDs = new[] { "HumanHealth", "Debug1", "Debug2" };
|
||||
Assert.That(alertIDs, Is.SupersetOf(expectedIDs));
|
||||
});
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
alertsSystem.ClearAlert(playerUid, AlertType.Debug1);
|
||||
alertsSystem.ClearAlert(playerUid, "Debug1");
|
||||
});
|
||||
|
||||
await pair.RunTicksSync(5);
|
||||
@@ -104,8 +103,8 @@ namespace Content.IntegrationTests.Tests.GameObjects.Components.Mobs
|
||||
// we should be seeing 2 alerts now because one was cleared
|
||||
Assert.That(clientAlertsUI.AlertContainer.ChildCount, Is.GreaterThanOrEqualTo(2));
|
||||
var alertControls = clientAlertsUI.AlertContainer.Children.Select(c => (AlertControl) c);
|
||||
var alertIDs = alertControls.Select(ac => ac.Alert.AlertType).ToArray();
|
||||
var expectedIDs = new[] { AlertType.HumanHealth, AlertType.Debug2 };
|
||||
var alertIDs = alertControls.Select(ac => ac.Alert.ID).ToArray();
|
||||
var expectedIDs = new[] { "HumanHealth", "Debug2" };
|
||||
Assert.That(alertIDs, Is.SupersetOf(expectedIDs));
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Server.Gravity;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Gravity;
|
||||
using Robust.Shared.GameObjects;
|
||||
|
||||
namespace Content.IntegrationTests.Tests.Gravity
|
||||
@@ -38,6 +39,7 @@ namespace Content.IntegrationTests.Tests.Gravity
|
||||
|
||||
var entityManager = server.ResolveDependency<IEntityManager>();
|
||||
var alertsSystem = server.ResolveDependency<IEntitySystemManager>().GetEntitySystem<AlertsSystem>();
|
||||
var weightlessAlert = SharedGravitySystem.WeightlessAlert;
|
||||
|
||||
EntityUid human = default;
|
||||
|
||||
@@ -56,7 +58,7 @@ namespace Content.IntegrationTests.Tests.Gravity
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
// No gravity without a gravity generator
|
||||
Assert.That(alertsSystem.IsShowingAlert(human, AlertType.Weightless));
|
||||
Assert.That(alertsSystem.IsShowingAlert(human, weightlessAlert));
|
||||
|
||||
generatorUid = entityManager.SpawnEntity("WeightlessGravityGeneratorDummy", entityManager.GetComponent<TransformComponent>(human).Coordinates);
|
||||
});
|
||||
@@ -66,7 +68,7 @@ namespace Content.IntegrationTests.Tests.Gravity
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
Assert.That(alertsSystem.IsShowingAlert(human, AlertType.Weightless), Is.False);
|
||||
Assert.That(alertsSystem.IsShowingAlert(human, weightlessAlert), Is.False);
|
||||
|
||||
// This should kill gravity
|
||||
entityManager.DeleteEntity(generatorUid);
|
||||
@@ -76,7 +78,7 @@ namespace Content.IntegrationTests.Tests.Gravity
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
{
|
||||
Assert.That(alertsSystem.IsShowingAlert(human, AlertType.Weightless));
|
||||
Assert.That(alertsSystem.IsShowingAlert(human, weightlessAlert));
|
||||
});
|
||||
|
||||
await pair.RunTicksSync(10);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Content.Shared.Alert;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
@@ -47,5 +48,12 @@ namespace Content.Server.Abilities.Mime
|
||||
/// </summary>
|
||||
[DataField("vowCooldown")]
|
||||
public TimeSpan VowCooldown = TimeSpan.FromMinutes(5);
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> VowAlert = "VowOfSilence";
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> VowBrokenAlert = "VowBroken";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Content.Server.Popups;
|
||||
using Content.Server.Speech.Muting;
|
||||
using Content.Shared.Actions;
|
||||
using Content.Shared.Actions.Events;
|
||||
using Content.Shared.Alert;
|
||||
@@ -54,7 +53,7 @@ namespace Content.Server.Abilities.Mime
|
||||
private void OnComponentInit(EntityUid uid, MimePowersComponent component, ComponentInit args)
|
||||
{
|
||||
EnsureComp<MutedComponent>(uid);
|
||||
_alertsSystem.ShowAlert(uid, AlertType.VowOfSilence);
|
||||
_alertsSystem.ShowAlert(uid, component.VowAlert);
|
||||
_actionsSystem.AddAction(uid, ref component.InvisibleWallActionEntity, component.InvisibleWallAction, uid);
|
||||
}
|
||||
|
||||
@@ -115,8 +114,8 @@ namespace Content.Server.Abilities.Mime
|
||||
mimePowers.VowBroken = true;
|
||||
mimePowers.VowRepentTime = _timing.CurTime + mimePowers.VowCooldown;
|
||||
RemComp<MutedComponent>(uid);
|
||||
_alertsSystem.ClearAlert(uid, AlertType.VowOfSilence);
|
||||
_alertsSystem.ShowAlert(uid, AlertType.VowBroken);
|
||||
_alertsSystem.ClearAlert(uid, mimePowers.VowAlert);
|
||||
_alertsSystem.ShowAlert(uid, mimePowers.VowBrokenAlert);
|
||||
_actionsSystem.RemoveAction(uid, mimePowers.InvisibleWallActionEntity);
|
||||
}
|
||||
|
||||
@@ -138,8 +137,8 @@ namespace Content.Server.Abilities.Mime
|
||||
mimePowers.ReadyToRepent = false;
|
||||
mimePowers.VowBroken = false;
|
||||
AddComp<MutedComponent>(uid);
|
||||
_alertsSystem.ClearAlert(uid, AlertType.VowBroken);
|
||||
_alertsSystem.ShowAlert(uid, AlertType.VowOfSilence);
|
||||
_alertsSystem.ClearAlert(uid, mimePowers.VowAlert);
|
||||
_alertsSystem.ShowAlert(uid, mimePowers.VowBrokenAlert);
|
||||
_actionsSystem.AddAction(uid, ref mimePowers.InvisibleWallActionEntity, mimePowers.InvisibleWallAction, uid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,13 +40,13 @@ namespace Content.Server.Alert.Commands
|
||||
|
||||
var alertType = args[0];
|
||||
var alertsSystem = _e.System<AlertsSystem>();
|
||||
if (!alertsSystem.TryGet(Enum.Parse<AlertType>(alertType), out var alert))
|
||||
if (!alertsSystem.TryGet(alertType, out var alert))
|
||||
{
|
||||
shell.WriteLine("unrecognized alertType " + alertType);
|
||||
return;
|
||||
}
|
||||
|
||||
alertsSystem.ClearAlert(attachedEntity, alert.AlertType);
|
||||
alertsSystem.ClearAlert(attachedEntity, alert.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Content.Server.Alert.Commands
|
||||
var alertType = args[0];
|
||||
var severity = args[1];
|
||||
var alertsSystem = _e.System<AlertsSystem>();
|
||||
if (!alertsSystem.TryGet(Enum.Parse<AlertType>(alertType), out var alert))
|
||||
if (!alertsSystem.TryGet(alertType, out var alert))
|
||||
{
|
||||
shell.WriteLine("unrecognized alertType " + alertType);
|
||||
return;
|
||||
@@ -53,7 +53,7 @@ namespace Content.Server.Alert.Commands
|
||||
}
|
||||
|
||||
short? severity1 = sevint == -1 ? null : sevint;
|
||||
alertsSystem.ShowAlert(attachedEntity, alert.AlertType, severity1, null);
|
||||
alertsSystem.ShowAlert(attachedEntity, alert.ID, severity1, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Atmos.Components
|
||||
{
|
||||
@@ -46,5 +48,13 @@ namespace Content.Server.Atmos.Components
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool HasImmunity = false;
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> HighPressureAlert = "HighPressure";
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> LowPressureAlert = "LowPressure";
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertCategoryPrototype> PressureAlertCategory = "Pressure";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Damage;
|
||||
using Robust.Shared.Physics.Collision.Shapes;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Atmos.Components
|
||||
{
|
||||
@@ -77,5 +79,8 @@ namespace Content.Server.Atmos.Components
|
||||
/// </summary>
|
||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||
public float FirestackFade = -0.1f;
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> FireAlert = "Fire";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
_adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} started taking low pressure damage");
|
||||
}
|
||||
|
||||
_alertsSystem.ShowAlert(uid, AlertType.LowPressure, 2);
|
||||
_alertsSystem.ShowAlert(uid, barotrauma.LowPressureAlert, 2);
|
||||
}
|
||||
else if (pressure >= Atmospherics.HazardHighPressure)
|
||||
{
|
||||
@@ -260,7 +260,7 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
_adminLogger.Add(LogType.Barotrauma, $"{ToPrettyString(uid):entity} started taking high pressure damage");
|
||||
}
|
||||
|
||||
_alertsSystem.ShowAlert(uid, AlertType.HighPressure, 2);
|
||||
_alertsSystem.ShowAlert(uid, barotrauma.HighPressureAlert, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -275,13 +275,13 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
switch (pressure)
|
||||
{
|
||||
case <= Atmospherics.WarningLowPressure:
|
||||
_alertsSystem.ShowAlert(uid, AlertType.LowPressure, 1);
|
||||
_alertsSystem.ShowAlert(uid, barotrauma.LowPressureAlert, 1);
|
||||
break;
|
||||
case >= Atmospherics.WarningHighPressure:
|
||||
_alertsSystem.ShowAlert(uid, AlertType.HighPressure, 1);
|
||||
_alertsSystem.ShowAlert(uid, barotrauma.HighPressureAlert, 1);
|
||||
break;
|
||||
default:
|
||||
_alertsSystem.ClearAlertCategory(uid, AlertCategory.Pressure);
|
||||
_alertsSystem.ClearAlertCategory(uid, barotrauma.PressureAlertCategory);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,11 +415,11 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|
||||
if (!flammable.OnFire)
|
||||
{
|
||||
_alertsSystem.ClearAlert(uid, AlertType.Fire);
|
||||
_alertsSystem.ClearAlert(uid, flammable.FireAlert);
|
||||
continue;
|
||||
}
|
||||
|
||||
_alertsSystem.ShowAlert(uid, AlertType.Fire);
|
||||
_alertsSystem.ShowAlert(uid, flammable.FireAlert);
|
||||
|
||||
if (flammable.FireStacks > 0)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Content.Server.Body.Systems;
|
||||
using Content.Server.Chemistry.EntitySystems;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Content.Shared.Chemistry.Reagent;
|
||||
using Content.Shared.Damage;
|
||||
@@ -171,5 +172,8 @@ namespace Content.Server.Body.Components
|
||||
/// </summary>
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public TimeSpan StatusTime;
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> BleedingAlert = "Bleed";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
using Content.Shared.Alert;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Body.Components
|
||||
{
|
||||
/// <summary>
|
||||
@@ -18,5 +21,8 @@ namespace Content.Server.Body.Components
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField]
|
||||
public TimeSpan Delay = TimeSpan.FromSeconds(3);
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> InternalsAlert = "Internals";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using Content.Server.Atmos;
|
||||
using Content.Server.Body.Systems;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Chemistry.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Body.Components;
|
||||
|
||||
@@ -33,5 +33,5 @@ public sealed partial class LungComponent : Component
|
||||
/// The type of gas this lung needs. Used only for the breathing alerts, not actual metabolism.
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public AlertType Alert = AlertType.LowOxygen;
|
||||
public ProtoId<AlertPrototype> Alert = "LowOxygen";
|
||||
}
|
||||
|
||||
@@ -392,11 +392,11 @@ public sealed class BloodstreamSystem : EntitySystem
|
||||
component.BleedAmount = Math.Clamp(component.BleedAmount, 0, component.MaxBleedAmount);
|
||||
|
||||
if (component.BleedAmount == 0)
|
||||
_alertsSystem.ClearAlert(uid, AlertType.Bleed);
|
||||
_alertsSystem.ClearAlert(uid, component.BleedingAlert);
|
||||
else
|
||||
{
|
||||
var severity = (short) Math.Clamp(Math.Round(component.BleedAmount, MidpointRounding.ToZero), 0, 10);
|
||||
_alertsSystem.ShowAlert(uid, AlertType.Bleed, severity);
|
||||
_alertsSystem.ShowAlert(uid, component.BleedingAlert, severity);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -144,12 +144,12 @@ public sealed class InternalsSystem : EntitySystem
|
||||
|
||||
private void OnInternalsStartup(Entity<InternalsComponent> ent, ref ComponentStartup args)
|
||||
{
|
||||
_alerts.ShowAlert(ent, AlertType.Internals, GetSeverity(ent));
|
||||
_alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent));
|
||||
}
|
||||
|
||||
private void OnInternalsShutdown(Entity<InternalsComponent> ent, ref ComponentShutdown args)
|
||||
{
|
||||
_alerts.ClearAlert(ent, AlertType.Internals);
|
||||
_alerts.ClearAlert(ent, ent.Comp.InternalsAlert);
|
||||
}
|
||||
|
||||
private void OnInhaleLocation(Entity<InternalsComponent> ent, ref InhaleLocationEvent args)
|
||||
@@ -159,7 +159,7 @@ public sealed class InternalsSystem : EntitySystem
|
||||
var gasTank = Comp<GasTankComponent>(ent.Comp.GasTankEntity!.Value);
|
||||
args.Gas = _gasTank.RemoveAirVolume((ent.Comp.GasTankEntity.Value, gasTank), Atmospherics.BreathVolume);
|
||||
// TODO: Should listen to gas tank updates instead I guess?
|
||||
_alerts.ShowAlert(ent, AlertType.Internals, GetSeverity(ent));
|
||||
_alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent));
|
||||
}
|
||||
}
|
||||
public void DisconnectBreathTool(Entity<InternalsComponent> ent)
|
||||
@@ -173,7 +173,7 @@ public sealed class InternalsSystem : EntitySystem
|
||||
DisconnectTank(ent);
|
||||
}
|
||||
|
||||
_alerts.ShowAlert(ent, AlertType.Internals, GetSeverity(ent));
|
||||
_alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent));
|
||||
}
|
||||
|
||||
public void ConnectBreathTool(Entity<InternalsComponent> ent, EntityUid toolEntity)
|
||||
@@ -184,7 +184,7 @@ public sealed class InternalsSystem : EntitySystem
|
||||
}
|
||||
|
||||
ent.Comp.BreathToolEntity = toolEntity;
|
||||
_alerts.ShowAlert(ent, AlertType.Internals, GetSeverity(ent));
|
||||
_alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent));
|
||||
}
|
||||
|
||||
public void DisconnectTank(InternalsComponent? component)
|
||||
@@ -196,7 +196,7 @@ public sealed class InternalsSystem : EntitySystem
|
||||
_gasTank.DisconnectFromInternals((component.GasTankEntity.Value, tank));
|
||||
|
||||
component.GasTankEntity = null;
|
||||
_alerts.ShowAlert(component.Owner, AlertType.Internals, GetSeverity(component));
|
||||
_alerts.ShowAlert(component.Owner, component.InternalsAlert, GetSeverity(component));
|
||||
}
|
||||
|
||||
public bool TryConnectTank(Entity<InternalsComponent> ent, EntityUid tankEntity)
|
||||
@@ -208,7 +208,7 @@ public sealed class InternalsSystem : EntitySystem
|
||||
_gasTank.DisconnectFromInternals((ent.Comp.GasTankEntity.Value, tank));
|
||||
|
||||
ent.Comp.GasTankEntity = tankEntity;
|
||||
_alerts.ShowAlert(ent, AlertType.Internals, GetSeverity(ent));
|
||||
_alerts.ShowAlert(ent, ent.Comp.InternalsAlert, GetSeverity(ent));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ public sealed partial class AdjustAlert : ReagentEffect
|
||||
/// <summary>
|
||||
/// The specific Alert that will be adjusted
|
||||
/// </summary>
|
||||
[DataField("alertType", required: true)]
|
||||
public AlertType Type;
|
||||
[DataField(required: true)]
|
||||
public ProtoId<AlertPrototype> AlertType;
|
||||
|
||||
/// <summary>
|
||||
/// If true, the alert is removed after Time seconds. If Time was not specified the alert is removed immediately.
|
||||
@@ -42,7 +42,7 @@ public sealed partial class AdjustAlert : ReagentEffect
|
||||
|
||||
if (Clear && Time <= 0)
|
||||
{
|
||||
alertSys.ClearAlert(args.SolutionEntity, Type);
|
||||
alertSys.ClearAlert(args.SolutionEntity, AlertType);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -52,7 +52,7 @@ public sealed partial class AdjustAlert : ReagentEffect
|
||||
if ((ShowCooldown || Clear) && Time > 0)
|
||||
cooldown = (timing.CurTime, timing.CurTime + TimeSpan.FromSeconds(Time));
|
||||
|
||||
alertSys.ShowAlert(args.SolutionEntity, Type, cooldown: cooldown, autoRemove: Clear, showCooldown: ShowCooldown);
|
||||
alertSys.ShowAlert(args.SolutionEntity, AlertType, cooldown: cooldown, autoRemove: Clear, showCooldown: ShowCooldown);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,11 +29,11 @@ public sealed class MagbootsSystem : SharedMagbootsSystem
|
||||
|
||||
if (state)
|
||||
{
|
||||
_alerts.ShowAlert(parent, AlertType.Magboots);
|
||||
_alerts.ShowAlert(parent, component.MagbootsAlert);
|
||||
}
|
||||
else
|
||||
{
|
||||
_alerts.ClearAlert(parent, AlertType.Magboots);
|
||||
_alerts.ClearAlert(parent, component.MagbootsAlert);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -163,8 +163,8 @@ public sealed partial class EnsnareableSystem
|
||||
public void UpdateAlert(EntityUid target, EnsnareableComponent component)
|
||||
{
|
||||
if (!component.IsEnsnared)
|
||||
_alerts.ClearAlert(target, AlertType.Ensnared);
|
||||
_alerts.ClearAlert(target, component.EnsnaredAlert);
|
||||
else
|
||||
_alerts.ShowAlert(target, AlertType.Ensnared);
|
||||
_alerts.ShowAlert(target, component.EnsnaredAlert);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,20 +102,23 @@ public sealed class SpaceNinjaSystem : SharedSpaceNinjaSystem
|
||||
/// </summary>
|
||||
public void SetSuitPowerAlert(EntityUid uid, SpaceNinjaComponent? comp = null)
|
||||
{
|
||||
if (!Resolve(uid, ref comp, false) || comp.Deleted || comp.Suit == null)
|
||||
if (!Resolve(uid, ref comp, false))
|
||||
return;
|
||||
|
||||
if (comp.Deleted || comp.Suit == null)
|
||||
{
|
||||
_alerts.ClearAlert(uid, AlertType.SuitPower);
|
||||
_alerts.ClearAlert(uid, comp.SuitPowerAlert);
|
||||
return;
|
||||
}
|
||||
|
||||
if (GetNinjaBattery(uid, out _, out var battery))
|
||||
{
|
||||
var severity = ContentHelpers.RoundToLevels(MathF.Max(0f, battery.CurrentCharge), battery.MaxCharge, 8);
|
||||
_alerts.ShowAlert(uid, AlertType.SuitPower, (short) severity);
|
||||
_alerts.ShowAlert(uid, comp.SuitPowerAlert, (short) severity);
|
||||
}
|
||||
else
|
||||
{
|
||||
_alerts.ClearAlert(uid, AlertType.SuitPower);
|
||||
_alerts.ClearAlert(uid, comp.SuitPowerAlert);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ public sealed partial class RevenantSystem : EntitySystem
|
||||
if (TryComp<StoreComponent>(uid, out var store))
|
||||
_store.UpdateUserInterface(uid, uid, store);
|
||||
|
||||
_alerts.ShowAlert(uid, AlertType.Essence);
|
||||
_alerts.ShowAlert(uid, component.EssenceAlert);
|
||||
|
||||
if (component.Essence <= 0)
|
||||
{
|
||||
|
||||
@@ -317,7 +317,7 @@ public sealed partial class ShuttleConsoleSystem : SharedShuttleConsoleSystem
|
||||
|
||||
component.SubscribedPilots.Add(entity);
|
||||
|
||||
_alertsSystem.ShowAlert(entity, AlertType.PilotingShuttle);
|
||||
_alertsSystem.ShowAlert(entity, pilotComponent.PilotingAlert);
|
||||
|
||||
pilotComponent.Console = uid;
|
||||
ActionBlockerSystem.UpdateCanMove(entity);
|
||||
@@ -339,7 +339,7 @@ public sealed partial class ShuttleConsoleSystem : SharedShuttleConsoleSystem
|
||||
if (!helm.SubscribedPilots.Remove(pilotUid))
|
||||
return;
|
||||
|
||||
_alertsSystem.ClearAlert(pilotUid, AlertType.PilotingShuttle);
|
||||
_alertsSystem.ClearAlert(pilotUid, pilotComponent.PilotingAlert);
|
||||
|
||||
_popup.PopupEntity(Loc.GetString("shuttle-pilot-end"), pilotUid, pilotUid);
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ public sealed partial class BorgSystem : SharedBorgSystem
|
||||
|
||||
private void OnMapInit(EntityUid uid, BorgChassisComponent component, MapInitEvent args)
|
||||
{
|
||||
UpdateBatteryAlert(uid);
|
||||
UpdateBatteryAlert((uid, component));
|
||||
_movementSpeedModifier.RefreshMovementSpeedModifiers(uid);
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ public sealed partial class BorgSystem : SharedBorgSystem
|
||||
|
||||
private void OnPowerCellChanged(EntityUid uid, BorgChassisComponent component, PowerCellChangedEvent args)
|
||||
{
|
||||
UpdateBatteryAlert(uid);
|
||||
UpdateBatteryAlert((uid, component));
|
||||
|
||||
if (!TryComp<PowerCellDrawComponent>(uid, out var draw))
|
||||
return;
|
||||
@@ -256,12 +256,12 @@ public sealed partial class BorgSystem : SharedBorgSystem
|
||||
args.Cancel();
|
||||
}
|
||||
|
||||
private void UpdateBatteryAlert(EntityUid uid, PowerCellSlotComponent? slotComponent = null)
|
||||
private void UpdateBatteryAlert(Entity<BorgChassisComponent> ent, PowerCellSlotComponent? slotComponent = null)
|
||||
{
|
||||
if (!_powerCell.TryGetBatteryFromSlot(uid, out var battery, slotComponent))
|
||||
if (!_powerCell.TryGetBatteryFromSlot(ent, out var battery, slotComponent))
|
||||
{
|
||||
_alerts.ClearAlert(uid, AlertType.BorgBattery);
|
||||
_alerts.ShowAlert(uid, AlertType.BorgBatteryNone);
|
||||
_alerts.ClearAlert(ent, ent.Comp.BatteryAlert);
|
||||
_alerts.ShowAlert(ent, ent.Comp.NoBatteryAlert);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -269,13 +269,13 @@ public sealed partial class BorgSystem : SharedBorgSystem
|
||||
|
||||
// we make sure 0 only shows if they have absolutely no battery.
|
||||
// also account for floating point imprecision
|
||||
if (chargePercent == 0 && _powerCell.HasDrawCharge(uid, cell: slotComponent))
|
||||
if (chargePercent == 0 && _powerCell.HasDrawCharge(ent, cell: slotComponent))
|
||||
{
|
||||
chargePercent = 1;
|
||||
}
|
||||
|
||||
_alerts.ClearAlert(uid, AlertType.BorgBatteryNone);
|
||||
_alerts.ShowAlert(uid, AlertType.BorgBattery, chargePercent);
|
||||
_alerts.ClearAlert(ent, ent.Comp.NoBatteryAlert);
|
||||
_alerts.ShowAlert(ent, ent.Comp.BatteryAlert, chargePercent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using Content.Server.Temperature.Systems;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Atmos;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Temperature.Components;
|
||||
|
||||
@@ -78,4 +80,10 @@ public sealed partial class TemperatureComponent : Component
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool TakingDamage = false;
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> HotAlert = "Hot";
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> ColdAlert = "Cold";
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ using Content.Shared.Inventory;
|
||||
using Content.Shared.Rejuvenate;
|
||||
using Content.Shared.Temperature;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Server.Temperature.Systems;
|
||||
|
||||
@@ -33,6 +34,9 @@ public sealed class TemperatureSystem : EntitySystem
|
||||
|
||||
private float _accumulatedFrametime;
|
||||
|
||||
[ValidatePrototypeId<AlertCategoryPrototype>]
|
||||
public const string TemperatureAlertCategory = "Temperature";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<TemperatureComponent, OnTemperatureChangeEvent>(EnqueueDamage);
|
||||
@@ -180,13 +184,13 @@ public sealed class TemperatureSystem : EntitySystem
|
||||
|
||||
private void ServerAlert(EntityUid uid, AlertsComponent status, OnTemperatureChangeEvent args)
|
||||
{
|
||||
AlertType type;
|
||||
ProtoId<AlertPrototype> type;
|
||||
float threshold;
|
||||
float idealTemp;
|
||||
|
||||
if (!TryComp<TemperatureComponent>(uid, out var temperature))
|
||||
{
|
||||
_alerts.ClearAlertCategory(uid, AlertCategory.Temperature);
|
||||
_alerts.ClearAlertCategory(uid, TemperatureAlertCategory);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -203,12 +207,12 @@ public sealed class TemperatureSystem : EntitySystem
|
||||
|
||||
if (args.CurrentTemperature <= idealTemp)
|
||||
{
|
||||
type = AlertType.Cold;
|
||||
type = temperature.ColdAlert;
|
||||
threshold = temperature.ColdDamageThreshold;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = AlertType.Hot;
|
||||
type = temperature.HotAlert;
|
||||
threshold = temperature.HeatDamageThreshold;
|
||||
}
|
||||
|
||||
@@ -230,7 +234,7 @@ public sealed class TemperatureSystem : EntitySystem
|
||||
break;
|
||||
|
||||
case > 0.66f:
|
||||
_alerts.ClearAlertCategory(uid, AlertCategory.Temperature);
|
||||
_alerts.ClearAlertCategory(uid, TemperatureAlertCategory);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
namespace Content.Shared.Alert;
|
||||
|
||||
/// <summary>
|
||||
/// Every category of alert. Corresponds to category field in alert prototypes defined in YML
|
||||
/// </summary>
|
||||
public enum AlertCategory
|
||||
{
|
||||
Pressure,
|
||||
Temperature,
|
||||
Breathing,
|
||||
Buckled,
|
||||
Health,
|
||||
Internals,
|
||||
Stamina,
|
||||
Piloting,
|
||||
Hunger,
|
||||
Thirst,
|
||||
Toxins,
|
||||
Battery
|
||||
}
|
||||
14
Content.Shared/Alert/AlertCategoryPrototype.cs
Normal file
14
Content.Shared/Alert/AlertCategoryPrototype.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Alert;
|
||||
|
||||
/// <summary>
|
||||
/// This is a prototype for a category for marking alerts as mutually exclusive.
|
||||
/// </summary>
|
||||
[Prototype]
|
||||
public sealed partial class AlertCategoryPrototype : IPrototype
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
[IdDataField]
|
||||
public string ID { get; } = default!;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.Manager;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Alert;
|
||||
|
||||
@@ -11,13 +11,13 @@ namespace Content.Shared.Alert;
|
||||
[Serializable, NetSerializable]
|
||||
public struct AlertKey
|
||||
{
|
||||
public AlertType? AlertType { get; private set; } = Alert.AlertType.Error;
|
||||
public readonly AlertCategory? AlertCategory;
|
||||
public ProtoId<AlertPrototype>? AlertType { get; private set; } = default!;
|
||||
public readonly ProtoId<AlertCategoryPrototype>? AlertCategory;
|
||||
|
||||
/// NOTE: if the alert has a category you must pass the category for this to work
|
||||
/// properly as a key. I.e. if the alert has a category and you pass only the alert type, and you
|
||||
/// compare this to another AlertKey that has both the category and the same alert type, it will not consider them equal.
|
||||
public AlertKey(AlertType? alertType, AlertCategory? alertCategory)
|
||||
public AlertKey(ProtoId<AlertPrototype>? alertType, ProtoId<AlertCategoryPrototype>? alertCategory)
|
||||
{
|
||||
AlertCategory = alertCategory;
|
||||
AlertType = alertType;
|
||||
@@ -49,7 +49,7 @@ public struct AlertKey
|
||||
/// <param name="category">alert category, must not be null</param>
|
||||
/// <returns>An alert key for the provided alert category. This must only be used for
|
||||
/// queries and never storage, as it is lacking an alert type.</returns>
|
||||
public static AlertKey ForCategory(AlertCategory category)
|
||||
public static AlertKey ForCategory(ProtoId<AlertCategoryPrototype> category)
|
||||
{
|
||||
return new(null, category);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Content.Shared.Alert
|
||||
/// <summary>
|
||||
/// Defines the order of alerts so they show up in a consistent order.
|
||||
/// </summary>
|
||||
[Prototype("alertOrder")]
|
||||
[Prototype]
|
||||
[DataDefinition]
|
||||
public sealed partial class AlertOrderPrototype : IPrototype, IComparer<AlertPrototype>
|
||||
{
|
||||
@@ -15,7 +15,7 @@ namespace Content.Shared.Alert
|
||||
[IdDataField]
|
||||
public string ID { get; private set; } = default!;
|
||||
|
||||
[DataField("order")]
|
||||
[DataField]
|
||||
private (string type, string alert)[] Order
|
||||
{
|
||||
// why would paul do this to me.
|
||||
@@ -46,10 +46,10 @@ namespace Content.Shared.Alert
|
||||
switch (type)
|
||||
{
|
||||
case "alertType":
|
||||
_typeToIdx[Enum.Parse<AlertType>(alert)] = i++;
|
||||
_typeToIdx[alert] = i++;
|
||||
break;
|
||||
case "category":
|
||||
_categoryToIdx[Enum.Parse<AlertCategory>(alert)] = i++;
|
||||
_categoryToIdx[alert] = i++;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException();
|
||||
@@ -58,17 +58,17 @@ namespace Content.Shared.Alert
|
||||
}
|
||||
}
|
||||
|
||||
private readonly Dictionary<AlertType, int> _typeToIdx = new();
|
||||
private readonly Dictionary<AlertCategory, int> _categoryToIdx = new();
|
||||
private readonly Dictionary<ProtoId<AlertPrototype>, int> _typeToIdx = new();
|
||||
private readonly Dictionary<ProtoId<AlertCategoryPrototype>, int> _categoryToIdx = new();
|
||||
|
||||
private int GetOrderIndex(AlertPrototype alert)
|
||||
{
|
||||
if (_typeToIdx.TryGetValue(alert.AlertType, out var idx))
|
||||
if (_typeToIdx.TryGetValue(alert.ID, out var idx))
|
||||
{
|
||||
return idx;
|
||||
}
|
||||
if (alert.Category != null &&
|
||||
_categoryToIdx.TryGetValue((AlertCategory) alert.Category, out idx))
|
||||
_categoryToIdx.TryGetValue(alert.Category.Value, out idx))
|
||||
{
|
||||
return idx;
|
||||
}
|
||||
@@ -78,20 +78,25 @@ namespace Content.Shared.Alert
|
||||
|
||||
public int Compare(AlertPrototype? x, AlertPrototype? y)
|
||||
{
|
||||
if ((x == null) && (y == null)) return 0;
|
||||
if (x == null) return 1;
|
||||
if (y == null) return -1;
|
||||
if (x == null && y == null)
|
||||
return 0;
|
||||
if (x == null)
|
||||
return 1;
|
||||
if (y == null)
|
||||
return -1;
|
||||
var idx = GetOrderIndex(x);
|
||||
var idy = GetOrderIndex(y);
|
||||
if (idx == -1 && idy == -1)
|
||||
{
|
||||
// break ties by type value
|
||||
// Must cast to int to avoid integer overflow when subtracting (enum's unsigned)
|
||||
return (int)x.AlertType - (int)y.AlertType;
|
||||
return string.Compare(x.ID, y.ID, StringComparison.InvariantCulture);
|
||||
}
|
||||
|
||||
if (idx == -1) return 1;
|
||||
if (idy == -1) return -1;
|
||||
if (idx == -1)
|
||||
return 1;
|
||||
if (idy == -1)
|
||||
return -1;
|
||||
var result = idx - idy;
|
||||
// not strictly necessary (we don't care about ones that go at the same index)
|
||||
// but it makes the sort stable
|
||||
@@ -99,7 +104,7 @@ namespace Content.Shared.Alert
|
||||
{
|
||||
// break ties by type value
|
||||
// Must cast to int to avoid integer overflow when subtracting (enum's unsigned)
|
||||
return (int)x.AlertType - (int)y.AlertType;
|
||||
return string.Compare(x.ID, y.ID, StringComparison.InvariantCulture);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,28 +1,25 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
namespace Content.Shared.Alert
|
||||
{
|
||||
/// <summary>
|
||||
/// An alert popup with associated icon, tooltip, and other data.
|
||||
/// </summary>
|
||||
[Prototype("alert")]
|
||||
public sealed partial class AlertPrototype : IPrototype
|
||||
{
|
||||
[ViewVariables]
|
||||
string IPrototype.ID => AlertType.ToString();
|
||||
namespace Content.Shared.Alert;
|
||||
|
||||
/// <summary>
|
||||
/// An alert popup with associated icon, tooltip, and other data.
|
||||
/// </summary>
|
||||
[Prototype]
|
||||
public sealed partial class AlertPrototype : IPrototype
|
||||
{
|
||||
/// <summary>
|
||||
/// Type of alert, no 2 alert prototypes should have the same one.
|
||||
/// </summary>
|
||||
[IdDataField]
|
||||
public AlertType AlertType { get; private set; }
|
||||
public string ID { get; private set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// List of icons to use for this alert. Each entry corresponds to a different severity level, starting from the
|
||||
/// minimum and incrementing upwards. If severities are not supported, the first entry is used.
|
||||
/// </summary>
|
||||
[DataField("icons", required: true)]
|
||||
[DataField(required: true)]
|
||||
public List<SpriteSpecifier> Icons = new();
|
||||
|
||||
/// <summary>
|
||||
@@ -34,14 +31,14 @@ namespace Content.Shared.Alert
|
||||
/// <summary>
|
||||
/// Name to show in tooltip window. Accepts formatting.
|
||||
/// </summary>
|
||||
[DataField("name")]
|
||||
public string Name { get; private set; } = "";
|
||||
[DataField]
|
||||
public string Name { get; private set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Description to show in tooltip window. Accepts formatting.
|
||||
/// </summary>
|
||||
[DataField("description")]
|
||||
public string Description { get; private set; } = "";
|
||||
[DataField]
|
||||
public string Description { get; private set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Category the alert belongs to. Only one alert of a given category
|
||||
@@ -50,14 +47,14 @@ namespace Content.Shared.Alert
|
||||
/// replace each other and are mutually exclusive, for example lowpressure / highpressure,
|
||||
/// hot / cold. If left unspecified, the alert will not replace or be replaced by any other alerts.
|
||||
/// </summary>
|
||||
[DataField("category")]
|
||||
public AlertCategory? Category { get; private set; }
|
||||
[DataField]
|
||||
public ProtoId<AlertCategoryPrototype>? Category { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Key which is unique w.r.t category semantics (alerts with same category have equal keys,
|
||||
/// alerts with no category have different keys).
|
||||
/// </summary>
|
||||
public AlertKey AlertKey => new(AlertType, Category);
|
||||
public AlertKey AlertKey => new(ID, Category);
|
||||
|
||||
/// <summary>
|
||||
/// -1 (no effect) unless MaxSeverity is specified. Defaults to 1. Minimum severity level supported by this state.
|
||||
@@ -70,7 +67,7 @@ namespace Content.Shared.Alert
|
||||
/// Maximum severity level supported by this state. -1 (default) indicates
|
||||
/// no severity levels are supported by the state.
|
||||
/// </summary>
|
||||
[DataField("maxSeverity")]
|
||||
[DataField]
|
||||
public short MaxSeverity = -1;
|
||||
|
||||
/// <summary>
|
||||
@@ -82,7 +79,7 @@ namespace Content.Shared.Alert
|
||||
/// Defines what to do when the alert is clicked.
|
||||
/// This will always be null on clientside.
|
||||
/// </summary>
|
||||
[DataField("onClick", serverOnly: true)]
|
||||
[DataField(serverOnly: true)]
|
||||
public IAlertClick? OnClick { get; private set; }
|
||||
|
||||
/// <param name="severity">severity level, if supported by this alert</param>
|
||||
@@ -94,7 +91,7 @@ namespace Content.Shared.Alert
|
||||
: 1;
|
||||
|
||||
if (Icons.Count < minIcons)
|
||||
throw new InvalidOperationException($"Insufficient number of icons given for alert {AlertType}");
|
||||
throw new InvalidOperationException($"Insufficient number of icons given for alert {ID}");
|
||||
|
||||
if (!SupportsSeverity)
|
||||
return Icons[0];
|
||||
@@ -116,5 +113,4 @@ namespace Content.Shared.Alert
|
||||
|
||||
return Icons[severity.Value - _minSeverity];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Alert;
|
||||
@@ -9,5 +10,5 @@ public struct AlertState
|
||||
public (TimeSpan, TimeSpan)? Cooldown;
|
||||
public bool AutoRemove;
|
||||
public bool ShowCooldown;
|
||||
public AlertType Type;
|
||||
public ProtoId<AlertPrototype> Type;
|
||||
}
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
namespace Content.Shared.Alert
|
||||
{
|
||||
/// <summary>
|
||||
/// Every kind of alert. Corresponds to alertType field in alert prototypes defined in YML
|
||||
/// NOTE: Using byte for a compact encoding when sending this in messages, can upgrade
|
||||
/// to ushort
|
||||
/// </summary>
|
||||
public enum AlertType : byte
|
||||
{
|
||||
Error,
|
||||
LowOxygen,
|
||||
LowNitrogen,
|
||||
LowPressure,
|
||||
HighPressure,
|
||||
Fire,
|
||||
Cold,
|
||||
Hot,
|
||||
Weightless,
|
||||
Stun,
|
||||
Handcuffed,
|
||||
Ensnared,
|
||||
Buckled,
|
||||
HumanCrit,
|
||||
HumanDead,
|
||||
HumanHealth,
|
||||
BorgBattery,
|
||||
BorgBatteryNone,
|
||||
PilotingShuttle,
|
||||
Peckish,
|
||||
Starving,
|
||||
Thirsty,
|
||||
Parched,
|
||||
Stamina,
|
||||
Pulled,
|
||||
Pulling,
|
||||
Magboots,
|
||||
Internals,
|
||||
Toxins,
|
||||
Muted,
|
||||
VowOfSilence,
|
||||
VowBroken,
|
||||
Essence,
|
||||
Corporeal,
|
||||
Bleed,
|
||||
Pacified,
|
||||
Debug1,
|
||||
Debug2,
|
||||
Debug3,
|
||||
Debug4,
|
||||
Debug5,
|
||||
Debug6,
|
||||
SuitPower,
|
||||
BorgHealth,
|
||||
BorgCrit,
|
||||
BorgDead,
|
||||
Deflecting
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,7 +11,7 @@ public abstract class AlertsSystem : EntitySystem
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
|
||||
private FrozenDictionary<AlertType, AlertPrototype> _typeToAlert = default!;
|
||||
private FrozenDictionary<ProtoId<AlertPrototype>, AlertPrototype> _typeToAlert = default!;
|
||||
|
||||
public IReadOnlyDictionary<AlertKey, AlertState>? GetActiveAlerts(EntityUid euid)
|
||||
{
|
||||
@@ -20,23 +20,23 @@ public abstract class AlertsSystem : EntitySystem
|
||||
: null;
|
||||
}
|
||||
|
||||
public short GetSeverityRange(AlertType alertType)
|
||||
public short GetSeverityRange(ProtoId<AlertPrototype> alertType)
|
||||
{
|
||||
var minSeverity = _typeToAlert[alertType].MinSeverity;
|
||||
return (short)MathF.Max(minSeverity,_typeToAlert[alertType].MaxSeverity - minSeverity);
|
||||
}
|
||||
|
||||
public short GetMaxSeverity(AlertType alertType)
|
||||
public short GetMaxSeverity(ProtoId<AlertPrototype> alertType)
|
||||
{
|
||||
return _typeToAlert[alertType].MaxSeverity;
|
||||
}
|
||||
|
||||
public short GetMinSeverity(AlertType alertType)
|
||||
public short GetMinSeverity(ProtoId<AlertPrototype> alertType)
|
||||
{
|
||||
return _typeToAlert[alertType].MinSeverity;
|
||||
}
|
||||
|
||||
public bool IsShowingAlert(EntityUid euid, AlertType alertType)
|
||||
public bool IsShowingAlert(EntityUid euid, ProtoId<AlertPrototype> alertType)
|
||||
{
|
||||
if (!EntityManager.TryGetComponent(euid, out AlertsComponent? alertsComponent))
|
||||
return false;
|
||||
@@ -51,7 +51,7 @@ public abstract class AlertsSystem : EntitySystem
|
||||
}
|
||||
|
||||
/// <returns>true iff an alert of the indicated alert category is currently showing</returns>
|
||||
public bool IsShowingAlertCategory(EntityUid euid, AlertCategory alertCategory)
|
||||
public bool IsShowingAlertCategory(EntityUid euid, ProtoId<AlertCategoryPrototype> alertCategory)
|
||||
{
|
||||
return EntityManager.TryGetComponent(euid, out AlertsComponent? alertsComponent)
|
||||
&& alertsComponent.Alerts.ContainsKey(AlertKey.ForCategory(alertCategory));
|
||||
@@ -78,7 +78,7 @@ public abstract class AlertsSystem : EntitySystem
|
||||
/// 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="showCooldown">if true, the cooldown will be visibly shown over the alert icon</param>
|
||||
public void ShowAlert(EntityUid euid, AlertType alertType, short? severity = null, (TimeSpan, TimeSpan)? cooldown = null, bool autoRemove = false, bool showCooldown = true )
|
||||
public void ShowAlert(EntityUid euid, ProtoId<AlertPrototype> alertType, short? severity = null, (TimeSpan, TimeSpan)? cooldown = null, bool autoRemove = false, bool showCooldown = true )
|
||||
{
|
||||
// This should be handled as part of networking.
|
||||
if (_timing.ApplyingState)
|
||||
@@ -131,7 +131,7 @@ public abstract class AlertsSystem : EntitySystem
|
||||
/// <summary>
|
||||
/// Clear the alert with the given category, if one is currently showing.
|
||||
/// </summary>
|
||||
public void ClearAlertCategory(EntityUid euid, AlertCategory category)
|
||||
public void ClearAlertCategory(EntityUid euid, ProtoId<AlertCategoryPrototype> category)
|
||||
{
|
||||
if(!TryComp(euid, out AlertsComponent? alertsComponent))
|
||||
return;
|
||||
@@ -150,7 +150,7 @@ public abstract class AlertsSystem : EntitySystem
|
||||
/// <summary>
|
||||
/// Clear the alert of the given type if it is currently showing.
|
||||
/// </summary>
|
||||
public void ClearAlert(EntityUid euid, AlertType alertType)
|
||||
public void ClearAlert(EntityUid euid, ProtoId<AlertPrototype> alertType)
|
||||
{
|
||||
if (_timing.ApplyingState)
|
||||
return;
|
||||
@@ -286,13 +286,13 @@ public abstract class AlertsSystem : EntitySystem
|
||||
|
||||
protected virtual void LoadPrototypes()
|
||||
{
|
||||
var dict = new Dictionary<AlertType, AlertPrototype>();
|
||||
var dict = new Dictionary<ProtoId<AlertPrototype>, AlertPrototype>();
|
||||
foreach (var alert in _prototypeManager.EnumeratePrototypes<AlertPrototype>())
|
||||
{
|
||||
if (!dict.TryAdd(alert.AlertType, alert))
|
||||
if (!dict.TryAdd(alert.ID, alert))
|
||||
{
|
||||
Log.Error("Found alert with duplicate alertType {0} - all alerts must have" +
|
||||
" a unique alertType, this one will be skipped", alert.AlertType);
|
||||
" a unique alertType, this one will be skipped", alert.ID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,7 +303,7 @@ public abstract class AlertsSystem : EntitySystem
|
||||
/// Tries to get the alert of the indicated type
|
||||
/// </summary>
|
||||
/// <returns>true if found</returns>
|
||||
public bool TryGet(AlertType alertType, [NotNullWhen(true)] out AlertPrototype? alert)
|
||||
public bool TryGet(ProtoId<AlertPrototype> alertType, [NotNullWhen(true)] out AlertPrototype? alert)
|
||||
{
|
||||
return _typeToAlert.TryGetValue(alertType, out alert);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Alert;
|
||||
|
||||
@@ -8,9 +9,9 @@ namespace Content.Shared.Alert;
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class ClickAlertEvent : EntityEventArgs
|
||||
{
|
||||
public readonly AlertType Type;
|
||||
public readonly ProtoId<AlertPrototype> Type;
|
||||
|
||||
public ClickAlertEvent(AlertType alertType)
|
||||
public ClickAlertEvent(ProtoId<AlertPrototype> alertType)
|
||||
{
|
||||
Type = alertType;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Content.Shared.Alert;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Audio;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Buckle.Components;
|
||||
@@ -115,7 +116,7 @@ public sealed partial class StrapComponent : Component
|
||||
/// </summary>
|
||||
[DataField]
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public AlertType BuckledAlertType = AlertType.Buckled;
|
||||
public ProtoId<AlertPrototype> BuckledAlertType = "Buckled";
|
||||
|
||||
/// <summary>
|
||||
/// The sum of the sizes of all the buckled entities in this strap
|
||||
|
||||
@@ -40,6 +40,9 @@ public abstract partial class SharedBuckleSystem
|
||||
SubscribeLocalEvent<BuckleComponent, UpdateCanMoveEvent>(OnBuckleUpdateCanMove);
|
||||
}
|
||||
|
||||
[ValidatePrototypeId<AlertCategoryPrototype>]
|
||||
public const string BuckledAlertCategory = "Buckled";
|
||||
|
||||
private void OnBuckleComponentStartup(EntityUid uid, BuckleComponent component, ComponentStartup args)
|
||||
{
|
||||
UpdateBuckleStatus(uid, component);
|
||||
@@ -165,7 +168,7 @@ public abstract partial class SharedBuckleSystem
|
||||
}
|
||||
else
|
||||
{
|
||||
_alerts.ClearAlertCategory(uid, AlertCategory.Buckled);
|
||||
_alerts.ClearAlertCategory(uid, BuckledAlertCategory);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Content.Shared.Alert;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
|
||||
@@ -16,4 +17,7 @@ public sealed partial class MagbootsComponent : Component
|
||||
|
||||
[DataField("on"), AutoNetworkedField]
|
||||
public bool On;
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> MagbootsAlert = "Magboots";
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ using Content.Shared.Interaction.Events;
|
||||
using Content.Shared.Popups;
|
||||
using Content.Shared.Throwing;
|
||||
using Content.Shared.Weapons.Ranged.Events;
|
||||
using Content.Shared.Weapons.Ranged.Systems;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Shared.CombatMode.Pacification;
|
||||
@@ -109,7 +108,7 @@ public sealed class PacificationSystem : EntitySystem
|
||||
_actionsSystem.SetEnabled(combatMode.CombatToggleActionEntity, false);
|
||||
}
|
||||
|
||||
_alertsSystem.ShowAlert(uid, AlertType.Pacified);
|
||||
_alertsSystem.ShowAlert(uid, component.PacifiedAlert);
|
||||
}
|
||||
|
||||
private void OnShutdown(EntityUid uid, PacifiedComponent component, ComponentShutdown args)
|
||||
@@ -121,7 +120,7 @@ public sealed class PacificationSystem : EntitySystem
|
||||
_combatSystem.SetCanDisarm(uid, true, combatMode);
|
||||
|
||||
_actionsSystem.SetEnabled(combatMode.CombatToggleActionEntity, true);
|
||||
_alertsSystem.ClearAlert(uid, AlertType.Pacified);
|
||||
_alertsSystem.ClearAlert(uid, component.PacifiedAlert);
|
||||
}
|
||||
|
||||
private void OnBeforeThrow(Entity<PacifiedComponent> ent, ref BeforeThrowEvent args)
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Content.Shared.Alert;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.CombatMode.Pacification;
|
||||
|
||||
@@ -42,4 +44,6 @@ public sealed partial class PacifiedComponent : Component
|
||||
[DataField]
|
||||
public EntityUid? LastAttackedEntity = null;
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> PacifiedAlert = "Pacified";
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Damage;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -39,6 +41,9 @@ public sealed partial class CuffableComponent : Component
|
||||
/// </summary>
|
||||
[DataField("canStillInteract"), ViewVariables(VVAccess.ReadWrite)]
|
||||
public bool CanStillInteract = true;
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> CuffedAlert = "Handcuffed";
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
|
||||
@@ -172,9 +172,9 @@ namespace Content.Shared.Cuffs
|
||||
_actionBlocker.UpdateCanMove(uid);
|
||||
|
||||
if (component.CanStillInteract)
|
||||
_alerts.ClearAlert(uid, AlertType.Handcuffed);
|
||||
_alerts.ClearAlert(uid, component.CuffedAlert);
|
||||
else
|
||||
_alerts.ShowAlert(uid, AlertType.Handcuffed);
|
||||
_alerts.ShowAlert(uid, component.CuffedAlert);
|
||||
|
||||
var ev = new CuffedStateChangeEvent();
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Content.Shared.Alert;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
|
||||
namespace Content.Shared.Damage.Components;
|
||||
@@ -51,4 +53,7 @@ public sealed partial class StaminaComponent : Component
|
||||
[DataField(customTypeSerializer: typeof(TimeOffsetSerializer)), AutoNetworkedField]
|
||||
[AutoPausedField]
|
||||
public TimeSpan NextUpdate = TimeSpan.Zero;
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> StaminaAlert = "Stamina";
|
||||
}
|
||||
|
||||
@@ -79,8 +79,7 @@ public sealed partial class StaminaSystem : EntitySystem
|
||||
{
|
||||
RemCompDeferred<ActiveStaminaComponent>(uid);
|
||||
}
|
||||
|
||||
SetStaminaAlert(uid);
|
||||
_alerts.ClearAlert(uid, component.StaminaAlert);
|
||||
}
|
||||
|
||||
private void OnStartup(EntityUid uid, StaminaComponent component, ComponentStartup args)
|
||||
@@ -204,13 +203,10 @@ public sealed partial class StaminaSystem : EntitySystem
|
||||
private void SetStaminaAlert(EntityUid uid, StaminaComponent? component = null)
|
||||
{
|
||||
if (!Resolve(uid, ref component, false) || component.Deleted)
|
||||
{
|
||||
_alerts.ClearAlert(uid, AlertType.Stamina);
|
||||
return;
|
||||
}
|
||||
|
||||
var severity = ContentHelpers.RoundToLevels(MathF.Max(0f, component.CritThreshold - component.StaminaDamage), component.CritThreshold, 7);
|
||||
_alerts.ShowAlert(uid, AlertType.Stamina, (short) severity);
|
||||
_alerts.ShowAlert(uid, component.StaminaAlert, (short) severity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using Content.Shared.Alert;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Ensnaring.Components;
|
||||
@@ -40,6 +42,9 @@ public sealed partial class EnsnareableComponent : Component
|
||||
|
||||
[DataField("state")]
|
||||
public string? State;
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> EnsnaredAlert = "Ensnared";
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
|
||||
@@ -17,6 +17,9 @@ namespace Content.Shared.Gravity
|
||||
[Dependency] private readonly AlertsSystem _alerts = default!;
|
||||
[Dependency] private readonly InventorySystem _inventory = default!;
|
||||
|
||||
[ValidatePrototypeId<AlertPrototype>]
|
||||
public const string WeightlessAlert = "Weightless";
|
||||
|
||||
public bool IsWeightless(EntityUid uid, PhysicsComponent? body = null, TransformComponent? xform = null)
|
||||
{
|
||||
Resolve(uid, ref body, false);
|
||||
@@ -93,11 +96,11 @@ namespace Content.Shared.Gravity
|
||||
|
||||
if (!ev.HasGravity)
|
||||
{
|
||||
_alerts.ShowAlert(uid, AlertType.Weightless);
|
||||
_alerts.ShowAlert(uid, WeightlessAlert);
|
||||
}
|
||||
else
|
||||
{
|
||||
_alerts.ClearAlert(uid, AlertType.Weightless);
|
||||
_alerts.ClearAlert(uid, WeightlessAlert);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,11 +109,11 @@ namespace Content.Shared.Gravity
|
||||
{
|
||||
if (IsWeightless(ev.Euid))
|
||||
{
|
||||
_alerts.ShowAlert(ev.Euid, AlertType.Weightless);
|
||||
_alerts.ShowAlert(ev.Euid, WeightlessAlert);
|
||||
}
|
||||
else
|
||||
{
|
||||
_alerts.ClearAlert(ev.Euid, AlertType.Weightless);
|
||||
_alerts.ClearAlert(ev.Euid, WeightlessAlert);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,11 +121,11 @@ namespace Content.Shared.Gravity
|
||||
{
|
||||
if (IsWeightless(uid))
|
||||
{
|
||||
_alerts.ShowAlert(uid, AlertType.Weightless);
|
||||
_alerts.ShowAlert(uid, WeightlessAlert);
|
||||
}
|
||||
else
|
||||
{
|
||||
_alerts.ClearAlert(uid, AlertType.Weightless);
|
||||
_alerts.ClearAlert(uid, WeightlessAlert);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ using Content.Shared.Alert;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Mobs.Systems;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Mobs.Components;
|
||||
@@ -24,13 +25,16 @@ public sealed partial class MobThresholdsComponent : Component
|
||||
/// Used for alternate health alerts (silicons, for example)
|
||||
/// </summary>
|
||||
[DataField("stateAlertDict")]
|
||||
public Dictionary<MobState, AlertType> StateAlertDict = new()
|
||||
public Dictionary<MobState, ProtoId<AlertPrototype>> StateAlertDict = new()
|
||||
{
|
||||
{MobState.Alive, AlertType.HumanHealth},
|
||||
{MobState.Critical, AlertType.HumanCrit},
|
||||
{MobState.Dead, AlertType.HumanDead},
|
||||
{MobState.Alive, "HumanHealth"},
|
||||
{MobState.Critical, "HumanCrit"},
|
||||
{MobState.Dead, "HumanDead"},
|
||||
};
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertCategoryPrototype> HealthAlertCategory = "Health";
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not this entity should display damage overlays (robots don't feel pain, black out etc.)
|
||||
/// </summary>
|
||||
@@ -53,19 +57,19 @@ public sealed class MobThresholdsComponentState : ComponentState
|
||||
|
||||
public MobState CurrentThresholdState;
|
||||
|
||||
public Dictionary<MobState, AlertType> StateAlertDict = new()
|
||||
{
|
||||
{MobState.Alive, AlertType.HumanHealth},
|
||||
{MobState.Critical, AlertType.HumanCrit},
|
||||
{MobState.Dead, AlertType.HumanDead},
|
||||
};
|
||||
public Dictionary<MobState, ProtoId<AlertPrototype>> StateAlertDict;
|
||||
|
||||
public bool ShowOverlays;
|
||||
|
||||
public bool AllowRevives;
|
||||
|
||||
public MobThresholdsComponentState(Dictionary<FixedPoint2, MobState> unsortedThresholds, bool triggersAlerts, MobState currentThresholdState,
|
||||
Dictionary<MobState, AlertType> stateAlertDict, bool showOverlays, bool allowRevives)
|
||||
public MobThresholdsComponentState(Dictionary<FixedPoint2, MobState> unsortedThresholds,
|
||||
bool triggersAlerts,
|
||||
MobState currentThresholdState,
|
||||
Dictionary<MobState,
|
||||
ProtoId<AlertPrototype>> stateAlertDict,
|
||||
bool showOverlays,
|
||||
bool allowRevives)
|
||||
{
|
||||
UnsortedThresholds = unsortedThresholds;
|
||||
TriggersAlerts = triggersAlerts;
|
||||
|
||||
@@ -431,7 +431,7 @@ public sealed class MobThresholdSystem : EntitySystem
|
||||
private void MobThresholdShutdown(EntityUid target, MobThresholdsComponent component, ComponentShutdown args)
|
||||
{
|
||||
if (component.TriggersAlerts)
|
||||
_alerts.ClearAlertCategory(target, AlertCategory.Health);
|
||||
_alerts.ClearAlertCategory(target, component.HealthAlertCategory);
|
||||
}
|
||||
|
||||
private void OnUpdateMobState(EntityUid target, MobThresholdsComponent component, ref UpdateMobStateEvent args)
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Content.Shared.Alert;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Movement.Pulling.Components;
|
||||
|
||||
@@ -36,4 +38,7 @@ public sealed partial class PullableComponent : Component
|
||||
[Access(typeof(Systems.PullingSystem), Other = AccessPermissions.ReadExecute)]
|
||||
[AutoNetworkedField, DataField]
|
||||
public bool PrevFixedRotation;
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> PulledAlert = "Pulled";
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using Content.Shared.Movement.Pulling.Systems;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Movement.Pulling.Systems;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
|
||||
namespace Content.Shared.Movement.Pulling.Components;
|
||||
@@ -38,4 +40,7 @@ public sealed partial class PullerComponent : Component
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public bool NeedsHands = true;
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> PullingAlert = "Pulling";
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ public sealed class PullingSystem : EntitySystem
|
||||
if (TryComp<PullerComponent>(oldPuller, out var pullerComp))
|
||||
{
|
||||
var pullerUid = oldPuller.Value;
|
||||
_alertsSystem.ClearAlert(pullerUid, AlertType.Pulling);
|
||||
_alertsSystem.ClearAlert(pullerUid, pullerComp.PullingAlert);
|
||||
pullerComp.Pulling = null;
|
||||
Dirty(oldPuller.Value, pullerComp);
|
||||
|
||||
@@ -237,7 +237,7 @@ public sealed class PullingSystem : EntitySystem
|
||||
}
|
||||
|
||||
|
||||
_alertsSystem.ClearAlert(pullableUid, AlertType.Pulled);
|
||||
_alertsSystem.ClearAlert(pullableUid, pullableComp.PulledAlert);
|
||||
}
|
||||
|
||||
public bool IsPulled(EntityUid uid, PullableComponent? component = null)
|
||||
@@ -460,8 +460,8 @@ public sealed class PullingSystem : EntitySystem
|
||||
|
||||
// Messaging
|
||||
var message = new PullStartedMessage(pullerUid, pullableUid);
|
||||
_alertsSystem.ShowAlert(pullerUid, AlertType.Pulling);
|
||||
_alertsSystem.ShowAlert(pullableUid, AlertType.Pulled);
|
||||
_alertsSystem.ShowAlert(pullerUid, pullerComp.PullingAlert);
|
||||
_alertsSystem.ShowAlert(pullableUid, pullableComp.PulledAlert);
|
||||
|
||||
RaiseLocalEvent(pullerUid, message);
|
||||
RaiseLocalEvent(pullableUid, message);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Ninja.Systems;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
@@ -53,4 +54,7 @@ public sealed partial class SpaceNinjaComponent : Component
|
||||
/// </summary>
|
||||
[DataField]
|
||||
public EntProtoId SpiderChargeObjective = "SpiderChargeObjective";
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> SuitPowerAlert = "SuitPower";
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ using Content.Shared.Alert;
|
||||
using Content.Shared.Damage;
|
||||
using Content.Shared.Nutrition.EntitySystems;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Generic;
|
||||
@@ -65,15 +66,18 @@ public sealed partial class HungerComponent : Component
|
||||
/// <summary>
|
||||
/// A dictionary relating hunger thresholds to corresponding alerts.
|
||||
/// </summary>
|
||||
[DataField("hungerThresholdAlerts", customTypeSerializer: typeof(DictionarySerializer<HungerThreshold, AlertType>))]
|
||||
[DataField("hungerThresholdAlerts")]
|
||||
[AutoNetworkedField]
|
||||
public Dictionary<HungerThreshold, AlertType> HungerThresholdAlerts = new()
|
||||
public Dictionary<HungerThreshold, ProtoId<AlertPrototype>> HungerThresholdAlerts = new()
|
||||
{
|
||||
{ HungerThreshold.Peckish, AlertType.Peckish },
|
||||
{ HungerThreshold.Starving, AlertType.Starving },
|
||||
{ HungerThreshold.Dead, AlertType.Starving }
|
||||
{ HungerThreshold.Peckish, "Peckish" },
|
||||
{ HungerThreshold.Starving, "Starving" },
|
||||
{ HungerThreshold.Dead, "Starving" }
|
||||
};
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertCategoryPrototype> HungerAlertCategory = "Hunger";
|
||||
|
||||
/// <summary>
|
||||
/// A dictionary relating HungerThreshold to how much they modify <see cref="BaseDecayRate"/>.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Nutrition.EntitySystems;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom;
|
||||
|
||||
namespace Content.Shared.Nutrition.Components;
|
||||
@@ -56,11 +57,14 @@ public sealed partial class ThirstComponent : Component
|
||||
{ThirstThreshold.Dead, 0.0f},
|
||||
};
|
||||
|
||||
public static readonly Dictionary<ThirstThreshold, AlertType> ThirstThresholdAlertTypes = new()
|
||||
[DataField]
|
||||
public ProtoId<AlertCategoryPrototype> ThirstyCategory = "Thirst";
|
||||
|
||||
public static readonly Dictionary<ThirstThreshold, ProtoId<AlertPrototype>> ThirstThresholdAlertTypes = new()
|
||||
{
|
||||
{ThirstThreshold.Thirsty, AlertType.Thirsty},
|
||||
{ThirstThreshold.Parched, AlertType.Parched},
|
||||
{ThirstThreshold.Dead, AlertType.Parched},
|
||||
{ThirstThreshold.Thirsty, "Thirsty"},
|
||||
{ThirstThreshold.Parched, "Parched"},
|
||||
{ThirstThreshold.Dead, "Parched"},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ public sealed class HungerSystem : EntitySystem
|
||||
|
||||
private void OnShutdown(EntityUid uid, HungerComponent component, ComponentShutdown args)
|
||||
{
|
||||
_alerts.ClearAlertCategory(uid, AlertCategory.Hunger);
|
||||
_alerts.ClearAlertCategory(uid, component.HungerAlertCategory);
|
||||
}
|
||||
|
||||
private void OnRefreshMovespeed(EntityUid uid, HungerComponent component, RefreshMovementSpeedModifiersEvent args)
|
||||
@@ -142,7 +142,7 @@ public sealed class HungerSystem : EntitySystem
|
||||
}
|
||||
else
|
||||
{
|
||||
_alerts.ClearAlertCategory(uid, AlertCategory.Hunger);
|
||||
_alerts.ClearAlertCategory(uid, component.HungerAlertCategory);
|
||||
}
|
||||
|
||||
if (component.HungerThresholdDecayModifiers.TryGetValue(component.CurrentThreshold, out var modifier))
|
||||
|
||||
@@ -165,7 +165,7 @@ public sealed class ThirstSystem : EntitySystem
|
||||
}
|
||||
else
|
||||
{
|
||||
_alerts.ClearAlertCategory(uid, AlertCategory.Thirst);
|
||||
_alerts.ClearAlertCategory(uid, component.ThirstyCategory);
|
||||
}
|
||||
|
||||
switch (component.CurrentThirstThreshold)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.FixedPoint;
|
||||
using Content.Shared.Store;
|
||||
using Content.Shared.Whitelist;
|
||||
@@ -200,6 +201,9 @@ public sealed partial class RevenantComponent : Component
|
||||
public EntityWhitelist? MalfunctionBlacklist;
|
||||
#endregion
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> EssenceAlert = "Essence";
|
||||
|
||||
#region Visualizer
|
||||
[DataField("state")]
|
||||
public string State = "idle";
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System.Numerics;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Content.Shared.Shuttles.Components
|
||||
@@ -32,6 +34,9 @@ namespace Content.Shared.Shuttles.Components
|
||||
[ViewVariables]
|
||||
public ShuttleButtons HeldButtons = ShuttleButtons.None;
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> PilotingAlert = "PilotingShuttle";
|
||||
|
||||
public override bool SendOnlyToOwner => true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using Content.Shared.Whitelist;
|
||||
using Content.Shared.Alert;
|
||||
using Content.Shared.Whitelist;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Silicons.Borgs.Components;
|
||||
@@ -76,6 +78,12 @@ public sealed partial class BorgChassisComponent : Component
|
||||
[DataField("noMindState")]
|
||||
public string NoMindState = string.Empty;
|
||||
#endregion
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> BatteryAlert = "BorgBattery";
|
||||
|
||||
[DataField]
|
||||
public ProtoId<AlertPrototype> NoBatteryAlert = "BorgBatteryNone";
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Content.Shared.StatusEffect
|
||||
public string ID { get; private set; } = default!;
|
||||
|
||||
[DataField("alert")]
|
||||
public AlertType? Alert { get; private set; }
|
||||
public ProtoId<AlertPrototype>? Alert { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether a status effect should be able to apply to any entity,
|
||||
|
||||
@@ -219,7 +219,7 @@ namespace Content.Shared.StatusEffect
|
||||
/// This is mostly for stuns, since Stun and Knockdown share an alert key. Other times this pretty much
|
||||
/// will not be useful.
|
||||
/// </remarks>
|
||||
private (TimeSpan, TimeSpan)? GetAlertCooldown(EntityUid uid, AlertType alert, StatusEffectsComponent status)
|
||||
private (TimeSpan, TimeSpan)? GetAlertCooldown(EntityUid uid, ProtoId<AlertPrototype> alert, StatusEffectsComponent status)
|
||||
{
|
||||
(TimeSpan, TimeSpan)? maxCooldown = null;
|
||||
foreach (var kvp in status.ActiveEffects)
|
||||
|
||||
@@ -42,6 +42,9 @@ public sealed class ReflectSystem : EntitySystem
|
||||
[Dependency] private readonly StandingStateSystem _standing = default!;
|
||||
[Dependency] private readonly AlertsSystem _alerts = default!;
|
||||
|
||||
[ValidatePrototypeId<AlertPrototype>]
|
||||
private const string DeflectingAlert = "Deflecting";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
@@ -296,11 +299,11 @@ public sealed class ReflectSystem : EntitySystem
|
||||
|
||||
private void EnableAlert(EntityUid alertee)
|
||||
{
|
||||
_alerts.ShowAlert(alertee, AlertType.Deflecting);
|
||||
_alerts.ShowAlert(alertee, DeflectingAlert);
|
||||
}
|
||||
|
||||
private void DisableAlert(EntityUid alertee)
|
||||
{
|
||||
_alerts.ClearAlert(alertee, AlertType.Deflecting);
|
||||
_alerts.ClearAlert(alertee, DeflectingAlert);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.IO;
|
||||
using Content.Client.Alerts;
|
||||
using Content.Server.Alert;
|
||||
using Content.Shared.Alert;
|
||||
using NUnit.Framework;
|
||||
using Robust.Shared.GameObjects;
|
||||
@@ -45,15 +44,15 @@ namespace Content.Tests.Shared.Alert
|
||||
prototypeManager.Initialize();
|
||||
prototypeManager.LoadFromStream(new StringReader(PROTOTYPES));
|
||||
|
||||
Assert.That(alertsSystem.TryGet(AlertType.LowPressure, out var lowPressure));
|
||||
Assert.That(lowPressure.Icons[0], Is.EqualTo(new SpriteSpecifier.Texture(new ("/Textures/Interface/Alerts/Pressure/lowpressure.png"))));
|
||||
Assert.That(alertsSystem.TryGet(AlertType.HighPressure, out var highPressure));
|
||||
Assert.That(highPressure.Icons[0], Is.EqualTo(new SpriteSpecifier.Texture(new ("/Textures/Interface/Alerts/Pressure/highpressure.png"))));
|
||||
Assert.That(alertsSystem.TryGet("LowPressure", out var lowPressure));
|
||||
Assert.That(lowPressure!.Icons[0], Is.EqualTo(new SpriteSpecifier.Texture(new ("/Textures/Interface/Alerts/Pressure/lowpressure.png"))));
|
||||
Assert.That(alertsSystem.TryGet("HighPressure", out var highPressure));
|
||||
Assert.That(highPressure!.Icons[0], Is.EqualTo(new SpriteSpecifier.Texture(new ("/Textures/Interface/Alerts/Pressure/highpressure.png"))));
|
||||
|
||||
Assert.That(alertsSystem.TryGet(AlertType.LowPressure, out lowPressure));
|
||||
Assert.That(lowPressure.Icons[0], Is.EqualTo(new SpriteSpecifier.Texture(new ("/Textures/Interface/Alerts/Pressure/lowpressure.png"))));
|
||||
Assert.That(alertsSystem.TryGet(AlertType.HighPressure, out highPressure));
|
||||
Assert.That(highPressure.Icons[0], Is.EqualTo(new SpriteSpecifier.Texture(new ("/Textures/Interface/Alerts/Pressure/highpressure.png"))));
|
||||
Assert.That(alertsSystem.TryGet("LowPressure", out lowPressure));
|
||||
Assert.That(lowPressure!.Icons[0], Is.EqualTo(new SpriteSpecifier.Texture(new ("/Textures/Interface/Alerts/Pressure/lowpressure.png"))));
|
||||
Assert.That(alertsSystem.TryGet("HighPressure", out highPressure));
|
||||
Assert.That(highPressure!.Icons[0], Is.EqualTo(new SpriteSpecifier.Texture(new ("/Textures/Interface/Alerts/Pressure/highpressure.png"))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,24 +85,24 @@ namespace Content.Tests.Shared.Alert
|
||||
var alerts = prototypeManager.EnumeratePrototypes<AlertPrototype>();
|
||||
|
||||
// ensure they sort according to our expected criteria
|
||||
var expectedOrder = new List<AlertType>();
|
||||
expectedOrder.Add(AlertType.Handcuffed);
|
||||
expectedOrder.Add(AlertType.Ensnared);
|
||||
expectedOrder.Add(AlertType.HighPressure);
|
||||
var expectedOrder = new List<string>();
|
||||
expectedOrder.Add("Handcuffed");
|
||||
expectedOrder.Add("Ensnared");
|
||||
expectedOrder.Add("HighPressure");
|
||||
// stuff with only category + same category ordered by enum value
|
||||
expectedOrder.Add(AlertType.Peckish);
|
||||
expectedOrder.Add(AlertType.Hot);
|
||||
expectedOrder.Add(AlertType.Stun);
|
||||
expectedOrder.Add(AlertType.LowPressure);
|
||||
expectedOrder.Add(AlertType.Cold);
|
||||
// stuff at end of list ordered by enum value
|
||||
expectedOrder.Add(AlertType.Weightless);
|
||||
expectedOrder.Add(AlertType.PilotingShuttle);
|
||||
expectedOrder.Add("Peckish");
|
||||
expectedOrder.Add("Hot");
|
||||
expectedOrder.Add("Stun");
|
||||
expectedOrder.Add("LowPressure");
|
||||
expectedOrder.Add("Cold");
|
||||
// stuff at end of list ordered by ID
|
||||
expectedOrder.Add("PilotingShuttle");
|
||||
expectedOrder.Add("Weightless");
|
||||
|
||||
var actual = alerts.ToList();
|
||||
actual.Sort(alertOrder);
|
||||
|
||||
Assert.That(actual.Select(a => a.AlertType).ToList(), Is.EqualTo(expectedOrder));
|
||||
Assert.That(actual.Select(a => a.ID).ToList(), Is.EqualTo(expectedOrder));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,9 +39,9 @@ namespace Content.Tests.Shared.Alert
|
||||
[Test]
|
||||
public void TestAlertKey()
|
||||
{
|
||||
Assert.That(new AlertKey(AlertType.HumanHealth, null), Is.Not.EqualTo(AlertKey.ForCategory(AlertCategory.Health)));
|
||||
Assert.That((new AlertKey(null, AlertCategory.Health)), Is.EqualTo(AlertKey.ForCategory(AlertCategory.Health)));
|
||||
Assert.That((new AlertKey(AlertType.Buckled, AlertCategory.Health)), Is.EqualTo(AlertKey.ForCategory(AlertCategory.Health)));
|
||||
Assert.That(new AlertKey("HumanHealth", null), Is.Not.EqualTo(AlertKey.ForCategory("Health")));
|
||||
Assert.That((new AlertKey(null, "Health")), Is.EqualTo(AlertKey.ForCategory("Health")));
|
||||
Assert.That((new AlertKey("Buckled", "Health")), Is.EqualTo(AlertKey.ForCategory("Health")));
|
||||
}
|
||||
|
||||
[TestCase(0, "/Textures/Interface/Alerts/Human/human.rsi/human0.png")]
|
||||
|
||||
@@ -15,6 +15,9 @@ namespace Content.Tests.Shared.Alert
|
||||
public sealed class ServerAlertsComponentTests : ContentUnitTest
|
||||
{
|
||||
const string PROTOTYPES = @"
|
||||
- type: alertCategory
|
||||
id: Pressure
|
||||
|
||||
- type: alert
|
||||
id: LowPressure
|
||||
category: Pressure
|
||||
@@ -49,10 +52,10 @@ namespace Content.Tests.Shared.Alert
|
||||
var alertsComponent = new AlertsComponent();
|
||||
alertsComponent = IoCManager.InjectDependencies(alertsComponent);
|
||||
|
||||
Assert.That(entManager.System<AlertsSystem>().TryGet(AlertType.LowPressure, out var lowpressure));
|
||||
Assert.That(entManager.System<AlertsSystem>().TryGet(AlertType.HighPressure, out var highpressure));
|
||||
Assert.That(entManager.System<AlertsSystem>().TryGet("LowPressure", out var lowpressure));
|
||||
Assert.That(entManager.System<AlertsSystem>().TryGet("HighPressure", out var highpressure));
|
||||
|
||||
entManager.System<AlertsSystem>().ShowAlert(alertsComponent.Owner, AlertType.LowPressure, null, null);
|
||||
entManager.System<AlertsSystem>().ShowAlert(alertsComponent.Owner, "LowPressure");
|
||||
|
||||
var getty = new ComponentGetState();
|
||||
entManager.EventBus.RaiseComponentEvent(alertsComponent, getty);
|
||||
@@ -60,17 +63,17 @@ namespace Content.Tests.Shared.Alert
|
||||
var alertState = (AlertsComponent.AlertsComponent_AutoState) getty.State!;
|
||||
Assert.That(alertState, Is.Not.Null);
|
||||
Assert.That(alertState.Alerts.Count, Is.EqualTo(1));
|
||||
Assert.That(alertState.Alerts.ContainsKey(lowpressure.AlertKey));
|
||||
Assert.That(alertState.Alerts.ContainsKey(lowpressure!.AlertKey));
|
||||
|
||||
entManager.System<AlertsSystem>().ShowAlert(alertsComponent.Owner, AlertType.HighPressure, null, null);
|
||||
entManager.System<AlertsSystem>().ShowAlert(alertsComponent.Owner, "HighPressure");
|
||||
|
||||
// Lazy
|
||||
entManager.EventBus.RaiseComponentEvent(alertsComponent, getty);
|
||||
alertState = (AlertsComponent.AlertsComponent_AutoState) getty.State!;
|
||||
Assert.That(alertState.Alerts.Count, Is.EqualTo(1));
|
||||
Assert.That(alertState.Alerts.ContainsKey(highpressure.AlertKey));
|
||||
Assert.That(alertState.Alerts.ContainsKey(highpressure!.AlertKey));
|
||||
|
||||
entManager.System<AlertsSystem>().ClearAlertCategory(alertsComponent.Owner, AlertCategory.Pressure);
|
||||
entManager.System<AlertsSystem>().ClearAlertCategory(alertsComponent.Owner, "Pressure");
|
||||
|
||||
entManager.EventBus.RaiseComponentEvent(alertsComponent, getty);
|
||||
alertState = (AlertsComponent.AlertsComponent_AutoState) getty.State!;
|
||||
|
||||
35
Resources/Prototypes/Alerts/categories.yml
Normal file
35
Resources/Prototypes/Alerts/categories.yml
Normal file
@@ -0,0 +1,35 @@
|
||||
- type: alertCategory
|
||||
id: Pressure
|
||||
|
||||
- type: alertCategory
|
||||
id: Temperature
|
||||
|
||||
- type: alertCategory
|
||||
id: Breathing
|
||||
|
||||
- type: alertCategory
|
||||
id: Buckled
|
||||
|
||||
- type: alertCategory
|
||||
id: Health
|
||||
|
||||
- type: alertCategory
|
||||
id: Internals
|
||||
|
||||
- type: alertCategory
|
||||
id: Stamina
|
||||
|
||||
- type: alertCategory
|
||||
id: Piloting
|
||||
|
||||
- type: alertCategory
|
||||
id: Hunger
|
||||
|
||||
- type: alertCategory
|
||||
id: Thirst
|
||||
|
||||
- type: alertCategory
|
||||
id: Toxins
|
||||
|
||||
- type: alertCategory
|
||||
id: Battery
|
||||
Reference in New Issue
Block a user