From 8ad7bea43de7d553eadcf66d9ea0b3dfaf26bc0a Mon Sep 17 00:00:00 2001 From: Whatstone Date: Thu, 7 Nov 2024 15:07:25 -0500 Subject: [PATCH 01/61] gaslock wip --- .../UI/GasPressurePumpBoundUserInterface.cs | 65 +++++++++++ .../Atmos/UI/GasPressurePumpWindow.xaml.cs | 65 +++++++++++ .../Atmos/UI/GasPressurePumpWindow.xaml_bak | 22 ++++ .../Atmos/Components/DockablePumpComponent.cs | 23 ++++ .../Atmos/EntitySystems/DockablePumpSystem.cs | 66 +++++++++++ .../NodeContainer/Nodes/DockablePipeNode.cs | 39 +++++++ .../Entities/Structures/Specific/gaslock.yml | 104 ++++++++++++++++++ 7 files changed, 384 insertions(+) create mode 100644 Content.Client/_NF/Atmos/UI/GasPressurePumpBoundUserInterface.cs create mode 100644 Content.Client/_NF/Atmos/UI/GasPressurePumpWindow.xaml.cs create mode 100644 Content.Client/_NF/Atmos/UI/GasPressurePumpWindow.xaml_bak create mode 100644 Content.Server/_NF/Atmos/Components/DockablePumpComponent.cs create mode 100644 Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs create mode 100644 Content.Server/_NF/NodeContainer/Nodes/DockablePipeNode.cs create mode 100644 Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml diff --git a/Content.Client/_NF/Atmos/UI/GasPressurePumpBoundUserInterface.cs b/Content.Client/_NF/Atmos/UI/GasPressurePumpBoundUserInterface.cs new file mode 100644 index 00000000000..5816f79c206 --- /dev/null +++ b/Content.Client/_NF/Atmos/UI/GasPressurePumpBoundUserInterface.cs @@ -0,0 +1,65 @@ +// using Content.Shared.Atmos; +// using Content.Shared.Atmos.Piping.Binary.Components; +// using Content.Shared.Localizations; +// using JetBrains.Annotations; +// using Robust.Client.GameObjects; +// using Robust.Client.UserInterface; + +// namespace Content.Client.Atmos.UI +// { +// /// +// /// Initializes a and updates it when new server messages are received. +// /// +// [UsedImplicitly] +// public sealed class BidiGasPressurePumpBoundUserInterface : BoundUserInterface +// { +// [ViewVariables] +// private const float MaxPressure = Atmospherics.MaxOutputPressure; + +// [ViewVariables] +// private GasPressurePumpWindow? _window; + +// public BidiGasPressurePumpBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) +// { +// } + +// protected override void Open() +// { +// base.Open(); + +// _window = this.CreateWindow(); + +// _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed; +// _window.PumpOutputPressureChanged += OnPumpOutputPressurePressed; +// } + +// private void OnToggleStatusButtonPressed() +// { +// if (_window is null) return; +// SendMessage(new GasPressurePumpToggleStatusMessage(_window.PumpStatus)); +// } + +// private void OnPumpOutputPressurePressed(string value) +// { +// var pressure = UserInputParser.TryFloat(value, out var parsed) ? parsed : 0f; +// if (pressure > MaxPressure) pressure = MaxPressure; + +// SendMessage(new GasPressurePumpChangeOutputPressureMessage(pressure)); +// } + +// /// +// /// Update the UI state based on server-sent info +// /// +// /// +// protected override void UpdateState(BoundUserInterfaceState state) +// { +// base.UpdateState(state); +// if (_window == null || state is not BidiGasPressurePumpBoundUserInterfaceState cast) +// return; + +// _window.Title = (cast.PumpLabel); +// _window.SetPumpStatus(cast.Enabled); +// _window.SetOutputPressure(cast.OutputPressure); +// } +// } +// } diff --git a/Content.Client/_NF/Atmos/UI/GasPressurePumpWindow.xaml.cs b/Content.Client/_NF/Atmos/UI/GasPressurePumpWindow.xaml.cs new file mode 100644 index 00000000000..bc667ce206d --- /dev/null +++ b/Content.Client/_NF/Atmos/UI/GasPressurePumpWindow.xaml.cs @@ -0,0 +1,65 @@ +// using System; +// using System.Collections.Generic; +// using System.Globalization; +// using Content.Client.Atmos.EntitySystems; +// using Content.Shared.Atmos; +// using Content.Shared.Atmos.Prototypes; +// 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.UI +// { +// /// +// /// Client-side UI used to control a gas pressure pump. +// /// +// [GenerateTypedNameReferences] +// public sealed partial class GasPressurePumpWindow : DefaultWindow +// { +// public bool PumpStatus = true; + +// public event Action? ToggleStatusButtonPressed; +// public event Action? PumpOutputPressureChanged; + +// public GasPressurePumpWindow() +// { +// RobustXamlLoader.Load(this); + +// ToggleStatusButton.OnPressed += _ => SetPumpStatus(!PumpStatus); +// ToggleStatusButton.OnPressed += _ => ToggleStatusButtonPressed?.Invoke(); + +// PumpPressureOutputInput.OnTextChanged += _ => SetOutputPressureButton.Disabled = false; +// SetOutputPressureButton.OnPressed += _ => +// { +// PumpOutputPressureChanged?.Invoke(PumpPressureOutputInput.Text ??= ""); +// SetOutputPressureButton.Disabled = true; +// }; + +// SetMaxPressureButton.OnPressed += _ => +// { +// PumpPressureOutputInput.Text = Atmospherics.MaxOutputPressure.ToString(CultureInfo.CurrentCulture); +// SetOutputPressureButton.Disabled = false; +// }; +// } + +// public void SetOutputPressure(float pressure) +// { +// PumpPressureOutputInput.Text = pressure.ToString(CultureInfo.CurrentCulture); +// } + +// public void SetPumpStatus(bool enabled) +// { +// PumpStatus = enabled; +// if (enabled) +// { +// ToggleStatusButton.Text = Loc.GetString("comp-gas-pump-ui-status-enabled"); +// } +// else +// { +// ToggleStatusButton.Text = Loc.GetString("comp-gas-pump-ui-status-disabled"); +// } +// } +// } +// } diff --git a/Content.Client/_NF/Atmos/UI/GasPressurePumpWindow.xaml_bak b/Content.Client/_NF/Atmos/UI/GasPressurePumpWindow.xaml_bak new file mode 100644 index 00000000000..ba1559c6cca --- /dev/null +++ b/Content.Client/_NF/Atmos/UI/GasPressurePumpWindow.xaml_bak @@ -0,0 +1,22 @@ + diff --git a/Content.Server/_NF/Atmos/Components/DockablePumpComponent.cs b/Content.Server/_NF/Atmos/Components/DockablePumpComponent.cs new file mode 100644 index 00000000000..c29275d1405 --- /dev/null +++ b/Content.Server/_NF/Atmos/Components/DockablePumpComponent.cs @@ -0,0 +1,23 @@ +namespace Content.Server._NF.Atmos.Components; + +[RegisterComponent] +public sealed partial class DockablePumpComponent : Component +{ + /// + /// The name of the node that is available to dock. + /// + [DataField] + public string DockNodeName; + + /// + /// The name of the internal node + /// + [DataField] + public string InternalNodeName; + + /// + /// If true, the pump will be pumping inwards (dock node to internal node). + /// + [DataField] + public bool PumpingInwards; +} diff --git a/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs b/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs new file mode 100644 index 00000000000..febc87d136c --- /dev/null +++ b/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs @@ -0,0 +1,66 @@ +using Content.Server._NF.Atmos.Components; +using Content.Server.Atmos.Piping.Binary.Components; +using Content.Server.NodeContainer; +using Content.Server.NodeContainer.EntitySystems; +using Content.Server.NodeContainer.Nodes; +using Content.Server.Shuttles.Events; +using Robust.Shared.Timing; + +namespace Content.Server._NF.Atmos.EntitySystems; + +public sealed partial class DockablePumpSystem : EntitySystem +{ + [Dependency] private readonly NodeContainerSystem _nodeContainer = default!; + [Dependency] private readonly NodeGroupSystem _nodeGroup = default!; + + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnDock); + SubscribeLocalEvent(OnUndock); + } + + public void SetPipeDirection(EntityUid uid, DockablePumpComponent component, bool inwards) + { + if (component.PumpingInwards == inwards) + return; + + if (TryComp(uid, out GasPressurePumpComponent? pressurePump)) + { + pressurePump.InletName = inwards ? component.DockNodeName : component.InternalNodeName; + pressurePump.OutletName = inwards ? component.InternalNodeName : component.DockNodeName; + } + else if (TryComp(uid, out GasVolumePumpComponent? volumePump)) + { + volumePump.InletName = inwards ? component.DockNodeName : component.InternalNodeName; + volumePump.OutletName = inwards ? component.InternalNodeName : component.DockNodeName; + } + else return; // Not a pump type we support. + + component.PumpingInwards = inwards; + } + + private void OnDock(EntityUid uid, DockablePumpComponent component, ref DockEvent args) + { + // Reflood node? + if (string.IsNullOrEmpty(component.DockNodeName) || + !TryComp(uid, out NodeContainerComponent? nodeContainer) || + !_nodeContainer.TryGetNode(nodeContainer, component.DockNodeName, out DockablePipeNode? dockablePipe)) + return; + + _nodeGroup.QueueReflood(dockablePipe); + } + + private void OnUndock(EntityUid uid, DockablePumpComponent component, ref UndockEvent args) + { + // Clean up node? + if (string.IsNullOrEmpty(component.DockNodeName) || + !TryComp(uid, out NodeContainerComponent? nodeContainer) || + !_nodeContainer.TryGetNode(nodeContainer, component.DockNodeName, out DockablePipeNode? dockablePipe)) + return; + + _nodeGroup.QueueNodeRemove(dockablePipe); + } +} diff --git a/Content.Server/_NF/NodeContainer/Nodes/DockablePipeNode.cs b/Content.Server/_NF/NodeContainer/Nodes/DockablePipeNode.cs new file mode 100644 index 00000000000..4cdd421d043 --- /dev/null +++ b/Content.Server/_NF/NodeContainer/Nodes/DockablePipeNode.cs @@ -0,0 +1,39 @@ +using Content.Server.Atmos; +using Content.Server.Shuttles.Components; +using Robust.Shared.Map.Components; + +namespace Content.Server.NodeContainer.Nodes +{ + [DataDefinition] + [Virtual] + public partial class DockablePipeNode : PipeNode, IGasMixtureHolder, IRotatableNode + { + + public override IEnumerable GetReachableNodes(TransformComponent xform, + EntityQuery nodeQuery, + EntityQuery xformQuery, + MapGridComponent? grid, + IEntityManager entMan) + { + foreach (var pipe in base.GetReachableNodes(xform, nodeQuery, xformQuery, grid, entMan)) + { + yield return pipe; + } + + if (!xform.Anchored || grid == null) + yield break; + + if (entMan.TryGetComponent(Owner, out DockingComponent? docking) + && docking.DockedWith != null + && nodeQuery.TryComp(docking.DockedWith, out var otherNode)) + { + // Hack: this doesn't take into account the direction of the dockable port. + foreach (var node in otherNode.Nodes.Values) + { + if (node is DockablePipeNode pipe) + yield return pipe; + } + } + } + } +} diff --git a/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml b/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml new file mode 100644 index 00000000000..d35452079f3 --- /dev/null +++ b/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml @@ -0,0 +1,104 @@ +- type: entity + parent: [GasBinaryBase, BaseStructure] + id: Gaslock + suffix: Docking + name: external gaslock + description: Connects gas tanks on separate ships or stations together to allow gas transfer. Both stages must be set up to accept flow. + components: + - type: Transform + noRot: false + - type: Rotatable + - type: Docking + radarColor: darkcyan + highlightedRadarColor: cyan + - type: DockingSignalControl + - type: DeviceLinkSource + ports: + - DockStatus + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.49,-0.49,0.49,0.49" # don't want this colliding with walls or they won't close + density: 100 + mask: + - FullTileMask + layer: + - AirlockLayer + docking: + shape: + !type:PhysShapeCircle + radius: 0.2 + position: "0,-0.5" + hard: false + - type: Sprite + sprite: Structures/Doors/Airlocks/Standard/shuttle.rsi + snapCardinals: false + layers: + - state: closed + map: ["enum.DoorVisualLayers.Base"] + - sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeHalf + map: [ "enum.PipeVisualLayers.Pipe" ] + - sprite: Structures/Piping/Atmospherics/pump.rsi + state: pumpPressure + map: [ "enum.SubfloorLayers.FirstLayer", "enabled" ] + - state: panel_open + map: ["enum.WiresVisualLayers.MaintenancePanel"] + - type: Wires + layoutId: Docking + - type: Airtight + - type: Tag + tags: + - ForceNoFixRotations + - type: PaintableAirlock + group: Shuttle + department: null + # - type: Construction + # graph: AirlockShuttle + # node: airlock + - type: StaticPrice + price: 350 + # - type: ApcPowerReceiver + # powerLoad: 200 + - type: Appearance + - type: GenericVisualizer + visuals: + enum.PumpVisuals.Enabled: + enabled: + True: { state: pumpPressureOn } + False: { state: pumpPressure } + - type: PipeColorVisuals + - type: GasPressurePump + enabled: false + - type: NodeContainer + nodes: + inlet: + !type:PipeNode + nodeGroupID: Pipe + pipeDirection: North + outlet: + !type:DockablePipeNode + nodeGroupID: Pipe + pipeDirection: South + - type: UserInterface + interfaces: + enum.GasPressurePumpUiKey.Key: + type: GasPressurePumpBoundUserInterface + - type: DockablePump + dockNodeName: outlet + internalNodeName: inlet + +- type: entity + parent: Gaslock + id: GaslockReversed + suffix: Docking, Reversed + name: external gaslock + description: Connects gas tanks on separate ships or stations together to allow gas transfer. Both stages must be set up to accept flow. + components: + - type: GasPressurePump + inlet: outlet + outlet: inlet + - type: DockablePump + pumpingInwards: true From 9ba8cff6f0edacdf6e639d90fee837b95efccc05 Mon Sep 17 00:00:00 2001 From: Whatstone Date: Sun, 10 Nov 2024 11:29:21 -0500 Subject: [PATCH 02/61] gaslock WIP --- .../Shuttles/UI/ShuttleDockControl.xaml.cs | 6 ++- .../Shuttles/UI/ShuttleNavControl.xaml.cs | 3 +- .../Shuttles/Systems/ShuttleConsoleSystem.cs | 2 + .../Shuttles/BUIStates/DockingPortState.cs | 5 ++ .../Entities/Structures/Specific/gaslock.yml | 46 ++++++++++++++++--- 5 files changed, 53 insertions(+), 9 deletions(-) diff --git a/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs index 6e3b46d707a..17cc981cf6c 100644 --- a/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs +++ b/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs @@ -224,11 +224,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); } /* diff --git a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs index bbb04d09ade..7cc480ca41c 100644 --- a/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs +++ b/Content.Client/Shuttles/UI/ShuttleNavControl.xaml.cs @@ -355,7 +355,8 @@ private void DrawDocks(DrawingHandleScreen handle, EntityUid uid, Matrix3x2 matr if (uiPosition.Length() > (WorldRange * 2f) - DockScale) 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.Server/Shuttles/Systems/ShuttleConsoleSystem.cs b/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.cs index c0c9f15594d..a1d3669ba92 100644 --- a/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.cs +++ b/Content.Server/Shuttles/Systems/ShuttleConsoleSystem.cs @@ -241,6 +241,8 @@ public Dictionary> GetAllDocks() _xformQuery.TryGetComponent(comp.DockedWith, out var otherDockXform) ? GetNetEntity(otherDockXform.GridUid) : null, + RadarColor = comp.RadarColor, // Frontier + HighlightedRadarColor = comp.HighlightedRadarColor, // Frontier }; gridDocks.Add(state); diff --git a/Content.Shared/Shuttles/BUIStates/DockingPortState.cs b/Content.Shared/Shuttles/BUIStates/DockingPortState.cs index a605c2ea77d..cbb4d1332dd 100644 --- a/Content.Shared/Shuttles/BUIStates/DockingPortState.cs +++ b/Content.Shared/Shuttles/BUIStates/DockingPortState.cs @@ -17,4 +17,9 @@ public sealed class DockingPortState public bool Connected => GridDockedWith != null; public NetEntity? GridDockedWith; + + // Frontier: colors + public Color RadarColor; + public Color HighlightedRadarColor; + // End Frontier } diff --git a/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml b/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml index d35452079f3..d10ea7eccfa 100644 --- a/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml +++ b/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml @@ -1,9 +1,12 @@ +# Giant mess of a YAML definition but largely based on GasBinaryBase and Airlock - type: entity parent: [GasBinaryBase, BaseStructure] id: Gaslock suffix: Docking name: external gaslock - description: Connects gas tanks on separate ships or stations together to allow gas transfer. Both stages must be set up to accept flow. + description: Connects gas pipes on separate ships or stations together to allow gas transfer. Both sides must be docked and pumping in the same direction to accept flow. + placement: + mode: SnapgridCenter components: - type: Transform noRot: false @@ -15,6 +18,13 @@ - type: DeviceLinkSource ports: - DockStatus + # - type: DeviceLinkSink + # ports: + # - PumpOn + # - PumpOff + # - DirectionIn + # - DirectionOut + # - ToggleDirection - type: Fixtures fixtures: fix1: @@ -34,12 +44,16 @@ hard: false - type: Sprite sprite: Structures/Doors/Airlocks/Standard/shuttle.rsi - snapCardinals: false + granularLayersRendering: true + drawdepth: Doors layers: - state: closed map: ["enum.DoorVisualLayers.Base"] + - state: closed_unlit + shader: unshaded + map: ["enum.DoorVisualLayers.BaseUnlit"] - sprite: Structures/Piping/Atmospherics/pipe.rsi - state: pipeHalf + state: pipeStraight map: [ "enum.PipeVisualLayers.Pipe" ] - sprite: Structures/Piping/Atmospherics/pump.rsi state: pumpPressure @@ -48,20 +62,23 @@ map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: Wires layoutId: Docking + - type: WiresVisuals + - type: WiresPanel + - type: WiresPanelSecurity - type: Airtight - type: Tag tags: - ForceNoFixRotations - type: PaintableAirlock - group: Shuttle + group: External department: null # - type: Construction # graph: AirlockShuttle # node: airlock - type: StaticPrice price: 350 - # - type: ApcPowerReceiver - # powerLoad: 200 + - type: ApcPowerReceiver + powerLoad: 500 - type: Appearance - type: GenericVisualizer visuals: @@ -89,6 +106,23 @@ - type: DockablePump dockNodeName: outlet internalNodeName: inlet + - type: AmbientSound + enabled: false + volume: -9 + range: 5 + sound: + path: /Audio/Ambience/Objects/gas_pump.ogg + - type: BlockWeather + - type: PlacementReplacement + key: walls + - type: IconSmooth + key: walls + mode: NoSprite + - type: Occluder + - type: InteractionOutline + - type: StationAiWhitelist + - type: RadiationBlocker + resistance: 3 - type: entity parent: Gaslock From ce5370e1023611c50e1adde31efe044828f19763 Mon Sep 17 00:00:00 2001 From: Whatstone Date: Mon, 11 Nov 2024 18:24:09 -0500 Subject: [PATCH 03/61] gaslock: entity's more or less good --- .../Atmos/EntitySystems/DockablePumpSystem.cs | 12 ++++- .../_NF/Atmos/Visuals/DockablePumpVisuals.cs | 11 +++++ .../Entities/Structures/Specific/gaslock.yml | 44 +++++++++++++----- .../Atmospherics/gaslock.rsi/bolted_unlit.png | Bin 0 -> 4972 bytes .../Atmospherics/gaslock.rsi/closed.png | Bin 0 -> 1395 bytes .../Piping/Atmospherics/gaslock.rsi/meta.json | 41 ++++++++++++++++ .../Atmospherics/gaslock.rsi/panel_open.png | Bin 0 -> 5073 bytes .../Atmospherics/gaslock.rsi/pumpPressure.png | Bin 0 -> 1035 bytes .../gaslock.rsi/pumpPressureOnIn.png | Bin 0 -> 425 bytes .../gaslock.rsi/pumpPressureOnOut.png | Bin 0 -> 423 bytes 10 files changed, 95 insertions(+), 13 deletions(-) create mode 100644 Content.Server/_NF/Atmos/Visuals/DockablePumpVisuals.cs create mode 100644 Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/bolted_unlit.png create mode 100644 Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/closed.png create mode 100644 Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/meta.json create mode 100644 Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/panel_open.png create mode 100644 Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/pumpPressure.png create mode 100644 Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/pumpPressureOnIn.png create mode 100644 Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/pumpPressureOnOut.png diff --git a/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs b/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs index febc87d136c..d46e01decc9 100644 --- a/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs +++ b/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs @@ -4,7 +4,6 @@ using Content.Server.NodeContainer.EntitySystems; using Content.Server.NodeContainer.Nodes; using Content.Server.Shuttles.Events; -using Robust.Shared.Timing; namespace Content.Server._NF.Atmos.EntitySystems; @@ -63,4 +62,15 @@ private void OnUndock(EntityUid uid, DockablePumpComponent component, ref Undock _nodeGroup.QueueNodeRemove(dockablePipe); } + + private void OnAppearanceChange(EntityUid uid, DockablePumpComponent component, ref UndockEvent args) + { + // Clean up node? + if (string.IsNullOrEmpty(component.DockNodeName) || + !TryComp(uid, out NodeContainerComponent? nodeContainer) || + !_nodeContainer.TryGetNode(nodeContainer, component.DockNodeName, out DockablePipeNode? dockablePipe)) + return; + + _nodeGroup.QueueNodeRemove(dockablePipe); + } } diff --git a/Content.Server/_NF/Atmos/Visuals/DockablePumpVisuals.cs b/Content.Server/_NF/Atmos/Visuals/DockablePumpVisuals.cs new file mode 100644 index 00000000000..ad64a37932a --- /dev/null +++ b/Content.Server/_NF/Atmos/Visuals/DockablePumpVisuals.cs @@ -0,0 +1,11 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.Atmos.Visuals +{ + [Serializable, NetSerializable] + public enum DockablePumpVisuals : byte + { + Docked, // bool + PumpingOutwards, // bool + } +} diff --git a/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml b/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml index d10ea7eccfa..6219bec2515 100644 --- a/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml +++ b/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml @@ -1,6 +1,6 @@ -# Giant mess of a YAML definition but largely based on GasBinaryBase and Airlock +# Giant mess of a YAML definition but largely based on GasPressurePump and AirlockShuttle - type: entity - parent: [GasBinaryBase, BaseStructure] + parent: BaseStructure id: Gaslock suffix: Docking name: external gaslock @@ -10,6 +10,7 @@ components: - type: Transform noRot: false + - type: Anchorable - type: Rotatable - type: Docking radarColor: darkcyan @@ -44,20 +45,23 @@ hard: false - type: Sprite sprite: Structures/Doors/Airlocks/Standard/shuttle.rsi - granularLayersRendering: true + # granularLayersRendering: true drawdepth: Doors layers: - state: closed - map: ["enum.DoorVisualLayers.Base"] - state: closed_unlit shader: unshaded - map: ["enum.DoorVisualLayers.BaseUnlit"] + map: ["enum.GaslockVisualLayers.Docked"] - sprite: Structures/Piping/Atmospherics/pipe.rsi state: pipeStraight map: [ "enum.PipeVisualLayers.Pipe" ] - sprite: Structures/Piping/Atmospherics/pump.rsi state: pumpPressure - map: [ "enum.SubfloorLayers.FirstLayer", "enabled" ] + map: [ "enabled" ] + - sprite: Structures/Piping/Atmospherics/pump.rsi + state: pumpPressureOnOut + map: [ "enabled-unlit" ] + shader: unshaded - state: panel_open map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: Wires @@ -66,9 +70,6 @@ - type: WiresPanel - type: WiresPanelSecurity - type: Airtight - - type: Tag - tags: - - ForceNoFixRotations - type: PaintableAirlock group: External department: null @@ -79,13 +80,22 @@ price: 350 - type: ApcPowerReceiver powerLoad: 500 + - type: ExtensionCableReceiver - type: Appearance - type: GenericVisualizer visuals: enum.PumpVisuals.Enabled: - enabled: - True: { state: pumpPressureOn } - False: { state: pumpPressure } + enabled-unlit: + True: { visible: true } + False: { visible: false } + enum.DockablePumpVisuals.Docked: + enum.GaslockVisualLayers.Docked: + True: { visible: true } + False: { visible: false } + enum.DockablePumpVisuals.PumpingOutward: + enum.GaslockVisualLayers.Docked: + True: { state: pumpPressureOnOut } + False: { state: pumpPressureOnIn } - type: PipeColorVisuals - type: GasPressurePump enabled: false @@ -123,6 +133,16 @@ - type: StationAiWhitelist - type: RadiationBlocker resistance: 3 + - type: AtmosDevice + - type: Tag + tags: + - Unstackable + - Pipe + - ForceNoFixRotations + - type: PipeAppearance + - type: PipeRestrictOverlap + - type: AtmosUnsafeUnanchor + - type: AtmosPipeColor - type: entity parent: Gaslock diff --git a/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/bolted_unlit.png b/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/bolted_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..844bd201f1004c8edc847d6c63f14162e048f7c3 GIT binary patch literal 4972 zcmeHKc~}!?6JHPk5fqfe52%Kq)`Lwp2f0j81SC-+DWKfSX0w5nT;w2tP!GIXX)Ac) z2`G319%!keSPN1W#RIj1rCJo!s(^x}MFQU@pyKoOAD`#ze{P=L?9My$o0;FtJIQ_} znjdIq<7xu{fSrKvAA)}qjHk6Fe$}L?p7`}&SS!=QKPe4C!9Od z^vvHb;)pX0dL`(&XX!zg)l2)>wbc!S0CpPjzA0?q#PlPbPKk_0S!v?&#YSl)2LRYT5H!u();G zT@l3%GxL`}_1fk(j<8@nlvBnxW7bt9_KLNK zj#H~gsAbZ)*~cnve+?V4VRM$ijyKNnJhygm<|E^S>1 z#&9drk~H0ad~wQ#AuK71dL5N$(PK-n>Kir1pRTy6uD><6thMC(C%Ha6{fnaL?nO&& z$5W3k%c9EuI^a237*w=ve;rlcQ%rN-*O+tS)y)N4z{R=?8&B@ILw@R3eB-KXUXVOs z>2b@04Z~LcnY?EQ&Aw*p*m31Tv&nR2-KhOLQ)%Vw8PkvjQ>yq)JM9{?R-EU4rMrRe`jT# zYEct_n8DJ=SZ zjKkjYNr~>Y&ve(Xd4#^X{~c(ceO?@bL}3}tWoujS?u{z&aTf1Ew>V$QPsLOh0ty4a zIKm^Z;;buZ))J?$MIN_oN;tVOJ;Q~rIgT!Y=TAO(@U!^#`3sTZ zR^h((y+D#i6Qa!?)4$a*syapW>v#I@@%naP+1V>$Wr(}TyOuwxdG_RrX%>qeW;1&z ztJYNqWz2Wn*x|moyW{0+Qcc;JYX)}O=AD;-yjk2@Z58o1!tUQrXzSio!wWY#Hfx$G znIwMiMO{M+vu^lW1D7T%4DGCj#Rb=E)NW;a3dRIG1UfC)o4%|DUES#%e=-KWy7ZOH z8g=7k>Mz(R&lLe)zN>)$EZ8JkvwB>K>(t31Cnj`v1iGK&leWc7g4AC5=1w^et@<(g@~MM=Q=^*&D>dy3PEX?eb+4?j=98u;va6kE&gKa2PGG@Rz8lF6$@vEJ>x& z+s|0Vv;mpHrzQMv9rK@Fd%U8X*0awGQjP2?K6Tc+JE;dKJb3t#ol0e$hF25#P*7FL;@z^5yQQOkWl4^CSd$DH5!^WKMYArMA#DIOdlI=3I_*}qgt4dB9|#N zoD?3>gv-J2jbbv9U{cX0@`w>a5y4NXMhSEhodkgaDOfU<=wn0RswGlRi2s~H2>gjh zOwejo95Pw2*OT-#l2RQ{rm)#;GDIa)sUWTaYEl(iI0aN_JdF?o82+dRQDZ7Crc@A& zn6Ox>)AEQ!e4X$%KDkOLdeL7tkc=v{oNLEkth*N!ZF=4 zSah+J%A|lyI$jPs1@#8mkhd6Qv&2*hn?{2e63P%LfkLB&6$omC!of)xj)TAwIs>M% zKstlL0O?dZ6@(>-6l6g(s+bO=EDD=G1R_|C;av&KhDK$ClHgEGgvFphcnmO%Kp>sP zpn+nRm=3a0Dus=Ty~R|P!~|um1IJe+;1Q`L=)FWFgSAqnTFxT|VG3Q!`-Lz}j)rPs zBWV-{jSVpwOeVyjQy8ov)(cU!25&ecCIuou zyxDlYVFaY%1!vK{8FZAvFs1PhU89t0^{^WCjmI;^v%wq4lnr5uiQ}msYU>kFBY_Z= z0#c|T#15l)b07wX0)Y^n13^UcV8UeMu6~;_m;67Ra7_wB#sF?NAj8KCKCQ^_#?>Ha zMjHRcW3U$gq6ZxMlar6)_Y+;8==vxIK1%shcYUJkqZs%o%AxPZtTFaD!B~*V+7BAo^$PtPqQfYr^8J z+e3rTRP1EgI~b4bbI+pIKchQ+Z?`;Gqf@+iW4^rGzieMq>Fec`IVwHxaa#PiQhW2< qmw%XP<{oXowhKM=Q&Re4tNGEOQ;&z$=;OF^KoBtBzjSuo%Krk1BzZ&t literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/closed.png b/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/closed.png new file mode 100644 index 0000000000000000000000000000000000000000..a2b900458d280568e1d948be4e24e2ae9db10c6b GIT binary patch literal 1395 zcmV-(1&sQMP)+-7g~o)B;WwBIS=Jt5;O3)qgec`}gm;xVX3> z-~_MLYX3^`N~J=zTIJ&6f{-&dRPEJi+`=j`kZ zUDpq0qbLf3Ah6kNP!z=-Q&p8%EatH_O_Ovwjjrp2!(qzh@?iqWWD-?XQ4|GD)5vDC z9^>V5$!fJi5Cp>EF!T8w+qRKq8QZpzB*`Uo8})h}fKsV+m_Vb^z%)&!(40%s@-mf zWm%Y}NhlN|o6XW{wOFs$42MH{y%Znxv;=!o@t&6h7<4ij)N91a1P&1Swi%d%*<+o-C_qeqXh zEQ@$NPP5r0l}h=VER)H&za>fX`3nJj`t%975g4b8A3uH!;^u0>VzJ=<{rjv|D|aji zs;au#13Y>1g#DNyfalMjA9QdVqtOU}?RHC}(ctCFmzM8G@DJ2y=j_vlJiu+FbvA&GVyqvWHK4pgbr-`<{o2N7U^^v zfcbn*G#d5Urcx>2{`U}Y8p2U2=a314(*vbaiQm6}W7{^}ZWs8oMfZ`(WH>oF@trFN zn@~{{S2pj`f$?~ZrfCR*Kq{4TWqUrKd+b$JWi%SO{Z%Lw*pKPcfmW+^FnfS+-@c*i zI`Md%$z(#IP;iNKyIn$|KxrYFOa_j7tn2l(5 ziasTr&1TH!bAJB(iD4MN1U&>wr4rZI*W_|JH^4re=cs9#ds?p7YqHraq9~$iny&(p zNQ6WpL9tlm^z@XIlM~OpuiNtZJlEIPfej^!BC;$q9*gK%_oM4?b1 z7K^!S_P46<5i}YN-+j-)VzF=~b-7$32m;Y)l+9*CI2h*fy)^o5gryo9iU_2gk@7_IRS?1}}r@r?HxH&cZ z{k~^T6h-&9P_0(&^Ye4y@4uRT{`{HOuV3@**)ssXe*H?VR^##G$A4>mrBVUl&6_vy ze**SD!P~cQePi$5z57Q#&d<;7YPD($|Mlzn{{X!U1VNK&ziR*h002ovPDHLkV1jFx Bx*Pxi literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/meta.json b/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/meta.json new file mode 100644 index 00000000000..4ed24298ad1 --- /dev/null +++ b/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/meta.json @@ -0,0 +1,41 @@ +{ + "version":1, + "size":{ + "x":32, + "y":32 + }, + "license":"CC-BY-SA-3.0", + "copyright":"closed, bolted_unlit taken from CEV-Eris at commit https://github.com/discordia-space/CEV-Eris/commit/14517938186858388656a6aee14bf47af9e9649f - then modified by 20kdc, AJCM-git and whatston3", + "copyright":"pump* taken from https://github.com/tgstation/tgstation at commit 57cd1d59ca019dd0e7811ac451f295f818e573da, modified by whatston3.", + "states":[ + { + "name":"bolted_unlit" + }, + { + "name":"closed" + }, + { + "name":"panel_open" + }, + { + "name":"pumpPressure", + "directions":4 + }, + { + "name":"pumpPressureOnIn", + "directions":4, + "delays":[ [ 0.1, 0.1, 0.1, 0.1, 0.1 ], + [ 0.1, 0.1, 0.1, 0.1, 0.1 ], + [ 0.1, 0.1, 0.1, 0.1, 0.1 ], + [ 0.1, 0.1, 0.1, 0.1, 0.1 ] ] + }, + { + "name":"pumpPressureOnOut", + "directions":4, + "delays":[ [ 0.1, 0.1, 0.1, 0.1, 0.1 ], + [ 0.1, 0.1, 0.1, 0.1, 0.1 ], + [ 0.1, 0.1, 0.1, 0.1, 0.1 ], + [ 0.1, 0.1, 0.1, 0.1, 0.1 ] ] + } + ] +} diff --git a/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/panel_open.png b/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/panel_open.png new file mode 100644 index 0000000000000000000000000000000000000000..d7d4122c087da40e3ec3a97fd193ff1b5dc9982d GIT binary patch literal 5073 zcmeH~X;>5I7RLi3I|3DyO&Wu!Q6`z}iv%i!CB;BkL{KYCk_kk}LJ}nAs%TggsuV?0 zf!hLtSS^TKs})5+)G8<-RzWMbg5nhgR8&N++(|&i=k|-wbNkKAlVs+7&-**){NFPt znJiv#fR(wEISPfc;smn8kZ-i^ZEB2sDm9uR6v}9pCL&4|2Bo0o3Ykcp2%}YNWKiTL*4z z7@?{UFMMhHVD=nm%?xk5+!tZF+Nu7v9Ah_5{T{zpZ}*$IJi8onGq0p|<-rTPm!uq6 z>84?Q>DrpT?&zhoyz723S54YBPd)YW&%=uXyaPtTF6tt(X7H`1_pw(>A>@~3Ruxdv6OZVyOjBIs+`R6FuunM2N3&GBm0}gAAsFr)2 zZC2*tF6=Gz7`?Ze+%YF;rb)I{wT0+)TgFSt^WW>w77BWUV_|Kz{WRGxgZ;6;aG2rZ2QXFYV{;*cWI>y_%3P%0GVWC~^Ok z2cbw-^z`AQ z-lXUcWUwu7JA!K{T#CIO>N^=L4--P6L5}|7l*s zPaRyNN=2y!36&Y1zVRerYSU5!-Y(+zWZbDwyt4HtUgnNp!M@`*Q?yAoePzyTHd(W0 zDr)P2sG5dtso5)|TFzwMAxRJO`uZGJFX9Kxz*R`Kj~hk?>sS2_y<#`i0yRP2S}*O{ zF<;<}{K<)k^Qokgy=6BDBc|8={q_VL+9eO3S9m?w!}rjOj@wO+7=OnTw5lVsL;Bju zDyKBtXu?gb%ysbe-D7VSN{jf5+)8dO+nK#-)MM&W=zMn16Bpy0=bjYno)wQSt!m6j zaI8OZVXx%&#goyaCRSZ=P3WfGVY`nmT79eRkt9F6J3g{K*DJ_%`i#)V@{(r9ax=xO z6Xr}s&`Hm&ZPvB*m5n_2zWw_MXOo+3F$3wQL-?Px9?T#>gSwsZP_9x2Vte%YWcZy8+XYVEzW*X^P1 z7_(1T9_byVIgJeEmwGLBL!k`P#lF5gj<4^#MuD`4qV?NZfel}|G{%INF94{3$DY>8_FxECG z7wxmy-hC(J=6@(SJHzhDMb@ZqRSaggPt_L=j2XO5#vL!x#_9&7m7_gu64t@w*BF;x zfsyHB!)*oK>%LqR+-)@IJ!P5ZcFd1cNI#U_>|8!%`moCwS9QDKsL9HHR9Z-8;^nHI z3T)5wb8j5ihtDwWGF+d~e0TX9`g&Ab`_gB|bh?qh#m+PRPy4^WdiO2s`lA7p1#OD# z`N9+u($Jm6NaK#;E@28}5*#Fy@nM`=B1alK3gzjomP3LBScT@pabhV8GjO^VgBA-} zm}L|$$d&uT@!~*@0uI*%M+h_t0)`Od?Pcz%W+DIytb)*LNupHARI@O8E)zM|4dXFr zy@@J;g^A+w(7rMSj3(pAI1unti`Nh_Ugl^|g;2x{WBX4akSi7@UZs*V@%WUK6kG}k zCsV}X2@D1U4-)Z2B7j%`%C%Azqz0r)HyvV}!G@Irg;=f<%cN)>6XMH~RV)k!nMc2i zPa@}X-{Ymq2^A1M@M=hoC*VN5M1r5ZLaFjwgFq$%`pXr{2;}z<9|kLB$qE7Nw+5D~ z+$JLeI9%R)f-a>vu|%#<3K8!kXF|byJ9)AqQEwv@;Ne7Afe1wneRbtTxu|A4T zH=|Eyav+Gi_xz8n-{r11My$A8CR-**);Z;{Sr}csOrcC57BcmxFeo5WMGPXqpwb8c znL_3Rd=iBLF!%&IM1}Yy29Y!g#gQsikW>KcPzW3+MmR7X5>jB00zhOs4Io2&GJ>Gd z0gw;DB$z=E!ZdgiB19oZsuD_^9F-0wL{NMINF<41GQgmL5I`mh1xO$ef}$}Y5Z#Z7DyE9r_gA9*)k!) zxDzF`1{UfaA?wDc1o4nG4o2?piGq4JF8+(n0*QPfnLy*pFjLiHCIpfw zDNG_60Le@c#Na0q#_R6tcNu%)|3?!~y}_h5fUFxIL)r_{t?=*L)r4j`8UM!D#9sW3 z9uV|rC!eJ6XSqJh^+^hRlJV#2`YhKcDey_gpR4QtCYSk#2Oe08{0mA!9%pK9Y&An3 zg^c+@0c_Nm?kGM}k%x?!$pfR6D3rx?-P-_FP~?CNny5HjKa=~GW_FGaB@a#xBSWbi z_Tq@B20^UD)P1pbTeYDZjSA?DF~RhPxxv7>^u+BKo~2rjWO|G(lf;f$@9R688dp|c z;kbQPb!0a!Q~Pc27)VW0v^CB4xK#8=Bg%B%zQoe$%2?gMt2cTNZAb_ pCl`emEsS?H9QOj6``67crXi8j0r@(OI0gv?#qkSfSNX(h{|hX=qALIZ literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/pumpPressure.png b/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/pumpPressure.png new file mode 100644 index 0000000000000000000000000000000000000000..2aae9af99be029249917c9e1a7bc631476307ac4 GIT binary patch literal 1035 zcmV+m1oZofP)bJ@Iff8($>5kxzJNEuwdWv;6HE&_vpXio5FyC zwv@g`TC~SO9)vq0hD(r3se(bc(qtb@p?l0dlv!fBt<7)eTtnvrfn}MU?{|JXnP29Y z(a>kaVlf^Hg)lQSgT=)~lu9M6tgOIs95fmYt=Im(`9Dnd6MYweMx&uQj&trF_3bMF z^ljAsG)*3l$I)yyF;cCP#}T4FIGV5VK_h~<%@+PzAG!2Ea?Zgy_uUUU073Kp@v(;E zi>~Xwr+}|4Aj5zk?fdtpeS07WK$Zcj_T4+TG5p;Ka=EN852OIdG(geLWM=Vg zcmPA@5UyRjj!b5j?4jpHP#6G!A#(_h^Di=)Srm)g+_vpY$p+!@04j{3{`d(1AZ=OX zzDQX>rU5Ex%fkHpJj&%Vs?{pFA95N@TNV};7I1KIfc^b_vH>a;#_%g+t`{og08|*m zFA@w;nRxUFb8~ap+uOt8;UT#nUo#+|&!bc-pUyE#YX}Z7H3g~2dI97B$eMywWG%wJ)&Lo4h>EO5*w-2$BMnh#x6hFL=^GX1p2lpDyt?*&H{fV5%ipIRKibLDPa8 zcMz3mg&>hgaLcmz&dv^BUS8&jM51pO!=7t`u~^J=u%Ehr)gcu{z5bk3C=?2XLZMJ7 z6pDVLr=mhHHNcB1wcWeNi%xpV)b8Yq8|u2wv)SwywQaZ0K3l67^#jLo5DI-LN`3CQ zt2mVs4iEU&?#6RFJesfZ(R|H~xUTCwm&@YDjq9i|hVk)nR2V}tnM8##3=a>Z!WdGi z6e^6tG|i9B4%JdAUQ4Ao02B%Z6bc0_EiIk9?rztqZJOpe4WTJK2v1(x-Q&410E0#Z zgGR(PaR1&kqR}WGJos=nXl!f@05CN*1pt_woCE+&OiTa(ZYGn6Mx*FFMHY!fU>Jt` zoYw~c48uSq^0D^KWb&Mb&=k)JPhQ%ci~eQtt|k+=H?~jnCky}p002ovPDHLk FV1hgM=3oE- literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/pumpPressureOnIn.png b/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/pumpPressureOnIn.png new file mode 100644 index 0000000000000000000000000000000000000000..67307e8c2d4a7ffcfa1f8e0a60d8cb61d00c4cff GIT binary patch literal 425 zcmeAS@N?(olHy`uVBq!ia0vp^3xK$RgAGXbBqvETFfbN)x;TbZ%z1nFpzmP=5w?Wp zDT%wdg_5}4lDJ!r=*hM@?@YKZ6w)~T#FbZ{Ikt`sDm6Km$PFNB+A*?``y_ zfBN-B@c*2Gf5B7#TPgfsd#e7;y!tv%)&F1iJhXEAEWhf{_kTY(bn^;dVA1;MKF49P zzr&5gZJZfQQ~xOYEx4$z@J4Y@vG0Or{{;tuY$ZF!cK-zzg%e8tZT#QN46zA9I@IT# zo?~`DcjktfS$!XvLW*NPhZY-Xe$Ba9BOGBX{WHQcQIB~Vot5a=eKecz3rn*o56TQ=W`k$+Jb{Q>k{pXbzEBQ(K`|fpo z|4y*6pc}!E5VTWzUCDu`db=(OZZCPs78C3K_|G5P{B?^X|DE6eeS7JauK1nrCgyp3 i&EZL9W`gNI@W+nPGMsgbx7+3GATdu@KbLh*2~7aRnX2Ic literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/pumpPressureOnOut.png b/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/pumpPressureOnOut.png new file mode 100644 index 0000000000000000000000000000000000000000..85a879fdfc6756586baf1bf05e5650d76843e6b8 GIT binary patch literal 423 zcmeAS@N?(olHy`uVBq!ia0vp^3xK$RgAGXbBqvETFfitMx;TbZ%z1k^Fzb+m2gK%8t)FN?(7bF5f{@V|JGlfMUgE&?NiqCIr{Zq{E|KiwZybD0!;vdhW}~ebu@Hr%VwG2X+_ zpStXsGw&+PLqBf{dziAXSvF61&i(H!Ui+Dxc(tk)f86W8;ElGzl?VA!i+)1b$c6yf z2joMvEWJz*=exSBTs0#s&7@O*{{9VpX+OW;w%puT#y#Wa{qL_crtSZ**M8>zu=3Im zGVBUyMgY0`t4a>^%GNC9&VSQ$JO9#I^Xa#D%`VW~UTXd@DerUMq05i&IG8W2G7GX~ gfCd!#SO+rE)78&qol`;+0KpunaR2}S literal 0 HcmV?d00001 From 47dc232b2b80f9a8b183beb9814db17d60ae48b2 Mon Sep 17 00:00:00 2001 From: Whatstone Date: Tue, 12 Nov 2024 15:02:28 -0500 Subject: [PATCH 04/61] deposits & drills, WIP --- .../Atmos/Components/DockablePumpComponent.cs | 1 - .../Components/RandomGasDepositComponent.cs | 21 ++ .../Atmos/EntitySystems/DockablePumpSystem.cs | 20 +- .../Atmos/Prototypes/GasDepositPrototype.cs | 20 ++ .../_NF/Atmos/Visuals/DockablePumpVisuals.cs | 11 -- .../Debris/RandomEntityPopulatorComponent.cs | 67 +++++++ .../Debris/RandomEntityPopulatorSystem.cs | 84 ++++++++ .../_NF/Atmos/Visuals/DockablePumpVisuals.cs | 10 + .../en-US/_NF/devices/device-network.ftl | 1 + Resources/Prototypes/_NF/Atmos/deposits.yml | 130 +++++++++++++ .../Specific/Atmospherics/deposits.yml | 108 +++++++++++ .../Structures/Piping/Atmospherics/unary.yml | 65 +++++++ .../Entities/Structures/Specific/gaslock.yml | 180 ++++++++++++------ .../_NF/Entities/World/Debris/asteroids.yml | 31 ++- .../Atmospherics/deposit.rsi/deposit.png | Bin 0 -> 440 bytes .../Atmospherics/deposit.rsi/meta.json | 14 ++ .../Atmospherics/gaslock.rsi/bolted_unlit.png | Bin 4972 -> 0 bytes .../Atmospherics/gaslock.rsi/closed_unlit.png | Bin 0 -> 158 bytes .../Atmospherics/gaslock.rsi/frame_struts.png | Bin 0 -> 143 bytes .../Piping/Atmospherics/gaslock.rsi/meta.json | 7 +- .../Atmospherics/gaslock.rsi/pipeStraight.png | Bin 0 -> 3619 bytes 21 files changed, 691 insertions(+), 79 deletions(-) create mode 100644 Content.Server/_NF/Atmos/Components/RandomGasDepositComponent.cs create mode 100644 Content.Server/_NF/Atmos/Prototypes/GasDepositPrototype.cs delete mode 100644 Content.Server/_NF/Atmos/Visuals/DockablePumpVisuals.cs create mode 100644 Content.Server/_NF/Worldgen/Components/Debris/RandomEntityPopulatorComponent.cs create mode 100644 Content.Server/_NF/Worldgen/Systems/Debris/RandomEntityPopulatorSystem.cs create mode 100644 Content.Shared/_NF/Atmos/Visuals/DockablePumpVisuals.cs create mode 100644 Resources/Locale/en-US/_NF/devices/device-network.ftl create mode 100644 Resources/Prototypes/_NF/Atmos/deposits.yml create mode 100644 Resources/Prototypes/_NF/Entities/Objects/Specific/Atmospherics/deposits.yml create mode 100644 Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml create mode 100644 Resources/Textures/_NF/Objects/Specific/Atmospherics/deposit.rsi/deposit.png create mode 100644 Resources/Textures/_NF/Objects/Specific/Atmospherics/deposit.rsi/meta.json delete mode 100644 Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/bolted_unlit.png create mode 100644 Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/closed_unlit.png create mode 100644 Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/frame_struts.png create mode 100644 Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/pipeStraight.png diff --git a/Content.Server/_NF/Atmos/Components/DockablePumpComponent.cs b/Content.Server/_NF/Atmos/Components/DockablePumpComponent.cs index c29275d1405..68345d4bada 100644 --- a/Content.Server/_NF/Atmos/Components/DockablePumpComponent.cs +++ b/Content.Server/_NF/Atmos/Components/DockablePumpComponent.cs @@ -1,6 +1,5 @@ namespace Content.Server._NF.Atmos.Components; -[RegisterComponent] public sealed partial class DockablePumpComponent : Component { /// diff --git a/Content.Server/_NF/Atmos/Components/RandomGasDepositComponent.cs b/Content.Server/_NF/Atmos/Components/RandomGasDepositComponent.cs new file mode 100644 index 00000000000..208e0e6ab9f --- /dev/null +++ b/Content.Server/_NF/Atmos/Components/RandomGasDepositComponent.cs @@ -0,0 +1,21 @@ +using Content.Shared.Atmos; +using Robust.Shared.Prototypes; + +namespace Content.Server._NF.Atmos.Components; + +[RegisterComponent] +public sealed partial class RandomGasDepositComponent : Component +{ + /// + /// The name of the node that is available to dock. + /// If null or invalid, will be selected from existing set at random. + /// + [DataField] + public ProtoId? DepositPrototype; + + /// + /// Gases left in the deposit. + /// + [ViewVariables] + public GasMixture Deposit; +} diff --git a/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs b/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs index d46e01decc9..17cb173d962 100644 --- a/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs +++ b/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs @@ -1,9 +1,12 @@ using Content.Server._NF.Atmos.Components; +using Content.Server.Atmos.EntitySystems; using Content.Server.Atmos.Piping.Binary.Components; using Content.Server.NodeContainer; using Content.Server.NodeContainer.EntitySystems; using Content.Server.NodeContainer.Nodes; using Content.Server.Shuttles.Events; +using Content.Shared.Atmos.Visuals; +using Robust.Server.GameObjects; namespace Content.Server._NF.Atmos.EntitySystems; @@ -11,6 +14,8 @@ public sealed partial class DockablePumpSystem : EntitySystem { [Dependency] private readonly NodeContainerSystem _nodeContainer = default!; [Dependency] private readonly NodeGroupSystem _nodeGroup = default!; + [Dependency] private readonly AtmosphereSystem _atmosphere = default!; + [Dependency] private readonly AppearanceSystem _appearance = default!; public override void Initialize() @@ -39,6 +44,7 @@ public void SetPipeDirection(EntityUid uid, DockablePumpComponent component, boo else return; // Not a pump type we support. component.PumpingInwards = inwards; + _appearance.SetData(uid, DockablePumpVisuals.PumpingOutwards, !inwards); } private void OnDock(EntityUid uid, DockablePumpComponent component, ref DockEvent args) @@ -50,6 +56,7 @@ private void OnDock(EntityUid uid, DockablePumpComponent component, ref DockEven return; _nodeGroup.QueueReflood(dockablePipe); + _appearance.SetData(uid, DockablePumpVisuals.Docked, true); } private void OnUndock(EntityUid uid, DockablePumpComponent component, ref UndockEvent args) @@ -61,16 +68,7 @@ private void OnUndock(EntityUid uid, DockablePumpComponent component, ref Undock return; _nodeGroup.QueueNodeRemove(dockablePipe); - } - - private void OnAppearanceChange(EntityUid uid, DockablePumpComponent component, ref UndockEvent args) - { - // Clean up node? - if (string.IsNullOrEmpty(component.DockNodeName) || - !TryComp(uid, out NodeContainerComponent? nodeContainer) || - !_nodeContainer.TryGetNode(nodeContainer, component.DockNodeName, out DockablePipeNode? dockablePipe)) - return; - - _nodeGroup.QueueNodeRemove(dockablePipe); + _atmosphere.ReleaseGasTo(dockablePipe.Air, null, dockablePipe.Air.Pressure); + _appearance.SetData(uid, DockablePumpVisuals.Docked, false); } } diff --git a/Content.Server/_NF/Atmos/Prototypes/GasDepositPrototype.cs b/Content.Server/_NF/Atmos/Prototypes/GasDepositPrototype.cs new file mode 100644 index 00000000000..9327b5dfdd0 --- /dev/null +++ b/Content.Server/_NF/Atmos/Prototypes/GasDepositPrototype.cs @@ -0,0 +1,20 @@ +using System.Numerics; +using Content.Shared.Atmos; +using Robust.Shared.Prototypes; + +namespace Content.Server._NF.Atmos +{ + [Prototype("gasDeposit")] + public sealed partial class GasDepositPrototype : IPrototype + { + [ViewVariables] + [IdDataField] + public string ID { get; private set; } = default!; + + /// + /// 2-vectors (minAmount, maxAmount) in moles of each gas in the deposit. + /// + [DataField] + public Vector2[] Gases { get; private set; } = new Vector2[Atmospherics.TotalNumberOfGases]; + } +} diff --git a/Content.Server/_NF/Atmos/Visuals/DockablePumpVisuals.cs b/Content.Server/_NF/Atmos/Visuals/DockablePumpVisuals.cs deleted file mode 100644 index ad64a37932a..00000000000 --- a/Content.Server/_NF/Atmos/Visuals/DockablePumpVisuals.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Robust.Shared.Serialization; - -namespace Content.Shared.Atmos.Visuals -{ - [Serializable, NetSerializable] - public enum DockablePumpVisuals : byte - { - Docked, // bool - PumpingOutwards, // bool - } -} diff --git a/Content.Server/_NF/Worldgen/Components/Debris/RandomEntityPopulatorComponent.cs b/Content.Server/_NF/Worldgen/Components/Debris/RandomEntityPopulatorComponent.cs new file mode 100644 index 00000000000..1395d6051f9 --- /dev/null +++ b/Content.Server/_NF/Worldgen/Components/Debris/RandomEntityPopulatorComponent.cs @@ -0,0 +1,67 @@ +using System.Linq; +using Content.Server.Worldgen.Systems.Debris; +using Content.Server.Worldgen.Tools; +using Content.Shared.Storage; + +namespace Content.Server.Worldgen.Components.Debris; + +/// +/// This is used for populating a grid with random entities automatically. +/// +[RegisterComponent] +[Access(typeof(RandomEntityPopulatorSystem))] +public sealed partial class RandomEntityPopulatorComponent : Component +{ + private List<(RandomEntityParameters Params, EntitySpawnCollectionCache Cache)>? _caches; + + /// + /// The prototype facing floor plan populator entries. + /// + [DataField("entries", required: true)] + private List _entries = default!; + + /// + /// The spawn collections used to place entities on different tile types. + /// + [ViewVariables] + public List<(RandomEntityParameters Params, EntitySpawnCollectionCache Cache)> Caches + { + get + { + if (_caches is null) + { + _caches = _entries + .Select(x => (x.Params, new EntitySpawnCollectionCache(x.Entries))) + .ToList(); + } + + return _caches; + } + } +} + +// A random set of entities to spawn +[DataDefinition] +public sealed partial class RandomEntityParameters +{ + // The minimum number of this entity to spawn. + // Actual number is generated in a uniform range between min and max. + // Each entity is independently selected from the entity list below. + [DataField] + public int Min = 1; + // The minimum number of this entity to spawn. + // Actual number is generated in a uniform range. + [DataField] + public int Max = 1; + [DataField] + public bool CanBeAirSealed = false; +} + +[DataDefinition] +public sealed partial class RandomEntityEntrySet +{ + [DataField] + public RandomEntityParameters Params; + [DataField] + public List Entries; +} diff --git a/Content.Server/_NF/Worldgen/Systems/Debris/RandomEntityPopulatorSystem.cs b/Content.Server/_NF/Worldgen/Systems/Debris/RandomEntityPopulatorSystem.cs new file mode 100644 index 00000000000..915b419b898 --- /dev/null +++ b/Content.Server/_NF/Worldgen/Systems/Debris/RandomEntityPopulatorSystem.cs @@ -0,0 +1,84 @@ +using Content.Server.Atmos.EntitySystems; +using Content.Server.Worldgen.Components.Debris; +using Robust.Server.GameObjects; +using Robust.Shared.Map; +using Robust.Shared.Map.Components; +using Robust.Shared.Random; + +namespace Content.Server.Worldgen.Systems.Debris; + +/// +/// This is for placing a finite, random number of entities on separate tiles on a structure. +/// +public sealed class RandomEntityPopulatorSystem : BaseWorldSystem +{ + [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly MapSystem _map = default!; + [Dependency] private readonly AtmosphereSystem _atmosphere = default!; + + /// + public override void Initialize() + { + SubscribeLocalEvent(OnFloorPlanBuilt); + } + + private void OnFloorPlanBuilt(EntityUid uid, RandomEntityPopulatorComponent component, LocalStructureLoadedEvent args) + { + if (!TryComp(uid, out var mapGrid)) + return; + + var placeables = new List(4); + // For each entity populator in the set, select a number between min and max + foreach (var (paramSet, cache) in component.Caches) + { + var numToGenerate = _random.Next(paramSet.Min, paramSet.Max + 1); + for (int i = 0; i < numToGenerate; i++) + { + // Then find a spot (if we can) - on any failure, assume the asteroid is full and move onto the next one, which may have different parameters + if (!SelectRandomTile(uid, mapGrid, paramSet.CanBeAirSealed, out var coords)) + break; + + cache.GetSpawns(_random, ref placeables); + + foreach (var proto in placeables) + { + if (proto is null) + continue; + + Spawn(proto, coords); + } + } + } + } + + private bool SelectRandomTile(EntityUid gridUid, + MapGridComponent mapComp, + bool canBeAirSealed, + out EntityCoordinates targetCoords) + { + targetCoords = default; + + var aabb = mapComp.LocalAABB; + + bool found = false; + // Try to place on the local bounding box - this may fail. + for (var i = 0; i < 25; i++) + { + var randomX = _random.Next((int)aabb.Left, (int)aabb.Right); + var randomY = _random.Next((int)aabb.Bottom, (int)aabb.Top); + + var tile = new Vector2i(randomX, randomY); + if (_atmosphere.IsTileSpace(gridUid, Transform(gridUid).MapUid, tile) + || !canBeAirSealed && _atmosphere.IsTileAirBlocked(gridUid, tile, mapGridComp: mapComp)) + { + continue; + } + + found = true; + targetCoords = _map.GridTileToLocal(gridUid, mapComp, tile); + break; + } + + return found; + } +} diff --git a/Content.Shared/_NF/Atmos/Visuals/DockablePumpVisuals.cs b/Content.Shared/_NF/Atmos/Visuals/DockablePumpVisuals.cs new file mode 100644 index 00000000000..815438d0b1c --- /dev/null +++ b/Content.Shared/_NF/Atmos/Visuals/DockablePumpVisuals.cs @@ -0,0 +1,10 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared.Atmos.Visuals; + +[Serializable, NetSerializable] +public enum DockablePumpVisuals : byte +{ + Docked, // bool + PumpingOutwards, // bool +} diff --git a/Resources/Locale/en-US/_NF/devices/device-network.ftl b/Resources/Locale/en-US/_NF/devices/device-network.ftl new file mode 100644 index 00000000000..0c6ec588d3e --- /dev/null +++ b/Resources/Locale/en-US/_NF/devices/device-network.ftl @@ -0,0 +1 @@ +device-address-prefix-gas-drill = GDL- diff --git a/Resources/Prototypes/_NF/Atmos/deposits.yml b/Resources/Prototypes/_NF/Atmos/deposits.yml new file mode 100644 index 00000000000..90f3d26d18a --- /dev/null +++ b/Resources/Prototypes/_NF/Atmos/deposits.yml @@ -0,0 +1,130 @@ +# Generation presets for gas deposits +- type: gasDeposit + id: AirLike + gases: + - 10000, 15000 # oxygen + - 40000, 50000 # nitrogen + - 0, 1500 # carbon dioxide + - 0, 200 # plasma + - 0, 10 # tritium + - 0, 500 # water vapor + - 0, 500 # ammonia + - 0, 200 # nitrous oxide + - 0, 0 # frezon + +- type: gasDeposit + id: MostlyNitrogen + gases: + - 0, 2000 # oxygen + - 60000, 70000 # nitrogen + - 0, 1500 # carbon dioxide + - 0, 200 # plasma + - 0, 10 # tritium + - 0, 500 # water vapor + - 0, 500 # ammonia + - 0, 200 # nitrous oxide + - 0, 0 # frezon + +- type: gasDeposit + id: MostlyOxygen + gases: + - 60000, 70000 # oxygen + - 0, 2000 # nitrogen + - 0, 1500 # carbon dioxide + - 0, 200 # plasma + - 0, 10 # tritium + - 0, 500 # water vapor + - 0, 500 # ammonia + - 0, 200 # nitrous oxide + - 0, 0 # frezon + +- type: gasDeposit + id: MostlyCarbonDioxide + gases: + - 0, 2000 # oxygen + - 0, 1500 # nitrogen + - 60000, 70000 # carbon dioxide + - 0, 200 # plasma + - 0, 10 # tritium + - 0, 500 # water vapor + - 0, 500 # ammonia + - 0, 200 # nitrous oxide + - 0, 0 # frezon + +- type: gasDeposit + id: MostlyNitrousOxide + gases: + - 0, 2000 # oxygen + - 0, 1500 # nitrogen + - 0, 200 # carbon dioxide + - 0, 200 # plasma + - 0, 10 # tritium + - 0, 500 # water vapor + - 0, 500 # ammonia + - 60000, 70000 # n2o + - 0, 0 # frezon + +- type: gasDeposit + id: MostlyAmmonia + gases: + - 0, 2000 # oxygen + - 0, 1500 # nitrogen + - 0, 200 # carbon dioxide + - 0, 200 # plasma + - 0, 10 # tritium + - 0, 500 # water vapor + - 60000, 70000 # ammonia + - 0, 500 # n2o + - 0, 0 # frezon + +- type: gasDeposit + id: MostlyWaterVapor + gases: + - 0, 2000 # oxygen + - 0, 1500 # nitrogen + - 0, 200 # carbon dioxide + - 0, 200 # plasma + - 0, 10 # tritium + - 60000, 70000 # water vapor + - 0, 500 # ammonia + - 0, 500 # n2o + - 0, 0 # frezon + +- type: gasDeposit + id: MostlyTritium + gases: + - 0, 2000 # oxygen + - 0, 1500 # nitrogen + - 0, 200 # carbon dioxide + - 0, 5000 # plasma + - 15000, 20000 # tritium + - 0, 5000 # water vapor + - 0, 5000 # ammonia + - 0, 5000 # n2o + - 0, 0 # frezon + +- type: gasDeposit + id: MostlyPlasma + gases: + - 0, 2000 # oxygen + - 0, 1500 # nitrogen + - 0, 200 # carbon dioxide + - 30000, 50000 # plasma + - 0, 10 # tritium + - 0, 5000 # water vapor + - 0, 5000 # ammonia + - 0, 5000 # n2o + - 0, 0 # frezon + +- type: gasDeposit + id: MostlyFrezon + gases: + - 0, 5000 # oxygen + - 0, 0 # nitrogen (must be zero) + - 0, 5000 # carbon dioxide + - 0, 500 # plasma + - 0, 10 # tritium + - 0, 5000 # water vapor + - 0, 5000 # ammonia + - 0, 5000 # n2o + - 10000, 15000 # frezon diff --git a/Resources/Prototypes/_NF/Entities/Objects/Specific/Atmospherics/deposits.yml b/Resources/Prototypes/_NF/Entities/Objects/Specific/Atmospherics/deposits.yml new file mode 100644 index 00000000000..2974b17a0d4 --- /dev/null +++ b/Resources/Prototypes/_NF/Entities/Objects/Specific/Atmospherics/deposits.yml @@ -0,0 +1,108 @@ +# TODO move all of this to tiles once tile smoothing is supported +- type: entity + id: BaseGasDeposit + name: gas deposit + description: Solidified deposits of an element, normally a gas at room temperature, can be drilled, heated and piped out." + abstract: true + placement: + mode: SnapgridCenter + components: + - type: Transform + anchored: true + - type: Clickable + - type: Physics + bodyType: Static + - type: Fixtures + - type: RandomGasDeposit + - type: Sprite + sprite: _NF/Objects/Specific/Atmospherics/deposit.rsi + layers: + - state: deposit + +- type: entity + parent: BaseGasDeposit + id: OxygenGasDeposit + components: + - type: RandomGasDeposit + deposit: MostlyOxygen + - type: Sprite + color: "#DDDDEE" + +- type: entity + parent: BaseGasDeposit + id: NitrogenGasDeposit + components: + - type: RandomGasDeposit + deposit: MostlyNitrogen + - type: Sprite + color: "#FFCCCC" + +- type: entity + parent: BaseGasDeposit + id: CarbonDioxideGasDeposit + components: + - type: RandomGasDeposit + deposit: MostlyCarbonDioxide + - type: Sprite + color: "#CCCCCC" + +- type: entity + parent: BaseGasDeposit + id: PlasmaGasDeposit + components: + - type: RandomGasDeposit + deposit: MostlyPlasma + - type: Sprite + color: "#FFCCFF" + +- type: entity + parent: BaseGasDeposit + id: AmmoniaGasDeposit + components: + - type: RandomGasDeposit + deposit: MostlyAmmonia + - type: Sprite + color: "#FFFFCC" + +- type: entity + parent: BaseGasDeposit + id: TritiumGasDeposit + components: + - type: RandomGasDeposit + deposit: MostlyTritium + - type: Sprite + color: "#CCFFCC" + +- type: entity + parent: BaseGasDeposit + id: WaterVaporGasDeposit + components: + - type: RandomGasDeposit + deposit: MostlyWaterVapor + - type: Sprite + color: "#DDEEEE" + +- type: entity + parent: BaseGasDeposit + id: NitrousOxideGasDeposit + components: + - type: RandomGasDeposit + deposit: MostlyNitrousOxide + - type: Sprite + color: "#EEDDDD" + +- type: entity + parent: BaseGasDeposit + id: FrezonGasDeposit + components: + - type: RandomGasDeposit + deposit: MostlyFrezon + - type: Sprite + color: "#CCCCFF" + +- type: entity + parent: BaseGasDeposit + id: AirGasDeposit + components: + - type: RandomGasDeposit + deposit: AirLike diff --git a/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml b/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml new file mode 100644 index 00000000000..0984400102c --- /dev/null +++ b/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml @@ -0,0 +1,65 @@ +- type: entity + parent: [ BaseMachinePowered, ConstructibleMachine ] + id: GasMiningDrill + name: gas mining drill + description: A powerful, luggable drill for mining gas deposits on asteroids. Outputs gas through a pipe. + abstract: true + placement: + mode: SnapgridCenter + components: + - type: Appearance + - type: PipeColorVisuals + - type: Rotatable + - type: AtmosPipeColor + - type: AtmosDevice + # - type: UserInterface # FIXME + # interfaces: # FIXME + # enum.ThermomachineUiKey.Key: # FIXME + # type: GasThermomachineBoundUserInterface # FIXME + - type: ActivatableUI + inHandsOnly: false + # key: enum.ThermomachineUiKey.Key # FIXME + - type: WiresPanel + - type: WiresVisuals + - type: PipeRestrictOverlap + - type: NodeContainer + nodes: + pipe: + !type:PipeNode + nodeGroupID: Pipe + pipeDirection: South + - type: Transform + noRot: false + - type: DeviceNetwork + deviceNetId: AtmosDevices + receiveFrequencyId: AtmosMonitor + transmitFrequencyId: AtmosMonitor + sendBroadcastAttemptEvent: true + examinableAddress: true + - type: WiredNetworkConnection + - type: PowerSwitch + - type: StationAiWhitelist + - type: Sprite + sprite: Structures/Piping/Atmospherics/thermomachine.rsi + snapCardinals: true + granularLayersRendering: true + layers: + - state: freezerOff + map: [ "enum.PowerDeviceVisualLayers.Powered" ] + - state: freezerPanelOpen + map: [ "enum.WiresVisualLayers.MaintenancePanel" ] + - state: pipe + map: [ "enum.PipeVisualLayers.Pipe" ] + renderingStrategy: Default + - type: GenericVisualizer + visuals: + enum.PowerDeviceVisuals.Powered: + enum.PowerDeviceVisualLayers.Powered: + True: { state: freezerOn } + False: { state: freezerOff } + - type: ApcPowerReceiver + load: 4000 + - type: Machine + board: Null # FIXME + - type: DeviceNetwork + prefix: device-address-prefix-gas-drill diff --git a/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml b/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml index 6219bec2515..02f3ef76ea6 100644 --- a/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml +++ b/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml @@ -1,12 +1,10 @@ # Giant mess of a YAML definition but largely based on GasPressurePump and AirlockShuttle - type: entity parent: BaseStructure - id: Gaslock + id: BaseGaslock suffix: Docking name: external gaslock description: Connects gas pipes on separate ships or stations together to allow gas transfer. Both sides must be docked and pumping in the same direction to accept flow. - placement: - mode: SnapgridCenter components: - type: Transform noRot: false @@ -43,59 +41,21 @@ radius: 0.2 position: "0,-0.5" hard: false - - type: Sprite - sprite: Structures/Doors/Airlocks/Standard/shuttle.rsi - # granularLayersRendering: true - drawdepth: Doors - layers: - - state: closed - - state: closed_unlit - shader: unshaded - map: ["enum.GaslockVisualLayers.Docked"] - - sprite: Structures/Piping/Atmospherics/pipe.rsi - state: pipeStraight - map: [ "enum.PipeVisualLayers.Pipe" ] - - sprite: Structures/Piping/Atmospherics/pump.rsi - state: pumpPressure - map: [ "enabled" ] - - sprite: Structures/Piping/Atmospherics/pump.rsi - state: pumpPressureOnOut - map: [ "enabled-unlit" ] - shader: unshaded - - state: panel_open - map: ["enum.WiresVisualLayers.MaintenancePanel"] - type: Wires layoutId: Docking - type: WiresVisuals - type: WiresPanel - type: WiresPanelSecurity - - type: Airtight - type: PaintableAirlock group: External department: null # - type: Construction # graph: AirlockShuttle # node: airlock - - type: StaticPrice - price: 350 - type: ApcPowerReceiver powerLoad: 500 - type: ExtensionCableReceiver - type: Appearance - - type: GenericVisualizer - visuals: - enum.PumpVisuals.Enabled: - enabled-unlit: - True: { visible: true } - False: { visible: false } - enum.DockablePumpVisuals.Docked: - enum.GaslockVisualLayers.Docked: - True: { visible: true } - False: { visible: false } - enum.DockablePumpVisuals.PumpingOutward: - enum.GaslockVisualLayers.Docked: - True: { state: pumpPressureOnOut } - False: { state: pumpPressureOnIn } - type: PipeColorVisuals - type: GasPressurePump enabled: false @@ -122,33 +82,79 @@ range: 5 sound: path: /Audio/Ambience/Objects/gas_pump.ogg - - type: BlockWeather - - type: PlacementReplacement - key: walls - - type: IconSmooth - key: walls - mode: NoSprite - - type: Occluder - type: InteractionOutline - type: StationAiWhitelist - - type: RadiationBlocker - resistance: 3 - type: AtmosDevice - type: Tag tags: - Unstackable - Pipe - - ForceNoFixRotations - type: PipeAppearance - type: PipeRestrictOverlap - type: AtmosUnsafeUnanchor - type: AtmosPipeColor +- type: entity + parent: BaseGaslock + id: Gaslock + suffix: Airtight + placement: + mode: SnapgridCenter + components: + - type: Airtight + - type: RadiationBlocker + resistance: 3 + - type: Occluder + - type: Sprite + sprite: _NF/Structures/Piping/Atmospherics/gaslock.rsi + # granularLayersRendering: true + drawdepth: Doors + layers: + - state: closed + - state: closed_unlit + shader: unshaded + map: ["enum.GaslockVisualLayers.Docked"] + - state: pipeStraight + map: [ "enum.PipeVisualLayers.Pipe" ] + - state: pumpPressure + map: [ "enabled" ] + - state: pumpPressureOnOut + map: [ "enabled-unlit" ] + shader: unshaded + - state: panel_open + map: ["enum.WiresVisualLayers.MaintenancePanel"] + - type: GenericVisualizer + visuals: + enum.PumpVisuals.Enabled: + enabled-unlit: + True: { visible: true } + False: { visible: false } + enum.DockablePumpVisuals.Docked: + enum.GaslockVisualLayers.Docked: + True: { visible: true } + False: { visible: false } + enum.DockablePumpVisuals.PumpingOutward: + enum.GaslockVisualLayers.Docked: + True: { state: pumpPressureOnOut } + False: { state: pumpPressureOnIn } + - type: StaticPrice + price: 350 + - type: Tag + tags: + - Unstackable + - Pipe + - ForceNoFixRotations + - type: BlockWeather + - type: PlacementReplacement + key: walls + - type: IconSmooth + key: walls + mode: NoSprite + - type: entity parent: Gaslock id: GaslockReversed - suffix: Docking, Reversed - name: external gaslock + suffix: Airtight, Reversed description: Connects gas tanks on separate ships or stations together to allow gas transfer. Both stages must be set up to accept flow. components: - type: GasPressurePump @@ -156,3 +162,71 @@ outlet: inlet - type: DockablePump pumpingInwards: true + +- type: entity + parent: BaseGaslock + id: GaslockFrame + suffix: Docking + name: gas staging port + description: Connects gas pipes on separate ships or stations together to allow gas transfer. Both sides must be docked and pumping in the same direction to accept flow. + placement: + mode: SnapgridCenter + components: + - type: Sprite + sprite: _NF/Structures/Piping/Atmospherics/gaslock.rsi + # granularLayersRendering: true + drawdepth: Doors + layers: + - sprite: Structures/Walls/solid.rsi + state: wall_girder + - state: frame_struts + - state: closed_unlit + shader: unshaded + map: ["enum.GaslockVisualLayers.Docked"] + state: pipeStraight + map: [ "enum.PipeVisualLayers.Pipe" ] + state: pumpPressure + map: [ "enabled" ] + state: pumpPressureOnOut + map: [ "enabled-unlit" ] + shader: unshaded + - state: panel_open + map: ["enum.WiresVisualLayers.MaintenancePanel"] + - type: GenericVisualizer + visuals: + enum.PumpVisuals.Enabled: + enabled-unlit: + True: { visible: true } + False: { visible: false } + enum.DockablePumpVisuals.Docked: + enum.GaslockVisualLayers.Docked: + True: { visible: true } + False: { visible: false } + enum.DockablePumpVisuals.PumpingOutward: + enum.GaslockVisualLayers.Docked: + True: { state: pumpPressureOnOut } + False: { state: pumpPressureOnIn } + - type: StaticPrice + price: 100 + - type: Tag + tags: + - Unstackable + - Pipe + - ForceNoFixRotations + - type: BlockWeather + - type: PlacementReplacement + key: walls + - type: IconSmooth + key: walls + mode: NoSprite + +- type: entity + parent: GaslockFrame + id: GaslockFrameReversed + suffix: Docking, Reversed + components: + - type: GasPressurePump + inlet: outlet + outlet: inlet + - type: DockablePump + pumpingInwards: true diff --git a/Resources/Prototypes/_NF/Entities/World/Debris/asteroids.yml b/Resources/Prototypes/_NF/Entities/World/Debris/asteroids.yml index db359f817c8..e17fc0df63c 100644 --- a/Resources/Prototypes/_NF/Entities/World/Debris/asteroids.yml +++ b/Resources/Prototypes/_NF/Entities/World/Debris/asteroids.yml @@ -60,6 +60,23 @@ - type: IFF flags: HideLabel color: "#d67e27" + - type: RandomEntityPopulator + entries: &gasDeposits + - params: + min: 0 + max: 2 + canBeAirSealed: true + entries: + - OxygenGasDeposit + - NitrogenGasDeposit + - CarbonDioxideGasDeposit + - PlasmaGasDeposit + - AmmoniaGasDeposit + - TritiumGasDeposit + - WaterVaporGasDeposit + - NitrousOxideGasDeposit + - FrezonGasDeposit + - AirGasDeposit # Snow - type: entity @@ -120,6 +137,8 @@ orGroup: rock - type: IFF color: "#d6fffc" + - type: RandomEntityPopulator + entries: *gasDeposits # Andesite - type: entity @@ -180,6 +199,8 @@ orGroup: rock - type: IFF color: "#95c280" + - type: RandomEntityPopulator + entries: *gasDeposits # Basalt - type: entity @@ -240,6 +261,8 @@ orGroup: rock - type: IFF color: "#b5b5b5" + - type: RandomEntityPopulator + entries: *gasDeposits # Sand - type: entity @@ -300,6 +323,8 @@ orGroup: rock - type: IFF color: "#cad17b" + - type: RandomEntityPopulator + entries: *gasDeposits # Chromite - type: entity @@ -360,6 +385,8 @@ orGroup: rock - type: IFF color: "#8178cc" + - type: RandomEntityPopulator + entries: *gasDeposits # Asteroid Asteroid Debris, because yes, base asteroid is made NOT from asteroid - type: entity @@ -420,6 +447,8 @@ orGroup: rock - type: IFF color: "#BF8C5C" + - type: RandomEntityPopulator + entries: *gasDeposits # Concrete asteroids (Base type) - type: entity @@ -906,4 +935,4 @@ - type: entity id: NFAsteroidRockDebrisExtraGigantic parent: [NFBaseAsteroidRockDebris, NFAsteroidDebrisExtraGigantic] - categories: [ HideSpawnMenu ] \ No newline at end of file + categories: [ HideSpawnMenu ] diff --git a/Resources/Textures/_NF/Objects/Specific/Atmospherics/deposit.rsi/deposit.png b/Resources/Textures/_NF/Objects/Specific/Atmospherics/deposit.rsi/deposit.png new file mode 100644 index 0000000000000000000000000000000000000000..6a3a106f06b79fab19d74b6205628962b3946a2b GIT binary patch literal 440 zcmV;p0Z0CcP)zzX*B z^A7=d@Zcg4k^Y(k2qEqxfru26&H?`=QOyK@x^hLz|}}`90Oy_SU6g1SeC^&U)QxUszC%8W7ZF|EQ7A= zAW0IV);8NXj*w-UD~ubq&4-B2E_Y=qrSwjQQ-QwkfpfmGrD#UUW{_*x*e|9Y!AR?pVeGd2Je&wRFAICFJFJ=FVy|f_?p7`}&SS!=QKPe4C!9Od z^vvHb;)pX0dL`(&XX!zg)l2)>wbc!S0CpPjzA0?q#PlPbPKk_0S!v?&#YSl)2LRYT5H!u();G zT@l3%GxL`}_1fk(j<8@nlvBnxW7bt9_KLNK zj#H~gsAbZ)*~cnve+?V4VRM$ijyKNnJhygm<|E^S>1 z#&9drk~H0ad~wQ#AuK71dL5N$(PK-n>Kir1pRTy6uD><6thMC(C%Ha6{fnaL?nO&& z$5W3k%c9EuI^a237*w=ve;rlcQ%rN-*O+tS)y)N4z{R=?8&B@ILw@R3eB-KXUXVOs z>2b@04Z~LcnY?EQ&Aw*p*m31Tv&nR2-KhOLQ)%Vw8PkvjQ>yq)JM9{?R-EU4rMrRe`jT# zYEct_n8DJ=SZ zjKkjYNr~>Y&ve(Xd4#^X{~c(ceO?@bL}3}tWoujS?u{z&aTf1Ew>V$QPsLOh0ty4a zIKm^Z;;buZ))J?$MIN_oN;tVOJ;Q~rIgT!Y=TAO(@U!^#`3sTZ zR^h((y+D#i6Qa!?)4$a*syapW>v#I@@%naP+1V>$Wr(}TyOuwxdG_RrX%>qeW;1&z ztJYNqWz2Wn*x|moyW{0+Qcc;JYX)}O=AD;-yjk2@Z58o1!tUQrXzSio!wWY#Hfx$G znIwMiMO{M+vu^lW1D7T%4DGCj#Rb=E)NW;a3dRIG1UfC)o4%|DUES#%e=-KWy7ZOH z8g=7k>Mz(R&lLe)zN>)$EZ8JkvwB>K>(t31Cnj`v1iGK&leWc7g4AC5=1w^et@<(g@~MM=Q=^*&D>dy3PEX?eb+4?j=98u;va6kE&gKa2PGG@Rz8lF6$@vEJ>x& z+s|0Vv;mpHrzQMv9rK@Fd%U8X*0awGQjP2?K6Tc+JE;dKJb3t#ol0e$hF25#P*7FL;@z^5yQQOkWl4^CSd$DH5!^WKMYArMA#DIOdlI=3I_*}qgt4dB9|#N zoD?3>gv-J2jbbv9U{cX0@`w>a5y4NXMhSEhodkgaDOfU<=wn0RswGlRi2s~H2>gjh zOwejo95Pw2*OT-#l2RQ{rm)#;GDIa)sUWTaYEl(iI0aN_JdF?o82+dRQDZ7Crc@A& zn6Ox>)AEQ!e4X$%KDkOLdeL7tkc=v{oNLEkth*N!ZF=4 zSah+J%A|lyI$jPs1@#8mkhd6Qv&2*hn?{2e63P%LfkLB&6$omC!of)xj)TAwIs>M% zKstlL0O?dZ6@(>-6l6g(s+bO=EDD=G1R_|C;av&KhDK$ClHgEGgvFphcnmO%Kp>sP zpn+nRm=3a0Dus=Ty~R|P!~|um1IJe+;1Q`L=)FWFgSAqnTFxT|VG3Q!`-Lz}j)rPs zBWV-{jSVpwOeVyjQy8ov)(cU!25&ecCIuou zyxDlYVFaY%1!vK{8FZAvFs1PhU89t0^{^WCjmI;^v%wq4lnr5uiQ}msYU>kFBY_Z= z0#c|T#15l)b07wX0)Y^n13^UcV8UeMu6~;_m;67Ra7_wB#sF?NAj8KCKCQ^_#?>Ha zMjHRcW3U$gq6ZxMlar6)_Y+;8==vxIK1%shcYUJkqZs%o%AxPZtTFaD!B~*V+7BAo^$PtPqQfYr^8J z+e3rTRP1EgI~b4bbI+pIKchQ+Z?`;Gqf@+iW4^rGzieMq>Fec`IVwHxaa#PiQhW2< qmw%XP<{oXowhKM=Q&Re4tNGEOQ;&z$=;OF^KoBtBzjSuo%Krk1BzZ&t diff --git a/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/closed_unlit.png b/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/closed_unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..e87080e5239b79e81981af5a5ef502395e607320 GIT binary patch literal 158 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJR8JSjkcif|=QeUS7znsM++WbJ zAeiIYyUC@ST3)Z%`atX$@3~_gzD``+-QP>u`*%+U>S175kbgb}Ee;X%5Ux?rGe`ZBxQ`=ig=xwzcf`>bu<+o-&> o>5+ngv6r{ICim#Z?~pgJW=s+jz1zfl+7YD9)78&qol`;+0DH?Z5C8xG literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/meta.json b/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/meta.json index 4ed24298ad1..7bdf3d2680c 100644 --- a/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/meta.json +++ b/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/meta.json @@ -9,10 +9,13 @@ "copyright":"pump* taken from https://github.com/tgstation/tgstation at commit 57cd1d59ca019dd0e7811ac451f295f818e573da, modified by whatston3.", "states":[ { - "name":"bolted_unlit" + "name":"closed" }, { - "name":"closed" + "name":"closed_unlit" + }, + { + "name":"frame_struts" }, { "name":"panel_open" diff --git a/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/pipeStraight.png b/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/pipeStraight.png new file mode 100644 index 0000000000000000000000000000000000000000..a2fb4b7ff8bcf4b86b5ee8d1fdaed23a99339189 GIT binary patch literal 3619 zcmV+;4&3pHP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U;3ewj(JH{AU%jgcL8qa(GDR^bThE6N0pz>AKx^ z_4H?7mz_3{ASoh*$a3=EKh*sPf6?>dV&al(&IkTtjny}NDaZcXS32VQTz~QG!tYzV zdvuAP&n`zZIxhe3Jq8L^uc40wKe?Ct3Cc4JNNwh7QE-T zx7Z!+Y!CNPxFeqf@>`6~c1l0TZbj&75xrKvbyPm|xc*&Zr?aTa_O8W@NM(0A^>Af< z!$5>HhIL!Ui}6nQ&g)h2DsXWCu?aLgUc*r(k7z4Jn$$>1)^*T;iP4K^T)iK_z}iY+ zU;S8MM0=5X4mC^{3NRT!Euh&yZK1VpUF!`hSa}jgdctI6XuiMPPmO=)^_)o6s7rK| zXRKhCH%`M0L(V=i3V@KFF-*X%IIWE8kAedH|3mj}m-&6ENFK&f}bHKQCM0d)W zc%Bm=L|8k)7z#k($P^M~I@o(ALL3Y5X|UXf=sOUgl>8*8z$SzYaEiCJaSziP>yzKj zNG$*&K_U!jYG?o}#svOwEZ|T}Aw`!`%864+HMJaa%qi#0*>Y6lz>yPYW-eU0l~7_y zB^NHG)Y7W20VyoiT-nu9Yi$jSHcZ`ccf*L*y6>UKo_g-wORv2R&}YPvMjkxMsH06k z!-V{2p6q6sbv7XZl_W}%EG$K;GzHf*Xw;-xS&LR}Pt;CS@2Jrma(|5)ov0aNagE~_ zYG`JDOhJ}Tl3@nKd?X;wh5!id4YQ+AjNXtl%#P|IisXSBB?D)YAqE7akWWfa>|V(I zC2lUo-@?uR8FJ2``zMfd2HlC=uekky+H7k_2@4=op~dtFio}KiQkpN#_N4o@*9@Iv zO+8e4l2IEAl9q|KRIOEe)1G)XcBCWqkYx@92!dcpO%gb-;m_JI%y9G0xQ?vnPJTc=#j~FBuoA=;h*i8 z-(Az_huI2{6tkwLIl}DZ&{|^DVb;P|m~QKM7{&o@8nR8-dHP;z)5uCKl@*2&w2wKv>##*=!1dgRpp-b; z!tCp-7chm%NoFCPxntdNfZ3{GEvqKHdqDL>3BHUD_k*^{UD0GXb+%YdAP3W$D@VXM zWDJ=qFplxB;bVX{32zW5XaLoQU}8iFH+K)H@*N5H9aM9MApuc1tr9NBK$K-3VpB_V zc0srsa`zn-7Cl0pKt-1odAkZAz|bHG#59PkZ$L*5zYt}}av}%}u+cCPCvXEpGG_GS z2l4!Jb?@rxjmt0kG{NfN}aNF~6bpsJ{t z#~hnL&Tx9V(2+~PE_keU#i$Cv*ig*x#d1R;qpE#EF|`~KOLr(;<^meDPI4f5=#@#p z%;$^|S+t_4LEh@iB3OCQh+H(vGSsG+H#VgkPzKY>$;EQ_+j7ubo)Vp~7_@OLSC)Wh zOF0+eprSWF?}9KKnwFAO!=|J|_$|8Eufe zbuK=Qmm26P9e3iOh0N?<hGD#h~po*$K4I=zrmdQ)qTmFl?NcK zADAB&^W6<3U*Qk7+}Q~?yc`HGb{HU+tx6uzcRT#I)cUvL?@*@RQjf0G19n;R$(y~; z)RXzPYg1J4DZ|sE&Oe44eX!S7OP)9KgZt?-_ucQOo?lB;Z1uyXRijFVCsw24;4n<5 z)WEVgw<~t(m4wL;V7H1POW-gm0d>$v*2K2vuBrf zy=NnN-AivVkI}X-UJdvO$Mbc>a}b+^!GCxL88;*E59MaVXcRJDcLxE+*45$VrS}yD+{b8x5 zuAM9*9jKL)=s6o#lO5NWBWUM|lWp|d*v*-3t$9Y&&9!yQSUd2$7w)qg-R9ZhXM3bo z`0PVfi+EeXh5YKa56dR=V%kQz!(FXje?nm!*kMrgHz*2A&Ny&YyrB70F-)iZTl-xy2K;Q`3_K6|CXz7!b+_zf#BqjH) zmOd@zzSYtvDYa1qp;r?BNNnDoE!15Sw;3C1oU#zvwY}*URVN?a4)U-sjA)fFD%}l? zA(mSu*GHn&5q3vk9q`r4Sh0#2Uk%Y)KN14P45rD31{2}hW*UA~gwqOk543RNNqfNR zk77D&olVg-+Yza4kXkQ(xe1GccvIV(GxmQ#KB5Ffs+u9xt-0-p9BtVvt5j}guXpbT zdr{M{&w-59XY63|G?S&IjANMBPIhLMV!(MnV@Wb%)QlIpa-vnDIJHmA=uxqkVUMqOw3_8s(_YQfcu00$ z$D~!3snbobrS_#i__MKD9wEemOFMaFNpVH~>genR)xSMVP18{Gey6kcKouSP%t z#}mW3FkI-&h%+P`)KgCs>4{=D6deIeBx?!M_uoCs(znP=NS-Ac#0806b1K90$Xxo+!hl5H0+J3_@48t%C!!V408hRWw9&6g;clYla{(8AwA`cud z7K^9h!`ykvkCVydsRPq>9nRD~_&XZRu zB@hvub8yaqh;Td}5kden_l?Q?n0xeH*MXTao6W$?xLhv%Jl}LW?N@bvHZ!Pg+b{mS z_W#}fwrz=;rs36U1@C=7fb6}8_Z~6E{=b;0uWwE%EBodDe1SusZJ zb~^y~(f3Dx2%-NU-|eT@9~)Fvg_P3Ms!M+EF>wH2Mpf&&MoI}OrGEJ;?~ZwE{;ie$ pt6g|ZzhM}LVHk#C7>4mb@B_wv0yVF03$FkG002ovPDHLkV1m8Z)A|4a literal 0 HcmV?d00001 From 097e68a4fceb96dab16d688e049bd02c41192768 Mon Sep 17 00:00:00 2001 From: Whatstone Date: Wed, 13 Nov 2024 09:22:12 -0500 Subject: [PATCH 05/61] gas deposit drill WIP --- .../Components/GasDepositDrillComponent.cs | 32 +++++ .../EntitySystems/GasDepositDrillSystem.cs | 129 ++++++++++++++++++ .../_NF/atmos/gas-deposit-drill-component.ftl | 1 + 3 files changed, 162 insertions(+) create mode 100644 Content.Server/_NF/Atmos/Components/GasDepositDrillComponent.cs create mode 100644 Content.Server/_NF/Atmos/EntitySystems/GasDepositDrillSystem.cs create mode 100644 Resources/Locale/en-US/_NF/atmos/gas-deposit-drill-component.ftl diff --git a/Content.Server/_NF/Atmos/Components/GasDepositDrillComponent.cs b/Content.Server/_NF/Atmos/Components/GasDepositDrillComponent.cs new file mode 100644 index 00000000000..cd26d114c58 --- /dev/null +++ b/Content.Server/_NF/Atmos/Components/GasDepositDrillComponent.cs @@ -0,0 +1,32 @@ +namespace Content.Server._NF.Atmos.Components; + +[RegisterComponent] +public sealed partial class GasDepositExtractorComponent : Component +{ + /// + /// Whether or not the extractor is on and extracting gas. + /// + [DataField] + public bool Enabled; + + /// + /// The amount of gas to extract per second, in mol/s. + /// + [DataField] + public float ExtractionRate; + + /// + /// The maximum pressure output, in kPa. + /// + [DataField] + public float MaxOutputPressure; + + /// + /// The entity to be extracted from. + /// + [DataField] + public EntityUid? DepositEntity; + + [DataField("port")] + public string PortName { get; set; } = "port"; +} diff --git a/Content.Server/_NF/Atmos/EntitySystems/GasDepositDrillSystem.cs b/Content.Server/_NF/Atmos/EntitySystems/GasDepositDrillSystem.cs new file mode 100644 index 00000000000..24bf114a27c --- /dev/null +++ b/Content.Server/_NF/Atmos/EntitySystems/GasDepositDrillSystem.cs @@ -0,0 +1,129 @@ +using Content.Server._NF.Atmos.Components; +using Content.Server.Atmos.Piping.Components; +using Content.Server.NodeContainer.EntitySystems; +using Content.Server.NodeContainer.Nodes; +using Content.Server.Popups; +using Content.Server.Power.Components; +using Content.Shared.Atmos; +using Content.Shared.Construction.Components; +using Robust.Server.GameObjects; +using Robust.Shared.Map.Components; +using Robust.Shared.Prototypes; +using Robust.Shared.Random; + +namespace Content.Server._NF.Atmos.EntitySystems; + +// System for handling gas deposits and machines for extracting from gas deposits +public sealed class GasDepositSystem : EntitySystem +{ + [Dependency] private readonly EntityLookupSystem _lookup = default!; + [Dependency] private readonly MapSystem _map = default!; + [Dependency] private readonly PrototypeManager _prototype = default!; + [Dependency] private readonly RobustRandom _random = default!; + [Dependency] private readonly PopupSystem _popup = default!; + [Dependency] private readonly NodeContainerSystem _nodeContainer = default!; + [Dependency] private readonly AmbientSoundSystem _ambientSound = default!; + + /// + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnDepositInit); + + SubscribeLocalEvent(OnAnchorAttempt); + SubscribeLocalEvent(OnAnchorChanged); + } + + public void OnAnchorAttempt(EntityUid uid, GasDepositExtractorComponent component, AnchorAttemptEvent args) + { + if (args.Cancelled) + return; + + if (!TryComp(uid, out TransformComponent? xform) + || xform.GridUid is not { Valid: true } grid + || !TryComp(uid, out MapGridComponent? gridComp)) + { + args.Cancel(); + return; + } + + var indices = _map.TileIndicesFor(grid, gridComp, xform.Coordinates); + var enumerator = _map.GetAnchoredEntitiesEnumerator(grid, gridComp, indices); + + while (enumerator.MoveNext(out var otherEnt)) + { + // Don't match yourself. + if (otherEnt == uid) + continue; + + // Is another storage entity is already anchored here? + if (HasComp(otherEnt)) + { + component.DepositEntity = otherEnt; + return; + } + } + + _popup.PopupEntity(Loc.GetString("gas-deposit-drill-no-resources"), uid); + args.Cancel(); + } + + public void OnAnchorChanged(EntityUid uid, GasDepositExtractorComponent component, AnchorStateChangedEvent args) + { + if (!args.Anchored) + component.DepositEntity = null; + } + + public override void Update(float frameTime) + { + base.Update(frameTime); + + var query = EntityQueryEnumerator(); + + while (query.MoveNext(out var ent, out var drill, out var xform)) + { + } + } + + public void OnDepositInit(EntityUid uid, RandomGasDepositComponent component, ComponentInit args) + { + if (!_prototype.TryIndex(component.DepositPrototype, out var depositPrototype)) + { + if (!_prototype.TryGetRandom(_random, out var randomPrototype)) + return; + depositPrototype = (GasDepositPrototype)randomPrototype; + } + for (int i = 0; i < (depositPrototype?.Gases?.Length ?? 0) && i < Atmospherics.TotalNumberOfGases; i++) + { + var gasRange = depositPrototype!.Gases[i]; + component.Deposit.SetMoles(i, gasRange[0] + _random.NextFloat() * (gasRange[1] - gasRange[0])); + } + } + + private void OnDrillUpdate(EntityUid uid, GasDepositExtractorComponent drill, ref AtmosDeviceUpdateEvent args) + { + if (!drill.Enabled + || TryComp(uid, out var power) && !power.Powered + || !_nodeContainer.TryGetNode(uid, drill.PortName, out PipeNode? port)) + { + _ambientSound.SetAmbience(uid, false); + return; + } + + // How many moles could we theoretically spawn. Cap by pressure and amount. + var allowableMoles = Math.Max( + (drill.MaxOutputPressure - port.Air.Pressure) * port.Air.Volume / (drill.SpawnTemperature * Atmospherics.R), + 0); + + if (allowableMoles < Atmospherics.GasMinMoles) + { + _ambientSound.SetAmbience(uid, false); + return; + } + + var toSpawnReal = Math.Clamp(allowableMoles, , toSpawnTarget); + + _ambientSoundSystem.SetAmbience(uid, toSpawnReal > 0f); + } +} diff --git a/Resources/Locale/en-US/_NF/atmos/gas-deposit-drill-component.ftl b/Resources/Locale/en-US/_NF/atmos/gas-deposit-drill-component.ftl new file mode 100644 index 00000000000..3ae1335ace9 --- /dev/null +++ b/Resources/Locale/en-US/_NF/atmos/gas-deposit-drill-component.ftl @@ -0,0 +1 @@ +gas-deposit-drill-no-resources = Nothing to extract here! From e3668607087c8dd5570ef98795b39bfe63a54c72 Mon Sep 17 00:00:00 2001 From: Whatstone Date: Wed, 13 Nov 2024 21:01:45 -0500 Subject: [PATCH 06/61] More work on deposits and drills, still WIP --- .../Shuttles/UI/ShuttleDockControl.xaml.cs | 2 +- ...ent.cs => GasDepositExtractorComponent.cs} | 18 ++++- ...ositDrillSystem.cs => GasDepositSystem.cs} | 72 +++++++++++++------ .../Debris/RandomEntityPopulatorComponent.cs | 3 + .../Debris/RandomEntityPopulatorSystem.cs | 3 + .../Specific/Atmospherics/deposits.yml | 12 ++++ .../Structures/Piping/Atmospherics/unary.yml | 15 ++-- .../_NF/Entities/World/Debris/asteroids.yml | 31 +++++--- 8 files changed, 116 insertions(+), 40 deletions(-) rename Content.Server/_NF/Atmos/Components/{GasDepositDrillComponent.cs => GasDepositExtractorComponent.cs} (58%) rename Content.Server/_NF/Atmos/EntitySystems/{GasDepositDrillSystem.cs => GasDepositSystem.cs} (57%) diff --git a/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs index 17cc981cf6c..56062427bf3 100644 --- a/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs +++ b/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs @@ -230,7 +230,7 @@ protected override void Draw(DrawingHandleScreen handle) else { // otherDockColor = Color.ToSrgb(Color.Purple); // Frontier - otherDockColor = Color.ToSrgb(dock.RadarColor); + otherDockColor = Color.ToSrgb(dock.RadarColor); // Frontier } /* diff --git a/Content.Server/_NF/Atmos/Components/GasDepositDrillComponent.cs b/Content.Server/_NF/Atmos/Components/GasDepositExtractorComponent.cs similarity index 58% rename from Content.Server/_NF/Atmos/Components/GasDepositDrillComponent.cs rename to Content.Server/_NF/Atmos/Components/GasDepositExtractorComponent.cs index cd26d114c58..34ffdde0f55 100644 --- a/Content.Server/_NF/Atmos/Components/GasDepositDrillComponent.cs +++ b/Content.Server/_NF/Atmos/Components/GasDepositExtractorComponent.cs @@ -1,3 +1,5 @@ +using Content.Shared.Atmos; + namespace Content.Server._NF.Atmos.Components; [RegisterComponent] @@ -19,13 +21,25 @@ public sealed partial class GasDepositExtractorComponent : Component /// The maximum pressure output, in kPa. /// [DataField] - public float MaxOutputPressure; + public float MaxOutputPressure = Atmospherics.MaxOutputPressure; + + [DataField] + public float TargetPressure = Atmospherics.OneAtmosphere; + + /// + /// The output temperature, in K. + /// + [DataField] + public float OutputTemperature = Atmospherics.T20C; /// /// The entity to be extracted from. /// + /// + /// Should abstract into a general GasDepositComponent later. + /// [DataField] - public EntityUid? DepositEntity; + public Entity? DepositEntity; [DataField("port")] public string PortName { get; set; } = "port"; diff --git a/Content.Server/_NF/Atmos/EntitySystems/GasDepositDrillSystem.cs b/Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs similarity index 57% rename from Content.Server/_NF/Atmos/EntitySystems/GasDepositDrillSystem.cs rename to Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs index 24bf114a27c..233331c0cb6 100644 --- a/Content.Server/_NF/Atmos/EntitySystems/GasDepositDrillSystem.cs +++ b/Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs @@ -1,11 +1,16 @@ using Content.Server._NF.Atmos.Components; +using Content.Server.Administration.Logs; +using Content.Server.Atmos.EntitySystems; using Content.Server.Atmos.Piping.Components; +using Content.Server.Audio; using Content.Server.NodeContainer.EntitySystems; using Content.Server.NodeContainer.Nodes; using Content.Server.Popups; using Content.Server.Power.Components; using Content.Shared.Atmos; +using Content.Shared.Atmos.Piping.Binary.Components; using Content.Shared.Construction.Components; +using Content.Shared.Database; using Robust.Server.GameObjects; using Robust.Shared.Map.Components; using Robust.Shared.Prototypes; @@ -23,6 +28,9 @@ public sealed class GasDepositSystem : EntitySystem [Dependency] private readonly PopupSystem _popup = default!; [Dependency] private readonly NodeContainerSystem _nodeContainer = default!; [Dependency] private readonly AmbientSoundSystem _ambientSound = default!; + [Dependency] private readonly AtmosphereSystem _atmosphere = default!; + [Dependency] private readonly AdminLogManager _adminLog = default!; + [Dependency] private readonly UserInterfaceSystem _ui = default!; /// public override void Initialize() @@ -33,6 +41,11 @@ public override void Initialize() SubscribeLocalEvent(OnAnchorAttempt); SubscribeLocalEvent(OnAnchorChanged); + SubscribeLocalEvent(OnExtractorUpdate); + + SubscribeLocalEvent(OnOutputPressureChangeMessage); + SubscribeLocalEvent(OnToggleStatusMessage); + } public void OnAnchorAttempt(EntityUid uid, GasDepositExtractorComponent component, AnchorAttemptEvent args) @@ -58,9 +71,9 @@ public void OnAnchorAttempt(EntityUid uid, GasDepositExtractorComponent componen continue; // Is another storage entity is already anchored here? - if (HasComp(otherEnt)) + if (TryComp(otherEnt, out var deposit)) { - component.DepositEntity = otherEnt; + component.DepositEntity = (otherEnt.Value, deposit); return; } } @@ -75,17 +88,6 @@ public void OnAnchorChanged(EntityUid uid, GasDepositExtractorComponent componen component.DepositEntity = null; } - public override void Update(float frameTime) - { - base.Update(frameTime); - - var query = EntityQueryEnumerator(); - - while (query.MoveNext(out var ent, out var drill, out var xform)) - { - } - } - public void OnDepositInit(EntityUid uid, RandomGasDepositComponent component, ComponentInit args) { if (!_prototype.TryIndex(component.DepositPrototype, out var depositPrototype)) @@ -101,20 +103,22 @@ public void OnDepositInit(EntityUid uid, RandomGasDepositComponent component, Co } } - private void OnDrillUpdate(EntityUid uid, GasDepositExtractorComponent drill, ref AtmosDeviceUpdateEvent args) + private void OnExtractorUpdate(EntityUid uid, GasDepositExtractorComponent extractor, ref AtmosDeviceUpdateEvent args) { - if (!drill.Enabled + if (!extractor.Enabled + || extractor.DepositEntity == null || TryComp(uid, out var power) && !power.Powered - || !_nodeContainer.TryGetNode(uid, drill.PortName, out PipeNode? port)) + || !_nodeContainer.TryGetNode(uid, extractor.PortName, out PipeNode? port)) { _ambientSound.SetAmbience(uid, false); return; } + var targetPressure = float.Clamp(extractor.TargetPressure, 0, extractor.MaxOutputPressure); + // How many moles could we theoretically spawn. Cap by pressure and amount. - var allowableMoles = Math.Max( - (drill.MaxOutputPressure - port.Air.Pressure) * port.Air.Volume / (drill.SpawnTemperature * Atmospherics.R), - 0); + var allowableMoles = float.Max(0, + (targetPressure - port.Air.Pressure) * port.Air.Volume / (extractor.OutputTemperature * Atmospherics.R)); if (allowableMoles < Atmospherics.GasMinMoles) { @@ -122,8 +126,34 @@ private void OnDrillUpdate(EntityUid uid, GasDepositExtractorComponent drill, re return; } - var toSpawnReal = Math.Clamp(allowableMoles, , toSpawnTarget); + var removed = extractor.DepositEntity.Value.Comp.Deposit.Remove(allowableMoles); + _atmosphere.Merge(port.Air, removed); + + _ambientSound.SetAmbience(uid, true); + } + + private void OnToggleStatusMessage(EntityUid uid, GasDepositExtractorComponent extractor, GasPressurePumpToggleStatusMessage args) + { + extractor.Enabled = args.Enabled; + _adminLog.Add(LogType.AtmosPowerChanged, LogImpact.Low, + $"{ToPrettyString(args.Actor):player} set the power on {ToPrettyString(uid):device} to {args.Enabled}"); + DirtyUI(uid, extractor); + } + + private void OnOutputPressureChangeMessage(EntityUid uid, GasDepositExtractorComponent extractor, GasPressurePumpChangeOutputPressureMessage args) + { + extractor.TargetPressure = Math.Clamp(args.Pressure, 0f, Atmospherics.MaxOutputPressure); + _adminLog.Add(LogType.AtmosPressureChanged, LogImpact.Medium, + $"{ToPrettyString(args.Actor):player} set the pressure on {ToPrettyString(uid):device} to {args.Pressure}kPa"); + DirtyUI(uid, extractor); + } + + private void DirtyUI(EntityUid uid, GasDepositExtractorComponent? extractor) + { + if (!Resolve(uid, ref extractor)) + return; - _ambientSoundSystem.SetAmbience(uid, toSpawnReal > 0f); + _ui.SetUiState(uid, GasPressurePumpUiKey.Key, + new GasPressurePumpBoundUserInterfaceState(EntityManager.GetComponent(uid).EntityName, extractor.TargetPressure, extractor.Enabled)); } } diff --git a/Content.Server/_NF/Worldgen/Components/Debris/RandomEntityPopulatorComponent.cs b/Content.Server/_NF/Worldgen/Components/Debris/RandomEntityPopulatorComponent.cs index 1395d6051f9..fc018c16019 100644 --- a/Content.Server/_NF/Worldgen/Components/Debris/RandomEntityPopulatorComponent.cs +++ b/Content.Server/_NF/Worldgen/Components/Debris/RandomEntityPopulatorComponent.cs @@ -55,6 +55,9 @@ public sealed partial class RandomEntityParameters public int Max = 1; [DataField] public bool CanBeAirSealed = false; + // The probability to generate this set of entities. + [DataField] + public float Prob = 1.0f; } [DataDefinition] diff --git a/Content.Server/_NF/Worldgen/Systems/Debris/RandomEntityPopulatorSystem.cs b/Content.Server/_NF/Worldgen/Systems/Debris/RandomEntityPopulatorSystem.cs index 915b419b898..f9639db3cff 100644 --- a/Content.Server/_NF/Worldgen/Systems/Debris/RandomEntityPopulatorSystem.cs +++ b/Content.Server/_NF/Worldgen/Systems/Debris/RandomEntityPopulatorSystem.cs @@ -31,6 +31,9 @@ private void OnFloorPlanBuilt(EntityUid uid, RandomEntityPopulatorComponent comp // For each entity populator in the set, select a number between min and max foreach (var (paramSet, cache) in component.Caches) { + if (!_random.Prob(paramSet.Prob)) + continue; + var numToGenerate = _random.Next(paramSet.Min, paramSet.Max + 1); for (int i = 0; i < numToGenerate; i++) { diff --git a/Resources/Prototypes/_NF/Entities/Objects/Specific/Atmospherics/deposits.yml b/Resources/Prototypes/_NF/Entities/Objects/Specific/Atmospherics/deposits.yml index 2974b17a0d4..0756fedf7f7 100644 --- a/Resources/Prototypes/_NF/Entities/Objects/Specific/Atmospherics/deposits.yml +++ b/Resources/Prototypes/_NF/Entities/Objects/Specific/Atmospherics/deposits.yml @@ -106,3 +106,15 @@ components: - type: RandomGasDeposit deposit: AirLike + +# Debug item for detecting gas deposits +- type: entity + parent: PinpointerSyndicateNuclear + id: PinpointerGasDeposit + name: gas deposit pinpointer + description: Pointing to the nearest gas deposit. + suffix: DEBUG + components: + - type: Pinpointer + component: RandomGasDeposit + targetName: RandomGasDeposit diff --git a/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml b/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml index 0984400102c..49b088219d1 100644 --- a/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml +++ b/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml @@ -12,19 +12,19 @@ - type: Rotatable - type: AtmosPipeColor - type: AtmosDevice - # - type: UserInterface # FIXME - # interfaces: # FIXME - # enum.ThermomachineUiKey.Key: # FIXME - # type: GasThermomachineBoundUserInterface # FIXME + - type: UserInterface + interfaces: + enum.GasPressurePumpUiKey.Key: + type: GasPressurePumpBoundUserInterface - type: ActivatableUI inHandsOnly: false - # key: enum.ThermomachineUiKey.Key # FIXME + key: enum.GasPressurePumpUiKey.Key - type: WiresPanel - type: WiresVisuals - type: PipeRestrictOverlap - type: NodeContainer nodes: - pipe: + port: !type:PipeNode nodeGroupID: Pipe pipeDirection: South @@ -63,3 +63,6 @@ board: Null # FIXME - type: DeviceNetwork prefix: device-address-prefix-gas-drill + - type: GasDepositExtractor + extractionRate: 20 + port: port diff --git a/Resources/Prototypes/_NF/Entities/World/Debris/asteroids.yml b/Resources/Prototypes/_NF/Entities/World/Debris/asteroids.yml index e17fc0df63c..d58d6a9a340 100644 --- a/Resources/Prototypes/_NF/Entities/World/Debris/asteroids.yml +++ b/Resources/Prototypes/_NF/Entities/World/Debris/asteroids.yml @@ -63,20 +63,31 @@ - type: RandomEntityPopulator entries: &gasDeposits - params: + prob: 0.5 min: 0 max: 2 canBeAirSealed: true entries: - - OxygenGasDeposit - - NitrogenGasDeposit - - CarbonDioxideGasDeposit - - PlasmaGasDeposit - - AmmoniaGasDeposit - - TritiumGasDeposit - - WaterVaporGasDeposit - - NitrousOxideGasDeposit - - FrezonGasDeposit - - AirGasDeposit + - id: OxygenGasDeposit + orGroup: deposit + - id: NitrogenGasDeposit + orGroup: deposit + - id: CarbonDioxideGasDeposit + orGroup: deposit + - id: PlasmaGasDeposit + orGroup: deposit + - id: AmmoniaGasDeposit + orGroup: deposit + - id: TritiumGasDeposit + orGroup: deposit + - id: WaterVaporGasDeposit + orGroup: deposit + - id: NitrousOxideGasDeposit + orGroup: deposit + - id: FrezonGasDeposit + orGroup: deposit + - id: AirGasDeposit + orGroup: deposit # Snow - type: entity From 63db0913361b4ce89f70d8458187e240928c821f Mon Sep 17 00:00:00 2001 From: Whatstone Date: Wed, 13 Nov 2024 23:48:35 -0500 Subject: [PATCH 07/61] random gas deposits, drill fixes --- .../Atmos/Components/DockablePumpComponent.cs | 1 + .../Components/RandomGasDepositComponent.cs | 2 +- .../Atmos/EntitySystems/GasDepositSystem.cs | 9 +++--- .../Debris/RandomEntityPopulatorSystem.cs | 29 ++++++++++++------- .../Specific/Atmospherics/deposits.yml | 21 +++++++------- .../Structures/Piping/Atmospherics/unary.yml | 4 +-- 6 files changed, 38 insertions(+), 28 deletions(-) diff --git a/Content.Server/_NF/Atmos/Components/DockablePumpComponent.cs b/Content.Server/_NF/Atmos/Components/DockablePumpComponent.cs index 68345d4bada..c29275d1405 100644 --- a/Content.Server/_NF/Atmos/Components/DockablePumpComponent.cs +++ b/Content.Server/_NF/Atmos/Components/DockablePumpComponent.cs @@ -1,5 +1,6 @@ namespace Content.Server._NF.Atmos.Components; +[RegisterComponent] public sealed partial class DockablePumpComponent : Component { /// diff --git a/Content.Server/_NF/Atmos/Components/RandomGasDepositComponent.cs b/Content.Server/_NF/Atmos/Components/RandomGasDepositComponent.cs index 208e0e6ab9f..8f74d2865aa 100644 --- a/Content.Server/_NF/Atmos/Components/RandomGasDepositComponent.cs +++ b/Content.Server/_NF/Atmos/Components/RandomGasDepositComponent.cs @@ -17,5 +17,5 @@ public sealed partial class RandomGasDepositComponent : Component /// Gases left in the deposit. /// [ViewVariables] - public GasMixture Deposit; + public GasMixture Deposit = new(); } diff --git a/Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs b/Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs index 233331c0cb6..3c7ae7e4eab 100644 --- a/Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs +++ b/Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs @@ -23,13 +23,13 @@ public sealed class GasDepositSystem : EntitySystem { [Dependency] private readonly EntityLookupSystem _lookup = default!; [Dependency] private readonly MapSystem _map = default!; - [Dependency] private readonly PrototypeManager _prototype = default!; - [Dependency] private readonly RobustRandom _random = default!; + [Dependency] private readonly IPrototypeManager _prototype = default!; + [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly PopupSystem _popup = default!; [Dependency] private readonly NodeContainerSystem _nodeContainer = default!; [Dependency] private readonly AmbientSoundSystem _ambientSound = default!; [Dependency] private readonly AtmosphereSystem _atmosphere = default!; - [Dependency] private readonly AdminLogManager _adminLog = default!; + [Dependency] private readonly IAdminLogManager _adminLog = default!; [Dependency] private readonly UserInterfaceSystem _ui = default!; /// @@ -55,7 +55,7 @@ public void OnAnchorAttempt(EntityUid uid, GasDepositExtractorComponent componen if (!TryComp(uid, out TransformComponent? xform) || xform.GridUid is not { Valid: true } grid - || !TryComp(uid, out MapGridComponent? gridComp)) + || !TryComp(grid, out MapGridComponent? gridComp)) { args.Cancel(); return; @@ -127,6 +127,7 @@ private void OnExtractorUpdate(EntityUid uid, GasDepositExtractorComponent extra } var removed = extractor.DepositEntity.Value.Comp.Deposit.Remove(allowableMoles); + removed.Temperature = extractor.OutputTemperature; _atmosphere.Merge(port.Air, removed); _ambientSound.SetAmbience(uid, true); diff --git a/Content.Server/_NF/Worldgen/Systems/Debris/RandomEntityPopulatorSystem.cs b/Content.Server/_NF/Worldgen/Systems/Debris/RandomEntityPopulatorSystem.cs index f9639db3cff..fa8f52907cb 100644 --- a/Content.Server/_NF/Worldgen/Systems/Debris/RandomEntityPopulatorSystem.cs +++ b/Content.Server/_NF/Worldgen/Systems/Debris/RandomEntityPopulatorSystem.cs @@ -28,6 +28,7 @@ private void OnFloorPlanBuilt(EntityUid uid, RandomEntityPopulatorComponent comp return; var placeables = new List(4); + List? validTileIndices = null; // For each entity populator in the set, select a number between min and max foreach (var (paramSet, cache) in component.Caches) { @@ -38,7 +39,7 @@ private void OnFloorPlanBuilt(EntityUid uid, RandomEntityPopulatorComponent comp for (int i = 0; i < numToGenerate; i++) { // Then find a spot (if we can) - on any failure, assume the asteroid is full and move onto the next one, which may have different parameters - if (!SelectRandomTile(uid, mapGrid, paramSet.CanBeAirSealed, out var coords)) + if (!SelectRandomTile(uid, mapGrid, paramSet.CanBeAirSealed, ref validTileIndices, out var coords)) break; cache.GetSpawns(_random, ref placeables); @@ -57,28 +58,36 @@ private void OnFloorPlanBuilt(EntityUid uid, RandomEntityPopulatorComponent comp private bool SelectRandomTile(EntityUid gridUid, MapGridComponent mapComp, bool canBeAirSealed, + ref List? tileIndices, out EntityCoordinates targetCoords) { targetCoords = default; - var aabb = mapComp.LocalAABB; + if (tileIndices == null) + { + var tileIterator = _map.GetAllTiles(gridUid, mapComp, ignoreEmpty: true); + tileIndices = new List(); + foreach (var tile in tileIterator) + { + tileIndices.Add(tile.GridIndices); + } + } bool found = false; - // Try to place on the local bounding box - this may fail. - for (var i = 0; i < 25; i++) + for (var i = 0; i < 10; i++) { - var randomX = _random.Next((int)aabb.Left, (int)aabb.Right); - var randomY = _random.Next((int)aabb.Bottom, (int)aabb.Top); + if (tileIndices.Count <= 0) + return false; - var tile = new Vector2i(randomX, randomY); - if (_atmosphere.IsTileSpace(gridUid, Transform(gridUid).MapUid, tile) - || !canBeAirSealed && _atmosphere.IsTileAirBlocked(gridUid, tile, mapGridComp: mapComp)) + var idx = _random.Next(tileIndices.Count); + if (!canBeAirSealed && _atmosphere.IsTileAirBlocked(gridUid, tileIndices[idx], mapGridComp: mapComp)) { continue; } found = true; - targetCoords = _map.GridTileToLocal(gridUid, mapComp, tile); + targetCoords = _map.GridTileToLocal(gridUid, mapComp, tileIndices[idx]); + tileIndices.RemoveAt(idx); break; } diff --git a/Resources/Prototypes/_NF/Entities/Objects/Specific/Atmospherics/deposits.yml b/Resources/Prototypes/_NF/Entities/Objects/Specific/Atmospherics/deposits.yml index 0756fedf7f7..108d94acc4d 100644 --- a/Resources/Prototypes/_NF/Entities/Objects/Specific/Atmospherics/deposits.yml +++ b/Resources/Prototypes/_NF/Entities/Objects/Specific/Atmospherics/deposits.yml @@ -15,6 +15,7 @@ - type: Fixtures - type: RandomGasDeposit - type: Sprite + drawdepth: FloorTiles sprite: _NF/Objects/Specific/Atmospherics/deposit.rsi layers: - state: deposit @@ -24,7 +25,7 @@ id: OxygenGasDeposit components: - type: RandomGasDeposit - deposit: MostlyOxygen + depositPrototype: MostlyOxygen - type: Sprite color: "#DDDDEE" @@ -33,7 +34,7 @@ id: NitrogenGasDeposit components: - type: RandomGasDeposit - deposit: MostlyNitrogen + depositPrototype: MostlyNitrogen - type: Sprite color: "#FFCCCC" @@ -42,7 +43,7 @@ id: CarbonDioxideGasDeposit components: - type: RandomGasDeposit - deposit: MostlyCarbonDioxide + depositPrototype: MostlyCarbonDioxide - type: Sprite color: "#CCCCCC" @@ -51,7 +52,7 @@ id: PlasmaGasDeposit components: - type: RandomGasDeposit - deposit: MostlyPlasma + depositPrototype: MostlyPlasma - type: Sprite color: "#FFCCFF" @@ -60,7 +61,7 @@ id: AmmoniaGasDeposit components: - type: RandomGasDeposit - deposit: MostlyAmmonia + depositPrototype: MostlyAmmonia - type: Sprite color: "#FFFFCC" @@ -69,7 +70,7 @@ id: TritiumGasDeposit components: - type: RandomGasDeposit - deposit: MostlyTritium + depositPrototype: MostlyTritium - type: Sprite color: "#CCFFCC" @@ -78,7 +79,7 @@ id: WaterVaporGasDeposit components: - type: RandomGasDeposit - deposit: MostlyWaterVapor + depositPrototype: MostlyWaterVapor - type: Sprite color: "#DDEEEE" @@ -87,7 +88,7 @@ id: NitrousOxideGasDeposit components: - type: RandomGasDeposit - deposit: MostlyNitrousOxide + depositPrototype: MostlyNitrousOxide - type: Sprite color: "#EEDDDD" @@ -96,7 +97,7 @@ id: FrezonGasDeposit components: - type: RandomGasDeposit - deposit: MostlyFrezon + depositPrototype: MostlyFrezon - type: Sprite color: "#CCCCFF" @@ -105,7 +106,7 @@ id: AirGasDeposit components: - type: RandomGasDeposit - deposit: AirLike + depositPrototype: AirLike # Debug item for detecting gas deposits - type: entity diff --git a/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml b/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml index 49b088219d1..cf7f3d39f3c 100644 --- a/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml +++ b/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml @@ -3,7 +3,6 @@ id: GasMiningDrill name: gas mining drill description: A powerful, luggable drill for mining gas deposits on asteroids. Outputs gas through a pipe. - abstract: true placement: mode: SnapgridCenter components: @@ -36,6 +35,7 @@ transmitFrequencyId: AtmosMonitor sendBroadcastAttemptEvent: true examinableAddress: true + prefix: device-address-prefix-gas-drill - type: WiredNetworkConnection - type: PowerSwitch - type: StationAiWhitelist @@ -61,8 +61,6 @@ load: 4000 - type: Machine board: Null # FIXME - - type: DeviceNetwork - prefix: device-address-prefix-gas-drill - type: GasDepositExtractor extractionRate: 20 port: port From 53dc3f652377a20027c92548a271e0fed021553c Mon Sep 17 00:00:00 2001 From: Whatstone Date: Thu, 14 Nov 2024 16:05:23 -0500 Subject: [PATCH 08/61] drill visualizers, ignore deposits, yaml fixes --- Content.Client/Entry/EntryPoint.cs | 1 + .../GasDepositExtractorComponent.cs | 5 + .../Components/RandomGasDepositComponent.cs | 6 + .../Atmos/EntitySystems/GasDepositSystem.cs | 103 +++++++++++++++++- .../Atmos/Prototypes/GasDepositPrototype.cs | 25 ++--- .../Visuals/GasDepositExtractorVisuals.cs | 19 ++++ .../_NF/atmos/gas-deposit-drill-component.ftl | 1 - .../Locale/en-US/_NF/atmos/gas-deposit.ftl | 4 + .../Structures/Piping/Atmospherics/unary.yml | 40 +++++-- .../Entities/Structures/Specific/gaslock.yml | 26 ++--- .../extractor.rsi/base-powered.png | Bin 0 -> 99 bytes .../Atmospherics/extractor.rsi/base.png | Bin 0 -> 682 bytes .../extractor.rsi/drill-blocked-unlit.png | Bin 0 -> 291 bytes .../extractor.rsi/drill-empty-unlit.png | Bin 0 -> 258 bytes .../extractor.rsi/drill-low-unlit.png | Bin 0 -> 293 bytes .../Atmospherics/extractor.rsi/drill-off.png | Bin 0 -> 253 bytes .../extractor.rsi/drill-on-unlit.png | Bin 0 -> 361 bytes .../Atmospherics/extractor.rsi/drill.png | Bin 0 -> 270 bytes .../Atmospherics/extractor.rsi/meta.json | 76 +++++++++++++ 19 files changed, 267 insertions(+), 39 deletions(-) create mode 100644 Content.Shared/_NF/Atmos/Visuals/GasDepositExtractorVisuals.cs delete mode 100644 Resources/Locale/en-US/_NF/atmos/gas-deposit-drill-component.ftl create mode 100644 Resources/Locale/en-US/_NF/atmos/gas-deposit.ftl create mode 100644 Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/base-powered.png create mode 100644 Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/base.png create mode 100644 Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/drill-blocked-unlit.png create mode 100644 Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/drill-empty-unlit.png create mode 100644 Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/drill-low-unlit.png create mode 100644 Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/drill-off.png create mode 100644 Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/drill-on-unlit.png create mode 100644 Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/drill.png create mode 100644 Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/meta.json diff --git a/Content.Client/Entry/EntryPoint.cs b/Content.Client/Entry/EntryPoint.cs index 56d1a04c4ef..1e717ec2fef 100644 --- a/Content.Client/Entry/EntryPoint.cs +++ b/Content.Client/Entry/EntryPoint.cs @@ -122,6 +122,7 @@ public override void Init() _prototypeManager.RegisterIgnore("alertLevels"); _prototypeManager.RegisterIgnore("nukeopsRole"); _prototypeManager.RegisterIgnore("ghostRoleRaffleDecider"); + _prototypeManager.RegisterIgnore("gasDeposit"); // Frontier _componentFactory.GenerateNetIds(); _adminManager.Initialize(); diff --git a/Content.Server/_NF/Atmos/Components/GasDepositExtractorComponent.cs b/Content.Server/_NF/Atmos/Components/GasDepositExtractorComponent.cs index 34ffdde0f55..ead08881144 100644 --- a/Content.Server/_NF/Atmos/Components/GasDepositExtractorComponent.cs +++ b/Content.Server/_NF/Atmos/Components/GasDepositExtractorComponent.cs @@ -1,3 +1,4 @@ +using Content.Shared._NF.Atmos.Visuals; using Content.Shared.Atmos; namespace Content.Server._NF.Atmos.Components; @@ -43,4 +44,8 @@ public sealed partial class GasDepositExtractorComponent : Component [DataField("port")] public string PortName { get; set; } = "port"; + + // Storing the last + [ViewVariables] + public GasDepositExtractorState LastState { get; set; } = GasDepositExtractorState.Off; } diff --git a/Content.Server/_NF/Atmos/Components/RandomGasDepositComponent.cs b/Content.Server/_NF/Atmos/Components/RandomGasDepositComponent.cs index 8f74d2865aa..75634087ceb 100644 --- a/Content.Server/_NF/Atmos/Components/RandomGasDepositComponent.cs +++ b/Content.Server/_NF/Atmos/Components/RandomGasDepositComponent.cs @@ -18,4 +18,10 @@ public sealed partial class RandomGasDepositComponent : Component /// [ViewVariables] public GasMixture Deposit = new(); + + /// + /// The maximum number of moles for this deposit to be considered "mostly depleted". + /// + [ViewVariables] + public float LowMoles; } diff --git a/Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs b/Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs index 3c7ae7e4eab..d338a9339b1 100644 --- a/Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs +++ b/Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs @@ -7,12 +7,17 @@ using Content.Server.NodeContainer.Nodes; using Content.Server.Popups; using Content.Server.Power.Components; +using Content.Shared._NF.Atmos.Visuals; using Content.Shared.Atmos; using Content.Shared.Atmos.Piping.Binary.Components; using Content.Shared.Construction.Components; using Content.Shared.Database; +using Content.Shared.Examine; +using Content.Shared.Interaction; +using Content.Shared.Power; using Robust.Server.GameObjects; using Robust.Shared.Map.Components; +using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -31,6 +36,7 @@ public sealed class GasDepositSystem : EntitySystem [Dependency] private readonly AtmosphereSystem _atmosphere = default!; [Dependency] private readonly IAdminLogManager _adminLog = default!; [Dependency] private readonly UserInterfaceSystem _ui = default!; + [Dependency] private readonly AppearanceSystem _appearance = default!; /// public override void Initialize() @@ -39,15 +45,49 @@ public override void Initialize() SubscribeLocalEvent(OnDepositInit); + SubscribeLocalEvent(OnExtractorInit); + SubscribeLocalEvent(OnPowerChanged); + SubscribeLocalEvent(OnExamined); SubscribeLocalEvent(OnAnchorAttempt); SubscribeLocalEvent(OnAnchorChanged); SubscribeLocalEvent(OnExtractorUpdate); + SubscribeLocalEvent(OnPumpActivate); SubscribeLocalEvent(OnOutputPressureChangeMessage); SubscribeLocalEvent(OnToggleStatusMessage); } + private void OnExtractorInit(EntityUid uid, GasDepositExtractorComponent pump, ComponentInit args) + { + UpdateAppearance(uid, pump); + } + + private void OnPowerChanged(EntityUid uid, GasDepositExtractorComponent component, ref PowerChangedEvent args) + { + UpdateAppearance(uid, component); + } + + private void OnExamined(EntityUid uid, GasDepositExtractorComponent extractor, ExaminedEvent args) + { + if (!EntityManager.GetComponent(uid).Anchored || !args.IsInDetailsRange) + return; + + if (Loc.TryGetString("gas-deposit-drill-system-examined", out var str, + ("statusColor", "lightblue"), + ("rate", extractor.TargetPressure) + )) + args.PushMarkup(str); + if (extractor.DepositEntity != null) + { + if (Loc.TryGetString("gas-deposit-drill-system-examined-amount", out str, + ("statusColor", "lightblue"), + ("rate", extractor.DepositEntity.Value.Comp.Deposit.TotalMoles) + )) + args.PushMarkup(str); + } + } + public void OnAnchorAttempt(EntityUid uid, GasDepositExtractorComponent component, AnchorAttemptEvent args) { if (args.Cancelled) @@ -111,6 +151,15 @@ private void OnExtractorUpdate(EntityUid uid, GasDepositExtractorComponent extra || !_nodeContainer.TryGetNode(uid, extractor.PortName, out PipeNode? port)) { _ambientSound.SetAmbience(uid, false); + SetDepositState(uid, GasDepositExtractorState.Off, extractor); + return; + } + + var depositComp = extractor.DepositEntity.Value.Comp; + if (depositComp.Deposit.TotalMoles < Atmospherics.GasMinMoles) + { + _ambientSound.SetAmbience(uid, false); + SetDepositState(uid, GasDepositExtractorState.Empty, extractor); return; } @@ -123,14 +172,19 @@ private void OnExtractorUpdate(EntityUid uid, GasDepositExtractorComponent extra if (allowableMoles < Atmospherics.GasMinMoles) { _ambientSound.SetAmbience(uid, false); + SetDepositState(uid, GasDepositExtractorState.Blocked, extractor); return; } - var removed = extractor.DepositEntity.Value.Comp.Deposit.Remove(allowableMoles); + var removed = depositComp.Deposit.Remove(allowableMoles); removed.Temperature = extractor.OutputTemperature; _atmosphere.Merge(port.Air, removed); _ambientSound.SetAmbience(uid, true); + if (depositComp.Deposit.TotalMoles <= depositComp.LowMoles) + SetDepositState(uid, GasDepositExtractorState.Low, extractor); + else + SetDepositState(uid, GasDepositExtractorState.On, extractor); } private void OnToggleStatusMessage(EntityUid uid, GasDepositExtractorComponent extractor, GasPressurePumpToggleStatusMessage args) @@ -141,10 +195,31 @@ private void OnToggleStatusMessage(EntityUid uid, GasDepositExtractorComponent e DirtyUI(uid, extractor); } + private void OnPumpActivate(EntityUid uid, GasDepositExtractorComponent pump, ActivateInWorldEvent args) + { + if (args.Handled || !args.Complex) + return; + + if (!TryComp(args.User, out ActorComponent? actor)) + return; + + if (Transform(uid).Anchored) + { + _ui.OpenUi(uid, GasPressurePumpUiKey.Key, actor.PlayerSession); + DirtyUI(uid, pump); + } + else + { + _popup.PopupCursor(Loc.GetString("gas-deposit-drill-ui-needs-anchor"), args.User); + } + + args.Handled = true; + } + private void OnOutputPressureChangeMessage(EntityUid uid, GasDepositExtractorComponent extractor, GasPressurePumpChangeOutputPressureMessage args) { extractor.TargetPressure = Math.Clamp(args.Pressure, 0f, Atmospherics.MaxOutputPressure); - _adminLog.Add(LogType.AtmosPressureChanged, LogImpact.Medium, + _adminLog.Add(LogType.AtmosPressureChanged, LogImpact.Low, $"{ToPrettyString(args.Actor):player} set the pressure on {ToPrettyString(uid):device} to {args.Pressure}kPa"); DirtyUI(uid, extractor); } @@ -157,4 +232,28 @@ private void DirtyUI(EntityUid uid, GasDepositExtractorComponent? extractor) _ui.SetUiState(uid, GasPressurePumpUiKey.Key, new GasPressurePumpBoundUserInterfaceState(EntityManager.GetComponent(uid).EntityName, extractor.TargetPressure, extractor.Enabled)); } + + private void SetDepositState(EntityUid uid, GasDepositExtractorState newState, GasDepositExtractorComponent? extractor = null) + { + if (!Resolve(uid, ref extractor, false)) + return; + + if (newState != extractor.LastState) + { + extractor.LastState = newState; + UpdateAppearance(uid, extractor); + } + } + + private void UpdateAppearance(EntityUid uid, GasDepositExtractorComponent? extractor = null, AppearanceComponent? appearance = null) + { + if (!Resolve(uid, ref extractor, ref appearance, false)) + return; + + bool pumpOn = extractor.Enabled && (!TryComp(uid, out var power) || power.Powered); + if (!pumpOn) + _appearance.SetData(uid, GasDepositExtractorVisuals.State, GasDepositExtractorState.Off, appearance); + else + _appearance.SetData(uid, GasDepositExtractorVisuals.State, extractor.LastState, appearance); + } } diff --git a/Content.Server/_NF/Atmos/Prototypes/GasDepositPrototype.cs b/Content.Server/_NF/Atmos/Prototypes/GasDepositPrototype.cs index 9327b5dfdd0..d5c56e5d0bd 100644 --- a/Content.Server/_NF/Atmos/Prototypes/GasDepositPrototype.cs +++ b/Content.Server/_NF/Atmos/Prototypes/GasDepositPrototype.cs @@ -2,19 +2,18 @@ using Content.Shared.Atmos; using Robust.Shared.Prototypes; -namespace Content.Server._NF.Atmos +namespace Content.Server._NF.Atmos; + +[Prototype("gasDeposit")] +public sealed partial class GasDepositPrototype : IPrototype { - [Prototype("gasDeposit")] - public sealed partial class GasDepositPrototype : IPrototype - { - [ViewVariables] - [IdDataField] - public string ID { get; private set; } = default!; + [ViewVariables] + [IdDataField] + public string ID { get; private set; } = default!; - /// - /// 2-vectors (minAmount, maxAmount) in moles of each gas in the deposit. - /// - [DataField] - public Vector2[] Gases { get; private set; } = new Vector2[Atmospherics.TotalNumberOfGases]; - } + /// + /// 2-vectors (minAmount, maxAmount) in moles of each gas in the deposit. + /// + [DataField] + public Vector2[] Gases { get; private set; } = new Vector2[Atmospherics.TotalNumberOfGases]; } diff --git a/Content.Shared/_NF/Atmos/Visuals/GasDepositExtractorVisuals.cs b/Content.Shared/_NF/Atmos/Visuals/GasDepositExtractorVisuals.cs new file mode 100644 index 00000000000..17685487acb --- /dev/null +++ b/Content.Shared/_NF/Atmos/Visuals/GasDepositExtractorVisuals.cs @@ -0,0 +1,19 @@ +using Robust.Shared.Serialization; + +namespace Content.Shared._NF.Atmos.Visuals; + +[Serializable, NetSerializable] +public enum GasDepositExtractorVisuals : byte +{ + State, +} + +[Serializable, NetSerializable] +public enum GasDepositExtractorState : byte +{ + Off, // Not pumping. + On, // Actively pumping, lots of gas left. + Low, // Actively pumping, not much gas left. + Blocked, // Not pumping, gas left. + Empty, // Not pumping, no gas left. +} diff --git a/Resources/Locale/en-US/_NF/atmos/gas-deposit-drill-component.ftl b/Resources/Locale/en-US/_NF/atmos/gas-deposit-drill-component.ftl deleted file mode 100644 index 3ae1335ace9..00000000000 --- a/Resources/Locale/en-US/_NF/atmos/gas-deposit-drill-component.ftl +++ /dev/null @@ -1 +0,0 @@ -gas-deposit-drill-no-resources = Nothing to extract here! diff --git a/Resources/Locale/en-US/_NF/atmos/gas-deposit.ftl b/Resources/Locale/en-US/_NF/atmos/gas-deposit.ftl new file mode 100644 index 00000000000..7dcc5a813ef --- /dev/null +++ b/Resources/Locale/en-US/_NF/atmos/gas-deposit.ftl @@ -0,0 +1,4 @@ +gas-deposit-drill-no-resources = Nothing to extract here! +gas-deposit-drill-ui-needs-anchor = Anchor it first! +gas-deposit-drill-system-examined = The extractor is set to [color={$statusColor}]{PRESSURE($pressure)}[/color]. +gas-deposit-drill-system-examined-amount = The extractor reports [color={$statusColor}]{TOSTRING($value, "N3") } mol[/color] left. diff --git a/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml b/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml index cf7f3d39f3c..034c92fc74e 100644 --- a/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml +++ b/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml @@ -23,7 +23,7 @@ - type: PipeRestrictOverlap - type: NodeContainer nodes: - port: + outlet: !type:PipeNode nodeGroupID: Pipe pipeDirection: South @@ -40,27 +40,47 @@ - type: PowerSwitch - type: StationAiWhitelist - type: Sprite - sprite: Structures/Piping/Atmospherics/thermomachine.rsi + sprite: _NF/Objects/Specific/Atmospherics/extractor.rsi snapCardinals: true granularLayersRendering: true layers: - - state: freezerOff - map: [ "enum.PowerDeviceVisualLayers.Powered" ] - - state: freezerPanelOpen - map: [ "enum.WiresVisualLayers.MaintenancePanel" ] - - state: pipe + - sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeHalf map: [ "enum.PipeVisualLayers.Pipe" ] renderingStrategy: Default + - state: drill-off + map: [ "drill" ] + - state: base + - state: base-powered + shader: unshaded + map: [ "enum.PowerDeviceVisualLayers.Powered" ] + - state: drill-empty-unlit + shader: unshaded + map: [ "light" ] - type: GenericVisualizer visuals: enum.PowerDeviceVisuals.Powered: enum.PowerDeviceVisualLayers.Powered: - True: { state: freezerOn } - False: { state: freezerOff } + True: { visible: true } + False: { visible: false } + enum.GasDepositExtractorVisuals.State: + drill: + Off: { state: drill-off } + Blocked: { state: drill-off } + Empty: { state: drill-off } + Low: { state: drill } + On: { state: drill } + light: + Off: { visible: false } + Blocked: { state: drill-blocked-unlit, visible: true } + Empty: { state: drill-empty-unlit, visible: true } + Low: { state: drill-low-unlit, visible: true } + On: { state: drill-on-unlit, visible: true } - type: ApcPowerReceiver load: 4000 - type: Machine board: Null # FIXME - type: GasDepositExtractor extractionRate: 20 - port: port + port: outlet + - type: PipeAppearance diff --git a/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml b/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml index 02f3ef76ea6..e7725aa854c 100644 --- a/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml +++ b/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml @@ -113,11 +113,11 @@ - state: closed - state: closed_unlit shader: unshaded - map: ["enum.GaslockVisualLayers.Docked"] - - state: pipeStraight + map: ["docked-unlit"] + - sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeStraight map: [ "enum.PipeVisualLayers.Pipe" ] - state: pumpPressure - map: [ "enabled" ] - state: pumpPressureOnOut map: [ "enabled-unlit" ] shader: unshaded @@ -130,11 +130,11 @@ True: { visible: true } False: { visible: false } enum.DockablePumpVisuals.Docked: - enum.GaslockVisualLayers.Docked: + docked-unlit: True: { visible: true } False: { visible: false } - enum.DockablePumpVisuals.PumpingOutward: - enum.GaslockVisualLayers.Docked: + enum.DockablePumpVisuals.PumpingOutwards: + enabled-unlit: True: { state: pumpPressureOnOut } False: { state: pumpPressureOnIn } - type: StaticPrice @@ -182,12 +182,12 @@ - state: frame_struts - state: closed_unlit shader: unshaded - map: ["enum.GaslockVisualLayers.Docked"] + map: ["docked-unlit"] + - sprite: Structures/Piping/Atmospherics/pipe.rsi state: pipeStraight map: [ "enum.PipeVisualLayers.Pipe" ] - state: pumpPressure - map: [ "enabled" ] - state: pumpPressureOnOut + - state: pumpPressure + - state: pumpPressureOnOut map: [ "enabled-unlit" ] shader: unshaded - state: panel_open @@ -199,11 +199,11 @@ True: { visible: true } False: { visible: false } enum.DockablePumpVisuals.Docked: - enum.GaslockVisualLayers.Docked: + docked-unlit: True: { visible: true } False: { visible: false } - enum.DockablePumpVisuals.PumpingOutward: - enum.GaslockVisualLayers.Docked: + enum.DockablePumpVisuals.PumpingOutwards: + enabled-unlit: True: { state: pumpPressureOnOut } False: { state: pumpPressureOnIn } - type: StaticPrice diff --git a/Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/base-powered.png b/Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/base-powered.png new file mode 100644 index 0000000000000000000000000000000000000000..3604019e79dcfe868ddb4f598c1e4fa86e65e97e GIT binary patch literal 99 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzEl(H6kcif|=L~rn3^*7JVhSGK wXFuk^d~%ZQ+9o#!h6BzwO>dg+muHxxQ*Xum`ft>^n?PL*p00i_>zopr0H{VC761SM literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/base.png b/Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/base.png new file mode 100644 index 0000000000000000000000000000000000000000..17f74701be37688d5d6a36234736a939f74a6566 GIT binary patch literal 682 zcmV;b0#*HqP)tZ7X;!&9#pg=PS zMHklzG*tp+1Dez!AwiK8MYm&piv&H2cf9xbNMMiu9S6G%KI``jlX2f49*pOGwF~iN zGAVs0Sq1<|l0^KaFcnfe;H=*-C^5-0w3p-35I?z<;P%A){_p$F|KAXXD9OddMxk)ONw$v3LpL0oue!Twq^~2h*8^}mK_j9h~PzSw_D6V zfBeSBhn|Pq_2PMjZ$`KaLurnI>q_5PV>lm;ih=9mxZ5oaAXx@N2 zR;$Ivi6YW81puUJ3deDnFp5%d7LQ;GUXX~YW|QYRY};l+s1x_gW$8?i4hMdpQZY0w zq60Jqyz`bN{;nToqbHY+hO9B_A) zSq4PYEY+q>pRAGL;?nm#D`lqp;*P^6`tNUkjtpD=+R?aw7lWsW$?mgvcxNkiKbRD+ zpQfZVX?p20-9tORzpzREm34m;>$cM`<94&|xprKU1L!g^XbAt~l4uI2_sZ5S zu5UROHeYeny4e!^u3LA>_YXD9a;(L=qKaQG)U0b!%T literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/drill-low-unlit.png b/Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/drill-low-unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..b600090177900954f58493a34990b82c663ce4dc GIT binary patch literal 293 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=Z#-QbLn`LHy=BPP&57O!-UUBBXwioH3IH zYIQta978O6lM^IZokcx7JU%=MJ#boE(eVIF9Fv-dfDvN`JEOKn=@ShJ2L^_qbxazs T53xl8^)Yz5`njxgN@xNAOT}!r literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/drill-on-unlit.png b/Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/drill-on-unlit.png new file mode 100644 index 0000000000000000000000000000000000000000..c03b8148d08a3f648b008766547a97226248ad78 GIT binary patch literal 361 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7T#lEU^MV_aSW-L^Y+%pEG9>RhKHS= z!XD~umm)m74k*6#QSNX(V76qZd&hI@JJu^62tRRrqvtE|a8`+#nv>P!hO^5&*m^?e zOl`gVfAzbryEA3;zIR0mGB5ISNpl77|oIWc_vx#d7zPe{nz^W zPd{c^Z8(#x=dd@rbo%$y+ET^t1>N@h?Sus<{;asUU2Nf&&u{n~XD#!4@?85uu7FkD z9Cy#`km9w0XMfIPZr$4LECBQZ1pME~KUcEYy}bD0wQpPa&mL6Ywvs_A;`e9qvzO=P zD@~KR_Bc8@KeplP(d_!Vk9&BcTF(Avl$!sWk?r_xz8QSt{%>dBUUQ}5{od61bNjD{ ze$XuluRIYpce?$@=3K_D`t1wKnOy(#GJ)-SaG{3zG+$qR0HgOIkbtMFpUXO@geCyi CNSNLL literal 0 HcmV?d00001 diff --git a/Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/drill.png b/Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/drill.png new file mode 100644 index 0000000000000000000000000000000000000000..cc7e1f131737313d4e4152266afbd75c2d1e628e GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^2|(Z*kwA#w>K@HX*=K5^(X5c!F@?RAG0~;m0f4h zo7+%61 zUiJ6K)IZtU?_U1dy<)j}uz&utdG~y5_eTC?De+GzxBaJAcL=28!-V|m{T;RsA3VMQ O;(EIJxvX Date: Thu, 14 Nov 2024 17:13:37 -0500 Subject: [PATCH 09/61] Gas deposits, pipe fixes for the drill --- .../Atmos/EntitySystems/GasDepositSystem.cs | 4 ++- .../Specific/Atmospherics/deposits.yml | 2 +- .../Structures/Piping/Atmospherics/unary.yml | 4 +-- .../Atmospherics/extractor.rsi/meta.json | 34 ++++++++++-------- .../Atmospherics/extractor.rsi/pipe.png | Bin 0 -> 1124 bytes 5 files changed, 24 insertions(+), 20 deletions(-) create mode 100644 Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/pipe.png diff --git a/Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs b/Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs index d338a9339b1..c016169b58e 100644 --- a/Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs +++ b/Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs @@ -26,7 +26,6 @@ namespace Content.Server._NF.Atmos.EntitySystems; // System for handling gas deposits and machines for extracting from gas deposits public sealed class GasDepositSystem : EntitySystem { - [Dependency] private readonly EntityLookupSystem _lookup = default!; [Dependency] private readonly MapSystem _map = default!; [Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly IRobustRandom _random = default!; @@ -38,6 +37,8 @@ public sealed class GasDepositSystem : EntitySystem [Dependency] private readonly UserInterfaceSystem _ui = default!; [Dependency] private readonly AppearanceSystem _appearance = default!; + private const float LowMoleCoefficient = 0.25f; + /// public override void Initialize() { @@ -141,6 +142,7 @@ public void OnDepositInit(EntityUid uid, RandomGasDepositComponent component, Co var gasRange = depositPrototype!.Gases[i]; component.Deposit.SetMoles(i, gasRange[0] + _random.NextFloat() * (gasRange[1] - gasRange[0])); } + component.LowMoles = component.Deposit.TotalMoles * LowMoleCoefficient; } private void OnExtractorUpdate(EntityUid uid, GasDepositExtractorComponent extractor, ref AtmosDeviceUpdateEvent args) diff --git a/Resources/Prototypes/_NF/Entities/Objects/Specific/Atmospherics/deposits.yml b/Resources/Prototypes/_NF/Entities/Objects/Specific/Atmospherics/deposits.yml index 108d94acc4d..4e3e66c9fe9 100644 --- a/Resources/Prototypes/_NF/Entities/Objects/Specific/Atmospherics/deposits.yml +++ b/Resources/Prototypes/_NF/Entities/Objects/Specific/Atmospherics/deposits.yml @@ -2,7 +2,7 @@ - type: entity id: BaseGasDeposit name: gas deposit - description: Solidified deposits of an element, normally a gas at room temperature, can be drilled, heated and piped out." + description: Solidified deposits of an element, normally a gas at room temperature, can be drilled, heated and piped out. abstract: true placement: mode: SnapgridCenter diff --git a/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml b/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml index 034c92fc74e..8d4170101ec 100644 --- a/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml +++ b/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml @@ -44,8 +44,7 @@ snapCardinals: true granularLayersRendering: true layers: - - sprite: Structures/Piping/Atmospherics/pipe.rsi - state: pipeHalf + - state: pipe map: [ "enum.PipeVisualLayers.Pipe" ] renderingStrategy: Default - state: drill-off @@ -83,4 +82,3 @@ - type: GasDepositExtractor extractionRate: 20 port: outlet - - type: PipeAppearance diff --git a/Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/meta.json b/Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/meta.json index c7fc878632d..d3f9e1f3927 100644 --- a/Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/meta.json +++ b/Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/meta.json @@ -32,10 +32,10 @@ "name": "drill-blocked-unlit", "delays": [ [ - 0.45, - 0.15, - 0.15, - 0.15 + 0.6, + 0.1, + 0.2, + 0.1 ] ] }, @@ -43,10 +43,10 @@ "name": "drill-empty-unlit", "delays": [ [ - 0.45, - 0.15, - 0.15, - 0.15 + 0.6, + 0.1, + 0.2, + 0.1 ] ] }, @@ -54,10 +54,10 @@ "name": "drill-low-unlit", "delays": [ [ - 0.6, - 0.2, + 0.9, + 0.1, 0.2, - 0.2 + 0.1 ] ] }, @@ -65,12 +65,16 @@ "name": "drill-on-unlit", "delays": [ [ - 0.9, - 0.3, - 0.3, - 0.3 + 1.2, + 0.1, + 0.2, + 0.1 ] ] + }, + { + "name": "pipe", + "directions": 4 } ] } diff --git a/Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/pipe.png b/Resources/Textures/_NF/Objects/Specific/Atmospherics/extractor.rsi/pipe.png new file mode 100644 index 0000000000000000000000000000000000000000..4a068c41778f699cd4a6e384771aa8349def4a10 GIT binary patch literal 1124 zcmV-q1e^PbP)OPfXD8H%m)sHk$x|v9U3nG#Xefm9##z z2`^dDE52g}IHjDONGkeK*nGzTm|b_Pr4kOSRb(<5)94d;5SK#OeABdWT72khjx|Q) zXGiEI-|;@cYUQ1N`=I~;qmwh8`(Hmse(ry2(CuMnK#+V_Yd|6%H*F(uvo?A=@}sc% zp4I>sJ~}zmVcWybfS~w>0I>J_Rx@A+2h3-{&9g+W`Gaf+b~UxT`yz0&G&Gxm`9i@q z2vP90MR2iLR7FwLqFt#}3_#kP9o%Y_Run~J9oK5Q6*(%tZWkz*%cxW;c(<~GR5FQH zyNy&bsTpDiX5n=Ee4(HLhlhuuC<@Nc&M=qH zeZEk@@l6c?u=uiwlSacZ##}yc`op8-YiYPxEUI()JSN7+bsZ#Gh9pTitX3V(v#@kJ z4N(+zugzu?9a)CiB@hK)mjM&w?0@iYV+dT?-{?(FRNI-84HeSI<%gm?g=Ho(Qj#TBKx zKCW`pFYNk&Ao+b=9}one*9QazXHAgzygncR@%n%e`Mf^BsROSM;PnB)ozHvu<0S0* z0LK8>Z9i_#=V=og8yk*>0N~5+ZYX>+dCmYY=kvK-&IuPP-%N%8Se?(aCfuIS(!}WJiW*SeLjEEXh80mdPaO?1Yz?5=zjS{+11!z(`T$-Zz{SP&AL=)PR==CR?5b-30000 Date: Thu, 14 Nov 2024 19:35:03 -0500 Subject: [PATCH 10/61] gaslock RSI fix --- .../Piping/Atmospherics/gaslock.rsi/meta.json | 52 ++++++++++--------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/meta.json b/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/meta.json index 7bdf3d2680c..65558db99a1 100644 --- a/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/meta.json +++ b/Resources/Textures/_NF/Structures/Piping/Atmospherics/gaslock.rsi/meta.json @@ -1,44 +1,48 @@ { - "version":1, + "version": 1, "size":{ - "x":32, - "y":32 + "x": 32, + "y": 32 }, - "license":"CC-BY-SA-3.0", - "copyright":"closed, bolted_unlit taken from CEV-Eris at commit https://github.com/discordia-space/CEV-Eris/commit/14517938186858388656a6aee14bf47af9e9649f - then modified by 20kdc, AJCM-git and whatston3", - "copyright":"pump* taken from https://github.com/tgstation/tgstation at commit 57cd1d59ca019dd0e7811ac451f295f818e573da, modified by whatston3.", + "license": "CC-BY-SA-3.0", + "copyright": "closed, bolted_unlit taken from CEV-Eris at commit https://github.com/discordia-space/CEV-Eris/commit/14517938186858388656a6aee14bf47af9e9649f - then modified by 20kdc, AJCM-git and whatston3", + "copyright": "pump* taken from https://github.com/tgstation/tgstation at commit 57cd1d59ca019dd0e7811ac451f295f818e573da, modified by whatston3.", "states":[ { - "name":"closed" + "name": "closed" }, { - "name":"closed_unlit" + "name": "closed_unlit" }, { - "name":"frame_struts" + "name": "frame_struts" }, { - "name":"panel_open" + "name": "panel_open" }, { - "name":"pumpPressure", - "directions":4 + "name": "pipeStraight", + "directions": 4 }, { - "name":"pumpPressureOnIn", - "directions":4, - "delays":[ [ 0.1, 0.1, 0.1, 0.1, 0.1 ], - [ 0.1, 0.1, 0.1, 0.1, 0.1 ], - [ 0.1, 0.1, 0.1, 0.1, 0.1 ], - [ 0.1, 0.1, 0.1, 0.1, 0.1 ] ] + "name": "pumpPressure", + "directions": 4 }, { - "name":"pumpPressureOnOut", - "directions":4, - "delays":[ [ 0.1, 0.1, 0.1, 0.1, 0.1 ], - [ 0.1, 0.1, 0.1, 0.1, 0.1 ], - [ 0.1, 0.1, 0.1, 0.1, 0.1 ], - [ 0.1, 0.1, 0.1, 0.1, 0.1 ] ] + "name": "pumpPressureOnIn", + "directions": 4, + "delays": [ [ 0.1, 0.1, 0.1, 0.1, 0.1 ], + [ 0.1, 0.1, 0.1, 0.1, 0.1 ], + [ 0.1, 0.1, 0.1, 0.1, 0.1 ], + [ 0.1, 0.1, 0.1, 0.1, 0.1 ] ] + }, + { + "name": "pumpPressureOnOut", + "directions": 4, + "delays": [ [ 0.1, 0.1, 0.1, 0.1, 0.1 ], + [ 0.1, 0.1, 0.1, 0.1, 0.1 ], + [ 0.1, 0.1, 0.1, 0.1, 0.1 ], + [ 0.1, 0.1, 0.1, 0.1, 0.1 ] ] } ] } From 8cc633acee4edd322bececa4cf701f9115422731 Mon Sep 17 00:00:00 2001 From: Whatstone Date: Sun, 17 Nov 2024 12:16:05 -0500 Subject: [PATCH 11/61] gaslock to binary.yml, joinSystem test --- .../Structures/Piping/Atmospherics/binary.yml | 236 +++++++++++++++++- .../Structures/Piping/Atmospherics/unary.yml | 1 + .../Entities/Structures/Specific/gaslock.yml | 232 ----------------- 3 files changed, 236 insertions(+), 233 deletions(-) delete mode 100644 Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml diff --git a/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/binary.yml b/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/binary.yml index 9a427c10851..f1570d179c6 100644 --- a/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/binary.yml +++ b/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/binary.yml @@ -26,4 +26,238 @@ mode: SnapgridCenter components: - type: GasVolumePump - startOnMapInit: true \ No newline at end of file + startOnMapInit: true + +# Giant mess of a YAML definition but largely based on GasPressurePump and AirlockShuttle +- type: entity + parent: BaseStructure + id: BaseGaslock + suffix: Docking + name: external gaslock + description: Connects gas pipes on separate ships or stations together to allow gas transfer. Both sides must be docked and pumping in the same direction to accept flow. + components: + - type: Transform + noRot: false + - type: Anchorable + - type: Rotatable + - type: Docking + radarColor: darkcyan + highlightedRadarColor: cyan + - type: DockingSignalControl + - type: DeviceLinkSource + ports: + - DockStatus + # - type: DeviceLinkSink + # ports: + # - PumpOn + # - PumpOff + # - DirectionIn + # - DirectionOut + # - ToggleDirection + - type: Fixtures + fixtures: + fix1: + shape: + !type:PhysShapeAabb + bounds: "-0.49,-0.49,0.49,0.49" # don't want this colliding with walls or they won't close + density: 100 + mask: + - FullTileMask + layer: + - AirlockLayer + docking: + shape: + !type:PhysShapeCircle + radius: 0.2 + position: "0,-0.5" + hard: false + - type: Wires + layoutId: Docking + - type: WiresVisuals + - type: WiresPanel + - type: WiresPanelSecurity + - type: PaintableAirlock + group: External + department: null + # - type: Construction + # graph: AirlockShuttle + # node: airlock + - type: ApcPowerReceiver + powerLoad: 500 + - type: ExtensionCableReceiver + - type: Appearance + - type: PipeColorVisuals + - type: GasPressurePump + enabled: false + - type: NodeContainer + nodes: + inlet: + !type:PipeNode + nodeGroupID: Pipe + pipeDirection: North + outlet: + !type:DockablePipeNode + nodeGroupID: Pipe + pipeDirection: South + - type: UserInterface + interfaces: + enum.GasPressurePumpUiKey.Key: + type: GasPressurePumpBoundUserInterface + - type: DockablePump + dockNodeName: outlet + internalNodeName: inlet + - type: AmbientSound + enabled: false + volume: -9 + range: 5 + sound: + path: /Audio/Ambience/Objects/gas_pump.ogg + - type: InteractionOutline + - type: StationAiWhitelist + - type: AtmosDevice + joinSystem: true # Any pipe system on an asteroid should update. + - type: Tag + tags: + - Unstackable + - Pipe + - type: PipeAppearance + - type: PipeRestrictOverlap + - type: AtmosUnsafeUnanchor + - type: AtmosPipeColor + +- type: entity + parent: BaseGaslock + id: Gaslock + suffix: Airtight + placement: + mode: SnapgridCenter + components: + - type: Airtight + - type: RadiationBlocker + resistance: 3 + - type: Occluder + - type: Sprite + sprite: _NF/Structures/Piping/Atmospherics/gaslock.rsi + # granularLayersRendering: true + drawdepth: Doors + layers: + - state: closed + - state: closed_unlit + shader: unshaded + map: ["docked-unlit"] + - sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeStraight + map: [ "enum.PipeVisualLayers.Pipe" ] + - state: pumpPressure + - state: pumpPressureOnOut + map: [ "enabled-unlit" ] + shader: unshaded + - state: panel_open + map: ["enum.WiresVisualLayers.MaintenancePanel"] + - type: GenericVisualizer + visuals: + enum.PumpVisuals.Enabled: + enabled-unlit: + True: { visible: true } + False: { visible: false } + enum.DockablePumpVisuals.Docked: + docked-unlit: + True: { visible: true } + False: { visible: false } + enum.DockablePumpVisuals.PumpingOutwards: + enabled-unlit: + True: { state: pumpPressureOnOut } + False: { state: pumpPressureOnIn } + - type: StaticPrice + price: 350 + - type: Tag + tags: + - Unstackable + - Pipe + - ForceNoFixRotations + - type: BlockWeather + - type: PlacementReplacement + key: walls + - type: IconSmooth + key: walls + mode: NoSprite + +- type: entity + parent: Gaslock + id: GaslockReversed + suffix: Airtight, Reversed + description: Connects gas tanks on separate ships or stations together to allow gas transfer. Both stages must be set up to accept flow. + components: + - type: GasPressurePump + inlet: outlet + outlet: inlet + - type: DockablePump + pumpingInwards: true + +- type: entity + parent: BaseGaslock + id: GaslockFrame + suffix: Docking + name: gas staging port + description: Connects gas pipes on separate ships or stations together to allow gas transfer. Both sides must be docked and pumping in the same direction to accept flow. + placement: + mode: SnapgridCenter + components: + - type: Sprite + sprite: _NF/Structures/Piping/Atmospherics/gaslock.rsi + # granularLayersRendering: true + drawdepth: Doors + layers: + - sprite: Structures/Walls/solid.rsi + state: wall_girder + - state: frame_struts + - state: closed_unlit + shader: unshaded + map: ["docked-unlit"] + - sprite: Structures/Piping/Atmospherics/pipe.rsi + state: pipeStraight + map: [ "enum.PipeVisualLayers.Pipe" ] + - state: pumpPressure + - state: pumpPressureOnOut + map: [ "enabled-unlit" ] + shader: unshaded + - state: panel_open + map: ["enum.WiresVisualLayers.MaintenancePanel"] + - type: GenericVisualizer + visuals: + enum.PumpVisuals.Enabled: + enabled-unlit: + True: { visible: true } + False: { visible: false } + enum.DockablePumpVisuals.Docked: + docked-unlit: + True: { visible: true } + False: { visible: false } + enum.DockablePumpVisuals.PumpingOutwards: + enabled-unlit: + True: { state: pumpPressureOnOut } + False: { state: pumpPressureOnIn } + - type: StaticPrice + price: 100 + - type: Tag + tags: + - Unstackable + - Pipe + - ForceNoFixRotations + - type: BlockWeather + - type: PlacementReplacement + key: walls + - type: IconSmooth + key: walls + mode: NoSprite + +- type: entity + parent: GaslockFrame + id: GaslockFrameReversed + suffix: Docking, Reversed + components: + - type: GasPressurePump + inlet: outlet + outlet: inlet + - type: DockablePump + pumpingInwards: true diff --git a/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml b/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml index 8d4170101ec..1d07cbce9e8 100644 --- a/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml +++ b/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/unary.yml @@ -11,6 +11,7 @@ - type: Rotatable - type: AtmosPipeColor - type: AtmosDevice + joinSystem: true - type: UserInterface interfaces: enum.GasPressurePumpUiKey.Key: diff --git a/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml b/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml deleted file mode 100644 index e7725aa854c..00000000000 --- a/Resources/Prototypes/_NF/Entities/Structures/Specific/gaslock.yml +++ /dev/null @@ -1,232 +0,0 @@ -# Giant mess of a YAML definition but largely based on GasPressurePump and AirlockShuttle -- type: entity - parent: BaseStructure - id: BaseGaslock - suffix: Docking - name: external gaslock - description: Connects gas pipes on separate ships or stations together to allow gas transfer. Both sides must be docked and pumping in the same direction to accept flow. - components: - - type: Transform - noRot: false - - type: Anchorable - - type: Rotatable - - type: Docking - radarColor: darkcyan - highlightedRadarColor: cyan - - type: DockingSignalControl - - type: DeviceLinkSource - ports: - - DockStatus - # - type: DeviceLinkSink - # ports: - # - PumpOn - # - PumpOff - # - DirectionIn - # - DirectionOut - # - ToggleDirection - - type: Fixtures - fixtures: - fix1: - shape: - !type:PhysShapeAabb - bounds: "-0.49,-0.49,0.49,0.49" # don't want this colliding with walls or they won't close - density: 100 - mask: - - FullTileMask - layer: - - AirlockLayer - docking: - shape: - !type:PhysShapeCircle - radius: 0.2 - position: "0,-0.5" - hard: false - - type: Wires - layoutId: Docking - - type: WiresVisuals - - type: WiresPanel - - type: WiresPanelSecurity - - type: PaintableAirlock - group: External - department: null - # - type: Construction - # graph: AirlockShuttle - # node: airlock - - type: ApcPowerReceiver - powerLoad: 500 - - type: ExtensionCableReceiver - - type: Appearance - - type: PipeColorVisuals - - type: GasPressurePump - enabled: false - - type: NodeContainer - nodes: - inlet: - !type:PipeNode - nodeGroupID: Pipe - pipeDirection: North - outlet: - !type:DockablePipeNode - nodeGroupID: Pipe - pipeDirection: South - - type: UserInterface - interfaces: - enum.GasPressurePumpUiKey.Key: - type: GasPressurePumpBoundUserInterface - - type: DockablePump - dockNodeName: outlet - internalNodeName: inlet - - type: AmbientSound - enabled: false - volume: -9 - range: 5 - sound: - path: /Audio/Ambience/Objects/gas_pump.ogg - - type: InteractionOutline - - type: StationAiWhitelist - - type: AtmosDevice - - type: Tag - tags: - - Unstackable - - Pipe - - type: PipeAppearance - - type: PipeRestrictOverlap - - type: AtmosUnsafeUnanchor - - type: AtmosPipeColor - -- type: entity - parent: BaseGaslock - id: Gaslock - suffix: Airtight - placement: - mode: SnapgridCenter - components: - - type: Airtight - - type: RadiationBlocker - resistance: 3 - - type: Occluder - - type: Sprite - sprite: _NF/Structures/Piping/Atmospherics/gaslock.rsi - # granularLayersRendering: true - drawdepth: Doors - layers: - - state: closed - - state: closed_unlit - shader: unshaded - map: ["docked-unlit"] - - sprite: Structures/Piping/Atmospherics/pipe.rsi - state: pipeStraight - map: [ "enum.PipeVisualLayers.Pipe" ] - - state: pumpPressure - - state: pumpPressureOnOut - map: [ "enabled-unlit" ] - shader: unshaded - - state: panel_open - map: ["enum.WiresVisualLayers.MaintenancePanel"] - - type: GenericVisualizer - visuals: - enum.PumpVisuals.Enabled: - enabled-unlit: - True: { visible: true } - False: { visible: false } - enum.DockablePumpVisuals.Docked: - docked-unlit: - True: { visible: true } - False: { visible: false } - enum.DockablePumpVisuals.PumpingOutwards: - enabled-unlit: - True: { state: pumpPressureOnOut } - False: { state: pumpPressureOnIn } - - type: StaticPrice - price: 350 - - type: Tag - tags: - - Unstackable - - Pipe - - ForceNoFixRotations - - type: BlockWeather - - type: PlacementReplacement - key: walls - - type: IconSmooth - key: walls - mode: NoSprite - -- type: entity - parent: Gaslock - id: GaslockReversed - suffix: Airtight, Reversed - description: Connects gas tanks on separate ships or stations together to allow gas transfer. Both stages must be set up to accept flow. - components: - - type: GasPressurePump - inlet: outlet - outlet: inlet - - type: DockablePump - pumpingInwards: true - -- type: entity - parent: BaseGaslock - id: GaslockFrame - suffix: Docking - name: gas staging port - description: Connects gas pipes on separate ships or stations together to allow gas transfer. Both sides must be docked and pumping in the same direction to accept flow. - placement: - mode: SnapgridCenter - components: - - type: Sprite - sprite: _NF/Structures/Piping/Atmospherics/gaslock.rsi - # granularLayersRendering: true - drawdepth: Doors - layers: - - sprite: Structures/Walls/solid.rsi - state: wall_girder - - state: frame_struts - - state: closed_unlit - shader: unshaded - map: ["docked-unlit"] - - sprite: Structures/Piping/Atmospherics/pipe.rsi - state: pipeStraight - map: [ "enum.PipeVisualLayers.Pipe" ] - - state: pumpPressure - - state: pumpPressureOnOut - map: [ "enabled-unlit" ] - shader: unshaded - - state: panel_open - map: ["enum.WiresVisualLayers.MaintenancePanel"] - - type: GenericVisualizer - visuals: - enum.PumpVisuals.Enabled: - enabled-unlit: - True: { visible: true } - False: { visible: false } - enum.DockablePumpVisuals.Docked: - docked-unlit: - True: { visible: true } - False: { visible: false } - enum.DockablePumpVisuals.PumpingOutwards: - enabled-unlit: - True: { state: pumpPressureOnOut } - False: { state: pumpPressureOnIn } - - type: StaticPrice - price: 100 - - type: Tag - tags: - - Unstackable - - Pipe - - ForceNoFixRotations - - type: BlockWeather - - type: PlacementReplacement - key: walls - - type: IconSmooth - key: walls - mode: NoSprite - -- type: entity - parent: GaslockFrame - id: GaslockFrameReversed - suffix: Docking, Reversed - components: - - type: GasPressurePump - inlet: outlet - outlet: inlet - - type: DockablePump - pumpingInwards: true From 0f92d2b99e86a0d0872b5e31e0a56bb22825a776 Mon Sep 17 00:00:00 2001 From: Whatstone Date: Sun, 17 Nov 2024 15:46:29 -0500 Subject: [PATCH 12/61] GasDepositExtractor: push into net, not pipe --- .../EntitySystems/AtmosphereSystem.GridAtmosphere.cs | 1 + .../_NF/Atmos/EntitySystems/GasDepositSystem.cs | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.GridAtmosphere.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.GridAtmosphere.cs index 3983234dea6..03bc1a3e206 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.GridAtmosphere.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.GridAtmosphere.cs @@ -1,3 +1,4 @@ +using Content.Server._NF.Atmos.Components; using Content.Server.Atmos.Components; using Content.Server.Atmos.Reactions; using Content.Shared.Atmos; diff --git a/Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs b/Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs index c016169b58e..1b75de32cfd 100644 --- a/Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs +++ b/Content.Server/_NF/Atmos/EntitySystems/GasDepositSystem.cs @@ -4,6 +4,7 @@ using Content.Server.Atmos.Piping.Components; using Content.Server.Audio; using Content.Server.NodeContainer.EntitySystems; +using Content.Server.NodeContainer.NodeGroups; using Content.Server.NodeContainer.Nodes; using Content.Server.Popups; using Content.Server.Power.Components; @@ -150,7 +151,8 @@ private void OnExtractorUpdate(EntityUid uid, GasDepositExtractorComponent extra if (!extractor.Enabled || extractor.DepositEntity == null || TryComp(uid, out var power) && !power.Powered - || !_nodeContainer.TryGetNode(uid, extractor.PortName, out PipeNode? port)) + || !_nodeContainer.TryGetNode(uid, extractor.PortName, out PipeNode? port) + || port.NodeGroup is not PipeNet { NodeCount: > 1 } net) { _ambientSound.SetAmbience(uid, false); SetDepositState(uid, GasDepositExtractorState.Off, extractor); @@ -169,7 +171,7 @@ private void OnExtractorUpdate(EntityUid uid, GasDepositExtractorComponent extra // How many moles could we theoretically spawn. Cap by pressure and amount. var allowableMoles = float.Max(0, - (targetPressure - port.Air.Pressure) * port.Air.Volume / (extractor.OutputTemperature * Atmospherics.R)); + (targetPressure - net.Air.Pressure) * net.Air.Volume / (extractor.OutputTemperature * Atmospherics.R)); if (allowableMoles < Atmospherics.GasMinMoles) { @@ -180,7 +182,7 @@ private void OnExtractorUpdate(EntityUid uid, GasDepositExtractorComponent extra var removed = depositComp.Deposit.Remove(allowableMoles); removed.Temperature = extractor.OutputTemperature; - _atmosphere.Merge(port.Air, removed); + _atmosphere.Merge(net.Air, removed); _ambientSound.SetAmbience(uid, true); if (depositComp.Deposit.TotalMoles <= depositComp.LowMoles) From d4926064f3901250a4366c7c948d06df50690bad Mon Sep 17 00:00:00 2001 From: Whatstone Date: Sun, 17 Nov 2024 15:49:03 -0500 Subject: [PATCH 13/61] Clear pump on undock --- Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs b/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs index 17cb173d962..8b4a021ff1a 100644 --- a/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs +++ b/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs @@ -68,7 +68,7 @@ private void OnUndock(EntityUid uid, DockablePumpComponent component, ref Undock return; _nodeGroup.QueueNodeRemove(dockablePipe); - _atmosphere.ReleaseGasTo(dockablePipe.Air, null, dockablePipe.Air.Pressure); + dockablePipe.Air.Clear(); _appearance.SetData(uid, DockablePumpVisuals.Docked, false); } } From f33f05c0e10ad6fd856b810ebd7bbaf295333156 Mon Sep 17 00:00:00 2001 From: Whatstone Date: Sun, 17 Nov 2024 21:13:00 -0500 Subject: [PATCH 14/61] WIP docking types, sale point --- .../Shuttles/Systems/DockingSystem.cs | 13 +++++++++++ .../Atmos/EntitySystems/DockablePumpSystem.cs | 1 - .../Components/SharedDockingComponent.cs | 22 +++++++++++++++++++ .../Structures/Piping/Atmospherics/binary.yml | 10 +++++++++ 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/Content.Server/Shuttles/Systems/DockingSystem.cs b/Content.Server/Shuttles/Systems/DockingSystem.cs index fcdd6c0c1ae..4837b7e56e6 100644 --- a/Content.Server/Shuttles/Systems/DockingSystem.cs +++ b/Content.Server/Shuttles/Systems/DockingSystem.cs @@ -403,6 +403,14 @@ private void OnRequestDock(EntityUid uid, ShuttleConsoleComponent component, Doc return; } + // Frontier: ensure dock initiator isn't receive only. + if (ourDockComp.ReceiveOnly) + { + _popup.PopupCursor(Loc.GetString("shuttle-console-dock-fail")); + return; + } + // End Frontier + // Cheating? if (!TryComp(ourDock, out TransformComponent? xformA) || xformA.GridUid != shuttleUid) @@ -444,6 +452,11 @@ public bool CanDock(Entity dockA, Entity doc return false; } + // Frontier: mask docking types + if ((dockA.Comp.DockType & dockB.Comp.DockType) == DockType.None) + return false; + // End Frontier + var xformA = Transform(dockA); var xformB = Transform(dockB); diff --git a/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs b/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs index 8b4a021ff1a..5cdece10c29 100644 --- a/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs +++ b/Content.Server/_NF/Atmos/EntitySystems/DockablePumpSystem.cs @@ -14,7 +14,6 @@ public sealed partial class DockablePumpSystem : EntitySystem { [Dependency] private readonly NodeContainerSystem _nodeContainer = default!; [Dependency] private readonly NodeGroupSystem _nodeGroup = default!; - [Dependency] private readonly AtmosphereSystem _atmosphere = default!; [Dependency] private readonly AppearanceSystem _appearance = default!; diff --git a/Content.Shared/Shuttles/Components/SharedDockingComponent.cs b/Content.Shared/Shuttles/Components/SharedDockingComponent.cs index 15af045cc4b..2bec6a6e50e 100644 --- a/Content.Shared/Shuttles/Components/SharedDockingComponent.cs +++ b/Content.Shared/Shuttles/Components/SharedDockingComponent.cs @@ -6,5 +6,27 @@ public abstract partial class SharedDockingComponent : Component // and I was too lazy to delete it. public abstract bool Docked { get; } + + /// + /// Frontier: type of dock. + /// + [ViewVariables(VVAccess.ReadWrite), DataField] + public DockType DockType = DockType.Airlock; + + /// + /// Frontier: if true, can only receive docking, cannot initialize. + /// + [ViewVariables(VVAccess.ReadWrite), DataField] + public bool ReceiveOnly = false; + } + + // Frontier: prevent mismatched dock types from docking + [Flags] + public enum DockType : byte + { + None = 0, + Airlock = 1 << 0, + Gas = 1 << 1, } + // End Frontier } diff --git a/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/binary.yml b/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/binary.yml index f1570d179c6..b6009adaad3 100644 --- a/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/binary.yml +++ b/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/binary.yml @@ -43,6 +43,7 @@ - type: Docking radarColor: darkcyan highlightedRadarColor: cyan + dockType: Gas - type: DockingSignalControl - type: DeviceLinkSource ports: @@ -250,6 +251,8 @@ - type: IconSmooth key: walls mode: NoSprite + - type: Docking + receiveOnly: true - type: entity parent: GaslockFrame @@ -261,3 +264,10 @@ outlet: inlet - type: DockablePump pumpingInwards: true + +- type: entity + parent: [ BaseGaslock ] + id: GasSalePoint + name: gas sale point + description: Gas piped into here can be sold using the linked console. Bluespace linked to massive storage vaults off-site. + # TODO: fill this out From 124c548839b9deaf0c3587517e3c8b20d8cbd238 Mon Sep 17 00:00:00 2001 From: Whatstone Date: Mon, 18 Nov 2024 16:34:21 -0500 Subject: [PATCH 15/61] selective docking WIP --- Content.Client/Shuttles/UI/DockingScreen.xaml.cs | 3 +++ Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs | 3 ++- Content.Server/Shuttles/Components/DockingComponent.cs | 2 +- Content.Shared/Shuttles/BUIStates/DockingPortState.cs | 5 ++++- .../_NF/Entities/Structures/Piping/Atmospherics/binary.yml | 1 + 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/Content.Client/Shuttles/UI/DockingScreen.xaml.cs b/Content.Client/Shuttles/UI/DockingScreen.xaml.cs index c0aa7942148..c7ef59b1de2 100644 --- a/Content.Client/Shuttles/UI/DockingScreen.xaml.cs +++ b/Content.Client/Shuttles/UI/DockingScreen.xaml.cs @@ -90,6 +90,7 @@ private void BuildDocks(EntityUid? shuttle) // Build the dock buttons for our docks. foreach (var dock in shuttleDocks) { + if (dock.) idx++; dockText.Clear(); dockText.Append(dock.Name); @@ -105,11 +106,13 @@ private void BuildDocks(EntityUid? shuttle) button.OnMouseEntered += args => { DockingControl.HighlightedDock = dock.Entity; + DockingControl.HighlightedDockState = dock; // Frontier }; button.OnMouseExited += args => { DockingControl.HighlightedDock = null; + DockingControl.HighlightedDockState = null; // Frontier }; button.Label.Margin = new Thickness(3f); diff --git a/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs index 56062427bf3..be2e845fe38 100644 --- a/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs +++ b/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs @@ -24,6 +24,7 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl private readonly SharedTransformSystem _xformSystem; public NetEntity? HighlightedDock; + public DockingPortState? HighlightedDockState; // Frontier public NetEntity? ViewedDock => _viewedState?.Entity; private DockingPortState? _viewedState; @@ -320,7 +321,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; var connectionColor = Color.Pink; handle.DrawRect(ourDockConnection, connectionColor.WithAlpha(0.2f)); diff --git a/Content.Server/Shuttles/Components/DockingComponent.cs b/Content.Server/Shuttles/Components/DockingComponent.cs index 4c83b3f5bd5..cf7a9365d42 100644 --- a/Content.Server/Shuttles/Components/DockingComponent.cs +++ b/Content.Server/Shuttles/Components/DockingComponent.cs @@ -22,7 +22,7 @@ public sealed partial class DockingComponent : SharedDockingComponent /// Color that gets shown on the radar screen. /// [ViewVariables(VVAccess.ReadWrite), DataField("radarColor")] - public Color RadarColor = Color.DarkViolet; + public Color RadarColor = Color.Purple; // Frontier: DarkViolet /// Color that gets shown on the radar screen when the dock is highlighted. diff --git a/Content.Shared/Shuttles/BUIStates/DockingPortState.cs b/Content.Shared/Shuttles/BUIStates/DockingPortState.cs index cbb4d1332dd..73dbb846c99 100644 --- a/Content.Shared/Shuttles/BUIStates/DockingPortState.cs +++ b/Content.Shared/Shuttles/BUIStates/DockingPortState.cs @@ -1,5 +1,6 @@ using Robust.Shared.Map; using Robust.Shared.Serialization; +using Content.Shared.Shuttles.Components; // Frontier namespace Content.Shared.Shuttles.BUIStates; @@ -18,8 +19,10 @@ public sealed class DockingPortState public NetEntity? GridDockedWith; - // Frontier: colors + // Frontier: colors, type, receive only public Color RadarColor; public Color HighlightedRadarColor; + public bool ReceiveOnly; + public DockType DockType; // End Frontier } diff --git a/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/binary.yml b/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/binary.yml index b6009adaad3..371c7289930 100644 --- a/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/binary.yml +++ b/Resources/Prototypes/_NF/Entities/Structures/Piping/Atmospherics/binary.yml @@ -43,6 +43,7 @@ - type: Docking radarColor: darkcyan highlightedRadarColor: cyan + highlightedRadarColor: lightcyan dockType: Gas - type: DockingSignalControl - type: DeviceLinkSource From 3ddf8761947d2d324f417415343d63390dc9ed67 Mon Sep 17 00:00:00 2001 From: Whatstone Date: Wed, 20 Nov 2024 16:30:38 -0500 Subject: [PATCH 16/61] WIP gas sale point, console, gas sale UI --- .../Shuttles/UI/DockingScreen.xaml.cs | 3 - .../Shuttles/UI/ShuttleDockControl.xaml.cs | 18 +- .../BUI/GasSaleConsoleBoundUserInterface.cs | 40 ++++ .../UI/GasPressurePumpBoundUserInterface.cs | 65 ----- .../Atmos/UI/GasPressurePumpWindow.xaml.cs | 65 ----- .../Atmos/UI/GasPressurePumpWindow.xaml_bak | 22 -- Content.Client/_NF/Atmos/UI/GasSaleMenu.cs | 65 +++++ Content.Client/_NF/Atmos/UI/GasSaleMenu.xaml | 29 +++ .../Shuttles/Systems/ShuttleConsoleSystem.cs | 2 + .../Components/GasSaleConsoleComponent.cs | 25 ++ .../Atmos/Components/GasSalePointComponent.cs | 23 ++ .../Atmos/EntitySystems/GasDepositSystem.cs | 153 ++++++++++++ .../ContentLocalizationManager.cs | 8 + .../GasSaleConsoleBoundUserInterfaceState.cs | 36 +++ .../_NF/Atmos/Events/GasSaleSellMessage.cs | 9 + Resources/Locale/en-US/_NF/_lib.ftl | 12 + .../_NF/atmos/gas-sale-console-component.ftl | 9 + .../en-US/_NF/devices/device-network.ftl | 3 + Resources/Locale/en-US/_NF/gases/gases.ftl | 1 + .../_NF/machine-linking/receiver_ports.ftl | 5 + .../_NF/machine-linking/transmitter_ports.ftl | 5 + Resources/Locale/en-US/_lib.ftl | 3 +- .../_NF/DeviceLinking/sink_ports.yml | 9 + .../_NF/DeviceLinking/source_ports.yml | 11 + .../Structures/Piping/Atmospherics/binary.yml | 94 ++++---- .../Structures/Piping/Atmospherics/unary.yml | 223 ++++++++++++------ .../Atmospherics/salepoint.rsi/base-unlit.png | Bin 0 -> 608 bytes .../Atmospherics/salepoint.rsi/base.png | Bin 0 -> 811 bytes .../salepoint.rsi/docked-unlit.png | Bin 0 -> 156 bytes .../Atmospherics/salepoint.rsi/meta.json | 31 +++ .../Atmospherics/salepoint.rsi/on-unlit.png | Bin 0 -> 391 bytes 31 files changed, 682 insertions(+), 287 deletions(-) create mode 100644 Content.Client/_NF/Atmos/BUI/GasSaleConsoleBoundUserInterface.cs delete mode 100644 Content.Client/_NF/Atmos/UI/GasPressurePumpBoundUserInterface.cs delete mode 100644 Content.Client/_NF/Atmos/UI/GasPressurePumpWindow.xaml.cs delete mode 100644 Content.Client/_NF/Atmos/UI/GasPressurePumpWindow.xaml_bak create mode 100644 Content.Client/_NF/Atmos/UI/GasSaleMenu.cs create mode 100644 Content.Client/_NF/Atmos/UI/GasSaleMenu.xaml create mode 100644 Content.Server/_NF/Atmos/Components/GasSaleConsoleComponent.cs create mode 100644 Content.Server/_NF/Atmos/Components/GasSalePointComponent.cs create mode 100644 Content.Shared/_NF/Atmos/BUI/GasSaleConsoleBoundUserInterfaceState.cs create mode 100644 Content.Shared/_NF/Atmos/Events/GasSaleSellMessage.cs create mode 100644 Resources/Locale/en-US/_NF/_lib.ftl create mode 100644 Resources/Locale/en-US/_NF/atmos/gas-sale-console-component.ftl create mode 100644 Resources/Locale/en-US/_NF/gases/gases.ftl create mode 100644 Resources/Locale/en-US/_NF/machine-linking/receiver_ports.ftl create mode 100644 Resources/Locale/en-US/_NF/machine-linking/transmitter_ports.ftl create mode 100644 Resources/Prototypes/_NF/DeviceLinking/sink_ports.yml create mode 100644 Resources/Prototypes/_NF/DeviceLinking/source_ports.yml create mode 100644 Resources/Textures/_NF/Structures/Piping/Atmospherics/salepoint.rsi/base-unlit.png create mode 100644 Resources/Textures/_NF/Structures/Piping/Atmospherics/salepoint.rsi/base.png create mode 100644 Resources/Textures/_NF/Structures/Piping/Atmospherics/salepoint.rsi/docked-unlit.png create mode 100644 Resources/Textures/_NF/Structures/Piping/Atmospherics/salepoint.rsi/meta.json create mode 100644 Resources/Textures/_NF/Structures/Piping/Atmospherics/salepoint.rsi/on-unlit.png diff --git a/Content.Client/Shuttles/UI/DockingScreen.xaml.cs b/Content.Client/Shuttles/UI/DockingScreen.xaml.cs index c7ef59b1de2..c0aa7942148 100644 --- a/Content.Client/Shuttles/UI/DockingScreen.xaml.cs +++ b/Content.Client/Shuttles/UI/DockingScreen.xaml.cs @@ -90,7 +90,6 @@ private void BuildDocks(EntityUid? shuttle) // Build the dock buttons for our docks. foreach (var dock in shuttleDocks) { - if (dock.) idx++; dockText.Clear(); dockText.Append(dock.Name); @@ -106,13 +105,11 @@ private void BuildDocks(EntityUid? shuttle) button.OnMouseEntered += args => { DockingControl.HighlightedDock = dock.Entity; - DockingControl.HighlightedDockState = dock; // Frontier }; button.OnMouseExited += args => { DockingControl.HighlightedDock = null; - DockingControl.HighlightedDockState = null; // Frontier }; button.Label.Margin = new Thickness(3f); diff --git a/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs b/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs index be2e845fe38..fe837fd5210 100644 --- a/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs +++ b/Content.Client/Shuttles/UI/ShuttleDockControl.xaml.cs @@ -24,7 +24,6 @@ public sealed partial class ShuttleDockControl : BaseShuttleControl private readonly SharedTransformSystem _xformSystem; public NetEntity? HighlightedDock; - public DockingPortState? HighlightedDockState; // Frontier public NetEntity? ViewedDock => _viewedState?.Entity; private DockingPortState? _viewedState; @@ -131,6 +130,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); @@ -249,6 +251,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 @@ -275,18 +278,25 @@ protected override void Draw(DrawingHandleScreen handle) var canDock = distance < SharedDockingSystem.DockRange && 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 } } diff --git a/Content.Client/_NF/Atmos/BUI/GasSaleConsoleBoundUserInterface.cs b/Content.Client/_NF/Atmos/BUI/GasSaleConsoleBoundUserInterface.cs new file mode 100644 index 00000000000..249eadbcf2d --- /dev/null +++ b/Content.Client/_NF/Atmos/BUI/GasSaleConsoleBoundUserInterface.cs @@ -0,0 +1,40 @@ +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.SellRequested += OnSell; + } + + 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/UI/GasPressurePumpBoundUserInterface.cs b/Content.Client/_NF/Atmos/UI/GasPressurePumpBoundUserInterface.cs deleted file mode 100644 index 5816f79c206..00000000000 --- a/Content.Client/_NF/Atmos/UI/GasPressurePumpBoundUserInterface.cs +++ /dev/null @@ -1,65 +0,0 @@ -// using Content.Shared.Atmos; -// using Content.Shared.Atmos.Piping.Binary.Components; -// using Content.Shared.Localizations; -// using JetBrains.Annotations; -// using Robust.Client.GameObjects; -// using Robust.Client.UserInterface; - -// namespace Content.Client.Atmos.UI -// { -// /// -// /// Initializes a and updates it when new server messages are received. -// /// -// [UsedImplicitly] -// public sealed class BidiGasPressurePumpBoundUserInterface : BoundUserInterface -// { -// [ViewVariables] -// private const float MaxPressure = Atmospherics.MaxOutputPressure; - -// [ViewVariables] -// private GasPressurePumpWindow? _window; - -// public BidiGasPressurePumpBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey) -// { -// } - -// protected override void Open() -// { -// base.Open(); - -// _window = this.CreateWindow(); - -// _window.ToggleStatusButtonPressed += OnToggleStatusButtonPressed; -// _window.PumpOutputPressureChanged += OnPumpOutputPressurePressed; -// } - -// private void OnToggleStatusButtonPressed() -// { -// if (_window is null) return; -// SendMessage(new GasPressurePumpToggleStatusMessage(_window.PumpStatus)); -// } - -// private void OnPumpOutputPressurePressed(string value) -// { -// var pressure = UserInputParser.TryFloat(value, out var parsed) ? parsed : 0f; -// if (pressure > MaxPressure) pressure = MaxPressure; - -// SendMessage(new GasPressurePumpChangeOutputPressureMessage(pressure)); -// } - -// /// -// /// Update the UI state based on server-sent info -// /// -// /// -// protected override void UpdateState(BoundUserInterfaceState state) -// { -// base.UpdateState(state); -// if (_window == null || state is not BidiGasPressurePumpBoundUserInterfaceState cast) -// return; - -// _window.Title = (cast.PumpLabel); -// _window.SetPumpStatus(cast.Enabled); -// _window.SetOutputPressure(cast.OutputPressure); -// } -// } -// } diff --git a/Content.Client/_NF/Atmos/UI/GasPressurePumpWindow.xaml.cs b/Content.Client/_NF/Atmos/UI/GasPressurePumpWindow.xaml.cs deleted file mode 100644 index bc667ce206d..00000000000 --- a/Content.Client/_NF/Atmos/UI/GasPressurePumpWindow.xaml.cs +++ /dev/null @@ -1,65 +0,0 @@ -// using System; -// using System.Collections.Generic; -// using System.Globalization; -// using Content.Client.Atmos.EntitySystems; -// using Content.Shared.Atmos; -// using Content.Shared.Atmos.Prototypes; -// 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.UI -// { -// /// -// /// Client-side UI used to control a gas pressure pump. -// /// -// [GenerateTypedNameReferences] -// public sealed partial class GasPressurePumpWindow : DefaultWindow -// { -// public bool PumpStatus = true; - -// public event Action? ToggleStatusButtonPressed; -// public event Action? PumpOutputPressureChanged; - -// public GasPressurePumpWindow() -// { -// RobustXamlLoader.Load(this); - -// ToggleStatusButton.OnPressed += _ => SetPumpStatus(!PumpStatus); -// ToggleStatusButton.OnPressed += _ => ToggleStatusButtonPressed?.Invoke(); - -// PumpPressureOutputInput.OnTextChanged += _ => SetOutputPressureButton.Disabled = false; -// SetOutputPressureButton.OnPressed += _ => -// { -// PumpOutputPressureChanged?.Invoke(PumpPressureOutputInput.Text ??= ""); -// SetOutputPressureButton.Disabled = true; -// }; - -// SetMaxPressureButton.OnPressed += _ => -// { -// PumpPressureOutputInput.Text = Atmospherics.MaxOutputPressure.ToString(CultureInfo.CurrentCulture); -// SetOutputPressureButton.Disabled = false; -// }; -// } - -// public void SetOutputPressure(float pressure) -// { -// PumpPressureOutputInput.Text = pressure.ToString(CultureInfo.CurrentCulture); -// } - -// public void SetPumpStatus(bool enabled) -// { -// PumpStatus = enabled; -// if (enabled) -// { -// ToggleStatusButton.Text = Loc.GetString("comp-gas-pump-ui-status-enabled"); -// } -// else -// { -// ToggleStatusButton.Text = Loc.GetString("comp-gas-pump-ui-status-disabled"); -// } -// } -// } -// } diff --git a/Content.Client/_NF/Atmos/UI/GasPressurePumpWindow.xaml_bak b/Content.Client/_NF/Atmos/UI/GasPressurePumpWindow.xaml_bak deleted file mode 100644 index ba1559c6cca..00000000000 --- a/Content.Client/_NF/Atmos/UI/GasPressurePumpWindow.xaml_bak +++ /dev/null @@ -1,22 +0,0 @@ - diff --git a/Content.Client/_NF/Atmos/UI/GasSaleMenu.cs b/Content.Client/_NF/Atmos/UI/GasSaleMenu.cs new file mode 100644 index 00000000000..e2020079dcb --- /dev/null +++ b/Content.Client/_NF/Atmos/UI/GasSaleMenu.cs @@ -0,0 +1,65 @@ +using Content.Client.UserInterface.Controls; +using Content.Shared._NF.Bank; +using Content.Shared.Atmos; +using Robust.Client.AutoGenerated; +using Robust.Client.UserInterface.Controls; +using Robust.Client.UserInterface.XAML; +using Robust.Shared.Utility; + +namespace Content.Client._NF.Atmos.UI; + +[GenerateTypedNameReferences] +public sealed partial class GasSaleMenu : FancyWindow +{ + public Action? SellRequested; + + public static readonly string[] GasStrings = + [ + "gases-nitrogen", // 0 + "gases-oxygen", // 1 + "gases-co2", // 2 + "gases-plasma", // 3 + "gases-tritium", // 4 + "gases-water-vapor", // 5 + "gases-ammonia", // 6 + "gases-n2o", // 7 + "gases-frezon", // 8 + ]; + + public string FallbackGasString = "gas-fallback"; + + public GasSaleMenu() + { + RobustXamlLoader.Load(this); + SellButton.OnPressed += OnSellPressed; + } + + public void SetMixture(GasMixture mixture, int appraisal) + { + FormattedMessage label = new(); + FormattedMessage values = new(); + for (int i = 0; i < Atmospherics.TotalNumberOfGases; i++) + { + if (i < GasStrings.Length) + label.AddMarkupOrThrow(Loc.GetString(GasStrings[i])); + else + label.AddMarkupOrThrow(Loc.GetString(FallbackGasString, ("number", i))); + label.PushNewline(); + + values.AddMarkupOrThrow(Loc.GetString("gas-sale-menu-quantity", ("value", mixture.GetMoles(i)))); + values.PushNewline(); + } + Gases.Text = label.ToString(); + GasAmounts.Text = values.ToString(); + AppraisalLabel.Text = BankSystemExtensions.ToSpesoString(appraisal); + } + public void SetEnabled(bool enabled) + { + SellButton.Disabled = !enabled; + } + + private void OnSellPressed(BaseButton.ButtonEventArgs obj) + { + SellRequested?.Invoke(); + } +} diff --git a/Content.Client/_NF/Atmos/UI/GasSaleMenu.xaml b/Content.Client/_NF/Atmos/UI/GasSaleMenu.xaml new file mode 100644 index 00000000000..01543514629 --- /dev/null +++ b/Content.Client/_NF/Atmos/UI/GasSaleMenu.xaml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +