diff --git a/.github/workflows/labeler-review.yml b/.github/workflows/labeler-review.yml
index a0341e42a1..0adfee7d0e 100644
--- a/.github/workflows/labeler-review.yml
+++ b/.github/workflows/labeler-review.yml
@@ -16,7 +16,7 @@ jobs:
with:
username: ${{ github.actor }}
team: "content-maintainers,junior-maintainers"
- GITHUB_TOKEN: ${{ secrets.GH_PAT }}
+ GITHUB_TOKEN: ${{ secrets.LABELER_PAT }}
- if: ${{ steps.checkUserMember.outputs.isTeamMember == 'true' }}
uses: actions-ecosystem/action-add-labels@v1
with:
diff --git a/Content.Client/Actions/ActionsSystem.cs b/Content.Client/Actions/ActionsSystem.cs
index 7b13233bab..b594817701 100644
--- a/Content.Client/Actions/ActionsSystem.cs
+++ b/Content.Client/Actions/ActionsSystem.cs
@@ -258,13 +258,13 @@ namespace Content.Client.Actions
public void LinkAllActions(ActionsComponent? actions = null)
{
- if (_playerManager.LocalEntity is not { } user ||
- !Resolve(user, ref actions, false))
- {
- return;
- }
+ if (_playerManager.LocalEntity is not { } user ||
+ !Resolve(user, ref actions, false))
+ {
+ return;
+ }
- LinkActions?.Invoke(actions);
+ LinkActions?.Invoke(actions);
}
public override void Shutdown()
diff --git a/Content.Client/Administration/UI/Notes/NoteEdit.xaml.cs b/Content.Client/Administration/UI/Notes/NoteEdit.xaml.cs
index a412e47396..c8e3afeb22 100644
--- a/Content.Client/Administration/UI/Notes/NoteEdit.xaml.cs
+++ b/Content.Client/Administration/UI/Notes/NoteEdit.xaml.cs
@@ -159,6 +159,7 @@ public sealed partial class NoteEdit : FancyWindow
SecretCheckBox.Pressed = false;
SeverityOption.Disabled = false;
PermanentCheckBox.Pressed = true;
+ SubmitButton.Disabled = true;
UpdatePermanentCheckboxFields();
break;
case (int) NoteType.Message: // Message: these are shown to the player when they log on
diff --git a/Content.Client/Atmos/Components/PipeColorVisualsComponent.cs b/Content.Client/Atmos/Components/PipeColorVisualsComponent.cs
index 355b10cb4a..9b24b1adc2 100644
--- a/Content.Client/Atmos/Components/PipeColorVisualsComponent.cs
+++ b/Content.Client/Atmos/Components/PipeColorVisualsComponent.cs
@@ -1,8 +1,4 @@
-using Robust.Shared.GameObjects;
-
namespace Content.Client.Atmos.Components;
[RegisterComponent]
-public sealed partial class PipeColorVisualsComponent : Component
-{
-}
+public sealed partial class PipeColorVisualsComponent : Component;
diff --git a/Content.Client/Atmos/Consoles/AtmosAlarmEntryContainer.xaml b/Content.Client/Atmos/Consoles/AtmosAlarmEntryContainer.xaml
index 6bdfb3989f..3dbe14e6b6 100644
--- a/Content.Client/Atmos/Consoles/AtmosAlarmEntryContainer.xaml
+++ b/Content.Client/Atmos/Consoles/AtmosAlarmEntryContainer.xaml
@@ -1,6 +1,5 @@
@@ -62,7 +61,7 @@
-
+
diff --git a/Content.Client/Atmos/Consoles/AtmosAlarmEntryContainer.xaml.cs b/Content.Client/Atmos/Consoles/AtmosAlarmEntryContainer.xaml.cs
index 79bb66560e..e533ef2dce 100644
--- a/Content.Client/Atmos/Consoles/AtmosAlarmEntryContainer.xaml.cs
+++ b/Content.Client/Atmos/Consoles/AtmosAlarmEntryContainer.xaml.cs
@@ -136,8 +136,9 @@ public sealed partial class AtmosAlarmEntryContainer : BoxContainer
GasGridContainer.RemoveAllChildren();
var gasData = focusData.Value.GasData.Where(g => g.Key != Gas.Oxygen);
+ var keyValuePairs = gasData.ToList();
- if (gasData.Count() == 0)
+ if (keyValuePairs.Count == 0)
{
// No other gases
var gasLabel = new Label()
@@ -158,13 +159,11 @@ public sealed partial class AtmosAlarmEntryContainer : BoxContainer
else
{
// Add an entry for each gas
- foreach ((var gas, (var mol, var percent, var alert)) in gasData)
+ foreach ((var gas, (var mol, var percent, var alert)) in keyValuePairs)
{
- var gasPercent = (FixedPoint2)0f;
- gasPercent = percent * 100f;
+ FixedPoint2 gasPercent = percent * 100f;
- if (!_gasShorthands.TryGetValue(gas, out var gasShorthand))
- gasShorthand = "X";
+ var gasShorthand = _gasShorthands.GetValueOrDefault(gas, "X");
var gasLabel = new Label()
{
diff --git a/Content.Client/Atmos/Consoles/AtmosAlertsComputerBoundUserInterface.cs b/Content.Client/Atmos/Consoles/AtmosAlertsComputerBoundUserInterface.cs
index 08cae979b9..6f0e7f80da 100644
--- a/Content.Client/Atmos/Consoles/AtmosAlertsComputerBoundUserInterface.cs
+++ b/Content.Client/Atmos/Consoles/AtmosAlertsComputerBoundUserInterface.cs
@@ -14,8 +14,6 @@ public sealed class AtmosAlertsComputerBoundUserInterface : BoundUserInterface
_menu = new AtmosAlertsComputerWindow(this, Owner);
_menu.OpenCentered();
_menu.OnClose += Close;
-
- EntMan.TryGetComponent(Owner, out var xform);
}
protected override void UpdateState(BoundUserInterfaceState state)
@@ -24,9 +22,6 @@ public sealed class AtmosAlertsComputerBoundUserInterface : BoundUserInterface
var castState = (AtmosAlertsComputerBoundInterfaceState) state;
- if (castState == null)
- return;
-
EntMan.TryGetComponent(Owner, out var xform);
_menu?.UpdateUI(xform?.Coordinates, castState.AirAlarms, castState.FireAlarms, castState.FocusData);
}
diff --git a/Content.Client/Atmos/Consoles/AtmosAlertsComputerWindow.xaml b/Content.Client/Atmos/Consoles/AtmosAlertsComputerWindow.xaml
index 8824a776ee..e5ede1b92e 100644
--- a/Content.Client/Atmos/Consoles/AtmosAlertsComputerWindow.xaml
+++ b/Content.Client/Atmos/Consoles/AtmosAlertsComputerWindow.xaml
@@ -1,7 +1,6 @@
(OnInit);
- SubscribeLocalEvent(OnAppearanceChanged, after: new[] { typeof(SubFloorHideSystem) });
+ SubscribeLocalEvent(OnAppearanceChanged, after: [typeof(SubFloorHideSystem)]);
}
private void OnInit(EntityUid uid, PipeAppearanceComponent component, ComponentInit args)
@@ -84,7 +82,8 @@ public sealed class AtmosPipeAppearanceSystem : EntitySystem
layer.Visible &= visible;
- if (!visible) continue;
+ if (!visible)
+ continue;
layer.Color = color;
}
diff --git a/Content.Client/Atmos/Monitor/AtmosAlarmableVisualsSystem.cs b/Content.Client/Atmos/Monitor/AtmosAlarmableVisualsSystem.cs
index 019f25f376..18ca223475 100644
--- a/Content.Client/Atmos/Monitor/AtmosAlarmableVisualsSystem.cs
+++ b/Content.Client/Atmos/Monitor/AtmosAlarmableVisualsSystem.cs
@@ -1,12 +1,7 @@
-using System.Collections.Generic;
using Content.Shared.Atmos.Monitor;
using Content.Shared.Power;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
-using Robust.Shared.GameObjects;
-using Robust.Shared.IoC;
-using Robust.Shared.Maths;
-using Robust.Shared.Serialization.Manager.Attributes;
namespace Content.Client.Atmos.Monitor;
@@ -27,7 +22,7 @@ public sealed class AtmosAlarmableVisualsSystem : VisualizerSystem "air-alarm-ui-mode-fill",
AirAlarmMode.Panic => "air-alarm-ui-mode-panic",
AirAlarmMode.None => "air-alarm-ui-mode-none",
- _ => "error"
+ _ => "error",
};
_modes.AddItem(Loc.GetString(text));
}
@@ -70,7 +69,7 @@ public sealed partial class AirAlarmWindow : FancyWindow
AirAlarmModeChanged!.Invoke((AirAlarmMode) args.Id);
};
- _autoMode.OnToggled += args =>
+ _autoMode.OnToggled += _ =>
{
AutoModeChanged!.Invoke(_autoMode.Pressed);
};
@@ -176,22 +175,18 @@ public sealed partial class AirAlarmWindow : FancyWindow
public static Color ColorForThreshold(float amount, AtmosAlarmThreshold threshold)
{
- threshold.CheckThreshold(amount, out AtmosAlarmType curAlarm);
+ threshold.CheckThreshold(amount, out var curAlarm);
return ColorForAlarm(curAlarm);
}
public static Color ColorForAlarm(AtmosAlarmType curAlarm)
{
- if(curAlarm == AtmosAlarmType.Danger)
+ return curAlarm switch
{
- return StyleNano.DangerousRedFore;
- }
- else if(curAlarm == AtmosAlarmType.Warning)
- {
- return StyleNano.ConcerningOrangeFore;
- }
-
- return StyleNano.GoodGreenFore;
+ AtmosAlarmType.Danger => StyleNano.DangerousRedFore,
+ AtmosAlarmType.Warning => StyleNano.ConcerningOrangeFore,
+ _ => StyleNano.GoodGreenFore,
+ };
}
diff --git a/Content.Client/Atmos/Monitor/UI/Widgets/PumpControl.xaml.cs b/Content.Client/Atmos/Monitor/UI/Widgets/PumpControl.xaml.cs
index 17b03b8468..2cd51d6fc7 100644
--- a/Content.Client/Atmos/Monitor/UI/Widgets/PumpControl.xaml.cs
+++ b/Content.Client/Atmos/Monitor/UI/Widgets/PumpControl.xaml.cs
@@ -1,12 +1,8 @@
-using System;
-using Content.Shared.Atmos.Monitor;
using Content.Shared.Atmos.Monitor.Components;
using Content.Shared.Atmos.Piping.Unary.Components;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
-using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
-using Robust.Shared.Localization;
namespace Content.Client.Atmos.Monitor.UI.Widgets;
@@ -25,7 +21,7 @@ public sealed partial class PumpControl : BoxContainer
private OptionButton _pressureCheck => CPressureCheck;
private FloatSpinBox _externalBound => CExternalBound;
private FloatSpinBox _internalBound => CInternalBound;
- private Button _copySettings => CCopySettings;
+ private Button _copySettings => CCopySettings;
public PumpControl(GasVentPumpData data, string address)
{
@@ -86,7 +82,7 @@ public sealed partial class PumpControl : BoxContainer
_data.PressureChecks = (VentPressureBound) args.Id;
PumpDataChanged?.Invoke(_address, _data);
};
-
+
_copySettings.OnPressed += _ =>
{
PumpDataCopied?.Invoke(_data);
diff --git a/Content.Client/Atmos/Monitor/UI/Widgets/ScrubberControl.xaml.cs b/Content.Client/Atmos/Monitor/UI/Widgets/ScrubberControl.xaml.cs
index f2241bcd8d..c16ff688c9 100644
--- a/Content.Client/Atmos/Monitor/UI/Widgets/ScrubberControl.xaml.cs
+++ b/Content.Client/Atmos/Monitor/UI/Widgets/ScrubberControl.xaml.cs
@@ -1,15 +1,9 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
using Content.Shared.Atmos;
-using Content.Shared.Atmos.Monitor;
using Content.Shared.Atmos.Monitor.Components;
using Content.Shared.Atmos.Piping.Unary.Components;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
-using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
-using Robust.Shared.Localization;
namespace Content.Client.Atmos.Monitor.UI.Widgets;
@@ -27,7 +21,7 @@ public sealed partial class ScrubberControl : BoxContainer
private OptionButton _pumpDirection => CPumpDirection;
private FloatSpinBox _volumeRate => CVolumeRate;
private CheckBox _wideNet => CWideNet;
- private Button _copySettings => CCopySettings;
+ private Button _copySettings => CCopySettings;
private GridContainer _gases => CGasContainer;
private Dictionary _gasControls = new();
@@ -77,7 +71,7 @@ public sealed partial class ScrubberControl : BoxContainer
_data.PumpDirection = (ScrubberPumpDirection) args.Id;
ScrubberDataChanged?.Invoke(_address, _data);
};
-
+
_copySettings.OnPressed += _ =>
{
ScrubberDataCopied?.Invoke(_data);
diff --git a/Content.Client/Atmos/Monitor/UI/Widgets/SensorInfo.xaml.cs b/Content.Client/Atmos/Monitor/UI/Widgets/SensorInfo.xaml.cs
index da602cd747..9e60b6cea6 100644
--- a/Content.Client/Atmos/Monitor/UI/Widgets/SensorInfo.xaml.cs
+++ b/Content.Client/Atmos/Monitor/UI/Widgets/SensorInfo.xaml.cs
@@ -43,7 +43,8 @@ public sealed partial class SensorInfo : BoxContainer
var label = new RichTextLabel();
var fractionGas = amount / data.TotalMoles;
- label.SetMarkup(Loc.GetString("air-alarm-ui-gases-indicator", ("gas", $"{gas}"),
+ label.SetMarkup(Loc.GetString("air-alarm-ui-gases-indicator",
+ ("gas", $"{gas}"),
("color", AirAlarmWindow.ColorForThreshold(fractionGas, data.GasThresholds[gas])),
("amount", $"{amount:0.####}"),
("percentage", $"{(100 * fractionGas):0.##}")));
@@ -53,9 +54,9 @@ public sealed partial class SensorInfo : BoxContainer
var threshold = data.GasThresholds[gas];
var gasThresholdControl = new ThresholdControl(Loc.GetString($"air-alarm-ui-thresholds-gas-title", ("gas", $"{gas}")), threshold, AtmosMonitorThresholdType.Gas, gas, 100);
gasThresholdControl.Margin = new Thickness(20, 2, 2, 2);
- gasThresholdControl.ThresholdDataChanged += (type, threshold, arg3) =>
+ gasThresholdControl.ThresholdDataChanged += (type, alarmThreshold, arg3) =>
{
- OnThresholdUpdate!(_address, type, threshold, arg3);
+ OnThresholdUpdate!(_address, type, alarmThreshold, arg3);
};
_gasThresholds.Add(gas, gasThresholdControl);
@@ -64,7 +65,8 @@ public sealed partial class SensorInfo : BoxContainer
_pressureThreshold = new ThresholdControl(Loc.GetString("air-alarm-ui-thresholds-pressure-title"), data.PressureThreshold, AtmosMonitorThresholdType.Pressure);
PressureThresholdContainer.AddChild(_pressureThreshold);
- _temperatureThreshold = new ThresholdControl(Loc.GetString("air-alarm-ui-thresholds-temperature-title"), data.TemperatureThreshold,
+ _temperatureThreshold = new ThresholdControl(Loc.GetString("air-alarm-ui-thresholds-temperature-title"),
+ data.TemperatureThreshold,
AtmosMonitorThresholdType.Temperature);
TemperatureThresholdContainer.AddChild(_temperatureThreshold);
@@ -103,7 +105,8 @@ public sealed partial class SensorInfo : BoxContainer
}
var fractionGas = amount / data.TotalMoles;
- label.SetMarkup(Loc.GetString("air-alarm-ui-gases-indicator", ("gas", $"{gas}"),
+ label.SetMarkup(Loc.GetString("air-alarm-ui-gases-indicator",
+ ("gas", $"{gas}"),
("color", AirAlarmWindow.ColorForThreshold(fractionGas, data.GasThresholds[gas])),
("amount", $"{amount:0.####}"),
("percentage", $"{(100 * fractionGas):0.##}")));
diff --git a/Content.Client/Atmos/Monitor/UI/Widgets/ThresholdBoundControl.xaml.cs b/Content.Client/Atmos/Monitor/UI/Widgets/ThresholdBoundControl.xaml.cs
index 3612d84de4..55f7c00898 100644
--- a/Content.Client/Atmos/Monitor/UI/Widgets/ThresholdBoundControl.xaml.cs
+++ b/Content.Client/Atmos/Monitor/UI/Widgets/ThresholdBoundControl.xaml.cs
@@ -1,7 +1,4 @@
-using Content.Client.Message;
-using Content.Shared.Atmos;
using Content.Shared.Atmos.Monitor;
-using Content.Shared.Temperature;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
diff --git a/Content.Client/Atmos/Monitor/UI/Widgets/ThresholdControl.xaml.cs b/Content.Client/Atmos/Monitor/UI/Widgets/ThresholdControl.xaml.cs
index 78c73fa573..651620f3e2 100644
--- a/Content.Client/Atmos/Monitor/UI/Widgets/ThresholdControl.xaml.cs
+++ b/Content.Client/Atmos/Monitor/UI/Widgets/ThresholdControl.xaml.cs
@@ -1,12 +1,8 @@
-using System;
using Content.Shared.Atmos;
using Content.Shared.Atmos.Monitor;
-using Content.Shared.Atmos.Monitor.Components;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface.Controls;
-using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
-using Robust.Shared.Localization;
// holy FUCK
// this technically works because some of this you can *not* do in XAML but holy FUCK
@@ -115,29 +111,38 @@ public sealed partial class ThresholdControl : BoxContainer
_enabled.Pressed = !_threshold.Ignore;
}
- private String LabelForBound(string boundType) //, DebugMessage)> state) =>
{
if (_system.TileData.TryGetValue(uid, out var data))
diff --git a/Content.Client/Clothing/FlippableClothingVisualizerSystem.cs b/Content.Client/Clothing/FlippableClothingVisualizerSystem.cs
index 2c3afb0324..1f09ae9eeb 100644
--- a/Content.Client/Clothing/FlippableClothingVisualizerSystem.cs
+++ b/Content.Client/Clothing/FlippableClothingVisualizerSystem.cs
@@ -7,7 +7,7 @@ using Robust.Client.GameObjects;
namespace Content.Client.Clothing;
-public sealed class FlippableClothingVisualizerSystem : VisualizerSystem
+public sealed class FlippableClothingVisualizerSystem : VisualizerSystem
{
[Dependency] private readonly SharedItemSystem _itemSys = default!;
diff --git a/Content.Client/Electrocution/ElectrocutionHUDVisualizerSystem.cs b/Content.Client/Electrocution/ElectrocutionHUDVisualizerSystem.cs
new file mode 100644
index 0000000000..b95c0d585d
--- /dev/null
+++ b/Content.Client/Electrocution/ElectrocutionHUDVisualizerSystem.cs
@@ -0,0 +1,95 @@
+using Content.Shared.Electrocution;
+using Robust.Client.GameObjects;
+using Robust.Client.Player;
+using Robust.Shared.Player;
+
+namespace Content.Client.Electrocution;
+
+///
+/// Shows the Electrocution HUD to entities with the ShowElectrocutionHUDComponent.
+///
+public sealed class ElectrocutionHUDVisualizerSystem : VisualizerSystem
+{
+ [Dependency] private readonly IPlayerManager _playerMan = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ SubscribeLocalEvent(OnInit);
+ SubscribeLocalEvent(OnShutdown);
+ SubscribeLocalEvent(OnPlayerAttached);
+ SubscribeLocalEvent(OnPlayerDetached);
+ }
+
+ private void OnPlayerAttached(Entity ent, ref LocalPlayerAttachedEvent args)
+ {
+ ShowHUD();
+ }
+
+ private void OnPlayerDetached(Entity ent, ref LocalPlayerDetachedEvent args)
+ {
+ RemoveHUD();
+ }
+
+ private void OnInit(Entity ent, ref ComponentInit args)
+ {
+ if (_playerMan.LocalEntity == ent)
+ {
+ ShowHUD();
+ }
+ }
+
+ private void OnShutdown(Entity ent, ref ComponentShutdown args)
+ {
+ if (_playerMan.LocalEntity == ent)
+ {
+ RemoveHUD();
+ }
+ }
+
+ // Show the HUD to the client.
+ // We have to look for all current entities that can be electrified and toggle the HUD layer on if they are.
+ private void ShowHUD()
+ {
+ var electrifiedQuery = AllEntityQuery();
+ while (electrifiedQuery.MoveNext(out var uid, out var _, out var appearanceComp, out var spriteComp))
+ {
+ if (!AppearanceSystem.TryGetData(uid, ElectrifiedVisuals.IsElectrified, out var electrified, appearanceComp))
+ continue;
+
+ if (electrified)
+ spriteComp.LayerSetVisible(ElectrifiedLayers.HUD, true);
+ else
+ spriteComp.LayerSetVisible(ElectrifiedLayers.HUD, false);
+ }
+ }
+
+ // Remove the HUD from the client.
+ // Find all current entities that can be electrified and hide the HUD layer.
+ private void RemoveHUD()
+ {
+ var electrifiedQuery = AllEntityQuery();
+ while (electrifiedQuery.MoveNext(out var uid, out var _, out var appearanceComp, out var spriteComp))
+ {
+
+ spriteComp.LayerSetVisible(ElectrifiedLayers.HUD, false);
+ }
+ }
+
+ // Toggle the HUD layer if an entity becomes (de-)electrified
+ protected override void OnAppearanceChange(EntityUid uid, ElectrocutionHUDVisualsComponent comp, ref AppearanceChangeEvent args)
+ {
+ if (args.Sprite == null)
+ return;
+
+ if (!AppearanceSystem.TryGetData(uid, ElectrifiedVisuals.IsElectrified, out var electrified, args.Component))
+ return;
+
+ var player = _playerMan.LocalEntity;
+ if (electrified && HasComp(player))
+ args.Sprite.LayerSetVisible(ElectrifiedLayers.HUD, true);
+ else
+ args.Sprite.LayerSetVisible(ElectrifiedLayers.HUD, false);
+ }
+}
diff --git a/Content.Client/Eui/BaseEui.cs b/Content.Client/Eui/BaseEui.cs
index 7f86ded7e4..c11ba5a9b6 100644
--- a/Content.Client/Eui/BaseEui.cs
+++ b/Content.Client/Eui/BaseEui.cs
@@ -55,7 +55,7 @@ namespace Content.Client.Eui
///
protected void SendMessage(EuiMessageBase msg)
{
- var netMsg = _netManager.CreateNetMessage();
+ var netMsg = new MsgEuiMessage();
netMsg.Id = Id;
netMsg.Message = msg;
diff --git a/Content.Client/Ghost/GhostSystem.cs b/Content.Client/Ghost/GhostSystem.cs
index f4f7e3459f..805b65a0e0 100644
--- a/Content.Client/Ghost/GhostSystem.cs
+++ b/Content.Client/Ghost/GhostSystem.cs
@@ -112,7 +112,12 @@ namespace Content.Client.Ghost
_actions.RemoveAction(uid, component.ToggleLightingActionEntity);
_actions.RemoveAction(uid, component.ToggleFoVActionEntity);
_actions.RemoveAction(uid, component.ToggleGhostsActionEntity);
- _actions.RemoveAction(uid, component.ToggleGhostHearingActionEntity);
+ //_actions.RemoveAction(uid, component.ToggleGhostHearingActionEntity); //Dont need in CP14
+ //CP14
+ _actions.RemoveAction(uid, component.CP14ZLevelUpActionEntity);
+ _actions.RemoveAction(uid, component.CP14ZLevelDownActionEntity);
+ _actions.RemoveAction(uid, component.CP14ToggleRoofActionEntity);
+ //CP14 end
if (uid != _playerManager.LocalEntity)
return;
diff --git a/Content.Client/Inventory/StrippableBoundUserInterface.cs b/Content.Client/Inventory/StrippableBoundUserInterface.cs
index af7815935d..90e52d7283 100644
--- a/Content.Client/Inventory/StrippableBoundUserInterface.cs
+++ b/Content.Client/Inventory/StrippableBoundUserInterface.cs
@@ -191,9 +191,15 @@ namespace Content.Client.Inventory
return;
if (ev.Function == ContentKeyFunctions.ExamineEntity)
+ {
_examine.DoExamine(slot.Entity.Value);
+ ev.Handle();
+ }
else if (ev.Function == EngineKeyFunctions.UseSecondary)
+ {
_ui.GetUIController().OpenVerbMenu(slot.Entity.Value);
+ ev.Handle();
+ }
}
private void AddInventoryButton(EntityUid invUid, string slotId, InventoryComponent inv)
diff --git a/Content.Client/Light/HandheldLightSystem.cs b/Content.Client/Light/HandheldLightSystem.cs
index ddd99c7c48..d25b28756f 100644
--- a/Content.Client/Light/HandheldLightSystem.cs
+++ b/Content.Client/Light/HandheldLightSystem.cs
@@ -21,6 +21,22 @@ public sealed class HandheldLightSystem : SharedHandheldLightSystem
SubscribeLocalEvent(OnAppearanceChange);
}
+ ///
+ /// TODO: Not properly predicted yet. Don't call this function if you want a the actual return value!
+ ///
+ public override bool TurnOff(Entity ent, bool makeNoise = true)
+ {
+ return true;
+ }
+
+ ///
+ /// TODO: Not properly predicted yet. Don't call this function if you want a the actual return value!
+ ///
+ public override bool TurnOn(EntityUid user, Entity uid)
+ {
+ return true;
+ }
+
private void OnAppearanceChange(EntityUid uid, HandheldLightComponent? component, ref AppearanceChangeEvent args)
{
if (!Resolve(uid, ref component))
diff --git a/Content.Client/Lobby/LobbyState.cs b/Content.Client/Lobby/LobbyState.cs
index 1aabc4ff38..1361ca57cd 100644
--- a/Content.Client/Lobby/LobbyState.cs
+++ b/Content.Client/Lobby/LobbyState.cs
@@ -116,7 +116,7 @@ namespace Content.Client.Lobby
return;
}
- Lobby!.StationTime.Text = Loc.GetString("lobby-state-player-status-round-not-started");
+ Lobby!.StationTime.Text = Loc.GetString("lobby-state-player-status-round-not-started");
string text;
if (_gameTicker.Paused)
@@ -136,6 +136,10 @@ namespace Content.Client.Lobby
{
text = Loc.GetString(seconds < -5 ? "lobby-state-right-now-question" : "lobby-state-right-now-confirmation");
}
+ else if (difference.TotalHours >= 1)
+ {
+ text = $"{Math.Floor(difference.TotalHours)}:{difference.Minutes:D2}:{difference.Seconds:D2}";
+ }
else
{
text = $"{difference.Minutes}:{difference.Seconds:D2}";
diff --git a/Content.Client/Overlays/StencilOverlay.Weather.cs b/Content.Client/Overlays/StencilOverlay.Weather.cs
index f709b06f04..bbf0162370 100644
--- a/Content.Client/Overlays/StencilOverlay.Weather.cs
+++ b/Content.Client/Overlays/StencilOverlay.Weather.cs
@@ -35,7 +35,7 @@ public sealed partial class StencilOverlay
var matty = Matrix3x2.Multiply(matrix, invMatrix);
worldHandle.SetTransform(matty);
- foreach (var tile in grid.Comp.GetTilesIntersecting(worldAABB))
+ foreach (var tile in _map.GetTilesIntersecting(grid.Owner, grid, worldAABB))
{
// Ignored tiles for stencil
if (_weather.CanWeatherAffect(grid.Owner, grid, tile))
diff --git a/Content.Client/Overlays/StencilOverlay.cs b/Content.Client/Overlays/StencilOverlay.cs
index 45112b3c8c..3af22c8138 100644
--- a/Content.Client/Overlays/StencilOverlay.cs
+++ b/Content.Client/Overlays/StencilOverlay.cs
@@ -26,6 +26,7 @@ public sealed partial class StencilOverlay : Overlay
[Dependency] private readonly IPrototypeManager _protoManager = default!;
private readonly ParallaxSystem _parallax;
private readonly SharedTransformSystem _transform;
+ private readonly SharedMapSystem _map;
private readonly SpriteSystem _sprite;
private readonly WeatherSystem _weather;
@@ -35,11 +36,12 @@ public sealed partial class StencilOverlay : Overlay
private readonly ShaderInstance _shader;
- public StencilOverlay(ParallaxSystem parallax, SharedTransformSystem transform, SpriteSystem sprite, WeatherSystem weather)
+ public StencilOverlay(ParallaxSystem parallax, SharedTransformSystem transform, SharedMapSystem map, SpriteSystem sprite, WeatherSystem weather)
{
ZIndex = ParallaxSystem.ParallaxZIndex + 1;
_parallax = parallax;
_transform = transform;
+ _map = map;
_sprite = sprite;
_weather = weather;
IoCManager.InjectDependencies(this);
diff --git a/Content.Client/Overlays/StencilOverlaySystem.cs b/Content.Client/Overlays/StencilOverlaySystem.cs
index c8a9553cfd..364ec0fddb 100644
--- a/Content.Client/Overlays/StencilOverlaySystem.cs
+++ b/Content.Client/Overlays/StencilOverlaySystem.cs
@@ -10,13 +10,14 @@ public sealed class StencilOverlaySystem : EntitySystem
[Dependency] private readonly IOverlayManager _overlay = default!;
[Dependency] private readonly ParallaxSystem _parallax = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
+ [Dependency] private readonly SharedMapSystem _map = default!;
[Dependency] private readonly SpriteSystem _sprite = default!;
[Dependency] private readonly WeatherSystem _weather = default!;
public override void Initialize()
{
base.Initialize();
- _overlay.AddOverlay(new StencilOverlay(_parallax, _transform, _sprite, _weather));
+ _overlay.AddOverlay(new StencilOverlay(_parallax, _transform, _map, _sprite, _weather));
}
public override void Shutdown()
diff --git a/Content.Client/Shuttles/UI/BaseShuttleControl.xaml.cs b/Content.Client/Shuttles/UI/BaseShuttleControl.xaml.cs
index b50d8fa6b2..a541100539 100644
--- a/Content.Client/Shuttles/UI/BaseShuttleControl.xaml.cs
+++ b/Content.Client/Shuttles/UI/BaseShuttleControl.xaml.cs
@@ -116,7 +116,7 @@ public partial class BaseShuttleControl : MapGridControl
}
}
- protected void DrawGrid(DrawingHandleScreen handle, Matrix3x2 matrix, Entity grid, Color color, float alpha = 0.01f)
+ protected void DrawGrid(DrawingHandleScreen handle, Matrix3x2 gridToView, Entity grid, Color color, float alpha = 0.01f)
{
var rator = Maps.GetAllTilesEnumerator(grid.Owner, grid.Comp);
var minimapScale = MinimapScale;
@@ -264,7 +264,7 @@ public partial class BaseShuttleControl : MapGridControl
Extensions.EnsureLength(ref _allVertices, totalData);
_drawJob.MidPoint = midpoint;
- _drawJob.Matrix = matrix;
+ _drawJob.Matrix = gridToView;
_drawJob.MinimapScale = minimapScale;
_drawJob.Vertices = gridData.Vertices;
_drawJob.ScaledVertices = _allVertices;
@@ -286,7 +286,7 @@ public partial class BaseShuttleControl : MapGridControl
private record struct GridDrawJob : IParallelRobustJob
{
- public int BatchSize => 16;
+ public int BatchSize => 64;
public float MinimapScale;
public Vector2 MidPoint;
@@ -297,12 +297,7 @@ public partial class BaseShuttleControl : MapGridControl
public void Execute(int index)
{
- var vert = Vertices[index];
- var adjustedVert = Vector2.Transform(vert, Matrix);
- adjustedVert = adjustedVert with { Y = -adjustedVert.Y };
-
- var scaledVert = ScalePosition(adjustedVert, MinimapScale, MidPoint);
- ScaledVertices[index] = scaledVert;
+ ScaledVertices[index] = Vector2.Transform(Vertices[index], Matrix);
}
}
}
diff --git a/Content.Client/Shuttles/UI/NavScreen.xaml.cs b/Content.Client/Shuttles/UI/NavScreen.xaml.cs
index 91d95aaa04..7236714ef2 100644
--- a/Content.Client/Shuttles/UI/NavScreen.xaml.cs
+++ b/Content.Client/Shuttles/UI/NavScreen.xaml.cs
@@ -15,6 +15,7 @@ public sealed partial class NavScreen : BoxContainer
[Dependency] private readonly IEntityManager _entManager = default!;
private SharedTransformSystem _xformSystem;
+ private EntityUid? _consoleEntity; // Entity of controlling console
private EntityUid? _shuttleEntity;
public NavScreen()
@@ -35,6 +36,12 @@ public sealed partial class NavScreen : BoxContainer
_shuttleEntity = shuttle;
}
+ public void SetConsole(EntityUid? console)
+ {
+ _consoleEntity = console;
+ NavRadar.SetConsole(console);
+ }
+
private void OnIFFTogglePressed(BaseButton.ButtonEventArgs args)
{
NavRadar.ShowIFF ^= true;
diff --git a/Content.Client/Shuttles/UI/ShuttleConsoleWindow.xaml.cs b/Content.Client/Shuttles/UI/ShuttleConsoleWindow.xaml.cs
index a4b42fb672..d0e6f9ebf7 100644
--- a/Content.Client/Shuttles/UI/ShuttleConsoleWindow.xaml.cs
+++ b/Content.Client/Shuttles/UI/ShuttleConsoleWindow.xaml.cs
@@ -138,6 +138,7 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
{
var coordinates = _entManager.GetCoordinates(cState.NavState.Coordinates);
NavContainer.SetShuttle(coordinates?.EntityId);
+ NavContainer.SetConsole(owner);
MapContainer.SetShuttle(coordinates?.EntityId);
MapContainer.SetConsole(owner);
diff --git a/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs
index 61ae069926..2b575b4805 100644
--- a/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs
+++ b/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs
@@ -107,16 +107,19 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
DrawCircles(handle);
var gridNent = EntManager.GetNetEntity(GridEntity);
var mapPos = _xformSystem.ToMapCoordinates(_coordinates.Value);
- var ourGridMatrix = _xformSystem.GetWorldMatrix(GridEntity.Value);
- var dockMatrix = Matrix3Helpers.CreateTransform(_coordinates.Value.Position, Angle.Zero);
- var worldFromDock = Matrix3x2.Multiply(dockMatrix, ourGridMatrix);
+ var ourGridToWorld = _xformSystem.GetWorldMatrix(GridEntity.Value);
+ var selectedDockToOurGrid = Matrix3Helpers.CreateTransform(_coordinates.Value.Position, Angle.Zero);
+ var selectedDockToWorld = Matrix3x2.Multiply(selectedDockToOurGrid, ourGridToWorld);
- Matrix3x2.Invert(worldFromDock, out var offsetMatrix);
+ Box2 viewBoundsWorld = Matrix3Helpers.TransformBox(selectedDockToWorld, new Box2(-WorldRangeVector, WorldRangeVector));
+
+ Matrix3x2.Invert(selectedDockToWorld, out var worldToSelectedDock);
+ var selectedDockToView = Matrix3x2.CreateScale(new Vector2(MinimapScale, -MinimapScale)) * Matrix3x2.CreateTranslation(MidPointVector);
// Draw nearby grids
var controlBounds = PixelSizeBox;
_grids.Clear();
- _mapManager.FindGridsIntersecting(gridXform.MapID, new Box2(mapPos.Position - WorldRangeVector, mapPos.Position + WorldRangeVector), ref _grids);
+ _mapManager.FindGridsIntersecting(gridXform.MapID, viewBoundsWorld, ref _grids);
// offset the dotted-line position to the bounds.
Vector2? viewedDockPos = _viewedState != null ? MidPointVector : null;
@@ -136,11 +139,11 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
if (grid.Owner != GridEntity && !_shuttles.CanDraw(grid.Owner, iffComp: iffComp))
continue;
- var gridMatrix = _xformSystem.GetWorldMatrix(grid.Owner);
- var matty = Matrix3x2.Multiply(gridMatrix, offsetMatrix);
+ var curGridToWorld = _xformSystem.GetWorldMatrix(grid.Owner);
+ var curGridToView = curGridToWorld * worldToSelectedDock * selectedDockToView;
var color = _shuttles.GetIFFColor(grid.Owner, grid.Owner == GridEntity, component: iffComp);
- DrawGrid(handle, matty, grid, color);
+ DrawGrid(handle, curGridToView, grid, color);
// Draw any docks on that grid
if (!DockState.Docks.TryGetValue(EntManager.GetNetEntity(grid), out var gridDocks))
@@ -151,23 +154,24 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
if (ViewedDock == dock.Entity)
continue;
- var position = Vector2.Transform(dock.Coordinates.Position, matty);
-
var otherDockRotation = Matrix3Helpers.CreateRotation(dock.Angle);
- var scaledPos = ScalePosition(position with {Y = -position.Y});
- if (!controlBounds.Contains(scaledPos.Floored()))
+ // This box is the AABB of all the vertices we draw below.
+ var dockRenderBoundsLocal = new Box2(-0.5f, -0.7f, 0.5f, 0.5f);
+ var currentDockToCurGrid = Matrix3Helpers.CreateTransform(dock.Coordinates.Position, dock.Angle);
+ var currentDockToWorld = Matrix3x2.Multiply(currentDockToCurGrid, curGridToWorld);
+ var dockRenderBoundsWorld = Matrix3Helpers.TransformBox(currentDockToWorld, dockRenderBoundsLocal);
+ if (!viewBoundsWorld.Intersects(dockRenderBoundsWorld))
continue;
- // Draw the dock's collision
var collisionBL = Vector2.Transform(dock.Coordinates.Position +
- Vector2.Transform(new Vector2(-0.2f, -0.7f), otherDockRotation), matty);
+ Vector2.Transform(new Vector2(-0.2f, -0.7f), otherDockRotation), curGridToView);
var collisionBR = Vector2.Transform(dock.Coordinates.Position +
- Vector2.Transform(new Vector2(0.2f, -0.7f), otherDockRotation), matty);
+ Vector2.Transform(new Vector2(0.2f, -0.7f), otherDockRotation), curGridToView);
var collisionTR = Vector2.Transform(dock.Coordinates.Position +
- Vector2.Transform(new Vector2(0.2f, -0.5f), otherDockRotation), matty);
+ Vector2.Transform(new Vector2(0.2f, -0.5f), otherDockRotation), curGridToView);
var collisionTL = Vector2.Transform(dock.Coordinates.Position +
- Vector2.Transform(new Vector2(-0.2f, -0.5f), otherDockRotation), matty);
+ Vector2.Transform(new Vector2(-0.2f, -0.5f), otherDockRotation), curGridToView);
var verts = new[]
{
@@ -181,13 +185,6 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
collisionBL,
};
- for (var i = 0; i < verts.Length; i++)
- {
- var vert = verts[i];
- vert.Y = -vert.Y;
- verts[i] = ScalePosition(vert);
- }
-
var collisionCenter = verts[0] + verts[1] + verts[3] + verts[5];
var otherDockConnection = Color.ToSrgb(Color.Pink);
@@ -195,10 +192,10 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
handle.DrawPrimitives(DrawPrimitiveTopology.LineList, verts, otherDockConnection);
// Draw the dock itself
- var dockBL = Vector2.Transform(dock.Coordinates.Position + new Vector2(-0.5f, -0.5f), matty);
- var dockBR = Vector2.Transform(dock.Coordinates.Position + new Vector2(0.5f, -0.5f), matty);
- var dockTR = Vector2.Transform(dock.Coordinates.Position + new Vector2(0.5f, 0.5f), matty);
- var dockTL = Vector2.Transform(dock.Coordinates.Position + new Vector2(-0.5f, 0.5f), matty);
+ var dockBL = Vector2.Transform(dock.Coordinates.Position + new Vector2(-0.5f, -0.5f), curGridToView);
+ var dockBR = Vector2.Transform(dock.Coordinates.Position + new Vector2(0.5f, -0.5f), curGridToView);
+ var dockTR = Vector2.Transform(dock.Coordinates.Position + new Vector2(0.5f, 0.5f), curGridToView);
+ var dockTL = Vector2.Transform(dock.Coordinates.Position + new Vector2(-0.5f, 0.5f), curGridToView);
verts = new[]
{
@@ -212,13 +209,6 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
dockBL
};
- for (var i = 0; i < verts.Length; i++)
- {
- var vert = verts[i];
- vert.Y = -vert.Y;
- verts[i] = ScalePosition(vert);
- }
-
Color otherDockColor;
if (HighlightedDock == dock.Entity)
@@ -253,9 +243,11 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
collisionCenter /= 4;
var range = viewedDockPos.Value - collisionCenter;
- if (range.Length() < SharedDockingSystem.DockingHiglightRange * MinimapScale)
+ var maxRange = SharedDockingSystem.DockingHiglightRange * MinimapScale;
+ var maxRangeSq = maxRange * maxRange;
+ if (range.LengthSquared() < maxRangeSq)
{
- if (_viewedState?.GridDockedWith == null)
+ if (dock.GridDockedWith == null)
{
var coordsOne = EntManager.GetCoordinates(_viewedState!.Coordinates);
var coordsTwo = EntManager.GetCoordinates(dock.Coordinates);
@@ -265,10 +257,11 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
var rotA = _xformSystem.GetWorldRotation(coordsOne.EntityId) + _viewedState!.Angle;
var rotB = _xformSystem.GetWorldRotation(coordsTwo.EntityId) + dock.Angle;
- var distance = (mapOne.Position - mapTwo.Position).Length();
+ var distanceSq = (mapOne.Position - mapTwo.Position).LengthSquared();
var inAlignment = _dockSystem.InAlignment(mapOne, rotA, mapTwo, rotB);
- var canDock = distance < SharedDockingSystem.DockRange && inAlignment;
+ var maxDockDistSq = SharedDockingSystem.DockRange * SharedDockingSystem.DockRange;
+ var canDock = distanceSq < maxDockDistSq && inAlignment;
if (dockButton != null)
dockButton.Disabled = !canDock || !canDockChange;
@@ -297,7 +290,8 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl
{
// Because it's being layed out top-down we have to arrange for first frame.
container.Arrange(PixelRect);
- var containerPos = scaledPos / UIScale - container.DesiredSize / 2 - new Vector2(0f, 0.75f) * MinimapScale;
+ var dockPositionInView = Vector2.Transform(dock.Coordinates.Position, curGridToView);
+ var containerPos = dockPositionInView / UIScale - container.DesiredSize / 2 - new Vector2(0f, 0.75f) * MinimapScale;
SetPosition(container, containerPos);
}
diff --git a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs
index 2674343e05..805608c9a5 100644
--- a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs
+++ b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs
@@ -29,6 +29,11 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl
///
private EntityCoordinates? _coordinates;
+ ///
+ /// Entity of controlling console
+ ///
+ private EntityUid? _consoleEntity;
+
private Angle? _rotation;
private Dictionary> _docks = new();
@@ -57,6 +62,11 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl
_rotation = angle;
}
+ public void SetConsole(EntityUid? consoleEntity)
+ {
+ _consoleEntity = consoleEntity;
+ }
+
protected override void KeyBindUp(GUIBoundKeyEventArgs args)
{
base.KeyBindUp(args);
@@ -139,40 +149,35 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl
}
var mapPos = _transform.ToMapCoordinates(_coordinates.Value);
- var offset = _coordinates.Value.Position;
- var posMatrix = Matrix3Helpers.CreateTransform(offset, _rotation.Value);
+ var posMatrix = Matrix3Helpers.CreateTransform(_coordinates.Value.Position, _rotation.Value);
var ourEntRot = RotateWithEntity ? _transform.GetWorldRotation(xform) : _rotation.Value;
var ourEntMatrix = Matrix3Helpers.CreateTransform(_transform.GetWorldPosition(xform), ourEntRot);
- var ourWorldMatrix = Matrix3x2.Multiply(posMatrix, ourEntMatrix);
- Matrix3x2.Invert(ourWorldMatrix, out var ourWorldMatrixInvert);
+ var shuttleToWorld = Matrix3x2.Multiply(posMatrix, ourEntMatrix);
+ Matrix3x2.Invert(shuttleToWorld, out var worldToShuttle);
+ var shuttleToView = Matrix3x2.CreateScale(new Vector2(MinimapScale, -MinimapScale)) * Matrix3x2.CreateTranslation(MidPointVector);
// Draw our grid in detail
var ourGridId = xform.GridUid;
if (EntManager.TryGetComponent(ourGridId, out var ourGrid) &&
fixturesQuery.HasComponent(ourGridId.Value))
{
- var ourGridMatrix = _transform.GetWorldMatrix(ourGridId.Value);
- var matrix = Matrix3x2.Multiply(ourGridMatrix, ourWorldMatrixInvert);
+ var ourGridToWorld = _transform.GetWorldMatrix(ourGridId.Value);
+ var ourGridToShuttle = Matrix3x2.Multiply(ourGridToWorld, worldToShuttle);
+ var ourGridToView = ourGridToShuttle * shuttleToView;
var color = _shuttles.GetIFFColor(ourGridId.Value, self: true);
- DrawGrid(handle, matrix, (ourGridId.Value, ourGrid), color);
- DrawDocks(handle, ourGridId.Value, matrix);
+ DrawGrid(handle, ourGridToView, (ourGridId.Value, ourGrid), color);
+ DrawDocks(handle, ourGridId.Value, ourGridToView);
}
- var invertedPosition = _coordinates.Value.Position - offset;
- invertedPosition.Y = -invertedPosition.Y;
- // Don't need to transform the InvWorldMatrix again as it's already offset to its position.
-
// Draw radar position on the station
- var radarPos = invertedPosition;
const float radarVertRadius = 2f;
-
var radarPosVerts = new Vector2[]
{
- ScalePosition(radarPos + new Vector2(0f, -radarVertRadius)),
- ScalePosition(radarPos + new Vector2(radarVertRadius / 2f, 0f)),
- ScalePosition(radarPos + new Vector2(0f, radarVertRadius)),
- ScalePosition(radarPos + new Vector2(radarVertRadius / -2f, 0f)),
+ ScalePosition(new Vector2(0f, -radarVertRadius)),
+ ScalePosition(new Vector2(radarVertRadius / 2f, 0f)),
+ ScalePosition(new Vector2(0f, radarVertRadius)),
+ ScalePosition(new Vector2(radarVertRadius / -2f, 0f)),
};
handle.DrawPrimitives(DrawPrimitiveTopology.TriangleFan, radarPosVerts, Color.Lime);
@@ -197,8 +202,8 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl
if (!_shuttles.CanDraw(gUid, gridBody, iff))
continue;
- var gridMatrix = _transform.GetWorldMatrix(gUid);
- var matty = Matrix3x2.Multiply(gridMatrix, ourWorldMatrixInvert);
+ var curGridToWorld = _transform.GetWorldMatrix(gUid);
+ var curGridToView = curGridToWorld * worldToShuttle * shuttleToView;
var labelColor = _shuttles.GetIFFColor(grid, self: false, iff);
var coordColor = new Color(labelColor.R * 0.8f, labelColor.G * 0.8f, labelColor.B * 0.8f, 0.5f);
@@ -213,8 +218,7 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl
{
var gridBounds = grid.Comp.LocalAABB;
- var gridCentre = Vector2.Transform(gridBody.LocalCenter, matty);
- gridCentre.Y = -gridCentre.Y;
+ var gridCentre = Vector2.Transform(gridBody.LocalCenter, curGridToView);
var distance = gridCentre.Length();
var labelText = Loc.GetString("shuttle-console-iff-label", ("name", labelName),
@@ -230,9 +234,8 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl
// y-offset the control to always render below the grid (vertically)
var yOffset = Math.Max(gridBounds.Height, gridBounds.Width) * MinimapScale / 1.8f;
- // The actual position in the UI. We centre the label by offsetting the matrix position
- // by half the label's width, plus the y-offset
- var gridScaledPosition = ScalePosition(gridCentre) - new Vector2(0, -yOffset);
+ // The actual position in the UI.
+ var gridScaledPosition = gridCentre - new Vector2(0, -yOffset);
// Normalize the grid position if it exceeds the viewport bounds
// normalizing it instead of clamping it preserves the direction of the vector and prevents corner-hugging
@@ -264,18 +267,32 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl
}
// Detailed view
- var gridAABB = gridMatrix.TransformBox(grid.Comp.LocalAABB);
+ var gridAABB = curGridToWorld.TransformBox(grid.Comp.LocalAABB);
// Skip drawing if it's out of range.
if (!gridAABB.Intersects(viewAABB))
continue;
- DrawGrid(handle, matty, grid, labelColor);
- DrawDocks(handle, gUid, matty);
+ DrawGrid(handle, curGridToView, grid, labelColor);
+ DrawDocks(handle, gUid, curGridToView);
}
+
+ // If we've set the controlling console, and it's on a different grid
+ // to the shuttle itself, then draw an additional marker to help the
+ // player determine where they are relative to the shuttle.
+ if (_consoleEntity != null && xformQuery.TryGetComponent(_consoleEntity, out var consoleXform))
+ {
+ if (consoleXform.ParentUid != _coordinates.Value.EntityId)
+ {
+ var consolePositionWorld = _transform.GetWorldPosition((EntityUid)_consoleEntity);
+ var p = Vector2.Transform(consolePositionWorld, worldToShuttle * shuttleToView);
+ handle.DrawCircle(p, 5, Color.ToSrgb(Color.Cyan), true);
+ }
+ }
+
}
- private void DrawDocks(DrawingHandleScreen handle, EntityUid uid, Matrix3x2 matrix)
+ private void DrawDocks(DrawingHandleScreen handle, EntityUid uid, Matrix3x2 gridToView)
{
if (!ShowDocks)
return;
@@ -283,33 +300,32 @@ public sealed partial class ShuttleNavControl : BaseShuttleControl
const float DockScale = 0.6f;
var nent = EntManager.GetNetEntity(uid);
+ const float sqrt2 = 1.41421356f;
+ const float dockRadius = DockScale * sqrt2;
+ // Worst-case bounds used to cull a dock:
+ Box2 viewBounds = new Box2(-dockRadius, -dockRadius, Size.X + dockRadius, Size.Y + dockRadius);
if (_docks.TryGetValue(nent, out var docks))
{
foreach (var state in docks)
{
var position = state.Coordinates.Position;
- var uiPosition = Vector2.Transform(position, matrix);
- if (uiPosition.Length() > (WorldRange * 2f) - DockScale)
+ var positionInView = Vector2.Transform(position, gridToView);
+ if (!viewBounds.Contains(positionInView))
+ {
continue;
+ }
var color = Color.ToSrgb(Color.Magenta);
var verts = new[]
{
- Vector2.Transform(position + new Vector2(-DockScale, -DockScale), matrix),
- Vector2.Transform(position + new Vector2(DockScale, -DockScale), matrix),
- Vector2.Transform(position + new Vector2(DockScale, DockScale), matrix),
- Vector2.Transform(position + new Vector2(-DockScale, DockScale), matrix),
+ Vector2.Transform(position + new Vector2(-DockScale, -DockScale), gridToView),
+ Vector2.Transform(position + new Vector2(DockScale, -DockScale), gridToView),
+ Vector2.Transform(position + new Vector2(DockScale, DockScale), gridToView),
+ Vector2.Transform(position + new Vector2(-DockScale, DockScale), gridToView),
};
- for (var i = 0; i < verts.Length; i++)
- {
- var vert = verts[i];
- vert.Y = -vert.Y;
- verts[i] = ScalePosition(vert);
- }
-
handle.DrawPrimitives(DrawPrimitiveTopology.TriangleFan, verts, color.WithAlpha(0.8f));
handle.DrawPrimitives(DrawPrimitiveTopology.LineStrip, verts, color);
}
diff --git a/Content.Client/Silicons/Laws/Ui/LawDisplay.xaml.cs b/Content.Client/Silicons/Laws/Ui/LawDisplay.xaml.cs
index 4e412df858..bb0dba2f57 100644
--- a/Content.Client/Silicons/Laws/Ui/LawDisplay.xaml.cs
+++ b/Content.Client/Silicons/Laws/Ui/LawDisplay.xaml.cs
@@ -9,6 +9,7 @@ using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.Prototypes;
+using Robust.Shared.Timing;
using Robust.Shared.Utility;
namespace Content.Client.Silicons.Laws.Ui;
@@ -18,8 +19,13 @@ public sealed partial class LawDisplay : Control
{
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IChatManager _chatManager = default!;
+ [Dependency] private readonly IGameTiming _timing = default!;
[Dependency] private readonly EntityManager _entityManager = default!;
+ private static readonly TimeSpan PressCooldown = TimeSpan.FromSeconds(3);
+
+ private readonly Dictionary