diff --git a/Content.Client/Atmos/Consoles/AtmosAlertsComputerBoundUserInterface.cs b/Content.Client/Atmos/Consoles/AtmosAlertsComputerBoundUserInterface.cs index 6f0e7f80da1..afe4cb43c0e 100644 --- a/Content.Client/Atmos/Consoles/AtmosAlertsComputerBoundUserInterface.cs +++ b/Content.Client/Atmos/Consoles/AtmosAlertsComputerBoundUserInterface.cs @@ -1,4 +1,6 @@ using Content.Shared.Atmos.Components; +using Content.Shared.Shuttles.Events; // Frontier +using Content.Shared._NF.Atmos.BUI; // Frontier namespace Content.Client.Atmos.Consoles; @@ -23,7 +25,7 @@ protected override void UpdateState(BoundUserInterfaceState state) var castState = (AtmosAlertsComputerBoundInterfaceState) state; EntMan.TryGetComponent(Owner, out var xform); - _menu?.UpdateUI(xform?.Coordinates, castState.AirAlarms, castState.FireAlarms, castState.FocusData); + _menu?.UpdateUI(xform?.Coordinates, castState.AirAlarms, castState.FireAlarms, castState.FocusData, castState.Gaslocks, castState.FocusGaslockData); // Frontier: add gaslocks, focusGaslockData } public void SendFocusChangeMessage(NetEntity? netEntity) @@ -36,6 +38,28 @@ public void SendDeviceSilencedMessage(NetEntity netEntity, bool silenceDevice) SendMessage(new AtmosAlertsComputerDeviceSilencedMessage(netEntity, silenceDevice)); } + // Frontier: gaslock message + public void SendGaslockChangeDirectionMessage(NetEntity netEntity, bool direction) + { + SendMessage(new RemoteGasPressurePumpChangePumpDirectionMessage(netEntity, direction)); + } + + public void SendGaslockPressureChangeMessage(NetEntity netEntity, float pressure) + { + SendMessage(new RemoteGasPressurePumpChangeOutputPressureMessage(netEntity, pressure)); + } + + public void SendGaslockChangeEnabled(NetEntity netEntity, bool enabled) + { + SendMessage(new RemoteGasPressurePumpToggleStatusMessage(netEntity, enabled)); + } + + public void SendGaslockUndock(NetEntity netEntity) + { + SendMessage(new UndockRequestMessage { DockEntity = netEntity }); + } + // End Frontier + protected override void Dispose(bool disposing) { base.Dispose(disposing); diff --git a/Content.Client/Atmos/Consoles/AtmosAlertsComputerWindow.xaml b/Content.Client/Atmos/Consoles/AtmosAlertsComputerWindow.xaml index e5ede1b92e3..13ea770a67c 100644 --- a/Content.Client/Atmos/Consoles/AtmosAlertsComputerWindow.xaml +++ b/Content.Client/Atmos/Consoles/AtmosAlertsComputerWindow.xaml @@ -76,6 +76,11 @@ + + + + + diff --git a/Content.Client/Atmos/Consoles/AtmosAlertsComputerWindow.xaml.cs b/Content.Client/Atmos/Consoles/AtmosAlertsComputerWindow.xaml.cs index 81c9a409a3b..57ad482e02f 100644 --- a/Content.Client/Atmos/Consoles/AtmosAlertsComputerWindow.xaml.cs +++ b/Content.Client/Atmos/Consoles/AtmosAlertsComputerWindow.xaml.cs @@ -15,6 +15,7 @@ using Robust.Shared.Utility; using System.Diagnostics.CodeAnalysis; using System.Linq; +using Content.Client._NF.Atmos.Consoles; // Frontier namespace Content.Client.Atmos.Consoles; @@ -30,6 +31,7 @@ public sealed partial class AtmosAlertsComputerWindow : FancyWindow private AtmosAlertsComputerEntry[]? _airAlarms = null; private AtmosAlertsComputerEntry[]? _fireAlarms = null; + private AtmosAlertsComputerEntry[]? _gaslocks = null; // Frontier private IEnumerable? _allAlarms = null; private IEnumerable? _activeAlarms = null; @@ -38,6 +40,13 @@ public sealed partial class AtmosAlertsComputerWindow : FancyWindow public event Action? SendFocusChangeMessageAction; public event Action? SendDeviceSilencedMessageAction; + // Frontier: gaslock actions + public event Action? SendGaslockChangeDirectionMessageAction; + public event Action? SendGaslockPressureChangeMessageAction; + public event Action? SendGaslockChangeEnabledAction; + public event Action? SendGaslockUndockAction; + // End Frontier: gaslock actions + private bool _autoScrollActive = false; private bool _autoScrollAwaitsUpdate = false; @@ -77,7 +86,7 @@ public AtmosAlertsComputerWindow(AtmosAlertsComputerBoundUserInterface userInter { NavMap.MapUid = xform.GridUid; - // Assign station name + // Assign station name if (_entManager.TryGetComponent(xform.GridUid, out var stationMetaData)) stationName = stationMetaData.EntityName; @@ -103,6 +112,7 @@ public AtmosAlertsComputerWindow(AtmosAlertsComputerBoundUserInterface userInter MasterTabContainer.SetTabTitle(0, Loc.GetString("atmos-alerts-window-tab-no-alerts")); MasterTabContainer.SetTabTitle(1, Loc.GetString("atmos-alerts-window-tab-air-alarms")); MasterTabContainer.SetTabTitle(2, Loc.GetString("atmos-alerts-window-tab-fire-alarms")); + MasterTabContainer.SetTabTitle(3, Loc.GetString("atmos-alerts-window-tab-gaslocks")); // Frontier // Set UI toggles ShowInactiveAlarms.OnToggled += _ => OnShowAlarmsToggled(ShowInactiveAlarms, AtmosAlarmType.Invalid); @@ -113,6 +123,12 @@ public AtmosAlertsComputerWindow(AtmosAlertsComputerBoundUserInterface userInter // Set atmos monitoring message action SendFocusChangeMessageAction += userInterface.SendFocusChangeMessage; SendDeviceSilencedMessageAction += userInterface.SendDeviceSilencedMessage; + + // Frontier: set gaslock message actions + SendGaslockChangeDirectionMessageAction += userInterface.SendGaslockChangeDirectionMessage; + SendGaslockPressureChangeMessageAction += userInterface.SendGaslockPressureChangeMessage; + SendGaslockChangeEnabledAction += userInterface.SendGaslockChangeEnabled; + SendGaslockUndockAction += userInterface.SendGaslockUndock; } #region Toggle handling @@ -162,7 +178,7 @@ private void OnSilenceAlertsToggled(NetEntity netEntity, bool toggleState) #endregion - public void UpdateUI(EntityCoordinates? consoleCoords, AtmosAlertsComputerEntry[] airAlarms, AtmosAlertsComputerEntry[] fireAlarms, AtmosAlertsFocusDeviceData? focusData) + public void UpdateUI(EntityCoordinates? consoleCoords, AtmosAlertsComputerEntry[] airAlarms, AtmosAlertsComputerEntry[] fireAlarms, AtmosAlertsFocusDeviceData? focusData, AtmosAlertsComputerEntry[] gaslocks, AtmosAlertsFocusGaslockData? focusGaslockData) // Frontier: add gaslocks, gaslock data { if (_owner == null) return; @@ -179,7 +195,9 @@ public void UpdateUI(EntityCoordinates? consoleCoords, AtmosAlertsComputerEntry[ // Retain alarm data for use inbetween updates _airAlarms = airAlarms; _fireAlarms = fireAlarms; + _gaslocks = gaslocks; // Frontier _allAlarms = airAlarms.Concat(fireAlarms); + _allAlarms = airAlarms.Concat(gaslocks); // Frontier var silenced = console.SilencedDevices; @@ -245,6 +263,11 @@ public void UpdateUI(EntityCoordinates? consoleCoords, AtmosAlertsComputerEntry[ while (FireAlarmsTable.ChildCount > fireAlarms.Length) FireAlarmsTable.RemoveChild(FireAlarmsTable.GetChild(FireAlarmsTable.ChildCount - 1)); + // Frontier: gaslocks + while (GaslocksTable.ChildCount > gaslocks.Length) + GaslocksTable.RemoveChild(GaslocksTable.GetChild(GaslocksTable.ChildCount - 1)); + // End Frontier + // Update all entries in each table for (int index = 0; index < _activeAlarms.Count(); index++) { @@ -264,6 +287,14 @@ public void UpdateUI(EntityCoordinates? consoleCoords, AtmosAlertsComputerEntry[ UpdateUIEntry(entry, index, FireAlarmsTable, console, focusData); } + // Frontier: gaslocks + for (int index = 0; index < gaslocks.Count(); index++) + { + var entry = gaslocks.ElementAt(index); + UpdateGaslockUIEntry(entry, index, GaslocksTable, console, focusGaslockData); + } + // End Frontier + // If no alerts are active, display a message if (MasterTabContainer.CurrentTab == 0 && activeAlarmCount == 0) { @@ -391,6 +422,7 @@ private void UpdateUIEntry(AtmosAlertsComputerEntry entry, int index, Control ta UpdateConsoleTable(console, AlertsTable, _trackedEntity); UpdateConsoleTable(console, AirAlarmsTable, _trackedEntity); UpdateConsoleTable(console, FireAlarmsTable, _trackedEntity); + UpdateConsoleTable(console, GaslocksTable, _trackedEntity); // Frontier }; // On toggling the silence check box @@ -424,20 +456,92 @@ private void UpdateUIEntry(AtmosAlertsComputerEntry entry, int index, Control ta entryContainer.SilenceAlarmProgressBar.Visible = (table == AlertsTable && _deviceSilencingProgress.ContainsKey(entry.NetEntity)); } + // Frontier: separate UpdateUI function for gaslocks + private void UpdateGaslockUIEntry(AtmosAlertsComputerEntry entry, int index, Control table, AtmosAlertsComputerComponent console, AtmosAlertsFocusGaslockData? focusData = null) + { + // Make new UI entry if required + if (index >= table.ChildCount) + { + var newEntryContainer = new AtmosAlarmGaslockEntryContainer(entry.NetEntity, _entManager.GetCoordinates(entry.Coordinates)); + + newEntryContainer.SendChangeDirectionMessageAction += SendGaslockChangeDirectionMessageAction; + newEntryContainer.SendPressureChangeAction += SendGaslockPressureChangeMessageAction; + newEntryContainer.SendChangeEnabledAction += SendGaslockChangeEnabledAction; + newEntryContainer.SendUndockAction += SendGaslockUndockAction; + + // On click + newEntryContainer.FocusButton.OnButtonUp += args => + { + if (_trackedEntity == newEntryContainer.NetEntity) + { + _trackedEntity = null; + } + + else + { + _trackedEntity = newEntryContainer.NetEntity; + + if (newEntryContainer.Coordinates != null) + NavMap.CenterToCoordinates(newEntryContainer.Coordinates.Value); + } + + // Send message to console that the focus has changed + SendFocusChangeMessageAction?.Invoke(_trackedEntity); + + // Update affected UI elements across all tables + UpdateConsoleTable(console, AlertsTable, _trackedEntity); + UpdateConsoleTable(console, AirAlarmsTable, _trackedEntity); + UpdateConsoleTable(console, FireAlarmsTable, _trackedEntity); + UpdateConsoleTable(console, GaslocksTable, _trackedEntity); // Frontier + }; + + // Add the entry to the current table + table.AddChild(newEntryContainer); + } + + // Update values and UI elements + var tableChild = table.GetChild(index); + + if (tableChild is not AtmosAlarmGaslockEntryContainer) + { + table.RemoveChild(tableChild); + UpdateGaslockUIEntry(entry, index, table, console, focusData); + + return; + } + + var entryContainer = (AtmosAlarmGaslockEntryContainer)tableChild; + + entryContainer.UpdateEntry(entry, entry.NetEntity == _trackedEntity, focusData); + } + // End Frontier: separate UpdateUI function for gaslocks + private void UpdateConsoleTable(AtmosAlertsComputerComponent console, Control table, NetEntity? currTrackedEntity) { foreach (var tableChild in table.Children) { - if (tableChild is not AtmosAlarmEntryContainer) - continue; + // Frontier: multiple type checks + if (tableChild is AtmosAlarmEntryContainer) + { + var entryContainer = (AtmosAlarmEntryContainer)tableChild; - var entryContainer = (AtmosAlarmEntryContainer)tableChild; + if (entryContainer.NetEntity != currTrackedEntity) + entryContainer.RemoveAsFocus(); - if (entryContainer.NetEntity != currTrackedEntity) - entryContainer.RemoveAsFocus(); + else if (entryContainer.NetEntity == currTrackedEntity) + entryContainer.SetAsFocus(); + } + else if (tableChild is AtmosAlarmGaslockEntryContainer) + { + var entryContainer = (AtmosAlarmGaslockEntryContainer)tableChild; - else if (entryContainer.NetEntity == currTrackedEntity) - entryContainer.SetAsFocus(); + if (entryContainer.NetEntity != currTrackedEntity) + entryContainer.RemoveAsFocus(); + + else if (entryContainer.NetEntity == currTrackedEntity) + entryContainer.SetAsFocus(); + } + // End Frontier } } @@ -464,6 +568,8 @@ private void SetTrackedEntityFromNavMap(NetEntity? netEntity) MasterTabContainer.CurrentTab = 1; break; case AtmosAlertsComputerGroup.FireAlarm: MasterTabContainer.CurrentTab = 2; break; + case AtmosAlertsComputerGroup.Gaslock: // Frontier + MasterTabContainer.CurrentTab = 3; break; // Frontier } } @@ -565,12 +671,15 @@ private bool TryGetNextScrollPosition([NotNullWhen(true)] out float? nextScrollP foreach (var control in container.Children) { - if (control == null || control is not AtmosAlarmEntryContainer) + if (control == null) // Frontier: move type checks down continue; - if (((AtmosAlarmEntryContainer)control).NetEntity == _trackedEntity) + if (control is AtmosAlarmEntryContainer && ((AtmosAlarmEntryContainer)control).NetEntity == _trackedEntity) // Frontier: add type check return true; + if (control is AtmosAlarmGaslockEntryContainer && ((AtmosAlarmGaslockEntryContainer)control).NetEntity == _trackedEntity) // Frontier + return true; // Frontier + nextScrollPosition += control.Height; } diff --git a/Content.Client/Entry/EntryPoint.cs b/Content.Client/Entry/EntryPoint.cs index dbc3af3b809..99c6bd5ccbf 100644 --- a/Content.Client/Entry/EntryPoint.cs +++ b/Content.Client/Entry/EntryPoint.cs @@ -123,6 +123,7 @@ public override void Init() _prototypeManager.RegisterIgnore("alertLevels"); _prototypeManager.RegisterIgnore("nukeopsRole"); _prototypeManager.RegisterIgnore("ghostRoleRaffleDecider"); + _prototypeManager.RegisterIgnore("gasDeposit"); // Frontier _prototypeManager.RegisterIgnore("pointOfInterest"); // Frontier: worldgen-related, server-only _componentFactory.GenerateNetIds(); diff --git a/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs index 0121b5202e8..94c0db821d9 100644 --- a/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs +++ b/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs @@ -133,6 +133,9 @@ protected override void Draw(DrawingHandleScreen handle) var canDockChange = _timing.CurTime > _nextDockChange; var lineOffset = (float) _timing.RealTime.TotalSeconds * 30f; + var viewedDockType = _viewedState?.DockType ?? DockType.None; // Frontier: cache dock type + var viewedReceiveOnly = _viewedState?.ReceiveOnly ?? true; // Frontier: cache receive only + foreach (var grid in _grids) { EntManager.TryGetComponent(grid.Owner, out IFFComponent? iffComp); @@ -214,11 +217,13 @@ protected override void Draw(DrawingHandleScreen handle) if (HighlightedDock == dock.Entity) { - otherDockColor = Color.ToSrgb(Color.Magenta); + //otherDockColor = Color.ToSrgb(Color.Magenta); // Frontier + otherDockColor = Color.ToSrgb(dock.HighlightedRadarColor); // Frontier } else { - otherDockColor = Color.ToSrgb(Color.Purple); + // otherDockColor = Color.ToSrgb(Color.Purple); // Frontier + otherDockColor = Color.ToSrgb(dock.RadarColor); // Frontier } /* @@ -236,6 +241,7 @@ protected override void Draw(DrawingHandleScreen handle) if (dockButton != null && dock.GridDockedWith != null) { dockButton.Disabled = !canDockChange; + dockButton.Visible = true; // Frontier: undock should always be visible. } // If the dock is in range then also do highlighting @@ -265,18 +271,25 @@ protected override void Draw(DrawingHandleScreen handle) var canDock = distanceSq < maxDockDistSq && inAlignment; if (dockButton != null) + { dockButton.Disabled = !canDock && dock.GridDockedWith == null || !canDockChange; // Frontier: add "&& dock.GridDockedWith == null" + dockButton.Visible = dock.GridDockedWith != null || (dock.DockType & viewedDockType) != DockType.None && !viewedReceiveOnly; // Frontier: do not enable docking for receive-only docks + } var lineColor = inAlignment ? Color.Lime : Color.Red; handle.DrawDottedLine(viewedDockPos.Value, collisionCenter, lineColor, offset: lineOffset); } + else if (dockButton != null) + { + dockButton.Visible = dock.GridDockedWith != null; // Frontier: do not enable docking for receive-only docks + } canDraw = true; } - else + else if (dockButton != null) { - if (dockButton != null) - dockButton.Disabled = true; + dockButton.Disabled = true; + dockButton.Visible = dock.GridDockedWith != null || (dock.DockType & viewedDockType) != DockType.None && !viewedReceiveOnly; // Frontier } } @@ -312,7 +325,7 @@ protected override void Draw(DrawingHandleScreen handle) ScalePosition(Vector2.Transform(new Vector2(-0.5f, 0.5f), rotation)), ScalePosition(Vector2.Transform(new Vector2(0.5f, -0.5f), rotation))); - var dockColor = Color.Magenta; + var dockColor = _viewedState?.HighlightedRadarColor ?? Color.Magenta; // Frontier - use ViewedState var connectionColor = Color.Pink; handle.DrawRect(ourDockConnection, connectionColor.WithAlpha(0.2f)); diff --git a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs index 8518c6afc34..f28bab55f46 100644 --- a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs +++ b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs @@ -387,7 +387,8 @@ private void DrawDocks(DrawingHandleScreen handle, EntityUid uid, Matrix3x2 grid continue; } - var color = Color.ToSrgb(Color.Magenta); + //var color = Color.ToSrgb(Color.Magenta); // Frontier + var color = Color.ToSrgb(state.HighlightedRadarColor); // Frontier var verts = new[] { diff --git a/Content.Client/_NF/Atmos/BUI/GasSaleConsoleBoundUserInterface.cs b/Content.Client/_NF/Atmos/BUI/GasSaleConsoleBoundUserInterface.cs new file mode 100644 index 00000000000..f50ab1059ae --- /dev/null +++ b/Content.Client/_NF/Atmos/BUI/GasSaleConsoleBoundUserInterface.cs @@ -0,0 +1,46 @@ +using Content.Client._NF.Atmos.UI; +using Content.Shared._NF.Atmos.BUI; +using Content.Shared._NF.Atmos.Events; +using Robust.Client.UserInterface; + +namespace Content.Client._NF.Atmos.BUI; + +public sealed class GasSaleConsoleBoundUserInterface : BoundUserInterface +{ + [ViewVariables] + private GasSaleMenu? _menu; + + public GasSaleConsoleBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) + { + } + + protected override void Open() + { + base.Open(); + + _menu = this.CreateWindow(); + _menu.RefreshRequested += OnRefresh; + _menu.SellRequested += OnSell; + } + + private void OnRefresh() + { + SendMessage(new GasSaleRefreshMessage()); + } + + private void OnSell() + { + SendMessage(new GasSaleSellMessage()); + } + + protected override void UpdateState(BoundUserInterfaceState state) + { + base.UpdateState(state); + + if (state is not GasSaleConsoleBoundUserInterfaceState gasState) + return; + + _menu?.SetEnabled(gasState.Enabled); + _menu?.SetMixture(gasState.Mixture, gasState.Appraisal); + } +} diff --git a/Content.Client/_NF/Atmos/Consoles/AtmosAlarmGaslockEntryContainer.xaml b/Content.Client/_NF/Atmos/Consoles/AtmosAlarmGaslockEntryContainer.xaml new file mode 100644 index 00000000000..bd4b8613787 --- /dev/null +++ b/Content.Client/_NF/Atmos/Consoles/AtmosAlarmGaslockEntryContainer.xaml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + +