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