diff --git a/Content.Client/Atmos/Components/GasAnalyzerComponent.cs b/Content.Client/Atmos/Components/GasAnalyzerComponent.cs deleted file mode 100644 index 8f86235358..0000000000 --- a/Content.Client/Atmos/Components/GasAnalyzerComponent.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Content.Shared.Atmos.Components; - -namespace Content.Client.Atmos.Components -{ - [RegisterComponent] - internal sealed class GasAnalyzerComponent : SharedGasAnalyzerComponent - { - } -} diff --git a/Content.Client/Atmos/UI/GasAnalyzerBoundUserInterface.cs b/Content.Client/Atmos/UI/GasAnalyzerBoundUserInterface.cs index 6e6fd17d42..142fedc48f 100644 --- a/Content.Client/Atmos/UI/GasAnalyzerBoundUserInterface.cs +++ b/Content.Client/Atmos/UI/GasAnalyzerBoundUserInterface.cs @@ -1,5 +1,5 @@ using Robust.Client.GameObjects; -using static Content.Shared.Atmos.Components.SharedGasAnalyzerComponent; +using static Content.Shared.Atmos.Components.GasAnalyzerComponent; namespace Content.Client.Atmos.UI { @@ -16,7 +16,7 @@ namespace Content.Client.Atmos.UI { base.Open(); - _window = new GasAnalyzerWindow(this); + _window = new GasAnalyzerWindow(); _window.OnClose += OnClose; _window.OpenCentered(); } diff --git a/Content.Client/Atmos/UI/GasAnalyzerWindow.xaml.cs b/Content.Client/Atmos/UI/GasAnalyzerWindow.xaml.cs index 7f6edfede8..33c3e8644e 100644 --- a/Content.Client/Atmos/UI/GasAnalyzerWindow.xaml.cs +++ b/Content.Client/Atmos/UI/GasAnalyzerWindow.xaml.cs @@ -7,23 +7,17 @@ using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.CustomControls; using Robust.Client.AutoGenerated; -using Robust.Client.GameObjects; using Robust.Client.UserInterface.XAML; -using static Content.Shared.Atmos.Components.SharedGasAnalyzerComponent; +using static Content.Shared.Atmos.Components.GasAnalyzerComponent; namespace Content.Client.Atmos.UI { [GenerateTypedNameReferences] public sealed partial class GasAnalyzerWindow : DefaultWindow { - private GasAnalyzerBoundUserInterface _owner; - private IEntityManager _entityManager; - - public GasAnalyzerWindow(GasAnalyzerBoundUserInterface owner) + public GasAnalyzerWindow() { RobustXamlLoader.Load(this); - _entityManager = IoCManager.Resolve(); - _owner = owner; } public void Populate(GasAnalyzerUserMessage msg) @@ -74,7 +68,7 @@ namespace Content.Client.Atmos.UI _ => GridIcon.OverrideDirection }; - GridIcon.Sprite = _entityManager.GetComponent(msg.DeviceUid); + GridIcon.SetEntity(msg.DeviceUid); LeftPanel.RemoveAllChildren(); MiddlePanel.RemoveAllChildren(); RightPanel.RemoveAllChildren(); @@ -262,10 +256,9 @@ namespace Content.Client.Atmos.UI }); // This is the gas bar thingy var height = 30; - var minSize = 24; // This basically allows gases which are too small, to be shown properly - var gasBar = new SplitBar() + var gasBar = new SplitBar { - MinHeight = height + MinHeight = height, }; // Separator dataContainer.AddChild(new Control diff --git a/Content.Server/Atmos/Components/GasAnalyzerComponent.cs b/Content.Server/Atmos/Components/GasAnalyzerComponent.cs index e3bd45eb46..b2d10400cb 100644 --- a/Content.Server/Atmos/Components/GasAnalyzerComponent.cs +++ b/Content.Server/Atmos/Components/GasAnalyzerComponent.cs @@ -1,30 +1,18 @@ -using Content.Shared.Atmos.Components; -using Robust.Shared.Map; +namespace Content.Server.Atmos.Components; -namespace Content.Server.Atmos.Components +/// +/// Used to keep track of which analyzers are active for update purposes +/// +[RegisterComponent] +public sealed class ActiveGasAnalyzerComponent : Component { - [RegisterComponent] - [ComponentReference(typeof(SharedGasAnalyzerComponent))] - public sealed class GasAnalyzerComponent : SharedGasAnalyzerComponent - { - [ViewVariables] public EntityUid? Target; - [ViewVariables] public EntityUid User; - [ViewVariables] public EntityCoordinates? LastPosition; - [ViewVariables] public bool Enabled; - } + // Set to a tiny bit after the default because otherwise the user often gets a blank window when first using + [DataField("accumulatedFrameTime"), ViewVariables(VVAccess.ReadWrite)] + public float AccumulatedFrametime = 2.01f; /// - /// Used to keep track of which analyzers are active for update purposes + /// How often to update the analyzer /// - [RegisterComponent] - public sealed class ActiveGasAnalyzerComponent : Component - { - // Set to a tiny bit after the default because otherwise the user often gets a blank window when first using - public float AccumulatedFrametime = 2.01f; - - /// - /// How often to update the analyzer - /// - public float UpdateInterval = 1f; - } + [DataField("updateInterval"), ViewVariables(VVAccess.ReadWrite)] + public float UpdateInterval = 1f; } diff --git a/Content.Server/Atmos/EntitySystems/GasAnalyzerSystem.cs b/Content.Server/Atmos/EntitySystems/GasAnalyzerSystem.cs index 10cb79fadd..29ff787913 100644 --- a/Content.Server/Atmos/EntitySystems/GasAnalyzerSystem.cs +++ b/Content.Server/Atmos/EntitySystems/GasAnalyzerSystem.cs @@ -9,8 +9,7 @@ using Content.Shared.Interaction; using Content.Shared.Interaction.Events; using JetBrains.Annotations; using Robust.Server.GameObjects; -using Robust.Shared.Player; -using static Content.Shared.Atmos.Components.SharedGasAnalyzerComponent; +using static Content.Shared.Atmos.Components.GasAnalyzerComponent; namespace Content.Server.Atmos.EntitySystems { @@ -21,6 +20,7 @@ namespace Content.Server.Atmos.EntitySystems [Dependency] private readonly AtmosphereSystem _atmo = default!; [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly UserInterfaceSystem _userInterface = default!; + [Dependency] private readonly TransformSystem _transform = default!; public override void Initialize() { @@ -34,8 +34,8 @@ namespace Content.Server.Atmos.EntitySystems public override void Update(float frameTime) { - - foreach (var analyzer in EntityQuery()) + var query = EntityQueryEnumerator(); + while (query.MoveNext(out var uid, out var analyzer)) { // Don't update every tick analyzer.AccumulatedFrametime += frameTime; @@ -45,8 +45,8 @@ namespace Content.Server.Atmos.EntitySystems analyzer.AccumulatedFrametime -= analyzer.UpdateInterval; - if (!UpdateAnalyzer(analyzer.Owner)) - RemCompDeferred(analyzer.Owner); + if (!UpdateAnalyzer(uid)) + RemCompDeferred(uid); } } @@ -61,7 +61,7 @@ namespace Content.Server.Atmos.EntitySystems return; } ActivateAnalyzer(uid, component, args.User, args.Target); - OpenUserInterface(args.User, component); + OpenUserInterface(uid, args.User, component); args.Handled = true; } @@ -87,7 +87,7 @@ namespace Content.Server.Atmos.EntitySystems component.LastPosition = null; component.Enabled = true; Dirty(component); - UpdateAppearance(component); + UpdateAppearance(uid, component); if(!HasComp(uid)) AddComp(uid); UpdateAnalyzer(uid, component); @@ -98,7 +98,7 @@ namespace Content.Server.Atmos.EntitySystems /// private void OnDropped(EntityUid uid, GasAnalyzerComponent component, DroppedEvent args) { - if(args.User is { } userId && component.Enabled) + if(args.User is var userId && component.Enabled) _popup.PopupEntity(Loc.GetString("gas-analyzer-shutoff"), userId, userId); DisableAnalyzer(uid, component, args.User); } @@ -116,7 +116,7 @@ namespace Content.Server.Atmos.EntitySystems component.Enabled = false; Dirty(component); - UpdateAppearance(component); + UpdateAppearance(uid, component); RemCompDeferred(uid); } @@ -130,12 +130,15 @@ namespace Content.Server.Atmos.EntitySystems DisableAnalyzer(uid, component); } - private void OpenUserInterface(EntityUid user, GasAnalyzerComponent component) + private void OpenUserInterface(EntityUid uid, EntityUid user, GasAnalyzerComponent? component = null) { + if (!Resolve(uid, ref component, false)) + return; + if (!TryComp(user, out var actor)) return; - _userInterface.TryOpen(component.Owner, GasAnalyzerUiKey.Key, actor.PlayerSession); + _userInterface.TryOpen(uid, GasAnalyzerUiKey.Key, actor.PlayerSession); } /// @@ -157,7 +160,7 @@ namespace Content.Server.Atmos.EntitySystems if (component.LastPosition.HasValue) { // Check if position is out of range => don't update and disable - if (!component.LastPosition.Value.InRange(EntityManager, userPos, SharedInteractionSystem.InteractionRange)) + if (!component.LastPosition.Value.InRange(EntityManager, _transform, userPos, SharedInteractionSystem.InteractionRange)) { if(component.User is { } userId && component.Enabled) _popup.PopupEntity(Loc.GetString("gas-analyzer-shutoff"), userId, userId); @@ -169,7 +172,7 @@ namespace Content.Server.Atmos.EntitySystems var gasMixList = new List(); // Fetch the environmental atmosphere around the scanner. This must be the first entry - var tileMixture = _atmo.GetContainingMixture(component.Owner, true); + var tileMixture = _atmo.GetContainingMixture(uid, true); if (tileMixture != null) { gasMixList.Add(new GasMixEntry(Loc.GetString("gas-analyzer-window-environment-tab-label"), tileMixture.Pressure, tileMixture.Temperature, @@ -193,7 +196,7 @@ namespace Content.Server.Atmos.EntitySystems // gas analyzed was used on an entity, try to request gas data via event for override var ev = new GasAnalyzerScanEvent(); - RaiseLocalEvent(component.Target.Value, ev, false); + RaiseLocalEvent(component.Target.Value, ev); if (ev.GasMixtures != null) { @@ -223,7 +226,7 @@ namespace Content.Server.Atmos.EntitySystems if (gasMixList.Count == 0) return false; - _userInterface.TrySendUiMessage(component.Owner, GasAnalyzerUiKey.Key, + _userInterface.TrySendUiMessage(uid, GasAnalyzerUiKey.Key, new GasAnalyzerUserMessage(gasMixList.ToArray(), component.Target != null ? Name(component.Target.Value) : string.Empty, component.Target ?? EntityUid.Invalid, @@ -234,9 +237,9 @@ namespace Content.Server.Atmos.EntitySystems /// /// Sets the appearance based on the analyzers Enabled state /// - private void UpdateAppearance(GasAnalyzerComponent analyzer) + private void UpdateAppearance(EntityUid uid, GasAnalyzerComponent analyzer) { - _appearance.SetData(analyzer.Owner, GasAnalyzerVisuals.Enabled, analyzer.Enabled); + _appearance.SetData(uid, GasAnalyzerVisuals.Enabled, analyzer.Enabled); } /// diff --git a/Content.Shared/Atmos/Components/GasAnalyzerComponent.cs b/Content.Shared/Atmos/Components/GasAnalyzerComponent.cs new file mode 100644 index 0000000000..8a26059591 --- /dev/null +++ b/Content.Shared/Atmos/Components/GasAnalyzerComponent.cs @@ -0,0 +1,111 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Map; +using Robust.Shared.Serialization; + +namespace Content.Shared.Atmos.Components; + +[RegisterComponent, NetworkedComponent] +public sealed class GasAnalyzerComponent : Component +{ + [ViewVariables] + public EntityUid? Target; + + [ViewVariables] + public EntityUid User; + + [ViewVariables(VVAccess.ReadWrite)] + public EntityCoordinates? LastPosition; + + [DataField("enabled"), ViewVariables(VVAccess.ReadWrite)] + public bool Enabled; + + [Serializable, NetSerializable] + public enum GasAnalyzerUiKey + { + Key, + } + + /// + /// Atmospheric data is gathered in the system and sent to the user + /// + [Serializable, NetSerializable] + public sealed class GasAnalyzerUserMessage : BoundUserInterfaceMessage + { + public string DeviceName; + public EntityUid DeviceUid; + public bool DeviceFlipped; + public string? Error; + public GasMixEntry[] NodeGasMixes; + public GasAnalyzerUserMessage(GasMixEntry[] nodeGasMixes, string deviceName, EntityUid deviceUid, bool deviceFlipped, string? error = null) + { + NodeGasMixes = nodeGasMixes; + DeviceName = deviceName; + DeviceUid = deviceUid; + DeviceFlipped = deviceFlipped; + Error = error; + } + } + + /// + /// Contains information on a gas mix entry, turns into a tab in the UI + /// + [Serializable, NetSerializable] + public struct GasMixEntry + { + /// + /// Name of the tab in the UI + /// + public readonly string Name; + public readonly float Pressure; + public readonly float Temperature; + public readonly GasEntry[]? Gases; + + public GasMixEntry(string name, float pressure, float temperature, GasEntry[]? gases = null) + { + Name = name; + Pressure = pressure; + Temperature = temperature; + Gases = gases; + } + } + + /// + /// Individual gas entry data for populating the UI + /// + [Serializable, NetSerializable] + public struct GasEntry + { + public readonly string Name; + public readonly float Amount; + public readonly string Color; + + public GasEntry(string name, float amount, string color) + { + Name = name; + Amount = amount; + Color = color; + } + + public override string ToString() + { + // e.g. "Plasma: 2000 mol" + return Loc.GetString( + "gas-entry-info", + ("gasName", Name), + ("gasAmount", Amount)); + } + } + + [Serializable, NetSerializable] + public sealed class GasAnalyzerDisableMessage : BoundUserInterfaceMessage + { + + } +} + +[Serializable, NetSerializable] +public enum GasAnalyzerVisuals : byte +{ + Enabled, +} + diff --git a/Content.Shared/Atmos/Components/SharedGasAnalyzerComponent.cs b/Content.Shared/Atmos/Components/SharedGasAnalyzerComponent.cs deleted file mode 100644 index 2a167bf124..0000000000 --- a/Content.Shared/Atmos/Components/SharedGasAnalyzerComponent.cs +++ /dev/null @@ -1,99 +0,0 @@ -using Robust.Shared.GameStates; -using Robust.Shared.Serialization; - -namespace Content.Shared.Atmos.Components -{ - [NetworkedComponent()] - public abstract class SharedGasAnalyzerComponent : Component - { - - [Serializable, NetSerializable] - public enum GasAnalyzerUiKey - { - Key, - } - - /// - /// Atmospheric data is gathered in the system and sent to the user - /// - [Serializable, NetSerializable] - public sealed class GasAnalyzerUserMessage : BoundUserInterfaceMessage - { - public string DeviceName; - public EntityUid DeviceUid; - public bool DeviceFlipped; - public string? Error; - public GasMixEntry[] NodeGasMixes; - public GasAnalyzerUserMessage(GasMixEntry[] nodeGasMixes, string deviceName, EntityUid deviceUid, bool deviceFlipped, string? error = null) - { - NodeGasMixes = nodeGasMixes; - DeviceName = deviceName; - DeviceUid = deviceUid; - DeviceFlipped = deviceFlipped; - Error = error; - } - } - - /// - /// Contains information on a gas mix entry, turns into a tab in the UI - /// - [Serializable, NetSerializable] - public struct GasMixEntry - { - /// - /// Name of the tab in the UI - /// - public readonly string Name; - public readonly float Pressure; - public readonly float Temperature; - public readonly GasEntry[]? Gases; - - public GasMixEntry(string name, float pressure, float temperature, GasEntry[]? gases = null) - { - Name = name; - Pressure = pressure; - Temperature = temperature; - Gases = gases; - } - } - - /// - /// Individual gas entry data for populating the UI - /// - [Serializable, NetSerializable] - public struct GasEntry - { - public readonly string Name; - public readonly float Amount; - public readonly string Color; - - public GasEntry(string name, float amount, string color) - { - Name = name; - Amount = amount; - Color = color; - } - - public override string ToString() - { - // e.g. "Plasma: 2000 mol" - return Loc.GetString( - "gas-entry-info", - ("gasName", Name), - ("gasAmount", Amount)); - } - } - - [Serializable, NetSerializable] - public sealed class GasAnalyzerDisableMessage : BoundUserInterfaceMessage - { - public GasAnalyzerDisableMessage() {} - } - } - - [Serializable, NetSerializable] - public enum GasAnalyzerVisuals : byte - { - Enabled, - } -}