diff --git a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml
index b74df979cf..7fa07a6a6e 100644
--- a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml
+++ b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml
@@ -53,7 +53,7 @@
diff --git a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs
index 926b8c6567..b2330030c6 100644
--- a/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs
+++ b/Content.Client/Communications/UI/CommunicationsConsoleMenu.xaml.cs
@@ -6,6 +6,10 @@ using Robust.Client.UserInterface.XAML;
using Robust.Shared.Configuration;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
+// WL-Changes-start: Alert Level Rework
+using Robust.Shared.Prototypes;
+using Content.Shared.AlertLevel;
+// WL-Changes-end
namespace Content.Client.Communications.UI
{
@@ -15,6 +19,7 @@ namespace Content.Client.Communications.UI
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly ILocalizationManager _loc = default!;
+ [Dependency] private readonly IPrototypeManager _prototypeManager = default!; // Wl-Changes: Alert Level Rework
public bool CanAnnounce;
public bool CanBroadcast;
@@ -91,10 +96,17 @@ namespace Content.Client.Communications.UI
if (alerts == null)
{
var name = currentAlert;
- if (_loc.TryGetString($"alert-level-{currentAlert}", out var locName))
+ // Wl-Changes-start: Alert Level Rework
+ if (!_prototypeManager.TryIndex(currentAlert, out var index))
+ return;
+ if (_loc.TryGetString($"alert-level-{currentAlert.ToLower()}", out var locName))
{
name = locName;
}
+ else if (!string.IsNullOrEmpty(index.SetName))
+ name = index.SetName;
+ // WL-Changes-end
+
AlertLevelButton.AddItem(name);
AlertLevelButton.SetItemMetadata(AlertLevelButton.ItemCount - 1, currentAlert);
}
@@ -103,12 +115,20 @@ namespace Content.Client.Communications.UI
foreach (var alert in alerts)
{
var name = alert;
- if (_loc.TryGetString($"alert-level-{alert}", out var locName))
+ // WL-Changes-start: Alert Level Rework
+ if (_prototypeManager.TryIndex(alert, out var index))
{
- name = locName;
+ if (_loc.TryGetString($"alert-level-{alert.ToLower()}", out var locName))
+ {
+ name = locName;
+ }
+ else if (!string.IsNullOrEmpty(index.SetName))
+ name = index.SetName;
+
+ AlertLevelButton.AddItem(name);
+ AlertLevelButton.SetItemMetadata(AlertLevelButton.ItemCount - 1, alert);
}
- AlertLevelButton.AddItem(name);
- AlertLevelButton.SetItemMetadata(AlertLevelButton.ItemCount - 1, alert);
+ // WL-Changes-end
if (alert == currentAlert)
{
AlertLevelButton.Select(AlertLevelButton.ItemCount - 1);
diff --git a/Content.Client/Entry/EntryPoint.cs b/Content.Client/Entry/EntryPoint.cs
index f8ed1b3b7b..7bc93f9912 100644
--- a/Content.Client/Entry/EntryPoint.cs
+++ b/Content.Client/Entry/EntryPoint.cs
@@ -125,7 +125,7 @@ namespace Content.Client.Entry
_prototypeManager.RegisterIgnore("instantSpell");
_prototypeManager.RegisterIgnore("roundAnnouncement");
_prototypeManager.RegisterIgnore("wireLayout");
- _prototypeManager.RegisterIgnore("alertLevels");
+ _prototypeManager.RegisterIgnore("alertLevelsList"); // Wl-Changes: Alert Level Rework // alertLevels -> alertLevelsList
_prototypeManager.RegisterIgnore("nukeopsRole");
_prototypeManager.RegisterIgnore("stationGoal"); // Corvax-StationGoal
_prototypeManager.RegisterIgnore("ghostRoleRaffleDecider");
diff --git a/Content.Client/PDA/PdaMenu.xaml.cs b/Content.Client/PDA/PdaMenu.xaml.cs
index de601af976..828a270ea4 100644
--- a/Content.Client/PDA/PdaMenu.xaml.cs
+++ b/Content.Client/PDA/PdaMenu.xaml.cs
@@ -117,7 +117,7 @@ namespace Content.Client.PDA
StationTimeButton.OnPressed += _ =>
{
var stationTime = _gameTiming.CurTime.Subtract(_gameTicker.RoundStartTimeSpan);
- _clipboard.SetText((stationTime.ToString("hh\\:mm\\:ss")));
+ _clipboard.SetText(stationTime.ToString("hh\\:mm\\:ss"));
};
StationAlertLevelInstructionsButton.OnPressed += _ =>
@@ -132,6 +132,7 @@ namespace Content.Client.PDA
ToHomeScreen();
}
+ // WL-Changes-start: Loc -> _locMan
public void UpdateState(PdaUpdateState state)
{
FlashLightToggleButton.IsActive = state.FlashlightEnabled;
@@ -139,7 +140,7 @@ namespace Content.Client.PDA
if (state.PdaOwnerInfo.ActualOwnerName != null)
{
_pdaOwner = state.PdaOwnerInfo.ActualOwnerName;
- PdaOwnerLabel.SetMarkup(Loc.GetString("comp-pda-ui-owner",
+ PdaOwnerLabel.SetMarkup(_locMan.GetString("comp-pda-ui-owner",
("actualOwnerName", _pdaOwner)));
PdaOwnerLabel.Visible = true;
}
@@ -151,42 +152,41 @@ namespace Content.Client.PDA
if (state.PdaOwnerInfo.IdOwner != null || state.PdaOwnerInfo.JobTitle != null)
{
- _owner = state.PdaOwnerInfo.IdOwner ?? Loc.GetString("comp-pda-ui-unknown");
- _jobTitle = state.PdaOwnerInfo.JobTitle ?? Loc.GetString("comp-pda-ui-unassigned");
- IdInfoLabel.SetMarkup(Loc.GetString("comp-pda-ui",
+ _owner = state.PdaOwnerInfo.IdOwner ?? _locMan.GetString("comp-pda-ui-unknown");
+ _jobTitle = state.PdaOwnerInfo.JobTitle ?? _locMan.GetString("comp-pda-ui-unassigned");
+ IdInfoLabel.SetMarkup(_locMan.GetString("comp-pda-ui",
("owner", _owner),
("jobTitle", _jobTitle)));
}
else
{
- IdInfoLabel.SetMarkup(Loc.GetString("comp-pda-ui-blank"));
+ IdInfoLabel.SetMarkup(_locMan.GetString("comp-pda-ui-blank"));
}
- _stationName = state.StationName ?? Loc.GetString("comp-pda-ui-unknown");
- StationNameLabel.SetMarkup(Loc.GetString("comp-pda-ui-station",
+ _stationName = state.StationName ?? _locMan.GetString("comp-pda-ui-unknown");
+ StationNameLabel.SetMarkup(_locMan.GetString("comp-pda-ui-station",
("station", _stationName)));
var stationTime = _gameTiming.CurTime.Subtract(_gameTicker.RoundStartTimeSpan);
- StationTimeLabel.SetMarkup(Loc.GetString("comp-pda-ui-station-time",
+ StationTimeLabel.SetMarkup(_locMan.GetString("comp-pda-ui-station-time",
("time", stationTime.ToString("hh\\:mm\\:ss"))));
var alertLevel = state.PdaOwnerInfo.StationAlertLevel;
var alertColor = state.PdaOwnerInfo.StationAlertColor;
+ var alertName = state.PdaOwnerInfo.StationAlertName;
// WL-Changes-start: custom alert instructions in PDA
var alertInstructions = state.PdaOwnerInfo.StationAlertInstructions;
- if (alertLevel != null)
- {
- if (_locMan.TryGetString($"alert-level-{alertLevel}", out var locName))
- _alertLevel = locName;
- else
- _alertLevel = alertLevel;
- }
+ if (alertLevel != null
+ && _locMan.TryGetString($"alert-level-{alertLevel.ToLower()}", out var locName))
+ _alertLevel = locName;
+ else if (!string.IsNullOrEmpty(alertName))
+ _alertLevel = alertName;
else
- _alertLevel = Loc.GetString("alert-level-unknown");
+ _alertLevel = _locMan.GetString("alert-level-unknown");
- StationAlertLevelLabel.SetMarkup(Loc.GetString(
+ StationAlertLevelLabel.SetMarkup(_locMan.GetString(
"comp-pda-ui-station-alert-level",
("color", alertColor),
("level", _alertLevel)
@@ -194,13 +194,13 @@ namespace Content.Client.PDA
if (!string.IsNullOrEmpty(alertInstructions))
_instructions = alertInstructions;
- else if (alertLevel != null && _locMan.TryGetString($"alert-level-{alertLevel}-instructions", out var locInstruction))
+ else if (alertLevel != null && _locMan.TryGetString($"alert-level-{alertLevel.ToLower()}-instructions", out var locInstruction))
_instructions = locInstruction;
else
- _instructions = Loc.GetString("alert-level-unknown-instructions");
+ _instructions = _locMan.GetString("alert-level-unknown-instructions");
// WL-Changes-end
- StationAlertLevelInstructions.SetMarkup(Loc.GetString(
+ StationAlertLevelInstructions.SetMarkup(_locMan.GetString(
"comp-pda-ui-station-alert-level-instructions",
("instructions", _instructions))
);
@@ -223,7 +223,7 @@ namespace Content.Client.PDA
{
ProgramList.AddChild(new Label()
{
- Text = Loc.GetString("comp-pda-io-no-programs-available"),
+ Text = _locMan.GetString("comp-pda-io-no-programs-available"),
HorizontalAlignment = HAlignment.Center,
VerticalAlignment = VAlignment.Center,
VerticalExpand = true
@@ -256,17 +256,17 @@ namespace Content.Client.PDA
{
case InstallationStatus.Cartridge:
item.InstallButton.Visible = true;
- item.InstallButton.Text = Loc.GetString("cartridge-bound-user-interface-install-button");
+ item.InstallButton.Text = _locMan.GetString("cartridge-bound-user-interface-install-button");
item.InstallButton.OnPressed += _ => OnInstallButtonPressed?.Invoke(uid);
break;
case InstallationStatus.Installed:
item.InstallButton.Visible = true;
- item.InstallButton.Text = Loc.GetString("cartridge-bound-user-interface-uninstall-button");
+ item.InstallButton.Text = _locMan.GetString("cartridge-bound-user-interface-uninstall-button");
item.InstallButton.OnPressed += _ => OnUninstallButtonPressed?.Invoke(uid);
break;
}
- item.ProgramName.Text = Loc.GetString(component.ProgramName);
+ item.ProgramName.Text = _locMan.GetString(component.ProgramName);
item.SetHeight = 20;
row.AddChild(item);
@@ -360,8 +360,9 @@ namespace Content.Client.PDA
var stationTime = _gameTiming.CurTime.Subtract(_gameTicker.RoundStartTimeSpan);
- StationTimeLabel.SetMarkup(Loc.GetString("comp-pda-ui-station-time",
+ StationTimeLabel.SetMarkup(_locMan.GetString("comp-pda-ui-station-time",
("time", stationTime.ToString("hh\\:mm\\:ss"))));
}
+ // WL-Changes-end: Loc -> _locMan
}
}
diff --git a/Content.Server/AlertLevel/AlertLevelComponent.cs b/Content.Server/AlertLevel/AlertLevelComponent.cs
index cb45c6b40e..a95e0803a7 100644
--- a/Content.Server/AlertLevel/AlertLevelComponent.cs
+++ b/Content.Server/AlertLevel/AlertLevelComponent.cs
@@ -1,4 +1,7 @@
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
+// WL-Changes-start: Alert Level Rework
+using Content.Shared.AlertLevel;
+using Robust.Shared.Prototypes;
+// WL-Changes-end
namespace Content.Server.AlertLevel;
@@ -13,11 +16,13 @@ public sealed partial class AlertLevelComponent : Component
/// The current set of alert levels on the station.
///
[ViewVariables]
- public AlertLevelPrototype? AlertLevels;
+ // WL-Changes-start: Alert Level Rework
+ public AlertLevelsListPrototype? AlertLevels;
// Once stations are a prototype, this should be used.
- [DataField("alertLevelPrototype", required: true, customTypeSerializer: typeof(PrototypeIdSerializer))]
- public string AlertLevelPrototype = default!;
+ [DataField(required: true)]
+ public ProtoId AlertLevelsListPrototype;
+ // WL-Changes-end
///
/// The current level on the station.
@@ -40,11 +45,12 @@ public sealed partial class AlertLevelComponent : Component
{
get
{
+ var prototypeManager = IoCManager.Resolve();
if (AlertLevels == null
- || !AlertLevels.Levels.TryGetValue(CurrentLevel, out var level))
- {
+ // WL-Changes-start: Alert Level Rework
+ || !prototypeManager.TryIndex(CurrentLevel, out var level)) // TryGetValue -> TryIndex
return false;
- }
+ // WL-Changes-end
return level.Selectable && !level.DisableSelection && !IsLevelLocked;
}
diff --git a/Content.Server/AlertLevel/AlertLevelPrototype.cs b/Content.Server/AlertLevel/AlertLevelPrototype.cs
deleted file mode 100644
index 6f171543a3..0000000000
--- a/Content.Server/AlertLevel/AlertLevelPrototype.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-using Robust.Shared.Audio;
-using Robust.Shared.Prototypes;
-
-namespace Content.Server.AlertLevel;
-
-[Prototype("alertLevels")]
-public sealed partial class AlertLevelPrototype : IPrototype
-{
- [IdDataField] public string ID { get; private set; } = default!;
-
- ///
- /// Dictionary of alert levels. Keyed by string - the string key is the most important
- /// part here. Visualizers will use this in order to dictate what alert level to show on
- /// client side sprites, and localization uses each key to dictate the alert level name.
- ///
- [DataField("levels")] public Dictionary Levels = new();
-
- ///
- /// Default level that the station is on upon initialization.
- /// If this isn't in the dictionary, this will default to whatever .First() gives.
- ///
- [DataField("defaultLevel")] public string DefaultLevel { get; private set; } = default!;
-}
-
-///
-/// Alert level detail. Does not contain an ID, that is handled by
-/// the Levels field in AlertLevelPrototype.
-///
-[DataDefinition]
-public sealed partial class AlertLevelDetail
-{
- ///
- /// What is announced upon this alert level change. Can be a localized string.
- ///
- [DataField("announcement")] public string Announcement { get; private set; } = string.Empty;
-
- // WL-Changes-start: custom alert instructions in PDA
- ///
- /// Instruction of alert level in pda
- ///
- [DataField("instruction")] public string AlertLevelInstruction { get; private set; } = string.Empty;
- // WL-Changes-end
-
- ///
- /// Whether this alert level is selectable from a communications console.
- ///
- [DataField("selectable")] public bool Selectable { get; private set; } = true;
-
- ///
- /// If this alert level disables user selection while it is active. Beware -
- /// setting this while something is selectable will disable selection permanently!
- /// This should only apply to entities or gamemodes that auto-select an alert level,
- /// such as a nuclear bomb being set to active.
- ///
- [DataField("disableSelection")] public bool DisableSelection { get; private set; }
-
- ///
- /// The sound that this alert level will play in-game once selected.
- ///
- [DataField("sound")] public SoundSpecifier? Sound { get; private set; }
-
- ///
- /// The color that this alert level will show in-game in chat.
- ///
- [DataField("color")] public Color Color { get; private set; } = Color.White;
-
- ///
- /// The color to turn emergency lights on this station when they are active.
- ///
- [DataField("emergencyLightColor")] public Color EmergencyLightColor { get; private set; } = Color.FromHex("#FF4020");
-
- ///
- /// Will this alert level force emergency lights on for the station that's active?
- ///
- [DataField("forceEnableEmergencyLights")] public bool ForceEnableEmergencyLights { get; private set; } = false;
-
- ///
- /// How long it takes for the shuttle to arrive when called.
- ///
- [DataField("shuttleTime")] public TimeSpan ShuttleTime { get; private set; } = TimeSpan.FromMinutes(5);
-}
-
diff --git a/Content.Server/AlertLevel/AlertLevelSystem.cs b/Content.Server/AlertLevel/AlertLevelSystem.cs
index 3485e01704..5d522bde51 100644
--- a/Content.Server/AlertLevel/AlertLevelSystem.cs
+++ b/Content.Server/AlertLevel/AlertLevelSystem.cs
@@ -1,8 +1,8 @@
using System.Linq;
using Content.Server.Chat.Systems;
using Content.Server.Station.Systems;
+using Content.Shared.AlertLevel; // WL-Changes: Alert Level Rework
using Content.Shared.CCVar;
-using Robust.Shared.Audio;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Configuration;
using Robust.Shared.Prototypes;
@@ -51,7 +51,7 @@ public sealed class AlertLevelSystem : EntitySystem
if (!TryComp(args.Station, out var alertLevelComponent))
return;
- if (!_prototypeManager.TryIndex(alertLevelComponent.AlertLevelPrototype, out AlertLevelPrototype? alerts))
+ if (!_prototypeManager.TryIndex(alertLevelComponent.AlertLevelsListPrototype, out AlertLevelsListPrototype? alerts)) // WL-Changes: Alert Level Rework
{
return;
}
@@ -61,7 +61,7 @@ public sealed class AlertLevelSystem : EntitySystem
var defaultLevel = alertLevelComponent.AlertLevels.DefaultLevel;
if (string.IsNullOrEmpty(defaultLevel))
{
- defaultLevel = alertLevelComponent.AlertLevels.Levels.Keys.First();
+ defaultLevel = alertLevelComponent.AlertLevels.Levels.First(); // WL-Changes: Alert Level Rework
}
SetLevel(args.Station, defaultLevel, false, false, true);
@@ -69,31 +69,34 @@ public sealed class AlertLevelSystem : EntitySystem
private void OnPrototypeReload(PrototypesReloadedEventArgs args)
{
- if (!args.ByType.TryGetValue(typeof(AlertLevelPrototype), out var alertPrototypes)
- || !alertPrototypes.Modified.TryGetValue(DefaultAlertLevelSet, out var alertObject)
- || alertObject is not AlertLevelPrototype alerts)
- {
+ // WL-Changes-start: Alert Level Rework
+ if (!args.ByType.TryGetValue(typeof(AlertLevelsListPrototype), out var alertListPrototypes)
+ || !alertListPrototypes.Modified.TryGetValue(DefaultAlertLevelSet, out var alertObject)
+ || alertObject is not AlertLevelsListPrototype alerts)
return;
- }
+ // WL-Changes-end
var query = EntityQueryEnumerator();
while (query.MoveNext(out var uid, out var comp))
{
comp.AlertLevels = alerts;
- if (!comp.AlertLevels.Levels.ContainsKey(comp.CurrentLevel))
+ if (!comp.AlertLevels.Levels.Contains(comp.CurrentLevel)) // WL-Changes: Alert Level Rework
{
var defaultLevel = comp.AlertLevels.DefaultLevel;
- if (string.IsNullOrEmpty(defaultLevel))
- {
- defaultLevel = comp.AlertLevels.Levels.Keys.First();
- }
+ if (string.IsNullOrEmpty(defaultLevel)
+ // WL-Changes-start: Alert Level Rework
+ && comp.AlertLevels.Levels.Count > 0)
+ defaultLevel = comp.AlertLevels.Levels.First();
+ else
+ continue;
+ // WL-Changes-end
SetLevel(uid, defaultLevel, true, true, true);
}
}
- RaiseLocalEvent(new AlertLevelPrototypeReloadedEvent());
+ RaiseLocalEvent(new AlertLevelsListPrototypeReloadedEvent()); // WL-Changes: Alert Level Rework
}
public string GetLevel(EntityUid station, AlertLevelComponent? alert = null)
@@ -116,13 +119,6 @@ public sealed class AlertLevelSystem : EntitySystem
return alert.CurrentDelay;
}
- //WL-Changes-start
- public string GetLevelLocString(string level)
- {
- return Loc.GetString($"alert-level-{level}");
- }
- //WL-Changes-end
-
///
/// Get the default alert level for a station entity.
/// Returns an empty string if the station has no alert levels defined.
@@ -151,15 +147,17 @@ public sealed class AlertLevelSystem : EntitySystem
{
if (!Resolve(station, ref component, ref dataComponent)
|| component.AlertLevels == null
- || !component.AlertLevels.Levels.TryGetValue(level, out var detail)
- || component.CurrentLevel == level)
- {
+ // WL-Changes: Alert Level Rework
+ || component.CurrentLevel == level
+ || !component.AlertLevels.Levels.Contains(level)
+ || !_prototypeManager.TryIndex(level, out var prototype)
+ || prototype == null)
return;
- }
+ // WL-Changes-end
if (!force)
{
- if (!detail.Selectable
+ if (!prototype.Selectable // WL-Changes: Alert Level Rework
|| component.CurrentDelay > 0
|| component.IsLevelLocked)
{
@@ -175,20 +173,22 @@ public sealed class AlertLevelSystem : EntitySystem
var stationName = dataComponent.EntityName;
- var name = level.ToLower();
+ // WL-Changes-start: Alert Level Rework
+ var name = level;
- if (Loc.TryGetString($"alert-level-{level}", out var locName))
- {
- name = locName.ToLower();
- }
+ if (Loc.TryGetString($"alert-level-{level.ToLower()}", out var locId))
+ name = locId.ToLower();
+ else if (!string.IsNullOrEmpty(prototype.SetName))
+ name = prototype.SetName.ToLower();
+ else
+ name = Loc.GetString("alert-level-unknown").ToLower();
// Announcement text. Is passed into announcementFull.
- var announcement = detail.Announcement;
+ var announcement = prototype.Announcement;
- if (Loc.TryGetString(detail.Announcement, out var locAnnouncement))
- {
+ if (Loc.TryGetString(prototype.Announcement, out var locAnnouncement))
announcement = locAnnouncement;
- }
+ // WL-Changes-end
// The full announcement to be spat out into chat.
var announcementFull = Loc.GetString("alert-level-announcement", ("name", name), ("announcement", announcement));
@@ -196,10 +196,10 @@ public sealed class AlertLevelSystem : EntitySystem
var playDefault = false;
if (playSound)
{
- if (detail.Sound != null)
+ if (prototype.Sound != null) // WL-Changes: Alert Level Rework
{
var filter = _stationSystem.GetInOwningStation(station);
- _audio.PlayGlobal(detail.Sound, filter, true, detail.Sound.Params);
+ _audio.PlayGlobal(prototype.Sound, filter, true, prototype.Sound.Params); // WL-Changes: Alert Level Rework
}
else
{
@@ -210,7 +210,7 @@ public sealed class AlertLevelSystem : EntitySystem
if (announce)
{
_chatSystem.DispatchStationAnnouncement(station, announcementFull, playDefaultSound: playDefault,
- colorOverride: detail.Color, sender: stationName);
+ colorOverride: prototype.Color, sender: stationName); // WL-Changes: Alert Level Rework
}
RaiseLocalEvent(new AlertLevelChangedEvent(station, level));
@@ -220,7 +220,7 @@ public sealed class AlertLevelSystem : EntitySystem
public sealed class AlertLevelDelayFinishedEvent : EntityEventArgs
{}
-public sealed class AlertLevelPrototypeReloadedEvent : EntityEventArgs
+public sealed class AlertLevelsListPrototypeReloadedEvent : EntityEventArgs // WL-Changes: Alert Level Rework
{}
public sealed class AlertLevelChangedEvent : EntityEventArgs
diff --git a/Content.Server/AlertLevel/Commands/SetAlertLevelCommand.cs b/Content.Server/AlertLevel/Commands/SetAlertLevelCommand.cs
index 2a8e02fadb..0e7a56ab6f 100644
--- a/Content.Server/AlertLevel/Commands/SetAlertLevelCommand.cs
+++ b/Content.Server/AlertLevel/Commands/SetAlertLevelCommand.cs
@@ -78,12 +78,12 @@ namespace Content.Server.AlertLevel.Commands
private string[] GetStationLevelNames(EntityUid station)
{
if (!EntityManager.TryGetComponent(station, out var alertLevelComp))
- return new string[]{};
+ return [];
if (alertLevelComp.AlertLevels == null)
- return new string[]{};
+ return [];
- return alertLevelComp.AlertLevels.Levels.Keys.ToArray();
+ return alertLevelComp.AlertLevels.Levels.Select(protoId => protoId.ToString()).ToArray(); // WL-Changes: Alert Level Rework
}
}
}
diff --git a/Content.Server/Communications/CommunicationsConsoleSystem.cs b/Content.Server/Communications/CommunicationsConsoleSystem.cs
index 7d381f79ef..8e19ddd796 100644
--- a/Content.Server/Communications/CommunicationsConsoleSystem.cs
+++ b/Content.Server/Communications/CommunicationsConsoleSystem.cs
@@ -19,6 +19,7 @@ using Content.Shared.IdentityManagement;
using Content.Shared.Popups;
using Robust.Server.GameObjects;
using Robust.Shared.Configuration;
+using Robust.Shared.Prototypes; // WL-Changes: Alert Level Rework
namespace Content.Server.Communications
{
@@ -35,6 +36,7 @@ namespace Content.Server.Communications
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
+ [Dependency] private readonly IPrototypeManager _prototypeManager = default!; // WL-Changes: Alert Level Rework
private const float UIUpdateInterval = 5.0f;
@@ -144,13 +146,16 @@ namespace Content.Server.Communications
if (alertComp.IsSelectable)
{
levels = new();
- foreach (var (id, detail) in alertComp.AlertLevels.Levels)
+ // WL-Changes-start: Alert Level Rework
+ foreach (var protoId in alertComp.AlertLevels.Levels) // (id, detail) -> protoId
{
- if (detail.Selectable)
+ if (_prototypeManager.TryIndex(protoId, out var prototype)
+ && prototype.Selectable)
{
- levels.Add(id);
+ levels.Add(prototype.ID); // id -> prototype.ID
}
}
+ // WL-Changes-end
}
currentLevel = alertComp.CurrentLevel;
diff --git a/Content.Server/Light/EntitySystems/EmergencyLightSystem.cs b/Content.Server/Light/EntitySystems/EmergencyLightSystem.cs
index 0aea245c79..c175459b4c 100644
--- a/Content.Server/Light/EntitySystems/EmergencyLightSystem.cs
+++ b/Content.Server/Light/EntitySystems/EmergencyLightSystem.cs
@@ -12,6 +12,7 @@ using Content.Shared.Power.Components;
using Content.Shared.Station.Components;
using Robust.Server.GameObjects;
using Color = Robust.Shared.Maths.Color;
+using Robust.Shared.Prototypes; // WL-Changes: Alert Level Rework
namespace Content.Server.Light.EntitySystems;
@@ -22,6 +23,7 @@ public sealed class EmergencyLightSystem : SharedEmergencyLightSystem
[Dependency] private readonly PointLightSystem _pointLight = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly StationSystem _station = default!;
+ [Dependency] private readonly IPrototypeManager _prototypeManager = default!; // WL-Changes: Alert Level Rework
public override void Initialize()
{
@@ -66,8 +68,9 @@ public sealed class EmergencyLightSystem : SharedEmergencyLightSystem
var name = alerts.CurrentLevel;
var color = Color.White;
- if (alerts.AlertLevels.Levels.TryGetValue(alerts.CurrentLevel, out var details))
- color = details.Color;
+ if (alerts.AlertLevels.Levels.TryGetValue(alerts.CurrentLevel, out var details)
+ && _prototypeManager.TryIndex(details, out var alertPrototype)) // WL-Changes: Alert Level Rework
+ color = alertPrototype.Color;
args.PushMarkup(
Loc.GetString("emergency-light-component-on-examine-alert",
@@ -98,7 +101,9 @@ public sealed class EmergencyLightSystem : SharedEmergencyLightSystem
if (!TryComp(ev.Station, out var alert))
return;
- if (alert.AlertLevels == null || !alert.AlertLevels.Levels.TryGetValue(ev.AlertLevel, out var details))
+ if (alert.AlertLevels == null
+ || !alert.AlertLevels.Levels.TryGetValue(ev.AlertLevel, out var details)
+ || !_prototypeManager.TryIndex(details, out var alertPrototype)) // WL-Changes: Alert Level Rework
return;
var query = EntityQueryEnumerator();
@@ -107,15 +112,17 @@ public sealed class EmergencyLightSystem : SharedEmergencyLightSystem
if (CompOrNull(xform.GridUid)?.Station != ev.Station)
continue;
- _pointLight.SetColor(uid, details.EmergencyLightColor, pointLight);
- _appearance.SetData(uid, EmergencyLightVisuals.Color, details.EmergencyLightColor, appearance);
+ // WL-Changes-start: Alert Level Rework // details -> alertPrototype
+ _pointLight.SetColor(uid, alertPrototype.EmergencyLightColor, pointLight);
+ _appearance.SetData(uid, EmergencyLightVisuals.Color, alertPrototype.EmergencyLightColor, appearance);
- if (details.ForceEnableEmergencyLights && !light.ForciblyEnabled)
+ if (alertPrototype.ForceEnableEmergencyLights && !light.ForciblyEnabled)
{
light.ForciblyEnabled = true;
TurnOn((uid, light));
}
- else if (!details.ForceEnableEmergencyLights && light.ForciblyEnabled)
+ else if (!alertPrototype.ForceEnableEmergencyLights && light.ForciblyEnabled)
+ // WL-Changes-end
{
// Previously forcibly enabled, and we went down an alert level.
light.ForciblyEnabled = false;
@@ -177,7 +184,9 @@ public sealed class EmergencyLightSystem : SharedEmergencyLightSystem
if (!TryComp(_station.GetOwningStation(entity.Owner), out var alerts))
return;
- if (alerts.AlertLevels == null || !alerts.AlertLevels.Levels.TryGetValue(alerts.CurrentLevel, out var details))
+ if (alerts.AlertLevels == null
+ || !alerts.AlertLevels.Levels.TryGetValue(alerts.CurrentLevel, out var details)
+ || !_prototypeManager.TryIndex(details, out var alertPrototype)) // WL-Changes: Alert Level Rework
{
TurnOff(entity, Color.Red); // if no alert, default to off red state
return;
@@ -186,7 +195,7 @@ public sealed class EmergencyLightSystem : SharedEmergencyLightSystem
if (receiver.Powered && !entity.Comp.ForciblyEnabled) // Green alert
{
receiver.Load = (int) Math.Abs(entity.Comp.Wattage);
- TurnOff(entity, details.Color);
+ TurnOff(entity, alertPrototype.Color); // WL-Changes: Alert Level Rework // details -> alertPrototype
SetState(entity.Owner, entity.Comp, EmergencyLightState.Charging);
}
else if (!receiver.Powered) // If internal battery runs out it will end in off red state
@@ -196,7 +205,7 @@ public sealed class EmergencyLightSystem : SharedEmergencyLightSystem
}
else // Powered and enabled
{
- TurnOn(entity, details.Color);
+ TurnOn(entity, alertPrototype.Color); // WL-Changes: Alert Level Rework // details -> alertPrototype
SetState(entity.Owner, entity.Comp, EmergencyLightState.On);
}
}
diff --git a/Content.Server/PDA/PdaSystem.cs b/Content.Server/PDA/PdaSystem.cs
index 8fad21075f..3f4de4c071 100644
--- a/Content.Server/PDA/PdaSystem.cs
+++ b/Content.Server/PDA/PdaSystem.cs
@@ -21,6 +21,7 @@ using Robust.Server.Containers;
using Robust.Server.GameObjects;
using Robust.Shared.Containers;
using Robust.Shared.Player;
+using Robust.Shared.Prototypes; // WL-Changes: Alert Level Rework
using Robust.Shared.Utility;
namespace Content.Server.PDA
@@ -37,6 +38,7 @@ namespace Content.Server.PDA
[Dependency] private readonly UnpoweredFlashlightSystem _unpoweredFlashlight = default!;
[Dependency] private readonly ContainerSystem _containerSystem = default!;
[Dependency] private readonly IdCardSystem _idCard = default!;
+ [Dependency] private readonly IPrototypeManager _prototypeManager = default!; // WL-Changes: Alert Level Rework
public override void Initialize()
{
@@ -213,7 +215,8 @@ namespace Content.Server.PDA
JobTitle = id?.LocalizedJobTitle,
StationAlertLevel = pda.StationAlertLevel,
StationAlertColor = pda.StationAlertColor,
- StationAlertInstructions = pda.StationAlertInstructions // WL-Changes: custom alert instructions in PDA
+ StationAlertInstructions = pda.StationAlertInstructions, // WL-Changes: custom alert instructions in PDA
+ StationAlertName = pda.StationAlertName // WL-Changes: Alert Level Rework
},
pda.StationName,
showUplink,
@@ -309,10 +312,14 @@ namespace Content.Server.PDA
pda.StationAlertLevel = alertComp.CurrentLevel;
if (alertComp.AlertLevels.Levels.TryGetValue(alertComp.CurrentLevel, out var details))
{
- // WL-Changes-start: custom alert instructions in PDA
- pda.StationAlertColor = details.Color;
- if (details != null)
- pda.StationAlertInstructions = details.AlertLevelInstruction;
+ // WL-Changes-start: Alert Level Rework
+ if (_prototypeManager.TryIndex(details, out var index))
+ {
+ pda.StationAlertColor = index.Color;
+ pda.StationAlertInstructions = index.Instruction;
+ if (!string.IsNullOrEmpty(index.SetName))
+ pda.StationAlertName = index.SetName;
+ }
// WL-Changes-end
}
}
diff --git a/Content.Server/RoundEnd/RoundEndSystem.cs b/Content.Server/RoundEnd/RoundEndSystem.cs
index cb01a62836..05b72f9ba2 100644
--- a/Content.Server/RoundEnd/RoundEndSystem.cs
+++ b/Content.Server/RoundEnd/RoundEndSystem.cs
@@ -10,6 +10,7 @@ using Content.Server.Screens.Components;
using Content.Server.Shuttles.Components;
using Content.Server.Shuttles.Systems;
using Content.Server.Station.Systems;
+using Content.Shared.AlertLevel; // WL-Changes: Alert Level Rework
using Content.Shared.Database;
using Content.Shared.DeviceNetwork;
using Content.Shared.GameTicking;
@@ -135,8 +136,10 @@ namespace Content.Server.RoundEnd
if (TryComp(stationUid, out var alertLevel))
{
duration = _protoManager
- .Index(AlertLevelSystem.DefaultAlertLevelSet)
- .Levels[alertLevel.CurrentLevel].ShuttleTime;
+ // WL-Changes-start: Alert Level Rework
+ .Index(alertLevel.CurrentLevel)
+ .ShuttleTime;
+ // WL-Changes-end
}
}
diff --git a/Content.Shared/AlertLevel/AlertLevelPrototype.cs b/Content.Shared/AlertLevel/AlertLevelPrototype.cs
new file mode 100644
index 0000000000..c1dcf5c0c5
--- /dev/null
+++ b/Content.Shared/AlertLevel/AlertLevelPrototype.cs
@@ -0,0 +1,83 @@
+// WL-Changes-start: Alert Level Rework
+using Robust.Shared.Audio;
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared.AlertLevel;
+
+[Prototype("alertLevelsList")]
+public sealed class AlertLevelsListPrototype : IPrototype
+{
+ [IdDataField] public string ID { get; private set; } = default!;
+
+ ///
+ /// Set of allowed alert levels.
+ ///
+ [DataField] public HashSet> Levels = new();
+
+ ///
+ /// Default level that the station is on upon initialization.
+ /// If this isn't in the hashSet, this will default to whatever .First() gives.
+ ///
+ [DataField] public string DefaultLevel { get; private set; } = default!;
+}
+
+///
+/// Alert level detail.
+///
+[Prototype("alertLevel")]
+public sealed class AlertLevelPrototype : IPrototype
+{
+ [IdDataField] public string ID { get; private set; } = default!;
+
+ [DataField("name")] public string? SetName { get; private set; }
+ ///
+ /// What is announced upon this alert level change. Can be a localized string.
+ ///
+ [DataField] public string Announcement { get; private set; } = string.Empty;
+
+ // WL-Changes-start: custom alert instructions in PDA
+ ///
+ /// Instruction of alert level in pda
+ ///
+ [DataField] public string Instruction { get; private set; } = string.Empty;
+ // WL-Changes-end
+
+ ///
+ /// Whether this alert level is selectable from a communications console.
+ ///
+ [DataField] public bool Selectable { get; private set; } = true;
+
+ ///
+ /// If this alert level disables user selection while it is active. Beware -
+ /// setting this while something is selectable will disable selection permanently!
+ /// This should only apply to entities or gamemodes that auto-select an alert level,
+ /// such as a nuclear bomb being set to active.
+ ///
+ [DataField] public bool DisableSelection { get; private set; }
+
+ ///
+ /// The sound that this alert level will play in-game once selected.
+ ///
+ [DataField] public SoundSpecifier? Sound { get; private set; }
+
+ ///
+ /// The color that this alert level will show in-game in chat.
+ ///
+ [DataField] public Color Color { get; private set; } = Color.White;
+
+ ///
+ /// The color to turn emergency lights on this station when they are active.
+ ///
+ [DataField] public Color EmergencyLightColor { get; private set; } = Color.FromHex("#FF4020");
+
+ ///
+ /// Will this alert level force emergency lights on for the station that's active?
+ ///
+ [DataField] public bool ForceEnableEmergencyLights { get; private set; } = false;
+
+ ///
+ /// How long it takes for the shuttle to arrive when called.
+ ///
+ [DataField] public TimeSpan ShuttleTime { get; private set; } = TimeSpan.FromMinutes(5);
+}
+// WL-Changes-end
diff --git a/Content.Shared/PDA/PdaComponent.cs b/Content.Shared/PDA/PdaComponent.cs
index 2864b0e6b2..c3907d4d98 100644
--- a/Content.Shared/PDA/PdaComponent.cs
+++ b/Content.Shared/PDA/PdaComponent.cs
@@ -39,5 +39,6 @@ namespace Content.Shared.PDA
[ViewVariables] public string? StationAlertLevel;
[ViewVariables] public Color StationAlertColor = Color.White;
[ViewVariables] public string? StationAlertInstructions; // WL-Changes: custom alert instructions in PDA
+ [ViewVariables] public string? StationAlertName; // WL-Changes: Alert Level Rework
}
}
diff --git a/Content.Shared/PDA/PdaUpdateState.cs b/Content.Shared/PDA/PdaUpdateState.cs
index 352364578b..c807fb03e5 100644
--- a/Content.Shared/PDA/PdaUpdateState.cs
+++ b/Content.Shared/PDA/PdaUpdateState.cs
@@ -50,5 +50,6 @@ namespace Content.Shared.PDA
public string? StationAlertLevel;
public Color StationAlertColor;
public string? StationAlertInstructions; // WL-Changes: custom alert instructions in PDA
+ public string? StationAlertName; // WL-Changes: Alert Level Rework
}
}
diff --git a/Resources/Prototypes/AlertLevels/alert_levels.yml b/Resources/Prototypes/AlertLevels/alert_levels.yml
index 3d49a165a8..76ed844c4b 100644
--- a/Resources/Prototypes/AlertLevels/alert_levels.yml
+++ b/Resources/Prototypes/AlertLevels/alert_levels.yml
@@ -1,73 +1,99 @@
-- type: alertLevels
+# WL-Changes-start: Alert Level Rework
+- type: alertLevelsList
id: stationAlerts
- defaultLevel: green
+ defaultLevel: Green
levels:
- green:
- announcement: alert-level-green-announcement
- sound: /Audio/Corvax/Misc/green_down.ogg # Corvax-Announcements
- color: Green
- emergencyLightColor: LawnGreen
- shuttleTime: 600
- blue:
- announcement: alert-level-blue-announcement
- sound: /Audio/Corvax/Misc/blue.ogg # Corvax-Announcements #base:/Audio/Misc/bluealert.ogg
- color: DodgerBlue
- forceEnableEmergencyLights: true
- emergencyLightColor: DodgerBlue
- shuttleTime: 600
- violet:
- announcement: alert-level-violet-announcement
- sound: /Audio/Misc/notice1.ogg
- color: Violet
- emergencyLightColor: Violet
- forceEnableEmergencyLights: true
- shuttleTime: 600
- yellow:
- announcement: alert-level-yellow-announcement
- sound: /Audio/Misc/notice1.ogg
- color: Yellow
- emergencyLightColor: Goldenrod
- forceEnableEmergencyLights: true
- shuttleTime: 600
- red:
- announcement: alert-level-red-announcement
- sound: /Audio/Corvax/Misc/red.ogg # Corvax-Announcements #base:/Audio/Misc/redalert.ogg
- color: Red
- emergencyLightColor: Red
- forceEnableEmergencyLights: true
- shuttleTime: 600 #No reduction in time as we don't have swiping for red alert like in /tg/. Shuttle times are intended to create friction, so having a way to brainlessly bypass that would be dumb.
- gamma:
- announcement: alert-level-gamma-announcement
- selectable: false
- sound:
- path: /Audio/Corvax/Misc/siren.ogg # Corvax: Return of the old siren sound
- params:
- volume: -2
- disableSelection: true
- color: PaleVioletRed
- emergencyLightColor: PaleVioletRed
- forceEnableEmergencyLights: true
- delta:
- announcement: alert-level-delta-announcement
- selectable: false
- sound:
- path: /Audio/Corvax/Misc/delta.ogg # Corvax-Announcements #base:/Audio/Misc/delta.ogg
- params:
- volume: -6 # Corvax: Reduce sound volume
- disableSelection: true
- color: DarkRed
- emergencyLightColor: Orange
- forceEnableEmergencyLights: true
- shuttleTime: 1200
- epsilon:
- announcement: alert-level-epsilon-announcement
- selectable: false
- sound:
- path: /Audio/Misc/epsilon.ogg
- params:
- volume: -2
- disableSelection: true
- color: DarkViolet
- emergencyLightColor: DarkViolet
- forceEnableEmergencyLights: true
- shuttleTime: 1200
+ - Green
+ - Blue
+ - Violet
+ - Yellow
+ - Red
+ - Gamma
+ - Delta
+ - Epsilon
+
+- type: alertLevel
+ id: Green
+ announcement: alert-level-green-announcement
+ sound: /Audio/Corvax/Misc/green_down.ogg # Corvax-Announcements
+ color: Green
+ emergencyLightColor: LawnGreen
+ shuttleTime: 600
+
+- type: alertLevel
+ id: Blue
+ announcement: alert-level-blue-announcement
+ sound: /Audio/Corvax/Misc/blue.ogg # Corvax-Announcements #base:/Audio/Misc/bluealert.ogg
+ color: DodgerBlue
+ forceEnableEmergencyLights: true
+ emergencyLightColor: DodgerBlue
+ shuttleTime: 600
+
+- type: alertLevel
+ id: Violet
+ announcement: alert-level-violet-announcement
+ sound: /Audio/Misc/notice1.ogg
+ color: Violet
+ emergencyLightColor: Violet
+ forceEnableEmergencyLights: true
+ shuttleTime: 600
+
+- type: alertLevel
+ id: Yellow
+ announcement: alert-level-yellow-announcement
+ sound: /Audio/Misc/notice1.ogg
+ color: Yellow
+ emergencyLightColor: Goldenrod
+ forceEnableEmergencyLights: true
+ shuttleTime: 600
+
+- type: alertLevel
+ id: Red
+ announcement: alert-level-red-announcement
+ sound: /Audio/Corvax/Misc/red.ogg # Corvax-Announcements #base:/Audio/Misc/redalert.ogg
+ color: Red
+ emergencyLightColor: Red
+ forceEnableEmergencyLights: true
+ shuttleTime: 600 #No reduction in time as we don't have swiping for red alert like in /tg/. Shuttle times are intended to create friction, so having a way to brainlessly bypass that would be dumb.
+
+- type: alertLevel
+ id: Gamma
+ announcement: alert-level-gamma-announcement
+ selectable: false
+ sound:
+ path: /Audio/Corvax/Misc/siren.ogg # Corvax: Return of the old siren sound
+ params:
+ volume: -2
+ disableSelection: true
+ color: PaleVioletRed
+ emergencyLightColor: PaleVioletRed
+ forceEnableEmergencyLights: true
+
+- type: alertLevel
+ id: Delta
+ announcement: alert-level-delta-announcement
+ selectable: false
+ sound:
+ path: /Audio/Corvax/Misc/delta.ogg # Corvax-Announcements #base:/Audio/Misc/delta.ogg
+ params:
+ volume: -6 # Corvax: Reduce sound volume
+ disableSelection: true
+ color: DarkRed
+ emergencyLightColor: Orange
+ forceEnableEmergencyLights: true
+ shuttleTime: 1200
+
+- type: alertLevel
+ id: Epsilon
+ announcement: alert-level-epsilon-announcement
+ selectable: false
+ sound:
+ path: /Audio/Misc/epsilon.ogg
+ params:
+ volume: -2
+ disableSelection: true
+ color: DarkViolet
+ emergencyLightColor: DarkViolet
+ forceEnableEmergencyLights: true
+ shuttleTime: 1200
+# WL-Changes-end
diff --git a/Resources/Prototypes/Entities/Stations/base.yml b/Resources/Prototypes/Entities/Stations/base.yml
index ae3bf6e288..6cca0ca843 100644
--- a/Resources/Prototypes/Entities/Stations/base.yml
+++ b/Resources/Prototypes/Entities/Stations/base.yml
@@ -140,7 +140,7 @@
abstract: true
components:
- type: AlertLevel
- alertLevelPrototype: stationAlerts
+ alertLevelsListPrototype: stationAlerts # WL-Changes: Alert Level Rework
- type: entity
id: BaseStationExpeditions