diff --git a/Content.Client/Atmos/AlignAtmosPipeLayers.cs b/Content.Client/Atmos/AlignAtmosPipeLayers.cs new file mode 100644 index 0000000000..1bf3310a6c --- /dev/null +++ b/Content.Client/Atmos/AlignAtmosPipeLayers.cs @@ -0,0 +1,203 @@ +using Content.Client.Construction; +using Content.Shared.Atmos.Components; +using Content.Shared.Atmos.EntitySystems; +using Content.Shared.Construction.Prototypes; +using Robust.Client.GameObjects; +using Robust.Client.Graphics; +using Robust.Client.Placement; +using Robust.Client.Placement.Modes; +using Robust.Client.Utility; +using Robust.Shared.Enums; +using Robust.Shared.Map; +using Robust.Shared.Map.Components; +using Robust.Shared.Prototypes; +using Robust.Shared.Utility; +using System.Numerics; +using static Robust.Client.Placement.PlacementManager; + +namespace Content.Client.Atmos; + +/// +/// Allows users to place atmos pipes on different layers depending on how the mouse cursor is positioned within a grid tile. +/// +/// +/// This placement mode is not on the engine because it is content specific. +/// +public sealed class AlignAtmosPipeLayers : SnapgridCenter +{ + [Dependency] private readonly IEntityManager _entityManager = default!; + [Dependency] private readonly IPrototypeManager _protoManager = default!; + [Dependency] private readonly IMapManager _mapManager = default!; + [Dependency] private readonly IEyeManager _eyeManager = default!; + + private readonly SharedMapSystem _mapSystem; + private readonly SharedTransformSystem _transformSystem; + private readonly SharedAtmosPipeLayersSystem _pipeLayersSystem; + private readonly SpriteSystem _spriteSystem; + + private const float SearchBoxSize = 2f; + private EntityCoordinates _unalignedMouseCoords = default; + private const float MouseDeadzoneRadius = 0.25f; + + private Color _guideColor = new Color(0, 0, 0.5785f); + private const float GuideRadius = 0.1f; + private const float GuideOffset = 0.21875f; + + public AlignAtmosPipeLayers(PlacementManager pMan) : base(pMan) + { + IoCManager.InjectDependencies(this); + + _mapSystem = _entityManager.System(); + _transformSystem = _entityManager.System(); + _pipeLayersSystem = _entityManager.System(); + _spriteSystem = _entityManager.System(); + } + + /// + public override void Render(in OverlayDrawArgs args) + { + var gridUid = _entityManager.System().GetGrid(MouseCoords); + + if (gridUid == null || Grid == null) + return; + + // Draw guide circles for each pipe layer if we are not in line/grid placing mode + if (pManager.PlacementType == PlacementTypes.None) + { + var gridRotation = _transformSystem.GetWorldRotation(gridUid.Value); + var worldPosition = _mapSystem.LocalToWorld(gridUid.Value, Grid, MouseCoords.Position); + var direction = (_eyeManager.CurrentEye.Rotation + gridRotation + Math.PI / 2).GetCardinalDir(); + var multi = (direction == Direction.North || direction == Direction.South) ? -1f : 1f; + + args.WorldHandle.DrawCircle(worldPosition, GuideRadius, _guideColor); + args.WorldHandle.DrawCircle(worldPosition + gridRotation.RotateVec(new Vector2(multi * GuideOffset, GuideOffset)), GuideRadius, _guideColor); + args.WorldHandle.DrawCircle(worldPosition - gridRotation.RotateVec(new Vector2(multi * GuideOffset, GuideOffset)), GuideRadius, _guideColor); + } + + base.Render(args); + } + + /// + public override void AlignPlacementMode(ScreenCoordinates mouseScreen) + { + _unalignedMouseCoords = ScreenToCursorGrid(mouseScreen); + base.AlignPlacementMode(mouseScreen); + + // Exit early if we are in line/grid placing mode + if (pManager.PlacementType != PlacementTypes.None) + return; + + MouseCoords = _unalignedMouseCoords.AlignWithClosestGridTile(SearchBoxSize, _entityManager, _mapManager); + + var gridId = _transformSystem.GetGrid(MouseCoords); + + if (!_entityManager.TryGetComponent(gridId, out var mapGrid)) + return; + + var gridRotation = _transformSystem.GetWorldRotation(gridId.Value); + CurrentTile = _mapSystem.GetTileRef(gridId.Value, mapGrid, MouseCoords); + + float tileSize = mapGrid.TileSize; + GridDistancing = tileSize; + + MouseCoords = new EntityCoordinates(MouseCoords.EntityId, new Vector2(CurrentTile.X + tileSize / 2 + pManager.PlacementOffset.X, + CurrentTile.Y + tileSize / 2 + pManager.PlacementOffset.Y)); + + // Calculate the position of the mouse cursor with respect to the center of the tile to determine which layer to use + var mouseCoordsDiff = _unalignedMouseCoords.Position - MouseCoords.Position; + var layer = AtmosPipeLayer.Primary; + + if (mouseCoordsDiff.Length() > MouseDeadzoneRadius) + { + // Determine the direction of the mouse is relative to the center of the tile, adjusting for the player eye and grid rotation + var direction = (new Angle(mouseCoordsDiff) + _eyeManager.CurrentEye.Rotation + gridRotation + Math.PI / 2).GetCardinalDir(); + layer = (direction == Direction.North || direction == Direction.East) ? AtmosPipeLayer.Secondary : AtmosPipeLayer.Tertiary; + } + + // Update the construction menu placer + if (pManager.Hijack != null) + UpdateHijackedPlacer(layer, mouseScreen); + + // Otherwise update the debug placer + else + UpdatePlacer(layer); + } + + private void UpdateHijackedPlacer(AtmosPipeLayer layer, ScreenCoordinates mouseScreen) + { + // Try to get alternative prototypes from the construction prototype + var constructionSystem = (pManager.Hijack as ConstructionPlacementHijack)?.CurrentConstructionSystem; + var altPrototypes = (pManager.Hijack as ConstructionPlacementHijack)?.CurrentPrototype?.AlternativePrototypes; + + if (constructionSystem == null || altPrototypes == null || (int)layer >= altPrototypes.Length) + return; + + var newProtoId = altPrototypes[(int)layer]; + + if (!_protoManager.TryIndex(newProtoId, out var newProto)) + return; + + if (newProto.Type != ConstructionType.Structure) + { + pManager.Clear(); + return; + } + + if (newProto.ID == (pManager.Hijack as ConstructionPlacementHijack)?.CurrentPrototype?.ID) + return; + + // Start placing + pManager.BeginPlacing(new PlacementInformation() + { + IsTile = false, + PlacementOption = newProto.PlacementMode, + }, new ConstructionPlacementHijack(constructionSystem, newProto)); + + if (pManager.CurrentMode is AlignAtmosPipeLayers { } newMode) + newMode.RefreshGrid(mouseScreen); + + // Update construction guide + constructionSystem.GetGuide(newProto); + } + + private void UpdatePlacer(AtmosPipeLayer layer) + { + // Try to get alternative prototypes from the entity atmos pipe layer component + if (pManager.CurrentPermission?.EntityType == null) + return; + + if (!_protoManager.TryIndex(pManager.CurrentPermission.EntityType, out var currentProto)) + return; + + if (!currentProto.TryGetComponent(out var atmosPipeLayers, _entityManager.ComponentFactory)) + return; + + if (!_pipeLayersSystem.TryGetAlternativePrototype(atmosPipeLayers, layer, out var newProtoId)) + return; + + if (_protoManager.TryIndex(newProtoId, out var newProto)) + { + // Update the placed prototype + pManager.CurrentPermission.EntityType = newProtoId; + + // Update the appearance of the ghost sprite + if (newProto.TryGetComponent(out var sprite, _entityManager.ComponentFactory)) + { + var textures = new List(); + + foreach (var spriteLayer in sprite.AllLayers) + { + if (spriteLayer.ActualRsi?.Path != null && spriteLayer.RsiState.Name != null) + textures.Add(_spriteSystem.RsiStateLike(new SpriteSpecifier.Rsi(spriteLayer.ActualRsi.Path, spriteLayer.RsiState.Name))); + } + + pManager.CurrentTextures = textures; + } + } + } + + private void RefreshGrid(ScreenCoordinates mouseScreen) + { + base.AlignPlacementMode(mouseScreen); + } +} diff --git a/Content.Client/Atmos/Consoles/AtmosMonitoringConsoleNavMapControl.cs b/Content.Client/Atmos/Consoles/AtmosMonitoringConsoleNavMapControl.cs index c23ebb6435..20902722ff 100644 --- a/Content.Client/Atmos/Consoles/AtmosMonitoringConsoleNavMapControl.cs +++ b/Content.Client/Atmos/Consoles/AtmosMonitoringConsoleNavMapControl.cs @@ -17,6 +17,10 @@ public sealed partial class AtmosMonitoringConsoleNavMapControl : NavMapControl public int? FocusNetId = null; private const int ChunkSize = 4; + private const float ScaleModifier = 4f; + + private readonly float[] _layerFraction = { 0.5f, 0.75f, 0.25f }; + private const float LineThickness = 0.05f; private readonly Color _basePipeNetColor = Color.LightGray; private readonly Color _unfocusedPipeNetColor = Color.DimGray; @@ -95,23 +99,23 @@ public sealed partial class AtmosMonitoringConsoleNavMapControl : NavMapControl foreach (var chunkedLine in atmosPipeNetwork) { var leftTop = ScalePosition(new Vector2 - (Math.Min(chunkedLine.Origin.X, chunkedLine.Terminus.X) - 0.1f, - Math.Min(chunkedLine.Origin.Y, chunkedLine.Terminus.Y) - 0.1f) + (Math.Min(chunkedLine.Origin.X, chunkedLine.Terminus.X) - LineThickness, + Math.Min(chunkedLine.Origin.Y, chunkedLine.Terminus.Y) - LineThickness) - offset); var rightTop = ScalePosition(new Vector2 - (Math.Max(chunkedLine.Origin.X, chunkedLine.Terminus.X) + 0.1f, - Math.Min(chunkedLine.Origin.Y, chunkedLine.Terminus.Y) - 0.1f) + (Math.Max(chunkedLine.Origin.X, chunkedLine.Terminus.X) + LineThickness, + Math.Min(chunkedLine.Origin.Y, chunkedLine.Terminus.Y) - LineThickness) - offset); var leftBottom = ScalePosition(new Vector2 - (Math.Min(chunkedLine.Origin.X, chunkedLine.Terminus.X) - 0.1f, - Math.Max(chunkedLine.Origin.Y, chunkedLine.Terminus.Y) + 0.1f) + (Math.Min(chunkedLine.Origin.X, chunkedLine.Terminus.X) - LineThickness, + Math.Max(chunkedLine.Origin.Y, chunkedLine.Terminus.Y) + LineThickness) - offset); var rightBottom = ScalePosition(new Vector2 - (Math.Max(chunkedLine.Origin.X, chunkedLine.Terminus.X) + 0.1f, - Math.Max(chunkedLine.Origin.Y, chunkedLine.Terminus.Y) + 0.1f) + (Math.Max(chunkedLine.Origin.X, chunkedLine.Terminus.X) + LineThickness, + Math.Max(chunkedLine.Origin.Y, chunkedLine.Terminus.Y) + LineThickness) - offset); if (!pipeVertexUVs.TryGetValue(chunkedLine.Color, out var pipeVertexUV)) @@ -142,7 +146,7 @@ public sealed partial class AtmosMonitoringConsoleNavMapControl : NavMapControl if (chunks == null || grid == null) return decodedOutput; - // Clear stale look up table values + // Clear stale look up table values _horizLines.Clear(); _horizLinesReversed.Clear(); _vertLines.Clear(); @@ -158,7 +162,7 @@ public sealed partial class AtmosMonitoringConsoleNavMapControl : NavMapControl { var list = new List(); - foreach (var ((netId, hexColor), atmosPipeData) in chunk.AtmosPipeData) + foreach (var ((netId, layer, hexColor), atmosPipeData) in chunk.AtmosPipeData) { // Determine the correct coloration for the pipe var color = Color.FromHex(hexColor) * _basePipeNetColor; @@ -191,6 +195,9 @@ public sealed partial class AtmosMonitoringConsoleNavMapControl : NavMapControl _vertLinesReversed[color] = vertLinesReversed; } + var layerFraction = _layerFraction[(int)layer]; + var origin = new Vector2(grid.TileSize * layerFraction, -grid.TileSize * layerFraction); + // Loop over the chunk for (var tileIdx = 0; tileIdx < ChunkSize * ChunkSize; tileIdx++) { @@ -208,21 +215,22 @@ public sealed partial class AtmosMonitoringConsoleNavMapControl : NavMapControl // Calculate the draw point offsets var vertLineOrigin = (atmosPipeData & northMask << tileIdx * SharedNavMapSystem.Directions) > 0 ? - new Vector2(grid.TileSize * 0.5f, -grid.TileSize * 1f) : new Vector2(grid.TileSize * 0.5f, -grid.TileSize * 0.5f); + new Vector2(grid.TileSize * layerFraction, -grid.TileSize * 1f) : origin; var vertLineTerminus = (atmosPipeData & southMask << tileIdx * SharedNavMapSystem.Directions) > 0 ? - new Vector2(grid.TileSize * 0.5f, -grid.TileSize * 0f) : new Vector2(grid.TileSize * 0.5f, -grid.TileSize * 0.5f); + new Vector2(grid.TileSize * layerFraction, -grid.TileSize * 0f) : origin; var horizLineOrigin = (atmosPipeData & eastMask << tileIdx * SharedNavMapSystem.Directions) > 0 ? - new Vector2(grid.TileSize * 1f, -grid.TileSize * 0.5f) : new Vector2(grid.TileSize * 0.5f, -grid.TileSize * 0.5f); + new Vector2(grid.TileSize * 1f, -grid.TileSize * layerFraction) : origin; var horizLineTerminus = (atmosPipeData & westMask << tileIdx * SharedNavMapSystem.Directions) > 0 ? - new Vector2(grid.TileSize * 0f, -grid.TileSize * 0.5f) : new Vector2(grid.TileSize * 0.5f, -grid.TileSize * 0.5f); + new Vector2(grid.TileSize * 0f, -grid.TileSize * layerFraction) : origin; - // Since we can have pipe lines that have a length of a half tile, - // double the vectors and convert to vector2i so we can merge them - AddOrUpdateNavMapLine(ConvertVector2ToVector2i(tile + horizLineOrigin, 2), ConvertVector2ToVector2i(tile + horizLineTerminus, 2), horizLines, horizLinesReversed); - AddOrUpdateNavMapLine(ConvertVector2ToVector2i(tile + vertLineOrigin, 2), ConvertVector2ToVector2i(tile + vertLineTerminus, 2), vertLines, vertLinesReversed); + // Scale up the vectors and convert to vector2i so we can merge them + AddOrUpdateNavMapLine(ConvertVector2ToVector2i(tile + horizLineOrigin, ScaleModifier), + ConvertVector2ToVector2i(tile + horizLineTerminus, ScaleModifier), horizLines, horizLinesReversed); + AddOrUpdateNavMapLine(ConvertVector2ToVector2i(tile + vertLineOrigin, ScaleModifier), + ConvertVector2ToVector2i(tile + vertLineTerminus, ScaleModifier), vertLines, vertLinesReversed); } } } @@ -235,7 +243,7 @@ public sealed partial class AtmosMonitoringConsoleNavMapControl : NavMapControl foreach (var (origin, terminal) in horizLines) decodedOutput.Add(new AtmosMonitoringConsoleLine - (ConvertVector2iToVector2(origin, 0.5f), ConvertVector2iToVector2(terminal, 0.5f), sRGB)); + (ConvertVector2iToVector2(origin, 1f / ScaleModifier), ConvertVector2iToVector2(terminal, 1f / ScaleModifier), sRGB)); } foreach (var (color, vertLines) in _vertLines) @@ -245,7 +253,7 @@ public sealed partial class AtmosMonitoringConsoleNavMapControl : NavMapControl foreach (var (origin, terminal) in vertLines) decodedOutput.Add(new AtmosMonitoringConsoleLine - (ConvertVector2iToVector2(origin, 0.5f), ConvertVector2iToVector2(terminal, 0.5f), sRGB)); + (ConvertVector2iToVector2(origin, 1f / ScaleModifier), ConvertVector2iToVector2(terminal, 1f / ScaleModifier), sRGB)); } return decodedOutput; diff --git a/Content.Client/Atmos/Consoles/AtmosMonitoringConsoleSystem.cs b/Content.Client/Atmos/Consoles/AtmosMonitoringConsoleSystem.cs index bfbb05d2ab..6a4967e4a4 100644 --- a/Content.Client/Atmos/Consoles/AtmosMonitoringConsoleSystem.cs +++ b/Content.Client/Atmos/Consoles/AtmosMonitoringConsoleSystem.cs @@ -15,7 +15,7 @@ public sealed class AtmosMonitoringConsoleSystem : SharedAtmosMonitoringConsoleS private void OnHandleState(EntityUid uid, AtmosMonitoringConsoleComponent component, ref ComponentHandleState args) { - Dictionary> modifiedChunks; + Dictionary> modifiedChunks; Dictionary atmosDevices; switch (args.Current) @@ -54,7 +54,7 @@ public sealed class AtmosMonitoringConsoleSystem : SharedAtmosMonitoringConsoleS foreach (var (origin, chunk) in modifiedChunks) { var newChunk = new AtmosPipeChunk(origin); - newChunk.AtmosPipeData = new Dictionary<(int, string), ulong>(chunk); + newChunk.AtmosPipeData = new Dictionary(chunk); component.AtmosPipeChunks[origin] = newChunk; } diff --git a/Content.Client/Atmos/Consoles/AtmosMonitoringConsoleWindow.xaml.cs b/Content.Client/Atmos/Consoles/AtmosMonitoringConsoleWindow.xaml.cs index e25c3af9e9..1a084ea73b 100644 --- a/Content.Client/Atmos/Consoles/AtmosMonitoringConsoleWindow.xaml.cs +++ b/Content.Client/Atmos/Consoles/AtmosMonitoringConsoleWindow.xaml.cs @@ -13,6 +13,7 @@ using Robust.Shared.Timing; using Robust.Shared.Utility; using System.Diagnostics.CodeAnalysis; using System.Linq; +using System.Numerics; namespace Content.Client.Atmos.Consoles; @@ -33,6 +34,8 @@ public sealed partial class AtmosMonitoringConsoleWindow : FancyWindow private ProtoId _navMapConsoleProtoId = "NavMapConsole"; private ProtoId _gasPipeSensorProtoId = "GasPipeSensor"; + private readonly Vector2[] _pipeLayerOffsets = { new Vector2(0f, 0f), new Vector2(0.25f, 0.25f), new Vector2(-0.25f, -0.25f) }; + public AtmosMonitoringConsoleWindow(AtmosMonitoringConsoleBoundUserInterface userInterface, EntityUid? owner) { RobustXamlLoader.Load(this); @@ -53,7 +56,7 @@ public sealed partial class AtmosMonitoringConsoleWindow : FancyWindow consoleCoords = xform.Coordinates; NavMap.MapUid = xform.GridUid; - // Assign station name + // Assign station name if (_entManager.TryGetComponent(xform.GridUid, out var stationMetaData)) stationName = stationMetaData.EntityName; @@ -238,6 +241,10 @@ public sealed partial class AtmosMonitoringConsoleWindow : FancyWindow var blinks = proto.Blinks || _focusEntity == metaData.NetEntity; var coords = _entManager.GetCoordinates(metaData.NetCoordinates); + + if (proto.Placement == NavMapBlipPlacement.Offset && metaData.PipeLayer > 0) + coords = coords.Offset(_pipeLayerOffsets[(int)metaData.PipeLayer]); + var blip = new NavMapBlip(coords, _spriteSystem.Frame0(new SpriteSpecifier.Texture(texture)), color, blinks, proto.Selectable, proto.Scale); NavMap.TrackedEntities[metaData.NetEntity] = blip; } diff --git a/Content.Client/Atmos/EntitySystems/AtmosPipeAppearanceSystem.cs b/Content.Client/Atmos/EntitySystems/AtmosPipeAppearanceSystem.cs index 2029cb9be5..1a12c3967b 100644 --- a/Content.Client/Atmos/EntitySystems/AtmosPipeAppearanceSystem.cs +++ b/Content.Client/Atmos/EntitySystems/AtmosPipeAppearanceSystem.cs @@ -1,6 +1,7 @@ using Content.Client.SubFloor; using Content.Shared.Atmos; using Content.Shared.Atmos.Components; +using Content.Shared.Atmos.EntitySystems; using Content.Shared.Atmos.Piping; using JetBrains.Annotations; using Robust.Client.GameObjects; @@ -8,7 +9,7 @@ using Robust.Client.GameObjects; namespace Content.Client.Atmos.EntitySystems; [UsedImplicitly] -public sealed class AtmosPipeAppearanceSystem : EntitySystem +public sealed partial class AtmosPipeAppearanceSystem : SharedAtmosPipeAppearanceSystem { [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SpriteSystem _sprite = default!; @@ -26,26 +27,37 @@ public sealed class AtmosPipeAppearanceSystem : EntitySystem if (!TryComp(uid, out SpriteComponent? sprite)) return; + var numberOfPipeLayers = GetNumberOfPipeLayers(uid, out _); + foreach (var layerKey in Enum.GetValues()) { - var layer = _sprite.LayerMapReserve((uid, sprite), layerKey); - _sprite.LayerSetRsi((uid, sprite), layer, component.Sprite.RsiPath); - _sprite.LayerSetRsiState((uid, sprite), layer, component.Sprite.RsiState); - _sprite.LayerSetDirOffset((uid, sprite), layer, ToOffset(layerKey)); + for (byte i = 0; i < numberOfPipeLayers; i++) + { + var layerName = layerKey.ToString() + i.ToString(); + var layer = _sprite.LayerMapReserve((uid, sprite), layerName); + _sprite.LayerSetRsi((uid, sprite), layer, component.Sprite[i].RsiPath); + _sprite.LayerSetRsiState((uid, sprite), layer, component.Sprite[i].RsiState); + _sprite.LayerSetDirOffset((uid, sprite), layer, ToOffset(layerKey)); + } } } - private void HideAllPipeConnection(Entity entity) + private void HideAllPipeConnection(Entity entity, AtmosPipeLayersComponent? atmosPipeLayers, int numberOfPipeLayers) { var sprite = entity.Comp; foreach (var layerKey in Enum.GetValues()) { - if (!_sprite.LayerMapTryGet(entity.AsNullable(), layerKey, out var key, false)) - continue; + for (byte i = 0; i < numberOfPipeLayers; i++) + { + var layerName = layerKey.ToString() + i.ToString(); - var layer = sprite[key]; - layer.Visible = false; + if (!_sprite.LayerMapTryGet(entity.AsNullable(), layerName, out var key, false)) + continue; + + var layer = sprite[key]; + layer.Visible = false; + } } } @@ -61,33 +73,45 @@ public sealed class AtmosPipeAppearanceSystem : EntitySystem return; } - if (!_appearance.TryGetData(uid, PipeVisuals.VisualState, out var worldConnectedDirections, args.Component)) + var numberOfPipeLayers = GetNumberOfPipeLayers(uid, out var atmosPipeLayers); + + if (!_appearance.TryGetData(uid, PipeVisuals.VisualState, out var worldConnectedDirections, args.Component)) { - HideAllPipeConnection((uid, args.Sprite)); + HideAllPipeConnection((uid, args.Sprite), atmosPipeLayers, numberOfPipeLayers); return; } if (!_appearance.TryGetData(uid, PipeColorVisuals.Color, out var color, args.Component)) color = Color.White; - // transform connected directions to local-coordinates - var connectedDirections = worldConnectedDirections.RotatePipeDirection(-Transform(uid).LocalRotation); - - foreach (var layerKey in Enum.GetValues()) + for (byte i = 0; i < numberOfPipeLayers; i++) { - if (!_sprite.LayerMapTryGet((uid, args.Sprite), layerKey, out var key, false)) - continue; + // Extract the cardinal pipe orientations for the current pipe layer + // '15' is the four bit mask that is used to extract the pipe orientations of interest from 'worldConnectedDirections' + // Fun fact: a collection of four bits is called a 'nibble'! They aren't natively supported :( + var pipeLayerConnectedDirections = (PipeDirection)(15 & (worldConnectedDirections >> (PipeDirectionHelpers.PipeDirections * i))); - var layer = args.Sprite[key]; - var dir = (PipeDirection)layerKey; - var visible = connectedDirections.HasDirection(dir); + // Transform the connected directions to local-coordinates + var connectedDirections = pipeLayerConnectedDirections.RotatePipeDirection(-Transform(uid).LocalRotation); - layer.Visible &= visible; + foreach (var layerKey in Enum.GetValues()) + { + var layerName = layerKey.ToString() + i.ToString(); - if (!visible) - continue; + if (!_sprite.LayerMapTryGet((uid, args.Sprite), layerName, out var key, false)) + continue; - layer.Color = color; + var layer = args.Sprite[key]; + var dir = (PipeDirection)layerKey; + var visible = connectedDirections.HasDirection(dir); + + layer.Visible &= visible; + + if (!visible) + continue; + + layer.Color = color; + } } } diff --git a/Content.Client/Atmos/EntitySystems/AtmosPipeLayersSystem.cs b/Content.Client/Atmos/EntitySystems/AtmosPipeLayersSystem.cs new file mode 100644 index 0000000000..f560e0b833 --- /dev/null +++ b/Content.Client/Atmos/EntitySystems/AtmosPipeLayersSystem.cs @@ -0,0 +1,56 @@ +using Content.Shared.Atmos.Components; +using Content.Shared.Atmos.EntitySystems; +using Robust.Client.GameObjects; +using Robust.Client.ResourceManagement; +using Robust.Shared.Reflection; +using Robust.Shared.Serialization.TypeSerializers.Implementations; +using Robust.Shared.Utility; +using System.Diagnostics.CodeAnalysis; + +namespace Content.Client.Atmos.EntitySystems; + +/// +/// The system responsible for updating the appearance of layered gas pipe +/// +public sealed partial class AtmosPipeLayersSystem : SharedAtmosPipeLayersSystem +{ + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly IReflectionManager _reflection = default!; + [Dependency] private readonly IResourceCache _resourceCache = default!; + [Dependency] private readonly SpriteSystem _sprite = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnAppearanceChange); + } + + private void OnAppearanceChange(Entity ent, ref AppearanceChangeEvent ev) + { + if (!TryComp(ent, out var sprite)) + return; + + if (_appearance.TryGetData(ent, AtmosPipeLayerVisuals.Sprite, out var spriteRsi) && + _resourceCache.TryGetResource(SpriteSpecifierSerializer.TextureRoot / spriteRsi, out RSIResource? resource)) + { + _sprite.SetBaseRsi((ent, sprite), resource.RSI); + } + + if (_appearance.TryGetData>(ent, AtmosPipeLayerVisuals.SpriteLayers, out var pipeState)) + { + foreach (var (layerKey, rsiPath) in pipeState) + { + if (TryParseKey(layerKey, out var @enum)) + _sprite.LayerSetRsi((ent, sprite), @enum, new ResPath(rsiPath)); + else + _sprite.LayerSetRsi((ent, sprite), layerKey, new ResPath(rsiPath)); + } + } + } + + private bool TryParseKey(string keyString, [NotNullWhen(true)] out Enum? @enum) + { + return _reflection.TryParseEnumReference(keyString, out @enum); + } +} diff --git a/Content.Client/Atmos/UI/GasAnalyzerWindow.xaml.cs b/Content.Client/Atmos/UI/GasAnalyzerWindow.xaml.cs index bb24da44e1..e280523e43 100644 --- a/Content.Client/Atmos/UI/GasAnalyzerWindow.xaml.cs +++ b/Content.Client/Atmos/UI/GasAnalyzerWindow.xaml.cs @@ -136,6 +136,7 @@ namespace Content.Client.Atmos.UI else { // oh shit of fuck its more than 4 this ui isn't gonna look pretty anymore + CDeviceMixes.RemoveAllChildren(); for (var i = 1; i < msg.NodeGasMixes.Length; i++) { GenerateGasDisplay(msg.NodeGasMixes[i], CDeviceMixes); diff --git a/Content.Client/Construction/ConstructionPlacementHijack.cs b/Content.Client/Construction/ConstructionPlacementHijack.cs index e6a8e0f1f0..79112a8f8e 100644 --- a/Content.Client/Construction/ConstructionPlacementHijack.cs +++ b/Content.Client/Construction/ConstructionPlacementHijack.cs @@ -1,4 +1,4 @@ -using System.Linq; +using System.Linq; using Content.Shared.Construction.Prototypes; using Robust.Client.GameObjects; using Robust.Client.Placement; @@ -13,6 +13,9 @@ namespace Content.Client.Construction private readonly ConstructionSystem _constructionSystem; private readonly ConstructionPrototype? _prototype; + public ConstructionSystem? CurrentConstructionSystem { get { return _constructionSystem; } } + public ConstructionPrototype? CurrentPrototype { get { return _prototype; } } + public override bool CanRotate { get; } public ConstructionPlacementHijack(ConstructionSystem constructionSystem, ConstructionPrototype? prototype) diff --git a/Content.Server/Atmos/Consoles/AtmosMonitoringConsoleSystem.cs b/Content.Server/Atmos/Consoles/AtmosMonitoringConsoleSystem.cs index 532ba04d29..a7debbdc80 100644 --- a/Content.Server/Atmos/Consoles/AtmosMonitoringConsoleSystem.cs +++ b/Content.Server/Atmos/Consoles/AtmosMonitoringConsoleSystem.cs @@ -282,16 +282,11 @@ public sealed class AtmosMonitoringConsoleSystem : SharedAtmosMonitoringConsoleS return false; var direction = xform.LocalRotation.GetCardinalDir(); + var netId = TryGettingFirstPipeNode(uid, out var _, out var firstNetId) ? firstNetId : -1; + var color = TryComp(uid, out var atmosPipeColor) ? atmosPipeColor.Color : Color.White; + var layer = TryComp(uid, out var atmosPipeLayers) ? atmosPipeLayers.CurrentPipeLayer : AtmosPipeLayer.Primary; - if (!TryGettingFirstPipeNode(uid, out var _, out var netId)) - netId = -1; - - var color = Color.White; - - if (TryComp(uid, out var atmosPipeColor)) - color = atmosPipeColor.Color; - - device = new AtmosDeviceNavMapData(GetNetEntity(uid), GetNetCoordinates(xform.Coordinates), netId.Value, component.NavMapBlip.Value, direction, color); + device = new AtmosDeviceNavMapData(GetNetEntity(uid), GetNetCoordinates(xform.Coordinates), netId.Value, component.NavMapBlip.Value, direction, color, layer); return true; } @@ -371,7 +366,9 @@ public sealed class AtmosMonitoringConsoleSystem : SharedAtmosMonitoringConsoleS if (!TryComp(ent, out var entNodeContainer)) continue; - UpdateAtmosPipeChunk(ent, entNodeContainer, entAtmosPipeColor, tileIdx, ref chunk); + var showAbsentConnections = TryComp(ent, out var device) ? device.ShowAbsentConnections : true; + + UpdateAtmosPipeChunk(ent, entNodeContainer, entAtmosPipeColor, tileIdx, ref chunk, showAbsentConnections); } // Add or update the chunk on the associated grid @@ -393,7 +390,13 @@ public sealed class AtmosMonitoringConsoleSystem : SharedAtmosMonitoringConsoleS } } - private void UpdateAtmosPipeChunk(EntityUid uid, NodeContainerComponent nodeContainer, AtmosPipeColorComponent pipeColor, int tileIdx, ref AtmosPipeChunk chunk) + private void UpdateAtmosPipeChunk + (EntityUid uid, + NodeContainerComponent nodeContainer, + AtmosPipeColorComponent pipeColor, + int tileIdx, + ref AtmosPipeChunk chunk, + bool showAbsentConnections = true) { // Entities that are actively being deleted are not to be drawn if (MetaData(uid).EntityLifeStage >= EntityLifeStage.Terminating) @@ -401,16 +404,19 @@ public sealed class AtmosMonitoringConsoleSystem : SharedAtmosMonitoringConsoleS foreach ((var id, var node) in nodeContainer.Nodes) { - if (node is not PipeNode) + if (node is not PipeNode { } pipeNode) + continue; + + if (!showAbsentConnections && !pipeNode.ReachableNodes.Any(x => x.Owner != uid)) continue; - var pipeNode = (PipeNode)node; var netId = GetPipeNodeNetId(pipeNode); + var subnet = new AtmosMonitoringConsoleSubnet(netId, pipeNode.CurrentPipeLayer, pipeColor.Color.ToHex()); var pipeDirection = pipeNode.CurrentPipeDirection; - chunk.AtmosPipeData.TryGetValue((netId, pipeColor.Color.ToHex()), out var atmosPipeData); + chunk.AtmosPipeData.TryGetValue(subnet, out var atmosPipeData); atmosPipeData |= (ulong)pipeDirection << tileIdx * SharedNavMapSystem.Directions; - chunk.AtmosPipeData[(netId, pipeColor.Color.ToHex())] = atmosPipeData; + chunk.AtmosPipeData[subnet] = atmosPipeData; } } diff --git a/Content.Server/Atmos/EntitySystems/AtmosPipeLayersSystem.cs b/Content.Server/Atmos/EntitySystems/AtmosPipeLayersSystem.cs new file mode 100644 index 0000000000..0cb804bdbd --- /dev/null +++ b/Content.Server/Atmos/EntitySystems/AtmosPipeLayersSystem.cs @@ -0,0 +1,77 @@ +using Content.Server.Atmos.Components; +using Content.Server.NodeContainer.EntitySystems; +using Content.Server.NodeContainer.NodeGroups; +using Content.Server.NodeContainer.Nodes; +using Content.Shared.Atmos.Components; +using Content.Shared.Atmos.EntitySystems; +using Content.Shared.Construction.Components; +using Content.Shared.NodeContainer; +using Content.Shared.Popups; + +namespace Content.Server.Atmos.EntitySystems; + +/// +/// The system responsible for checking and adjusting the connection layering of gas pipes +/// +public sealed partial class AtmosPipeLayersSystem : SharedAtmosPipeLayersSystem +{ + [Dependency] private readonly NodeGroupSystem _nodeGroup = default!; + [Dependency] private readonly PipeRestrictOverlapSystem _pipeRestrictOverlap = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + [Dependency] private readonly SharedTransformSystem _xform = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnInit); + } + + private void OnInit(Entity ent, ref ComponentInit args) + { + SetPipeLayer(ent, ent.Comp.CurrentPipeLayer); + } + + /// + public override void SetPipeLayer(Entity ent, AtmosPipeLayer layer, EntityUid? user = null, EntityUid? used = null) + { + if (ent.Comp.PipeLayersLocked) + return; + + base.SetPipeLayer(ent, layer); + + if (!TryComp(ent, out var nodeContainer)) + return; + + // Update the layer values of all pipe nodes associated with the entity + foreach (var (id, node) in nodeContainer.Nodes) + { + if (node is not PipeNode { } pipeNode) + continue; + + if (pipeNode.CurrentPipeLayer == ent.Comp.CurrentPipeLayer) + continue; + + pipeNode.CurrentPipeLayer = ent.Comp.CurrentPipeLayer; + + if (pipeNode.NodeGroup != null) + _nodeGroup.QueueRemakeGroup((BaseNodeGroup)pipeNode.NodeGroup); + } + + // If a user wasn't responsible for unanchoring the pipe, leave it be + if (user == null || used == null) + return; + + // Unanchor the pipe if its new layer overlaps with another pipe + var xform = Transform(ent); + + if (!HasComp(ent) || !_pipeRestrictOverlap.CheckOverlap((ent, nodeContainer, xform))) + return; + + RaiseLocalEvent(ent, new BeforeUnanchoredEvent(user.Value, used.Value)); + _xform.Unanchor(ent, xform); + RaiseLocalEvent(ent, new UserUnanchoredEvent(user.Value, used.Value)); + + _popup.PopupEntity(Loc.GetString("pipe-restrict-overlap-popup-blocked", ("pipe", ent)), ent, user.Value); + } +} diff --git a/Content.Server/Atmos/EntitySystems/PipeRestrictOverlapSystem.cs b/Content.Server/Atmos/EntitySystems/PipeRestrictOverlapSystem.cs index f64aff47f4..351a754105 100644 --- a/Content.Server/Atmos/EntitySystems/PipeRestrictOverlapSystem.cs +++ b/Content.Server/Atmos/EntitySystems/PipeRestrictOverlapSystem.cs @@ -4,6 +4,7 @@ using Content.Server.NodeContainer; using Content.Server.NodeContainer.Nodes; using Content.Server.Popups; using Content.Shared.Atmos; +using Content.Shared.Atmos.Components; using Content.Shared.Construction.Components; using Content.Shared.NodeContainer; using JetBrains.Annotations; @@ -97,27 +98,27 @@ public sealed class PipeRestrictOverlapSystem : EntitySystem public bool PipeNodesOverlap(Entity ent, Entity other) { - var entDirs = GetAllDirections(ent).ToList(); - var otherDirs = GetAllDirections(other).ToList(); + var entDirsAndLayers = GetAllDirectionsAndLayers(ent).ToList(); + var otherDirsAndLayers = GetAllDirectionsAndLayers(other).ToList(); - foreach (var dir in entDirs) + foreach (var (dir, layer) in entDirsAndLayers) { - foreach (var otherDir in otherDirs) + foreach (var (otherDir, otherLayer) in otherDirsAndLayers) { - if ((dir & otherDir) != 0) + if ((dir & otherDir) != 0 && layer == otherLayer) return true; } } return false; - IEnumerable GetAllDirections(Entity pipe) + IEnumerable<(PipeDirection, AtmosPipeLayer)> GetAllDirectionsAndLayers(Entity pipe) { foreach (var node in pipe.Comp1.Nodes.Values) { // we need to rotate the pipe manually like this because the rotation doesn't update for pipes that are unanchored. if (node is PipeNode pipeNode) - yield return pipeNode.OriginalPipeDirection.RotatePipeDirection(pipe.Comp2.LocalRotation); + yield return (pipeNode.OriginalPipeDirection.RotatePipeDirection(pipe.Comp2.LocalRotation), pipeNode.CurrentPipeLayer); } } } diff --git a/Content.Server/Atmos/Piping/Components/GasPipeManifoldComponent.cs b/Content.Server/Atmos/Piping/Components/GasPipeManifoldComponent.cs new file mode 100644 index 0000000000..ded2ffcb07 --- /dev/null +++ b/Content.Server/Atmos/Piping/Components/GasPipeManifoldComponent.cs @@ -0,0 +1,11 @@ +namespace Content.Server.Atmos.Piping.Components; + +[RegisterComponent] +public sealed partial class GasPipeManifoldComponent : Component +{ + [DataField("inlets")] + public HashSet InletNames { get; set; } = new() { "south0", "south1", "south2" }; + + [DataField("outlets")] + public HashSet OutletNames { get; set; } = new() { "north0", "north1", "north2" }; +} diff --git a/Content.Server/Atmos/Piping/EntitySystems/AtmosPipeAppearanceSystem.cs b/Content.Server/Atmos/Piping/EntitySystems/AtmosPipeAppearanceSystem.cs index 3e14fea2d8..17f9d4652f 100644 --- a/Content.Server/Atmos/Piping/EntitySystems/AtmosPipeAppearanceSystem.cs +++ b/Content.Server/Atmos/Piping/EntitySystems/AtmosPipeAppearanceSystem.cs @@ -1,14 +1,14 @@ -using Content.Server.NodeContainer; using Content.Server.NodeContainer.EntitySystems; using Content.Server.NodeContainer.Nodes; using Content.Shared.Atmos; using Content.Shared.Atmos.Components; +using Content.Shared.Atmos.EntitySystems; using Content.Shared.NodeContainer; using Robust.Shared.Map.Components; namespace Content.Server.Atmos.Piping.EntitySystems; -public sealed class AtmosPipeAppearanceSystem : EntitySystem +public sealed partial class AtmosPipeAppearanceSystem : SharedAtmosPipeAppearanceSystem { [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly SharedMapSystem _map = default!; @@ -34,9 +34,12 @@ public sealed class AtmosPipeAppearanceSystem : EntitySystem if (!TryComp(xform.GridUid, out var grid)) return; + var numberOfPipeLayers = GetNumberOfPipeLayers(uid, out var atmosPipeLayers); + // get connected entities var anyPipeNodes = false; - HashSet connected = new(); + HashSet<(EntityUid, AtmosPipeLayer)> connected = new(); + foreach (var node in container.Nodes.Values) { if (node is not PipeNode) @@ -46,8 +49,8 @@ public sealed class AtmosPipeAppearanceSystem : EntitySystem foreach (var connectedNode in node.ReachableNodes) { - if (connectedNode is PipeNode) - connected.Add(connectedNode.Owner); + if (connectedNode is PipeNode { } pipeNode) + connected.Add((connectedNode.Owner, pipeNode.CurrentPipeLayer)); } } @@ -55,14 +58,22 @@ public sealed class AtmosPipeAppearanceSystem : EntitySystem return; // find the cardinal directions of any connected entities - var netConnectedDirections = PipeDirection.None; - var tile = _map.TileIndicesFor((xform.GridUid.Value, grid), xform.Coordinates); - foreach (var neighbour in connected) - { - // TODO z-levels, pipes across grids - we shouldn't assume that the neighboring tile's transform is on the same grid - var otherTile = _map.TileIndicesFor((xform.GridUid.Value, grid), Transform(neighbour).Coordinates); + var connectedDirections = new PipeDirection[numberOfPipeLayers]; + Array.Fill(connectedDirections, PipeDirection.None); - netConnectedDirections |= (otherTile - tile) switch + var tile = _map.TileIndicesFor(xform.GridUid.Value, grid, xform.Coordinates); + + foreach (var (neighbour, pipeLayer) in connected) + { + var pipeIndex = (int)pipeLayer; + + if (pipeIndex >= numberOfPipeLayers) + continue; + + var otherTile = _map.TileIndicesFor(xform.GridUid.Value, grid, Transform(neighbour).Coordinates); + var pipeLayerDirections = connectedDirections[pipeIndex]; + + pipeLayerDirections |= (otherTile - tile) switch { (0, 1) => PipeDirection.North, (0, -1) => PipeDirection.South, @@ -70,8 +81,16 @@ public sealed class AtmosPipeAppearanceSystem : EntitySystem (-1, 0) => PipeDirection.West, _ => PipeDirection.None }; + + connectedDirections[pipeIndex] = pipeLayerDirections; } + // Convert the pipe direction array into a single int for serialization + var netConnectedDirections = 0; + + for (var i = numberOfPipeLayers - 1; i >= 0; i--) + netConnectedDirections += (int)connectedDirections[i] << (PipeDirectionHelpers.PipeDirections * i); + _appearance.SetData(uid, PipeVisuals.VisualState, netConnectedDirections, appearance); } } diff --git a/Content.Server/Atmos/Piping/EntitySystems/GasPipeManifoldSystem.cs b/Content.Server/Atmos/Piping/EntitySystems/GasPipeManifoldSystem.cs new file mode 100644 index 0000000000..bb7678d28d --- /dev/null +++ b/Content.Server/Atmos/Piping/EntitySystems/GasPipeManifoldSystem.cs @@ -0,0 +1,68 @@ +using Content.Server.Atmos.EntitySystems; +using Content.Server.Atmos.Piping.Components; +using Content.Server.NodeContainer.EntitySystems; +using Content.Server.NodeContainer.Nodes; +using Content.Shared.Atmos; +using Content.Shared.NodeContainer; +using System.Linq; + +namespace Content.Server.Atmos.Piping.EntitySystems; + +public sealed partial class GasPipeManifoldSystem : EntitySystem +{ + [Dependency] private readonly NodeContainerSystem _nodeContainer = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnCompInit); + SubscribeLocalEvent(OnAnalyzed); + } + + private void OnCompInit(Entity ent, ref ComponentInit args) + { + if (!TryComp(ent, out var nodeContainer)) + return; + + foreach (var inletName in ent.Comp.InletNames) + { + if (!_nodeContainer.TryGetNode(nodeContainer, inletName, out PipeNode? inlet)) + continue; + + foreach (var outletName in ent.Comp.OutletNames) + { + if (!_nodeContainer.TryGetNode(nodeContainer, outletName, out PipeNode? outlet)) + continue; + + inlet.AddAlwaysReachable(outlet); + outlet.AddAlwaysReachable(inlet); + } + } + } + + private void OnAnalyzed(Entity ent, ref GasAnalyzerScanEvent args) + { + // All inlets and outlets have the same gas mixture + + args.GasMixtures = new List<(string, GasMixture?)>(); + + if (!TryComp(ent, out var nodeContainer)) + return; + + var pipeNames = ent.Comp.InletNames.Union(ent.Comp.OutletNames); + + foreach (var pipeName in pipeNames) + { + if (!_nodeContainer.TryGetNode(nodeContainer, pipeName, out PipeNode? pipe)) + continue; + + var pipeLocal = pipe.Air.Clone(); + pipeLocal.Multiply(pipe.Volume / pipe.Air.Volume); + pipeLocal.Volume = pipe.Volume; + + args.GasMixtures.Add((Name(ent), pipeLocal)); + break; + } + } +} diff --git a/Content.Server/NodeContainer/Nodes/PipeNode.cs b/Content.Server/NodeContainer/Nodes/PipeNode.cs index d30d3b1777..3a76666a2c 100644 --- a/Content.Server/NodeContainer/Nodes/PipeNode.cs +++ b/Content.Server/NodeContainer/Nodes/PipeNode.cs @@ -1,10 +1,8 @@ -using Content.Server.Atmos; using Content.Server.NodeContainer.EntitySystems; using Content.Server.NodeContainer.NodeGroups; using Content.Shared.Atmos; +using Content.Shared.Atmos.Components; using Content.Shared.NodeContainer; -using Content.Shared.NodeContainer.NodeGroups; -using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Utility; @@ -12,7 +10,7 @@ namespace Content.Server.NodeContainer.Nodes { /// /// Connects with other s whose - /// correctly correspond. + /// and correctly correspond. /// [DataDefinition] [Virtual] @@ -24,6 +22,12 @@ namespace Content.Server.NodeContainer.Nodes [DataField("pipeDirection")] public PipeDirection OriginalPipeDirection; + /// + /// The *current* layer to which the pipe node is assigned. + /// + [DataField("pipeLayer")] + public AtmosPipeLayer CurrentPipeLayer = AtmosPipeLayer.Primary; + /// /// The *current* pipe directions (accounting for rotation) /// Used to check if this pipe can connect to another pipe in a given direction. @@ -204,6 +208,7 @@ namespace Content.Server.NodeContainer.Nodes foreach (var pipe in PipesInDirection(pos, pipeDir, grid, nodeQuery)) { if (pipe.NodeGroupID == NodeGroupID + && pipe.CurrentPipeLayer == CurrentPipeLayer && pipe.CurrentPipeDirection.HasDirection(pipeDir.GetOpposite())) { yield return pipe; diff --git a/Content.Shared/Atmos/Components/AtmosPipeLayersComponent.cs b/Content.Shared/Atmos/Components/AtmosPipeLayersComponent.cs new file mode 100644 index 0000000000..3081bb8d01 --- /dev/null +++ b/Content.Shared/Atmos/Components/AtmosPipeLayersComponent.cs @@ -0,0 +1,122 @@ +using Content.Shared.Atmos.EntitySystems; +using Content.Shared.DoAfter; +using Content.Shared.Tools; +using Robust.Shared.GameStates; +using Robust.Shared.Prototypes; +using Robust.Shared.Serialization; + +namespace Content.Shared.Atmos.Components; + +/// +/// Contains layer data for atmos pipes. Layers allow multiple atmos pipes with the +/// same orientation to be anchored to the same tile without their contents mixing. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +[Access(typeof(SharedAtmosPipeLayersSystem))] +public sealed partial class AtmosPipeLayersComponent : Component +{ + /// + /// The number of pipe layers this entity supports. + /// Must be equal to or less than the number of values + /// in . + /// + [DataField] + public byte NumberOfPipeLayers = 3; + + /// + /// Determines which layer the pipe is currently assigned. + /// Only pipes on the same layer can connect with each other. + /// + [DataField("pipeLayer"), AutoNetworkedField] + [ViewVariables(VVAccess.ReadOnly)] + public AtmosPipeLayer CurrentPipeLayer = AtmosPipeLayer.Primary; + + /// + /// The RSI paths that the entity will use to update its sprite when its pipe layer changes; + /// if empty, the entity sprite will not update when it pipe layer changes. + /// If you want to set specific sprite layers to update when the pipe layer changes, use + /// instead. + /// + /// + /// If the dictionary is not empty there should be an entry for each atmos pipe layer. + /// + [DataField] + public Dictionary SpriteRsiPaths = new(); + + /// + /// Used to update specific sprite layers when the entity's pipe layer changes. + /// The dictionary key is the name of the sprite layer to be updated, and its value is + /// a second dictionary which contains the RSI paths indexed by pipe layer. + /// If you want to change the default RSI path used by the entity, use + /// instead. + /// + /// + /// If an dictionary is not empty there should be an entry for each pipe layer. + /// + [DataField] + public Dictionary> SpriteLayersRsiPaths = new(); + + /// + /// Entity prototypes that will be used to replace the current one when using + /// position dependent entity placement via AlignAtmosPipeLayers. + /// + /// + /// If the dictionary is not empty there should be an entry for each atmos pipe layer. + /// + [DataField] + public Dictionary AlternativePrototypes = new(); + + /// + /// The pipe layers of this entity cannot be changed when this value is true. + /// + [DataField] + public bool PipeLayersLocked; + + /// + /// Tool quality required to cause a pipe to change layers + /// + [DataField] + public ProtoId Tool = "Screwing"; + + /// + /// The base delay to use for changing layers. + /// + [DataField] + public float Delay = 1f; +} + +/// +/// Raised when a player attempts to cycle a pipe to its next layer +/// +[Serializable, NetSerializable] +public sealed partial class TrySetNextPipeLayerCompletedEvent : SimpleDoAfterEvent; + +/// +/// Raised when a player attempts to set a pipe a specified layer +/// +[Serializable, NetSerializable] +public sealed partial class TrySettingPipeLayerCompletedEvent : SimpleDoAfterEvent +{ + public AtmosPipeLayer PipeLayer; + + public TrySettingPipeLayerCompletedEvent(AtmosPipeLayer pipeLayer) + { + PipeLayer = pipeLayer; + } +} + +[Serializable, NetSerializable] +public enum AtmosPipeLayerVisuals +{ + Sprite, + SpriteLayers, + DrawDepth, +} + +[Serializable, NetSerializable] +public enum AtmosPipeLayer +{ + Primary, + Secondary, + Tertiary, +} diff --git a/Content.Shared/Atmos/Components/PipeAppearanceComponent.cs b/Content.Shared/Atmos/Components/PipeAppearanceComponent.cs index b5f979c482..f8599148ea 100644 --- a/Content.Shared/Atmos/Components/PipeAppearanceComponent.cs +++ b/Content.Shared/Atmos/Components/PipeAppearanceComponent.cs @@ -5,6 +5,8 @@ namespace Content.Shared.Atmos.Components; [RegisterComponent] public sealed partial class PipeAppearanceComponent : Component { - [DataField("sprite")] - public SpriteSpecifier.Rsi Sprite = new(new("Structures/Piping/Atmospherics/pipe.rsi"), "pipeConnector"); + [DataField] + public SpriteSpecifier.Rsi[] Sprite = [new(new("Structures/Piping/Atmospherics/pipe.rsi"), "pipeConnector"), + new(new("Structures/Piping/Atmospherics/pipe_alt1.rsi"), "pipeConnector"), + new(new("Structures/Piping/Atmospherics/pipe_alt2.rsi"), "pipeConnector")]; } diff --git a/Content.Shared/Atmos/Consoles/Components/AtmosMonitoringConsoleComponent.cs b/Content.Shared/Atmos/Consoles/Components/AtmosMonitoringConsoleComponent.cs index 2ac0d2a9af..d01fb4e8bc 100644 --- a/Content.Shared/Atmos/Consoles/Components/AtmosMonitoringConsoleComponent.cs +++ b/Content.Shared/Atmos/Consoles/Components/AtmosMonitoringConsoleComponent.cs @@ -64,10 +64,10 @@ public struct AtmosPipeChunk(Vector2i origin) /// /// Bitmask look up for atmos pipes, 1 for occupied and 0 for empty. - /// Indexed by the color hexcode of the pipe + /// Indexed by the net ID, layer and color hexcode of the pipe /// [ViewVariables] - public Dictionary<(int, string), ulong> AtmosPipeData = new(); + public Dictionary AtmosPipeData = new(); /// /// The last game tick that the chunk was updated @@ -90,7 +90,7 @@ public struct AtmosDeviceNavMapData public NetCoordinates NetCoordinates; /// - /// The associated pipe network ID + /// The associated pipe network ID /// public int NetId = -1; @@ -109,10 +109,21 @@ public struct AtmosDeviceNavMapData /// public Color PipeColor; + /// + /// The pipe layer the entity is on + /// + public AtmosPipeLayer PipeLayer; + /// /// Populate the atmos monitoring console nav map with a single entity /// - public AtmosDeviceNavMapData(NetEntity netEntity, NetCoordinates netCoordinates, int netId, ProtoId navMapBlip, Direction direction, Color pipeColor) + public AtmosDeviceNavMapData(NetEntity netEntity, + NetCoordinates netCoordinates, + int netId, + ProtoId navMapBlip, + Direction direction, + Color pipeColor, + AtmosPipeLayer pipeLayer) { NetEntity = netEntity; NetCoordinates = netCoordinates; @@ -120,6 +131,7 @@ public struct AtmosDeviceNavMapData NavMapBlip = navMapBlip; Direction = direction; PipeColor = pipeColor; + PipeLayer = pipeLayer; } } @@ -154,7 +166,7 @@ public struct AtmosMonitoringConsoleEntry public NetCoordinates Coordinates; /// - /// The associated pipe network ID + /// The associated pipe network ID /// public int NetId = -1; @@ -184,7 +196,7 @@ public struct AtmosMonitoringConsoleEntry public float TotalMolData; /// - /// Mol and percentage for all detected gases + /// Mol and percentage for all detected gases /// public Dictionary GasData = new(); @@ -216,6 +228,16 @@ public struct AtmosMonitoringConsoleEntry } } +/// +/// Used to group atmos pipe chunks into subnets based on their properties and +/// improve the efficiency of rendering these chunks on the atmos monitoring console. +/// +/// The associated network ID. +/// The associated pipe layer. +/// The color of the pipe. +[Serializable, NetSerializable] +public record AtmosMonitoringConsoleSubnet(int NetId, AtmosPipeLayer PipeLayer, string HexCode); + public enum AtmosPipeChunkDataFacing : byte { // Values represent bit shift offsets when retrieving data in the tile array. diff --git a/Content.Shared/Atmos/Consoles/Components/AtmosMonitoringConsoleDeviceComponent.cs b/Content.Shared/Atmos/Consoles/Components/AtmosMonitoringConsoleDeviceComponent.cs index 50c3abcfca..a7b83fde48 100644 --- a/Content.Shared/Atmos/Consoles/Components/AtmosMonitoringConsoleDeviceComponent.cs +++ b/Content.Shared/Atmos/Consoles/Components/AtmosMonitoringConsoleDeviceComponent.cs @@ -5,7 +5,7 @@ using Robust.Shared.Prototypes; namespace Content.Shared.Atmos.Components; /// -/// Entities with this component appear on the +/// Entities with this component appear on the /// nav maps of atmos monitoring consoles /// [RegisterComponent, NetworkedComponent] @@ -16,6 +16,14 @@ public sealed partial class AtmosMonitoringConsoleDeviceComponent : Component /// entity on the atmos monitoring console nav map. /// If null, no blip is drawn (i.e., null for pipes) /// - [DataField, ViewVariables] + [DataField] public ProtoId? NavMapBlip = null; + + /// + /// Sets whether attached atmos pipes will always be rendered + /// on the atmos monitoring console nav map, even if these + /// pipes are not connected to any pipes in a neighboring tile. + /// + [DataField] + public bool ShowAbsentConnections = true; } diff --git a/Content.Shared/Atmos/Consoles/SharedAtmosMonitoringConsoleSystem.cs b/Content.Shared/Atmos/Consoles/SharedAtmosMonitoringConsoleSystem.cs index e6dd455be7..7fe94efd84 100644 --- a/Content.Shared/Atmos/Consoles/SharedAtmosMonitoringConsoleSystem.cs +++ b/Content.Shared/Atmos/Consoles/SharedAtmosMonitoringConsoleSystem.cs @@ -15,7 +15,7 @@ public abstract class SharedAtmosMonitoringConsoleSystem : EntitySystem private void OnGetState(EntityUid uid, AtmosMonitoringConsoleComponent component, ref ComponentGetState args) { - Dictionary> chunks; + Dictionary> chunks; // Should this be a full component state or a delta-state? if (args.FromTick <= component.CreationTick || component.ForceFullUpdate) @@ -52,22 +52,22 @@ public abstract class SharedAtmosMonitoringConsoleSystem : EntitySystem [Serializable, NetSerializable] protected sealed class AtmosMonitoringConsoleState( - Dictionary> chunks, + Dictionary> chunks, Dictionary atmosDevices) : ComponentState { - public Dictionary> Chunks = chunks; + public Dictionary> Chunks = chunks; public Dictionary AtmosDevices = atmosDevices; } [Serializable, NetSerializable] protected sealed class AtmosMonitoringConsoleDeltaState( - Dictionary> modifiedChunks, + Dictionary> modifiedChunks, Dictionary atmosDevices, HashSet allChunks) : ComponentState, IComponentDeltaState { - public Dictionary> ModifiedChunks = modifiedChunks; + public Dictionary> ModifiedChunks = modifiedChunks; public Dictionary AtmosDevices = atmosDevices; public HashSet AllChunks = allChunks; @@ -81,7 +81,7 @@ public abstract class SharedAtmosMonitoringConsoleSystem : EntitySystem foreach (var (index, data) in ModifiedChunks) { - state.Chunks[index] = new Dictionary<(int, string), ulong>(data); + state.Chunks[index] = new Dictionary(data); } state.AtmosDevices.Clear(); @@ -93,7 +93,7 @@ public abstract class SharedAtmosMonitoringConsoleSystem : EntitySystem public AtmosMonitoringConsoleState CreateNewFullState(AtmosMonitoringConsoleState state) { - var chunks = new Dictionary>(state.Chunks.Count); + var chunks = new Dictionary>(state.Chunks.Count); foreach (var (index, data) in state.Chunks) { @@ -101,10 +101,10 @@ public abstract class SharedAtmosMonitoringConsoleSystem : EntitySystem continue; if (ModifiedChunks.ContainsKey(index)) - chunks[index] = new Dictionary<(int, string), ulong>(ModifiedChunks[index]); + chunks[index] = new Dictionary(ModifiedChunks[index]); else - chunks[index] = new Dictionary<(int, string), ulong>(state.Chunks[index]); + chunks[index] = new Dictionary(state.Chunks[index]); } return new AtmosMonitoringConsoleState(chunks, new(AtmosDevices)); diff --git a/Content.Shared/Atmos/EntitySystems/SharedAtmosPipeAppearanceSystem.cs b/Content.Shared/Atmos/EntitySystems/SharedAtmosPipeAppearanceSystem.cs new file mode 100644 index 0000000000..c6944ec2de --- /dev/null +++ b/Content.Shared/Atmos/EntitySystems/SharedAtmosPipeAppearanceSystem.cs @@ -0,0 +1,18 @@ +using Content.Shared.Atmos.Components; + +namespace Content.Shared.Atmos.EntitySystems; + +public abstract partial class SharedAtmosPipeAppearanceSystem : EntitySystem +{ + /// + /// Returns the max number of pipe layers supported by a entity. + /// + /// The entity being checked. + /// The entity's , if available. + /// Returns + /// if the entity has the component, or 1 if it does not. + protected int GetNumberOfPipeLayers(EntityUid uid, out AtmosPipeLayersComponent? atmosPipeLayers) + { + return TryComp(uid, out atmosPipeLayers) ? atmosPipeLayers.NumberOfPipeLayers : 1; + } +} diff --git a/Content.Shared/Atmos/EntitySystems/SharedAtmosPipeLayersSystem.cs b/Content.Shared/Atmos/EntitySystems/SharedAtmosPipeLayersSystem.cs new file mode 100644 index 0000000000..ff88601330 --- /dev/null +++ b/Content.Shared/Atmos/EntitySystems/SharedAtmosPipeLayersSystem.cs @@ -0,0 +1,264 @@ +using Content.Shared.Atmos.Components; +using Content.Shared.Database; +using Content.Shared.Examine; +using Content.Shared.Hands.EntitySystems; +using Content.Shared.Interaction; +using Content.Shared.Interaction.Events; +using Content.Shared.Popups; +using Content.Shared.SubFloor; +using Content.Shared.Tools; +using Content.Shared.Tools.Components; +using Content.Shared.Tools.Systems; +using Content.Shared.Verbs; +using Robust.Shared.Prototypes; +using System.Diagnostics.CodeAnalysis; + +namespace Content.Shared.Atmos.EntitySystems; + +/// +/// The system responsible for checking and adjusting the connection layering of gas pipes +/// +public abstract partial class SharedAtmosPipeLayersSystem : EntitySystem +{ + [Dependency] private readonly SharedAppearanceSystem _appearance = default!; + [Dependency] private readonly IPrototypeManager _protoManager = default!; + [Dependency] private readonly SharedToolSystem _tool = default!; + [Dependency] private readonly SharedHandsSystem _hands = default!; + [Dependency] private readonly SharedPopupSystem _popup = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnExamined); + SubscribeLocalEvent>(OnGetVerb); + SubscribeLocalEvent(OnInteractUsing); + SubscribeLocalEvent(OnUseInHandEvent); + SubscribeLocalEvent(OnSetNextPipeLayerCompleted); + SubscribeLocalEvent(OnSettingPipeLayerCompleted); + } + + private void OnExamined(Entity ent, ref ExaminedEvent args) + { + var layerName = GetPipeLayerName(ent.Comp.CurrentPipeLayer); + args.PushMarkup(Loc.GetString("atmos-pipe-layers-component-current-layer", ("layerName", layerName))); + } + + private void OnGetVerb(Entity ent, ref GetVerbsEvent args) + { + if (!args.CanAccess || !args.CanInteract || !args.CanComplexInteract) + return; + + if (ent.Comp.NumberOfPipeLayers <= 1 || ent.Comp.PipeLayersLocked) + return; + + if (!_protoManager.TryIndex(ent.Comp.Tool, out var toolProto)) + return; + + var user = args.User; + + if (TryComp(ent, out var subFloorHide) && subFloorHide.IsUnderCover) + { + var v = new Verb + { + Priority = 1, + Category = VerbCategory.Adjust, + Text = Loc.GetString("atmos-pipe-layers-component-pipes-are-covered"), + Disabled = true, + Impact = LogImpact.Low, + DoContactInteraction = true, + }; + + args.Verbs.Add(v); + } + + else if (!TryGetHeldTool(user, ent.Comp.Tool, out var tool)) + { + var v = new Verb + { + Priority = 1, + Category = VerbCategory.Adjust, + Text = Loc.GetString("atmos-pipe-layers-component-tool-missing", ("toolName", Loc.GetString(toolProto.ToolName).ToLower())), + Disabled = true, + Impact = LogImpact.Low, + DoContactInteraction = true, + }; + + args.Verbs.Add(v); + } + + else + { + for (var i = 0; i < ent.Comp.NumberOfPipeLayers; i++) + { + var index = i; + var layerName = GetPipeLayerName((AtmosPipeLayer)index); + var label = Loc.GetString("atmos-pipe-layers-component-select-layer", ("layerName", layerName)); + + var v = new Verb + { + Priority = 1, + Category = VerbCategory.Adjust, + Text = label, + Disabled = index == (int)ent.Comp.CurrentPipeLayer, + Impact = LogImpact.Low, + DoContactInteraction = true, + Act = () => + { + _tool.UseTool(tool.Value, user, ent, ent.Comp.Delay, tool.Value.Comp.Qualities, new TrySettingPipeLayerCompletedEvent((AtmosPipeLayer)index)); + } + }; + + args.Verbs.Add(v); + } + } + } + + private void OnInteractUsing(Entity ent, ref InteractUsingEvent args) + { + if (ent.Comp.NumberOfPipeLayers <= 1 || ent.Comp.PipeLayersLocked) + return; + + if (TryComp(ent, out var subFloorHide) && subFloorHide.IsUnderCover) + { + _popup.PopupPredicted(Loc.GetString("atmos-pipe-layers-component-cannot-adjust-pipes"), ent, args.User); + return; + } + + if (TryComp(args.Used, out var tool) && _tool.HasQuality(args.Used, ent.Comp.Tool, tool)) + _tool.UseTool(args.Used, args.User, ent, ent.Comp.Delay, tool.Qualities, new TrySetNextPipeLayerCompletedEvent()); + } + + private void OnUseInHandEvent(Entity ent, ref UseInHandEvent args) + { + if (ent.Comp.NumberOfPipeLayers <= 1 || ent.Comp.PipeLayersLocked) + return; + + if (!TryGetHeldTool(args.User, ent.Comp.Tool, out var tool)) + { + if (_protoManager.TryIndex(ent.Comp.Tool, out var toolProto)) + { + var toolName = Loc.GetString(toolProto.ToolName).ToLower(); + var message = Loc.GetString("atmos-pipe-layers-component-tool-missing", ("toolName", toolName)); + + _popup.PopupPredicted(message, ent, args.User); + } + + return; + } + + _tool.UseTool(tool.Value, args.User, ent, ent.Comp.Delay, tool.Value.Comp.Qualities, new TrySetNextPipeLayerCompletedEvent()); + } + + private void OnSetNextPipeLayerCompleted(Entity ent, ref TrySetNextPipeLayerCompletedEvent args) + { + if (args.Cancelled) + return; + + SetNextPipeLayer(ent, args.User, args.Used); + } + + private void OnSettingPipeLayerCompleted(Entity ent, ref TrySettingPipeLayerCompletedEvent args) + { + if (args.Cancelled) + return; + + SetPipeLayer(ent, args.PipeLayer, args.User, args.Used); + } + + /// + /// Increments an entity's pipe layer by 1, wrapping around to 0 if the max pipe layer is reached + /// + /// The pipe entity + /// The player entity who adjusting the pipe layer + /// The tool used to adjust the pipe layer + public void SetNextPipeLayer(Entity ent, EntityUid? user = null, EntityUid? used = null) + { + var newLayer = ((int)ent.Comp.CurrentPipeLayer + 1) % ent.Comp.NumberOfPipeLayers; + SetPipeLayer(ent, (AtmosPipeLayer)newLayer, user, used); + } + + /// + /// Sets an entity's pipe layer to a specified value + /// + /// The pipe entity + /// The new layer value + /// The player entity who adjusting the pipe layer + /// The tool used to adjust the pipe layer + public virtual void SetPipeLayer(Entity ent, AtmosPipeLayer layer, EntityUid? user = null, EntityUid? used = null) + { + if (ent.Comp.PipeLayersLocked) + return; + + ent.Comp.CurrentPipeLayer = (AtmosPipeLayer)Math.Clamp((int)layer, 0, ent.Comp.NumberOfPipeLayers - 1); + Dirty(ent); + + if (TryComp(ent, out var appearance)) + { + if (ent.Comp.SpriteRsiPaths.TryGetValue(ent.Comp.CurrentPipeLayer, out var path)) + _appearance.SetData(ent, AtmosPipeLayerVisuals.Sprite, path, appearance); + + if (ent.Comp.SpriteLayersRsiPaths.Count > 0) + { + var data = new Dictionary(); + + foreach (var (layerKey, rsiPaths) in ent.Comp.SpriteLayersRsiPaths) + { + if (rsiPaths.TryGetValue(ent.Comp.CurrentPipeLayer, out path)) + data.TryAdd(layerKey, path); + } + + _appearance.SetData(ent, AtmosPipeLayerVisuals.SpriteLayers, data, appearance); + } + } + + if (user != null) + { + var layerName = GetPipeLayerName(ent.Comp.CurrentPipeLayer); + var message = Loc.GetString("atmos-pipe-layers-component-change-layer", ("layerName", layerName)); + + _popup.PopupPredicted(message, ent, user); + } + } + + /// + /// Try to find an entity prototype associated with a specified . + /// + /// The with the alternative prototypes data. + /// The atmos pipe layer associated with the entity prototype. + /// The returned entity prototype. + /// True if there was an entity prototype associated with the layer. + public bool TryGetAlternativePrototype(AtmosPipeLayersComponent component, AtmosPipeLayer layer, out EntProtoId proto) + { + return component.AlternativePrototypes.TryGetValue(layer, out proto); + } + + /// + /// Checks a player entity's hands to see if they are holding a tool with a specified quality + /// + /// The player entity + /// The tool quality being checked for + /// A tool with the specified tool quality + /// True if an appropriate tool was found + private bool TryGetHeldTool(EntityUid user, ProtoId toolQuality, [NotNullWhen(true)] out Entity? heldTool) + { + heldTool = null; + + foreach (var heldItem in _hands.EnumerateHeld(user)) + { + if (TryComp(heldItem, out var tool) && + _tool.HasQuality(heldItem, toolQuality, tool)) + { + heldTool = new Entity(heldItem, tool); + return true; + } + } + + return false; + } + + private string GetPipeLayerName(AtmosPipeLayer layer) + { + return Loc.GetString("atmos-pipe-layers-component-layer-" + layer.ToString().ToLower()); + } +} diff --git a/Content.Shared/Construction/Prototypes/ConstructionPrototype.cs b/Content.Shared/Construction/Prototypes/ConstructionPrototype.cs index 0e1a50d9a2..cd38b22b9c 100644 --- a/Content.Shared/Construction/Prototypes/ConstructionPrototype.cs +++ b/Content.Shared/Construction/Prototypes/ConstructionPrototype.cs @@ -85,6 +85,12 @@ public sealed partial class ConstructionPrototype : IPrototype [DataField] public ProtoId? Mirror { get; private set; } + /// + /// Possible constructions to replace this one with as determined by the placement mode + /// + [DataField] + public ProtoId[] AlternativePrototypes = []; + public IReadOnlyList Conditions => _conditions; } diff --git a/Content.Shared/DrawDepth/DrawDepth.cs b/Content.Shared/DrawDepth/DrawDepth.cs index dbec886971..35fead5b3f 100644 --- a/Content.Shared/DrawDepth/DrawDepth.cs +++ b/Content.Shared/DrawDepth/DrawDepth.cs @@ -9,13 +9,15 @@ namespace Content.Shared.DrawDepth /// /// This is for sub-floors, the floors you see after prying off a tile. /// - LowFloors = DrawDepthTag.Default - 18, + LowFloors = DrawDepthTag.Default - 20, // various entity types that require different // draw depths, as to avoid hiding #region SubfloorEntities - ThickPipe = DrawDepthTag.Default - 17, - ThickWire = DrawDepthTag.Default - 16, + ThickPipe = DrawDepthTag.Default - 19, + ThickWire = DrawDepthTag.Default - 18, + ThinPipeAlt2 = DrawDepthTag.Default - 17, + ThinPipeAlt1 = DrawDepthTag.Default - 16, ThinPipe = DrawDepthTag.Default - 15, ThinWire = DrawDepthTag.Default - 14, #endregion diff --git a/Content.Shared/Prototypes/NavMapBlipPrototype.cs b/Content.Shared/Prototypes/NavMapBlipPrototype.cs index 2fcb6c5ccb..dff9f50054 100644 --- a/Content.Shared/Prototypes/NavMapBlipPrototype.cs +++ b/Content.Shared/Prototypes/NavMapBlipPrototype.cs @@ -39,4 +39,17 @@ public sealed partial class NavMapBlipPrototype : IPrototype /// [DataField] public float Scale { get; private set; } = 1f; + + /// + /// Describes how the blip should be positioned. + /// It's up to the individual system to enforce this + /// + [DataField] + public NavMapBlipPlacement Placement { get; private set; } = NavMapBlipPlacement.Centered; +} + +public enum NavMapBlipPlacement +{ + Centered, // The blip appears in the center of the tile + Offset // The blip is offset from the center of the tile (determined by the system using the blips) } diff --git a/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs b/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs index 812003aae8..c7edf01499 100644 --- a/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs +++ b/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs @@ -225,6 +225,7 @@ namespace Content.Shared.SubFloor ScannerRevealed, } + [Serializable, NetSerializable] public enum SubfloorLayers : byte { FirstLayer diff --git a/Content.Shared/Verbs/VerbCategory.cs b/Content.Shared/Verbs/VerbCategory.cs index 9b9197249a..418921d38e 100644 --- a/Content.Shared/Verbs/VerbCategory.cs +++ b/Content.Shared/Verbs/VerbCategory.cs @@ -85,5 +85,8 @@ namespace Content.Shared.Verbs public static readonly VerbCategory SelectType = new("verb-categories-select-type", null); public static readonly VerbCategory PowerLevel = new("verb-categories-power-level", null); + + public static readonly VerbCategory Adjust = + new("verb-categories-adjust", "/Textures/Interface/VerbIcons/screwdriver.png"); } } diff --git a/Resources/Locale/en-US/atmos/atmos-pipe-layers.ftl b/Resources/Locale/en-US/atmos/atmos-pipe-layers.ftl new file mode 100644 index 0000000000..27491efb5e --- /dev/null +++ b/Resources/Locale/en-US/atmos/atmos-pipe-layers.ftl @@ -0,0 +1,10 @@ +atmos-pipe-layers-component-layer-primary = primary +atmos-pipe-layers-component-layer-secondary = secondary +atmos-pipe-layers-component-layer-tertiary = tertiary + +atmos-pipe-layers-component-change-layer = Adjusted to its {$layerName} configuration. +atmos-pipe-layers-component-current-layer = It is in its {$layerName} configuration. +atmos-pipe-layers-component-select-layer = {CAPITALIZE($layerName)} configuration +atmos-pipe-layers-component-tool-missing = Requires {INDEFINITE($toolName)} {$toolName} +atmos-pipe-layers-component-pipes-are-covered = The pipes are covered +atmos-pipe-layers-component-cannot-adjust-pipes = You need to uncover the pipes before they can be adjusted. \ No newline at end of file diff --git a/Resources/Locale/en-US/verbs/verb-system.ftl b/Resources/Locale/en-US/verbs/verb-system.ftl index 64104f796e..d52b43c9a7 100644 --- a/Resources/Locale/en-US/verbs/verb-system.ftl +++ b/Resources/Locale/en-US/verbs/verb-system.ftl @@ -28,6 +28,7 @@ verb-categories-lever = Lever verb-categories-select-type = Select Type verb-categories-fax = Set Destination verb-categories-power-level = Power Level +verb-categories-adjust = Adjust verb-common-toggle-light = Toggle light verb-common-close = Close diff --git a/Resources/Prototypes/Entities/Structures/Machines/Computers/nav_map_blips.yml b/Resources/Prototypes/Entities/Structures/Machines/Computers/nav_map_blips.yml index bc51557186..93530976f7 100644 --- a/Resources/Prototypes/Entities/Structures/Machines/Computers/nav_map_blips.yml +++ b/Resources/Prototypes/Entities/Structures/Machines/Computers/nav_map_blips.yml @@ -13,21 +13,22 @@ color: "#ffcd00" texturePaths: - "/Textures/Interface/NavMap/beveled_star.png" - + placement: Offset + - type: navMapBlip id: GasVentOpening - scale: 0.6667 + scale: 0.75 color: LightGray texturePaths: - "/Textures/Interface/NavMap/beveled_square.png" - + - type: navMapBlip id: GasVentScrubber - scale: 0.6667 + scale: 0.75 color: LightGray texturePaths: - "/Textures/Interface/NavMap/beveled_circle.png" - + - type: navMapBlip id: GasFlowRegulator scale: 0.75 @@ -37,7 +38,8 @@ - "/Textures/Interface/NavMap/beveled_arrow_east.png" - "/Textures/Interface/NavMap/beveled_arrow_north.png" - "/Textures/Interface/NavMap/beveled_arrow_west.png" - + placement: Offset + - type: navMapBlip id: GasValve scale: 0.6667 @@ -45,12 +47,23 @@ texturePaths: - "/Textures/Interface/NavMap/beveled_diamond_north_south.png" - "/Textures/Interface/NavMap/beveled_diamond_east_west.png" - - "/Textures/Interface/NavMap/beveled_diamond_north_south.png" + - "/Textures/Interface/NavMap/beveled_diamond_north_south.png" - "/Textures/Interface/NavMap/beveled_diamond_east_west.png" - + placement: Offset + - type: navMapBlip id: Thermoregulator - scale: 0.6667 + scale: 0.75 color: LightGray texturePaths: - - "/Textures/Interface/NavMap/beveled_hexagon.png" \ No newline at end of file + - "/Textures/Interface/NavMap/beveled_hexagon.png" + +- type: navMapBlip + id: GasPipeManifold + scale: 0.9 + color: LightGray + texturePaths: + - "/Textures/Interface/NavMap/beveled_rectangle_east_west.png" + - "/Textures/Interface/NavMap/beveled_rectangle_north_south.png" + - "/Textures/Interface/NavMap/beveled_rectangle_east_west.png" + - "/Textures/Interface/NavMap/beveled_rectangle_north_south.png" diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/alt_layers.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/alt_layers.yml new file mode 100644 index 0000000000..1f4ab085f1 --- /dev/null +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/alt_layers.yml @@ -0,0 +1,133 @@ +## This file contains duplicated pipe prototypes with +## different layer offsets to faciliate mapping + +# Layer 1 +- type: entity + abstract: true + id: GasPipeLayerAlt1 + components: + - type: AtmosPipeLayers + pipeLayer: 1 + +# Layer 2 +- type: entity + abstract: true + id: GasPipeLayerAlt2 + components: + - type: AtmosPipeLayers + pipeLayer: 2 + +# GasPipeStraight +- type: entity + parent: [GasPipeLayerAlt1, GasPipeStraight] + id: GasPipeStraightAlt1 + categories: [ HideSpawnMenu ] + components: + - type: Sprite + drawdepth: ThinPipeAlt1 + sprite: Structures/Piping/Atmospherics/pipe_alt1.rsi + - type: Construction + node: straightAlt1 + +- type: entity + parent: [GasPipeLayerAlt2, GasPipeStraight] + id: GasPipeStraightAlt2 + categories: [ HideSpawnMenu ] + components: + - type: Sprite + drawdepth: ThinPipeAlt2 + sprite: Structures/Piping/Atmospherics/pipe_alt2.rsi + - type: Construction + node: straightAlt2 + +# GasPipeHalf +- type: entity + parent: [GasPipeLayerAlt1, GasPipeHalf] + id: GasPipeHalfAlt1 + categories: [ HideSpawnMenu ] + components: + - type: Sprite + drawdepth: ThinPipeAlt1 + sprite: Structures/Piping/Atmospherics/pipe_alt1.rsi + - type: Construction + node: halfAlt1 + +- type: entity + parent: [GasPipeLayerAlt2, GasPipeHalf] + id: GasPipeHalfAlt2 + categories: [ HideSpawnMenu ] + components: + - type: Sprite + drawdepth: ThinPipeAlt2 + sprite: Structures/Piping/Atmospherics/pipe_alt2.rsi + - type: Construction + node: halfAlt2 + +# GasPipeBend +- type: entity + parent: [GasPipeLayerAlt1, GasPipeBend] + id: GasPipeBendAlt1 + categories: [ HideSpawnMenu ] + components: + - type: Sprite + drawdepth: ThinPipeAlt1 + sprite: Structures/Piping/Atmospherics/pipe_alt1.rsi + - type: Construction + node: bendAlt1 + +- type: entity + parent: [GasPipeLayerAlt2, GasPipeBend] + id: GasPipeBendAlt2 + categories: [ HideSpawnMenu ] + components: + - type: Sprite + drawdepth: ThinPipeAlt2 + sprite: Structures/Piping/Atmospherics/pipe_alt2.rsi + - type: Construction + node: bendAlt2 + +# GasPipeTJunction +- type: entity + parent: [GasPipeLayerAlt1, GasPipeTJunction] + id: GasPipeTJunctionAlt1 + categories: [ HideSpawnMenu ] + components: + - type: Sprite + drawdepth: ThinPipeAlt1 + sprite: Structures/Piping/Atmospherics/pipe_alt1.rsi + - type: Construction + node: tjunctionAlt1 + +- type: entity + parent: [GasPipeLayerAlt2, GasPipeTJunction] + id: GasPipeTJunctionAlt2 + categories: [ HideSpawnMenu ] + components: + - type: Sprite + drawdepth: ThinPipeAlt2 + sprite: Structures/Piping/Atmospherics/pipe_alt2.rsi + - type: Construction + node: tjunctionAlt2 + +# GasPipeFourway +- type: entity + parent: [GasPipeLayerAlt1, GasPipeFourway] + id: GasPipeFourwayAlt1 + categories: [ HideSpawnMenu ] + components: + - type: Sprite + drawdepth: ThinPipeAlt1 + sprite: Structures/Piping/Atmospherics/pipe_alt1.rsi + - type: Construction + node: fourwayAlt1 + +- type: entity + parent: [GasPipeLayerAlt2, GasPipeFourway] + id: GasPipeFourwayAlt2 + categories: [ HideSpawnMenu ] + components: + - type: Sprite + drawdepth: ThinPipeAlt2 + sprite: Structures/Piping/Atmospherics/pipe_alt2.rsi + - type: Construction + node: fourwayAlt2 diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml index 33a8414961..88940f4882 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/binary.yml @@ -22,6 +22,11 @@ !type:PipeNode nodeGroupID: Pipe pipeDirection: South + - type: AtmosPipeLayers + spriteRsiPaths: + Primary: Structures/Piping/Atmospherics/pump.rsi + Secondary: Structures/Piping/Atmospherics/pump_alt1.rsi + Tertiary: Structures/Piping/Atmospherics/pump_alt2.rsi - type: entity parent: GasBinaryBase @@ -325,10 +330,12 @@ sprite: Structures/Piping/Atmospherics/gascanisterport.rsi layers: - sprite: Structures/Piping/Atmospherics/pipe.rsi - state: pipeHalf + state: pipeUnaryConnectors map: [ "enum.PipeVisualLayers.Pipe" ] - state: gasCanisterPort map: [ "enum.SubfloorLayers.FirstLayer" ] + - type: AtmosPipeLayers + spriteRsiPaths: {} - type: Appearance - type: PipeColorVisuals - type: GasPort @@ -363,10 +370,12 @@ sprite: Structures/Piping/Atmospherics/vent.rsi layers: - sprite: Structures/Piping/Atmospherics/pipe.rsi - state: pipeStraight + state: pipeBinaryConnectors map: [ "enum.PipeVisualLayers.Pipe" ] - state: vent_off map: [ "enabled", "enum.SubfloorLayers.FirstLayer" ] + - type: AtmosPipeLayers + spriteRsiPaths: {} - type: GenericVisualizer visuals: enum.VentPumpVisuals.State: @@ -423,18 +432,24 @@ sprite: Structures/Machines/gasrecycler.rsi layers: - sprite: Structures/Piping/Atmospherics/pipe.rsi - state: pipeStraight + state: pipeBinaryConnectors map: [ "enum.PipeVisualLayers.Pipe" ] - state: running - state: unlit shader: unshaded + - type: AtmosPipeLayers + spriteLayersRsiPaths: + enum.PipeVisualLayers.Pipe: + Primary: Structures/Piping/Atmospherics/pipe.rsi + Secondary: Structures/Piping/Atmospherics/pipe_alt1.rsi + Tertiary: Structures/Piping/Atmospherics/pipe_alt2.rsi + - type: Appearance - type: GenericVisualizer visuals: enum.PumpVisuals.Enabled: enabled: True: { state: running } False: { state: unlit } - - type: Appearance - type: PipeColorVisuals - type: Rotatable - type: GasRecycler @@ -494,6 +509,9 @@ map: [ "enum.PipeVisualLayers.Pipe" ] - state: heStraight map: [ "enum.SubfloorLayers.FirstLayer" ] + - type: AtmosPipeLayers + spriteRsiPaths: {} + numberOfPipeLayers: 1 - type: SubFloorHide visibleLayers: - enum.SubfloorLayers.FirstLayer diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/gas_pipe_sensor.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/gas_pipe_sensor.yml index 57574f7f7d..c70b33639e 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/gas_pipe_sensor.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/gas_pipe_sensor.yml @@ -1,5 +1,5 @@ - type: entity - parent: [AirSensorBase, GasPipeBase] + parent: [AirSensorBase, GasBinaryBase] id: GasPipeSensor name: gas pipe sensor description: Reports on the status of the gas in the attached pipe network. @@ -18,6 +18,11 @@ - map: [ "enum.PowerDeviceVisualLayers.Powered" ] state: lights shader: unshaded + - type: AtmosPipeLayers + spriteRsiPaths: + Primary: Structures/Piping/Atmospherics/gas_pipe_sensor.rsi + Secondary: Structures/Piping/Atmospherics/gas_pipe_sensor_alt1.rsi + Tertiary: Structures/Piping/Atmospherics/gas_pipe_sensor_alt2.rsi - type: Appearance - type: GenericVisualizer visuals: diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml index 4d100d434e..6d9d596760 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/pipes.yml @@ -1,7 +1,7 @@ - type: entity abstract: true - id: GasPipeBase parent: BaseItem + id: GasPipeSansLayers name: gas pipe description: Holds gas. placement: @@ -18,7 +18,6 @@ damageModifierSet: Metallic - type: SubFloorHide - type: CollideOnAnchor - - type: PipeAppearance - type: Anchorable - type: Rotatable - type: Destructible @@ -51,6 +50,7 @@ drawdepth: ThinPipe visible: false - type: Appearance + - type: PipeAppearance - type: PipeColorVisuals - type: NodeContainer - type: PipeRestrictOverlap @@ -66,12 +66,26 @@ - type: StaticPrice price: 30 +- type: entity + abstract: true + parent: GasPipeSansLayers + id: GasPipeBase + components: + - type: AtmosPipeLayers + spriteLayersRsiPaths: + enum.PipeVisualLayers.Pipe: + Primary: Structures/Piping/Atmospherics/pipe.rsi + Secondary: Structures/Piping/Atmospherics/pipe_alt1.rsi + Tertiary: Structures/Piping/Atmospherics/pipe_alt2.rsi + #Note: The PipeDirection of the PipeNode should be the south-facing version, because the entity starts at an angle of 0 (south) - type: entity parent: GasPipeBase id: GasPipeHalf suffix: Half + placement: + mode: AlignAtmosPipeLayers components: - type: NodeContainer nodes: @@ -81,11 +95,21 @@ pipeDirection: South - type: Sprite layers: - - state: pipeHalf - map: [ "enum.PipeVisualLayers.Pipe" ] + - state: pipeHalf + map: [ "enum.PipeVisualLayers.Pipe" ] + - type: AtmosPipeLayers + alternativePrototypes: + Primary: GasPipeHalf + Secondary: GasPipeHalfAlt1 + Tertiary: GasPipeHalfAlt2 - type: Construction graph: GasPipe node: half + - type: Item + size: Small + storedSprite: + sprite: Structures/Piping/Atmospherics/pipe.rsi + state: storageHalf - type: GuideHelp guides: - Pipes @@ -95,6 +119,8 @@ parent: GasPipeBase id: GasPipeStraight suffix: Straight + placement: + mode: AlignAtmosPipeLayers components: - type: NodeContainer nodes: @@ -104,13 +130,17 @@ pipeDirection: Longitudinal - type: Sprite layers: - - state: pipeStraight - map: [ "enum.PipeVisualLayers.Pipe" ] + - state: pipeStraight + map: [ "enum.PipeVisualLayers.Pipe" ] + - type: AtmosPipeLayers + alternativePrototypes: + Primary: GasPipeStraight + Secondary: GasPipeStraightAlt1 + Tertiary: GasPipeStraightAlt2 - type: Construction graph: GasPipe node: straight - type: Item - size: Normal storedSprite: sprite: Structures/Piping/Atmospherics/pipe.rsi state: storageStraight @@ -132,6 +162,8 @@ parent: GasPipeBase id: GasPipeBend suffix: Bend + placement: + mode: AlignAtmosPipeLayers components: - type: NodeContainer nodes: @@ -143,11 +175,15 @@ layers: - state: pipeBend map: [ "enum.PipeVisualLayers.Pipe" ] + - type: AtmosPipeLayers + alternativePrototypes: + Primary: GasPipeBend + Secondary: GasPipeBendAlt1 + Tertiary: GasPipeBendAlt2 - type: Construction graph: GasPipe node: bend - type: Item - size: Small shape: - 0,0,1,0 - 1,1,1,1 @@ -175,6 +211,8 @@ - type: entity parent: GasPipeBase id: GasPipeTJunction + placement: + mode: AlignAtmosPipeLayers suffix: TJunction components: - type: NodeContainer @@ -187,14 +225,15 @@ layers: - state: pipeTJunction map: [ "enum.PipeVisualLayers.Pipe" ] + - type: AtmosPipeLayers + alternativePrototypes: + Primary: GasPipeTJunction + Secondary: GasPipeTJunctionAlt1 + Tertiary: GasPipeTJunctionAlt2 - type: Construction graph: GasPipe node: tjunction - type: Item - size: Normal - shape: - - 0,0,2,0 - - 1,1,1,1 heldPrefix: TJunction storedSprite: sprite: Structures/Piping/Atmospherics/pipe.rsi @@ -216,6 +255,8 @@ parent: GasPipeBase id: GasPipeFourway suffix: Fourway + placement: + mode: AlignAtmosPipeLayers components: - type: Transform noRot: true @@ -229,15 +270,19 @@ layers: - state: pipeFourway map: [ "enum.PipeVisualLayers.Pipe" ] + - type: AtmosPipeLayers + alternativePrototypes: + Primary: GasPipeFourway + Secondary: GasPipeFourwayAlt1 + Tertiary: GasPipeFourwayAlt2 - type: Construction graph: GasPipe node: fourway - type: Item - size: Normal - shape: - - 1,0,1,2 - - 0,1,2,1 heldPrefix: Fourway + storedSprite: + sprite: Structures/Piping/Atmospherics/pipe.rsi + state: storageFourway - type: MeleeWeapon wideAnimationRotation: 90 attackRate: 0.75 @@ -264,9 +309,13 @@ layers: - state: pipeBroken map: [ "enum.PipeVisualLayers.Pipe" ] + - type: AtmosPipeLayers + numberOfPipeLayers: 1 - type: Construction graph: GasPipe node: broken + - type: Item + size: Small - type: Destructible thresholds: # override parent to avoid recursive destruction - trigger: @@ -279,3 +328,74 @@ guides: - Pipes - PipeNetworks + +- type: entity + parent: GasPipeSansLayers + id: GasPipeManifold + name: gas pipe manifold + description: Allows gas pipes of different configurations to be connected together. + placement: + mode: SnapgridCenter + components: + - type: Sprite + sprite: Structures/Piping/Atmospherics/manifold.rsi + layers: + - state: pipeManifold + map: [ "enum.PipeVisualLayers.Pipe" ] + - type: AtmosPipeLayers + pipeLayersLocked: true + - type: PipeAppearance + sprite: + - { sprite: Structures/Piping/Atmospherics/manifold.rsi, state: pipeConnector } + - { sprite: Structures/Piping/Atmospherics/manifold.rsi, state: pipeConnector_alt1 } + - { sprite: Structures/Piping/Atmospherics/manifold.rsi, state: pipeConnector_alt2 } + - type: Construction + graph: GasPipe + node: manifold + - type: Item + size: Small + shape: + - 0,0,1,0 + storedSprite: + sprite: Structures/Piping/Atmospherics/manifold.rsi + state: storageManifold + - type: NodeContainer + nodes: + south0: + !type:PipeNode + nodeGroupID: Pipe + pipeDirection: South + pipeLayer: 0 + south1: + !type:PipeNode + nodeGroupID: Pipe + pipeDirection: South + pipeLayer: 1 + south2: + !type:PipeNode + nodeGroupID: Pipe + pipeDirection: South + pipeLayer: 2 + north0: + !type:PipeNode + nodeGroupID: Pipe + pipeDirection: North + pipeLayer: 0 + north1: + !type:PipeNode + nodeGroupID: Pipe + pipeDirection: North + pipeLayer: 1 + north2: + !type:PipeNode + nodeGroupID: Pipe + pipeDirection: North + pipeLayer: 2 + - type: GasPipeManifold + - type: AtmosMonitoringConsoleDevice + navMapBlip: GasPipeManifold + showAbsentConnections: false + - type: AtmosDevice + - type: Tag + tags: + - Unstackable diff --git a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml index abb0ead4a0..612e144e53 100644 --- a/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml +++ b/Resources/Prototypes/Entities/Structures/Piping/Atmospherics/unary.yml @@ -44,7 +44,7 @@ sprite: Structures/Piping/Atmospherics/vent.rsi layers: - sprite: Structures/Piping/Atmospherics/pipe.rsi - state: pipeHalf + state: pipeUnaryConnectors map: [ "enum.PipeVisualLayers.Pipe" ] - state: vent_off map: [ "enabled", "enum.SubfloorLayers.FirstLayer" ] @@ -94,7 +94,7 @@ sprite: Structures/Piping/Atmospherics/vent.rsi layers: - sprite: Structures/Piping/Atmospherics/pipe.rsi - state: pipeHalf + state: pipeUnaryConnectors map: [ "enum.PipeVisualLayers.Pipe" ] - state: vent_passive map: [ "enum.SubfloorLayers.FirstLayer" ] @@ -134,7 +134,7 @@ sprite: Structures/Piping/Atmospherics/scrubber.rsi layers: - sprite: Structures/Piping/Atmospherics/pipe.rsi - state: pipeHalf + state: pipeUnaryConnectors map: [ "enum.PipeVisualLayers.Pipe" ] - state: scrub_off map: [ "enabled", "enum.SubfloorLayers.FirstLayer" ] @@ -180,7 +180,7 @@ drawdepth: FloorObjects sprite: Structures/Piping/Atmospherics/outletinjector.rsi layers: - - state: pipeHalf + - state: pipeUnaryConnectors sprite: Structures/Piping/Atmospherics/pipe.rsi map: [ "enum.PipeVisualLayers.Pipe" ] - state: injector @@ -189,6 +189,7 @@ shader: unshaded map: [ "enum.LightLayers.Unshaded" ] color: "#990000" + - type: Appearance - type: GenericVisualizer visuals: # toggle color of the unshaded light: @@ -196,7 +197,6 @@ enum.LightLayers.Unshaded: True: { color: "#5eff5e" } False: { color: "#990000" } - - type: Appearance - type: PipeColorVisuals - type: GasOutletInjector - type: Construction @@ -228,6 +228,12 @@ - type: Rotatable - type: GasThermoMachine - type: AtmosPipeColor + - type: AtmosPipeLayers + spriteLayersRsiPaths: + enum.PipeVisualLayers.Pipe: + Primary: Structures/Piping/Atmospherics/thermomachine.rsi + Secondary: Structures/Piping/Atmospherics/thermomachine_alt1.rsi + Tertiary: Structures/Piping/Atmospherics/thermomachine_alt2.rsi - type: AtmosDevice - type: UserInterface interfaces: @@ -405,6 +411,7 @@ map: ["enum.SolutionContainerLayers.Fill"] visible: false - state: trans + - type: Appearance - type: GenericVisualizer visuals: enum.PowerDeviceVisuals.Powered: @@ -414,11 +421,16 @@ - type: SolutionContainerVisuals maxFillLevels: 7 fillBaseName: fill- - - type: Appearance - type: PipeColorVisuals - type: Rotatable - type: GasCondenser - type: AtmosPipeColor + - type: AtmosPipeLayers + spriteLayersRsiPaths: + enum.PipeVisualLayers.Pipe: + Primary: Structures/Piping/Atmospherics/condenser.rsi + Secondary: Structures/Piping/Atmospherics/condenser_alt1.rsi + Tertiary: Structures/Piping/Atmospherics/condenser_alt2.rsi - type: AtmosDevice - type: PipeRestrictOverlap - type: ApcPowerReceiver @@ -470,3 +482,4 @@ - type: GuideHelp guides: - GasCondensing + diff --git a/Resources/Prototypes/Recipes/Construction/Graphs/utilities/atmos_pipes.yml b/Resources/Prototypes/Recipes/Construction/Graphs/utilities/atmos_pipes.yml index 771c63ebd5..14d487fdb5 100644 --- a/Resources/Prototypes/Recipes/Construction/Graphs/utilities/atmos_pipes.yml +++ b/Resources/Prototypes/Recipes/Construction/Graphs/utilities/atmos_pipes.yml @@ -10,30 +10,96 @@ amount: 1 doAfter: 1 + - to: halfAlt1 + steps: + - material: Steel + amount: 1 + doAfter: 1 + + - to: halfAlt2 + steps: + - material: Steel + amount: 1 + doAfter: 1 + - to: straight steps: - material: Steel amount: 1 doAfter: 1 + - to: straightAlt1 + steps: + - material: Steel + amount: 1 + doAfter: 1 + + - to: straightAlt2 + steps: + - material: Steel + amount: 1 + doAfter: 1 + - to: bend steps: - material: Steel amount: 1 doAfter: 1 + - to: bendAlt1 + steps: + - material: Steel + amount: 1 + doAfter: 1 + + - to: bendAlt2 + steps: + - material: Steel + amount: 1 + doAfter: 1 + - to: tjunction steps: - material: Steel amount: 1 doAfter: 1 + - to: tjunctionAlt1 + steps: + - material: Steel + amount: 1 + doAfter: 1 + + - to: tjunctionAlt2 + steps: + - material: Steel + amount: 1 + doAfter: 1 + - to: fourway steps: - material: Steel amount: 1 doAfter: 1 + - to: fourwayAlt1 + steps: + - material: Steel + amount: 1 + doAfter: 1 + + - to: fourwayAlt2 + steps: + - material: Steel + amount: 1 + doAfter: 1 + + - to: manifold + steps: + - material: Steel + amount: 2 + doAfter: 1 + - node: half entity: GasPipeHalf edges: @@ -50,6 +116,38 @@ - tool: Welding doAfter: 1 + - node: halfAlt1 + entity: GasPipeHalfAlt1 + edges: + - to: start + conditions: + - !type:EntityAnchored + anchored: false + completed: + - !type:SpawnPrototype + prototype: SheetSteel1 + amount: 1 + - !type:DeleteEntity + steps: + - tool: Welding + doAfter: 1 + + - node: halfAlt2 + entity: GasPipeHalfAlt2 + edges: + - to: start + conditions: + - !type:EntityAnchored + anchored: false + completed: + - !type:SpawnPrototype + prototype: SheetSteel1 + amount: 1 + - !type:DeleteEntity + steps: + - tool: Welding + doAfter: 1 + - node: straight entity: GasPipeStraight edges: @@ -66,6 +164,38 @@ - tool: Welding doAfter: 1 + - node: straightAlt1 + entity: GasPipeStraightAlt1 + edges: + - to: start + conditions: + - !type:EntityAnchored + anchored: false + completed: + - !type:SpawnPrototype + prototype: SheetSteel1 + amount: 1 + - !type:DeleteEntity + steps: + - tool: Welding + doAfter: 1 + + - node: straightAlt2 + entity: GasPipeStraightAlt2 + edges: + - to: start + conditions: + - !type:EntityAnchored + anchored: false + completed: + - !type:SpawnPrototype + prototype: SheetSteel1 + amount: 1 + - !type:DeleteEntity + steps: + - tool: Welding + doAfter: 1 + - node: bend entity: GasPipeBend edges: @@ -82,6 +212,38 @@ - tool: Welding doAfter: 1 + - node: bendAlt1 + entity: GasPipeBendAlt1 + edges: + - to: start + conditions: + - !type:EntityAnchored + anchored: false + completed: + - !type:SpawnPrototype + prototype: SheetSteel1 + amount: 1 + - !type:DeleteEntity + steps: + - tool: Welding + doAfter: 1 + + - node: bendAlt2 + entity: GasPipeBendAlt2 + edges: + - to: start + conditions: + - !type:EntityAnchored + anchored: false + completed: + - !type:SpawnPrototype + prototype: SheetSteel1 + amount: 1 + - !type:DeleteEntity + steps: + - tool: Welding + doAfter: 1 + - node: tjunction entity: GasPipeTJunction edges: @@ -98,6 +260,38 @@ - tool: Welding doAfter: 1 + - node: tjunctionAlt1 + entity: GasPipeTJunctionAlt1 + edges: + - to: start + conditions: + - !type:EntityAnchored + anchored: false + completed: + - !type:SpawnPrototype + prototype: SheetSteel1 + amount: 1 + - !type:DeleteEntity + steps: + - tool: Welding + doAfter: 1 + + - node: tjunctionAlt2 + entity: GasPipeTJunctionAlt2 + edges: + - to: start + conditions: + - !type:EntityAnchored + anchored: false + completed: + - !type:SpawnPrototype + prototype: SheetSteel1 + amount: 1 + - !type:DeleteEntity + steps: + - tool: Welding + doAfter: 1 + - node: fourway entity: GasPipeFourway edges: @@ -114,6 +308,38 @@ - tool: Welding doAfter: 1 + - node: fourwayAlt1 + entity: GasPipeFourwayAlt1 + edges: + - to: start + conditions: + - !type:EntityAnchored + anchored: false + completed: + - !type:SpawnPrototype + prototype: SheetSteel1 + amount: 1 + - !type:DeleteEntity + steps: + - tool: Welding + doAfter: 1 + + - node: fourwayAlt2 + entity: GasPipeFourwayAlt2 + edges: + - to: start + conditions: + - !type:EntityAnchored + anchored: false + completed: + - !type:SpawnPrototype + prototype: SheetSteel1 + amount: 1 + - !type:DeleteEntity + steps: + - tool: Welding + doAfter: 1 + - node: broken entity: GasPipeBroken edges: @@ -129,3 +355,19 @@ steps: - tool: Welding doAfter: 1 + + - node: manifold + entity: GasPipeManifold + edges: + - to: start + conditions: + - !type:EntityAnchored + anchored: false + completed: + - !type:SpawnPrototype + prototype: SheetSteel1 + amount: 2 + - !type:DeleteEntity + steps: + - tool: Welding + doAfter: 1 diff --git a/Resources/Prototypes/Recipes/Construction/utilities.yml b/Resources/Prototypes/Recipes/Construction/utilities.yml index 575ca3ae4e..67389f85af 100644 --- a/Resources/Prototypes/Recipes/Construction/utilities.yml +++ b/Resources/Prototypes/Recipes/Construction/utilities.yml @@ -281,8 +281,40 @@ startNode: start targetNode: half category: construction-category-utilities - placementMode: SnapgridCenter + placementMode: AlignAtmosPipeLayers canBuildInImpassable: true + alternativePrototypes: + - GasPipeHalf + - GasPipeHalfAlt1 + - GasPipeHalfAlt2 + +- type: construction + id: GasPipeHalfAlt1 + hide: true + graph: GasPipe + startNode: start + targetNode: halfAlt1 + category: construction-category-utilities + placementMode: AlignAtmosPipeLayers + canBuildInImpassable: true + alternativePrototypes: + - GasPipeHalf + - GasPipeHalfAlt1 + - GasPipeHalfAlt2 + +- type: construction + id: GasPipeHalfAlt2 + hide: true + graph: GasPipe + startNode: start + targetNode: halfAlt2 + category: construction-category-utilities + placementMode: AlignAtmosPipeLayers + canBuildInImpassable: true + alternativePrototypes: + - GasPipeHalf + - GasPipeHalfAlt1 + - GasPipeHalfAlt2 - type: construction id: GasPipeStraight @@ -290,8 +322,40 @@ startNode: start targetNode: straight category: construction-category-utilities - placementMode: SnapgridCenter + placementMode: AlignAtmosPipeLayers canBuildInImpassable: true + alternativePrototypes: + - GasPipeStraight + - GasPipeStraightAlt1 + - GasPipeStraightAlt2 + +- type: construction + id: GasPipeStraightAlt1 + hide: true + graph: GasPipe + startNode: start + targetNode: straightAlt1 + category: construction-category-utilities + placementMode: AlignAtmosPipeLayers + canBuildInImpassable: true + alternativePrototypes: + - GasPipeStraight + - GasPipeStraightAlt1 + - GasPipeStraightAlt2 + +- type: construction + id: GasPipeStraightAlt2 + hide: true + graph: GasPipe + startNode: start + targetNode: straightAlt2 + category: construction-category-utilities + placementMode: AlignAtmosPipeLayers + canBuildInImpassable: true + alternativePrototypes: + - GasPipeStraight + - GasPipeStraightAlt1 + - GasPipeStraightAlt2 - type: construction id: GasPipeBend @@ -299,8 +363,40 @@ startNode: start targetNode: bend category: construction-category-utilities - placementMode: SnapgridCenter + placementMode: AlignAtmosPipeLayers canBuildInImpassable: true + alternativePrototypes: + - GasPipeBend + - GasPipeBendAlt1 + - GasPipeBendAlt2 + +- type: construction + id: GasPipeBendAlt1 + hide: true + graph: GasPipe + startNode: start + targetNode: bendAlt1 + category: construction-category-utilities + placementMode: AlignAtmosPipeLayers + canBuildInImpassable: true + alternativePrototypes: + - GasPipeBend + - GasPipeBendAlt1 + - GasPipeBendAlt2 + +- type: construction + id: GasPipeBendAlt2 + hide: true + graph: GasPipe + startNode: start + targetNode: bendAlt2 + category: construction-category-utilities + placementMode: AlignAtmosPipeLayers + canBuildInImpassable: true + alternativePrototypes: + - GasPipeBend + - GasPipeBendAlt1 + - GasPipeBendAlt2 - type: construction id: GasPipeTJunction @@ -308,8 +404,40 @@ startNode: start targetNode: tjunction category: construction-category-utilities - placementMode: SnapgridCenter + placementMode: AlignAtmosPipeLayers canBuildInImpassable: true + alternativePrototypes: + - GasPipeTJunction + - GasPipeTJunctionAlt1 + - GasPipeTJunctionAlt2 + +- type: construction + id: GasPipeTJunctionAlt1 + hide: true + graph: GasPipe + startNode: start + targetNode: tjunctionAlt1 + category: construction-category-utilities + placementMode: AlignAtmosPipeLayers + canBuildInImpassable: true + alternativePrototypes: + - GasPipeTJunction + - GasPipeTJunctionAlt1 + - GasPipeTJunctionAlt2 + +- type: construction + id: GasPipeTJunctionAlt2 + hide: true + graph: GasPipe + startNode: start + targetNode: tjunctionAlt2 + category: construction-category-utilities + placementMode: AlignAtmosPipeLayers + canBuildInImpassable: true + alternativePrototypes: + - GasPipeTJunction + - GasPipeTJunctionAlt1 + - GasPipeTJunctionAlt2 - type: construction id: GasPipeFourway @@ -317,6 +445,47 @@ startNode: start targetNode: fourway category: construction-category-utilities + placementMode: AlignAtmosPipeLayers + canBuildInImpassable: true + alternativePrototypes: + - GasPipeFourway + - GasPipeFourwayAlt1 + - GasPipeFourwayAlt2 + +- type: construction + id: GasPipeFourwayAlt1 + hide: true + graph: GasPipe + startNode: start + targetNode: fourwayAlt1 + category: construction-category-utilities + placementMode: AlignAtmosPipeLayers + canBuildInImpassable: true + alternativePrototypes: + - GasPipeFourway + - GasPipeFourwayAlt1 + - GasPipeFourwayAlt2 + +- type: construction + id: GasPipeFourwayAlt2 + hide: true + graph: GasPipe + startNode: start + targetNode: fourwayAlt2 + category: construction-category-utilities + placementMode: AlignAtmosPipeLayers + canBuildInImpassable: true + alternativePrototypes: + - GasPipeFourway + - GasPipeFourwayAlt1 + - GasPipeFourwayAlt2 + +- type: construction + id: GasPipeManifold + graph: GasPipe + startNode: start + targetNode: manifold + category: construction-category-utilities placementMode: SnapgridCenter canBuildInImpassable: true diff --git a/Resources/Textures/Interface/NavMap/attributions.yml b/Resources/Textures/Interface/NavMap/attributions.yml index f624c0f448..344b871ae9 100644 --- a/Resources/Textures/Interface/NavMap/attributions.yml +++ b/Resources/Textures/Interface/NavMap/attributions.yml @@ -43,6 +43,16 @@ copyright: "Created by chromiumboy" source: "https://github.com/chromiumboy" +- files: ["beveled_rectangle_east_west.png"] + license: "CC-BY-SA-3.0" + copyright: "Created by chromiumboy" + source: "https://github.com/chromiumboy" + +- files: ["beveled_rectangle_north_south.png"] + license: "CC-BY-SA-3.0" + copyright: "Created by chromiumboy" + source: "https://github.com/chromiumboy" + - files: ["beveled_square.png"] license: "CC-BY-SA-3.0" copyright: "Created by chromiumboy" diff --git a/Resources/Textures/Interface/NavMap/beveled_rectangle_east_west.png b/Resources/Textures/Interface/NavMap/beveled_rectangle_east_west.png new file mode 100644 index 0000000000..9a972cb939 Binary files /dev/null and b/Resources/Textures/Interface/NavMap/beveled_rectangle_east_west.png differ diff --git a/Resources/Textures/Interface/NavMap/beveled_rectangle_east_west.png.yml b/Resources/Textures/Interface/NavMap/beveled_rectangle_east_west.png.yml new file mode 100644 index 0000000000..dabd6601f7 --- /dev/null +++ b/Resources/Textures/Interface/NavMap/beveled_rectangle_east_west.png.yml @@ -0,0 +1,2 @@ +sample: + filter: true diff --git a/Resources/Textures/Interface/NavMap/beveled_rectangle_north_south.png b/Resources/Textures/Interface/NavMap/beveled_rectangle_north_south.png new file mode 100644 index 0000000000..a2a870381d Binary files /dev/null and b/Resources/Textures/Interface/NavMap/beveled_rectangle_north_south.png differ diff --git a/Resources/Textures/Interface/NavMap/beveled_rectangle_north_south.png.yml b/Resources/Textures/Interface/NavMap/beveled_rectangle_north_south.png.yml new file mode 100644 index 0000000000..dabd6601f7 --- /dev/null +++ b/Resources/Textures/Interface/NavMap/beveled_rectangle_north_south.png.yml @@ -0,0 +1,2 @@ +sample: + filter: true diff --git a/Resources/Textures/Interface/VerbIcons/ATTRIBUTION.txt b/Resources/Textures/Interface/VerbIcons/ATTRIBUTION.txt index bb584a7c20..ee497a1c04 100644 --- a/Resources/Textures/Interface/VerbIcons/ATTRIBUTION.txt +++ b/Resources/Textures/Interface/VerbIcons/ATTRIBUTION.txt @@ -10,3 +10,6 @@ https://game-icons.net/1x1/delapouite/padlock-open.html bubbles.svg by Lorc under CC BY 3.0 https://game-icons.net/1x1/lorc/bubbles.html + +screwdriver.png by Lorc (edited by chromiumboy) under CC BY 3.0 +https://game-icons.net/1x1/lorc/screwdriver.html diff --git a/Resources/Textures/Interface/VerbIcons/screwdriver.png b/Resources/Textures/Interface/VerbIcons/screwdriver.png new file mode 100644 index 0000000000..e230262fe0 Binary files /dev/null and b/Resources/Textures/Interface/VerbIcons/screwdriver.png differ diff --git a/Resources/Textures/Interface/VerbIcons/screwdriver.png.yml b/Resources/Textures/Interface/VerbIcons/screwdriver.png.yml new file mode 100644 index 0000000000..5c43e23305 --- /dev/null +++ b/Resources/Textures/Interface/VerbIcons/screwdriver.png.yml @@ -0,0 +1,2 @@ +sample: + filter: true diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/meta.json index 05a1e617a5..0ad29bf3a8 100644 --- a/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/meta.json +++ b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/meta.json @@ -1,21 +1,18 @@ { - "version":1, - "size": - { - "x":32, - "y":32 + "version": 1, + "size": { + "x": 32, + "y": 32 }, - "copyright":"Created by EmoGarbage404 (github) for Space Station 14.", - "license":"CC0-1.0", - "states": - [ + "copyright": "Created by EmoGarbage404 (github) for Space Station 14, edited by chromiumboy.", + "license": "CC0-1.0", + "states": [ { - "name":"off" + "name": "off" }, { - "name":"on", - "delays": - [ + "name": "on", + "delays": [ [ 0.05, 0.05, @@ -26,38 +23,38 @@ ] }, { - "name":"panel" + "name": "panel" }, { - "name":"trans" + "name": "trans" }, { - "name":"pipe", - "directions":4 + "name": "pipe", + "directions": 4 }, { - "name":"display" + "name": "display" }, { - "name":"fill-1" + "name": "fill-1" }, { - "name":"fill-2" + "name": "fill-2" }, { - "name":"fill-3" + "name": "fill-3" }, { - "name":"fill-4" + "name": "fill-4" }, { - "name":"fill-5" + "name": "fill-5" }, { - "name":"fill-6" + "name": "fill-6" }, { - "name":"fill-7" + "name": "fill-7" } ] } diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/pipe.png b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/pipe.png index c9fbbec300..694a3a15b6 100644 Binary files a/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/pipe.png and b/Resources/Textures/Structures/Piping/Atmospherics/condenser.rsi/pipe.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser_alt1.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/condenser_alt1.rsi/meta.json new file mode 100644 index 0000000000..3176fce2dc --- /dev/null +++ b/Resources/Textures/Structures/Piping/Atmospherics/condenser_alt1.rsi/meta.json @@ -0,0 +1,15 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "copyright": "Created by EmoGarbage404 (github) for Space Station 14, edited by chromiumboy.", + "license": "CC0-1.0", + "states": [ + { + "name": "pipe", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser_alt1.rsi/pipe.png b/Resources/Textures/Structures/Piping/Atmospherics/condenser_alt1.rsi/pipe.png new file mode 100644 index 0000000000..e5ae1993fe Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/condenser_alt1.rsi/pipe.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser_alt2.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/condenser_alt2.rsi/meta.json new file mode 100644 index 0000000000..3176fce2dc --- /dev/null +++ b/Resources/Textures/Structures/Piping/Atmospherics/condenser_alt2.rsi/meta.json @@ -0,0 +1,15 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "copyright": "Created by EmoGarbage404 (github) for Space Station 14, edited by chromiumboy.", + "license": "CC0-1.0", + "states": [ + { + "name": "pipe", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Structures/Piping/Atmospherics/condenser_alt2.rsi/pipe.png b/Resources/Textures/Structures/Piping/Atmospherics/condenser_alt2.rsi/pipe.png new file mode 100644 index 0000000000..4ac647a2ad Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/condenser_alt2.rsi/pipe.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/base.png b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/base.png index 4a9a8f6f20..5858ec39fb 100644 Binary files a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/base.png and b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/base.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/lights.png b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/lights.png index 6108d2b994..f294bc3fce 100644 Binary files a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/lights.png and b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/lights.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/meta.json index 878c7817a2..bfe74c313c 100644 --- a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/meta.json +++ b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor.rsi/meta.json @@ -10,15 +10,29 @@ { "name": "icon" }, - { - "name": "base" + { + "name": "base", + "directions": 4 }, - { + { "name": "blank" }, { "name": "lights", + "directions": 4, "delays": [ + [ + 1.0, + 0.25 + ], + [ + 1.0, + 0.25 + ], + [ + 1.0, + 0.25 + ], [ 1.0, 0.25 diff --git a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt1.rsi/base.png b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt1.rsi/base.png new file mode 100644 index 0000000000..0afdd9f846 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt1.rsi/base.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt1.rsi/blank.png b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt1.rsi/blank.png new file mode 100644 index 0000000000..7bee0a002b Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt1.rsi/blank.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt1.rsi/icon.png b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt1.rsi/icon.png new file mode 100644 index 0000000000..4ac9e76480 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt1.rsi/icon.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt1.rsi/lights.png b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt1.rsi/lights.png new file mode 100644 index 0000000000..45d84c3d5c Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt1.rsi/lights.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt1.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt1.rsi/meta.json new file mode 100644 index 0000000000..bfe74c313c --- /dev/null +++ b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt1.rsi/meta.json @@ -0,0 +1,43 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Created by chromiumboy (github) for SS14, based on the digital valve from /tg/, taken from https://github.com/tgstation/tgstation at commit 57cd1d59ca019dd0e7811ac451f295f818e573da.", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "base", + "directions": 4 + }, + { + "name": "blank" + }, + { + "name": "lights", + "directions": 4, + "delays": [ + [ + 1.0, + 0.25 + ], + [ + 1.0, + 0.25 + ], + [ + 1.0, + 0.25 + ], + [ + 1.0, + 0.25 + ] + ] + } + ] +} diff --git a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt2.rsi/base.png b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt2.rsi/base.png new file mode 100644 index 0000000000..131d75e9d2 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt2.rsi/base.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt2.rsi/blank.png b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt2.rsi/blank.png new file mode 100644 index 0000000000..7bee0a002b Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt2.rsi/blank.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt2.rsi/icon.png b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt2.rsi/icon.png new file mode 100644 index 0000000000..4ac9e76480 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt2.rsi/icon.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt2.rsi/lights.png b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt2.rsi/lights.png new file mode 100644 index 0000000000..826c90d5a0 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt2.rsi/lights.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt2.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt2.rsi/meta.json new file mode 100644 index 0000000000..bfe74c313c --- /dev/null +++ b/Resources/Textures/Structures/Piping/Atmospherics/gas_pipe_sensor_alt2.rsi/meta.json @@ -0,0 +1,43 @@ +{ + "version": 1, + "license": "CC-BY-SA-3.0", + "copyright": "Created by chromiumboy (github) for SS14, based on the digital valve from /tg/, taken from https://github.com/tgstation/tgstation at commit 57cd1d59ca019dd0e7811ac451f295f818e573da.", + "size": { + "x": 32, + "y": 32 + }, + "states": [ + { + "name": "icon" + }, + { + "name": "base", + "directions": 4 + }, + { + "name": "blank" + }, + { + "name": "lights", + "directions": 4, + "delays": [ + [ + 1.0, + 0.25 + ], + [ + 1.0, + 0.25 + ], + [ + 1.0, + 0.25 + ], + [ + 1.0, + 0.25 + ] + ] + } + ] +} diff --git a/Resources/Textures/Structures/Piping/Atmospherics/hellfirethermomachine.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/hellfirethermomachine.rsi/meta.json index 979d804fb4..f216c2f60d 100644 --- a/Resources/Textures/Structures/Piping/Atmospherics/hellfirethermomachine.rsi/meta.json +++ b/Resources/Textures/Structures/Piping/Atmospherics/hellfirethermomachine.rsi/meta.json @@ -1,38 +1,67 @@ { - "version":1, - "size":{"x":32,"y":32}, - "copyright":"Base sprites taken from tgstation, split to display on two layers (machinebody/panel) by Menshin, and recolored and edited by EmoGarbage404 (github)", - "license":"CC-BY-SA-3.0", - "states":[ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "copyright": "Base sprites taken from tgstation, split to display on two layers (machinebody/panel) by Menshin, and recolored and edited by EmoGarbage404 (github) and chromiumboy (github)", + "license": "CC-BY-SA-3.0", + "states": [ { - "name":"freezerOff", - "directions":1 + "name": "freezerOff", + "directions": 1 }, { - "name":"freezerPanelOpen", - "directions":1 + "name": "freezerPanelOpen", + "directions": 1 }, { - "name":"freezerOn", - "directions":1, - "delays":[ [ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1] ] + "name": "freezerOn", + "directions": 1, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] }, { - "name":"heaterOff", - "directions":1 + "name": "heaterOff", + "directions": 1 }, { - "name":"heaterPanelOpen", - "directions":1 + "name": "heaterPanelOpen", + "directions": 1 }, { - "name":"heaterOn", - "directions":1, - "delays":[ [ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1] ] + "name": "heaterOn", + "directions": 1, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] }, { - "name":"pipe", - "directions":4 + "name": "pipe", + "directions": 4 } ] } diff --git a/Resources/Textures/Structures/Piping/Atmospherics/hellfirethermomachine.rsi/pipe.png b/Resources/Textures/Structures/Piping/Atmospherics/hellfirethermomachine.rsi/pipe.png index 620ba905be..e0209a7bc8 100644 Binary files a/Resources/Textures/Structures/Piping/Atmospherics/hellfirethermomachine.rsi/pipe.png and b/Resources/Textures/Structures/Piping/Atmospherics/hellfirethermomachine.rsi/pipe.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/manifold.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/manifold.rsi/meta.json new file mode 100644 index 0000000000..315063828b --- /dev/null +++ b/Resources/Textures/Structures/Piping/Atmospherics/manifold.rsi/meta.json @@ -0,0 +1,30 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "copyright": "Base sprites taken from tgstation at https://github.com/tgstation/tgstation/commit/662c08272acd7be79531550919f56f846726eabb and edited by chromiumboy (github)", + "license": "CC-BY-SA-3.0", + "states": [ + { + "name": "pipeManifold", + "directions": 4 + }, + { + "name": "storageManifold" + }, + { + "name": "pipeConnector", + "directions": 4 + }, + { + "name": "pipeConnector_alt1", + "directions": 4 + }, + { + "name": "pipeConnector_alt2", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Structures/Piping/Atmospherics/manifold.rsi/pipeConnector.png b/Resources/Textures/Structures/Piping/Atmospherics/manifold.rsi/pipeConnector.png new file mode 100644 index 0000000000..25e7906af1 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/manifold.rsi/pipeConnector.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/manifold.rsi/pipeConnector_alt1.png b/Resources/Textures/Structures/Piping/Atmospherics/manifold.rsi/pipeConnector_alt1.png new file mode 100644 index 0000000000..3f4debb814 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/manifold.rsi/pipeConnector_alt1.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/manifold.rsi/pipeConnector_alt2.png b/Resources/Textures/Structures/Piping/Atmospherics/manifold.rsi/pipeConnector_alt2.png new file mode 100644 index 0000000000..f64fc34cd3 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/manifold.rsi/pipeConnector_alt2.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/manifold.rsi/pipeManifold.png b/Resources/Textures/Structures/Piping/Atmospherics/manifold.rsi/pipeManifold.png new file mode 100644 index 0000000000..f81fbdc29c Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/manifold.rsi/pipeManifold.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/manifold.rsi/storageManifold.png b/Resources/Textures/Structures/Piping/Atmospherics/manifold.rsi/storageManifold.png new file mode 100644 index 0000000000..a9d3b0da05 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/manifold.rsi/storageManifold.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/meta.json index aecb62aee5..82106dbfe6 100644 --- a/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/meta.json +++ b/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/meta.json @@ -1,87 +1,98 @@ { - "version":1, - "size":{ - "x":32, - "y":32 - }, - "license":"CC-BY-SA-3.0", - "copyright":"Inhand sprites by alzore_(discord) for SS14. pipeTrinaryConnectors made by Menshin for SS14 based on pipeTJunction, the rest is taken from https://github.com/tgstation/tgstation at commit 57cd1d59ca019dd0e7811ac451f295f818e573da.", - "states":[ - { - "name": "inhand-left", - "directions":4 - }, - { - "name":"inhand-right", - "directions":4 - }, - { - "name": "Bend-inhand-left", - "directions":4 - }, - { - "name":"Bend-inhand-right", - "directions":4 - }, - { - "name": "TJunction-inhand-left", - "directions":4 - }, - { - "name":"TJunction-inhand-right", - "directions":4 - }, - { - "name": "Fourway-inhand-left", - "directions":4 - }, - { - "name":"Fourway-inhand-right", - "directions":4 - }, - { - "name":"pipeBroken", - "directions":1 - }, - { - "name":"pipeTJunction", - "directions":4 - }, - { - "name":"pipeHalf", - "directions":4 - }, - { - "name":"pipeBend", - "directions":4 - }, - { - "name": "pipeFourway", - "directions":4 - }, - { - "name":"pipeStraight", - "directions":4 - }, - { - "name":"pipeConnector", - "directions":4 - }, - { - "name":"pipeTrinaryConnectors", - "directions":4 - }, - { - "name":"storageStraight", - "directions":4 - }, - { - "name":"storageBend", - "directions":4 - }, - { - "name":"storageTJunction", - "directions":4 - } - ] + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Inhand sprites by alzore_(discord) for SS14. pipeTrinaryConnectors made by Menshin for SS14 based on pipeTJunction, the rest is taken from https://github.com/tgstation/tgstation at commit 57cd1d59ca019dd0e7811ac451f295f818e573da, edited by chromiumboy.", + "states": [ + { + "name": "inhand-left", + "directions": 4 + }, + { + "name": "inhand-right", + "directions": 4 + }, + { + "name": "Bend-inhand-left", + "directions": 4 + }, + { + "name": "Bend-inhand-right", + "directions": 4 + }, + { + "name": "TJunction-inhand-left", + "directions": 4 + }, + { + "name": "TJunction-inhand-right", + "directions": 4 + }, + { + "name": "Fourway-inhand-left", + "directions": 4 + }, + { + "name": "Fourway-inhand-right", + "directions": 4 + }, + { + "name": "pipeBroken", + "directions": 1 + }, + { + "name": "pipeTJunction", + "directions": 4 + }, + { + "name": "pipeHalf", + "directions": 4 + }, + { + "name": "pipeBend", + "directions": 4 + }, + { + "name": "pipeFourway", + "directions": 4 + }, + { + "name": "pipeStraight", + "directions": 4 + }, + { + "name": "pipeConnector", + "directions": 4 + }, + { + "name": "pipeUnaryConnectors", + "directions": 4 + }, + { + "name": "pipeBinaryConnectors", + "directions": 4 + }, + { + "name": "pipeTrinaryConnectors", + "directions": 4 + }, + { + "name": "storageStraight" + }, + { + "name": "storageHalf" + }, + { + "name": "storageBend" + }, + { + "name": "storageTJunction" + }, + { + "name": "storageFourway" + } + ] } diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/pipeBinaryConnectors.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/pipeBinaryConnectors.png new file mode 100644 index 0000000000..a2fb4b7ff8 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/pipeBinaryConnectors.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/pipeUnaryConnectors.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/pipeUnaryConnectors.png new file mode 100644 index 0000000000..a4e2286277 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/pipeUnaryConnectors.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/storageBend.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/storageBend.png index 39ffe213ef..003a49eaec 100644 Binary files a/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/storageBend.png and b/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/storageBend.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/storageFourway.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/storageFourway.png new file mode 100644 index 0000000000..911c0da5f6 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/storageFourway.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/storageHalf.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/storageHalf.png new file mode 100644 index 0000000000..5eba5e5e30 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/storageHalf.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/storageStraight.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/storageStraight.png index 715aeb5824..2805fe6626 100644 Binary files a/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/storageStraight.png and b/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/storageStraight.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/storageTJunction.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/storageTJunction.png index af8376a152..92b5d5a006 100644 Binary files a/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/storageTJunction.png and b/Resources/Textures/Structures/Piping/Atmospherics/pipe.rsi/storageTJunction.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/meta.json new file mode 100644 index 0000000000..31825d6fe5 --- /dev/null +++ b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/meta.json @@ -0,0 +1,51 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Inhand sprites by alzore_(discord) for SS14. pipeTrinaryConnectors made by Menshin for SS14 based on pipeTJunction, the rest is taken from https://github.com/tgstation/tgstation at commit 57cd1d59ca019dd0e7811ac451f295f818e573da, edited by chromiumboy.", + "states": [ + { + "name": "pipeBroken", + "directions": 1 + }, + { + "name": "pipeTJunction", + "directions": 4 + }, + { + "name": "pipeHalf", + "directions": 4 + }, + { + "name": "pipeBend", + "directions": 4 + }, + { + "name": "pipeFourway", + "directions": 4 + }, + { + "name": "pipeStraight", + "directions": 4 + }, + { + "name": "pipeConnector", + "directions": 4 + }, + { + "name": "pipeUnaryConnectors", + "directions": 4 + }, + { + "name": "pipeBinaryConnectors", + "directions": 4 + }, + { + "name": "pipeTrinaryConnectors", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeBend.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeBend.png new file mode 100644 index 0000000000..42fddaa1fd Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeBend.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeBinaryConnectors.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeBinaryConnectors.png new file mode 100644 index 0000000000..e2eccac093 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeBinaryConnectors.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeBroken.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeBroken.png new file mode 100644 index 0000000000..8a54fed66d Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeBroken.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeConnector.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeConnector.png new file mode 100644 index 0000000000..a464bcf59a Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeConnector.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeFourway.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeFourway.png new file mode 100644 index 0000000000..e9508bbcf4 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeFourway.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeHalf.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeHalf.png new file mode 100644 index 0000000000..c02216202e Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeHalf.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeStraight.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeStraight.png new file mode 100644 index 0000000000..d0b0105dc5 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeStraight.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeTJunction.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeTJunction.png new file mode 100644 index 0000000000..06b945f1c5 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeTJunction.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeTrinaryConnectors.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeTrinaryConnectors.png new file mode 100644 index 0000000000..f2dd866fbb Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeTrinaryConnectors.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeUnaryConnectors.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeUnaryConnectors.png new file mode 100644 index 0000000000..a1a79e3096 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt1.rsi/pipeUnaryConnectors.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/meta.json new file mode 100644 index 0000000000..31825d6fe5 --- /dev/null +++ b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/meta.json @@ -0,0 +1,51 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Inhand sprites by alzore_(discord) for SS14. pipeTrinaryConnectors made by Menshin for SS14 based on pipeTJunction, the rest is taken from https://github.com/tgstation/tgstation at commit 57cd1d59ca019dd0e7811ac451f295f818e573da, edited by chromiumboy.", + "states": [ + { + "name": "pipeBroken", + "directions": 1 + }, + { + "name": "pipeTJunction", + "directions": 4 + }, + { + "name": "pipeHalf", + "directions": 4 + }, + { + "name": "pipeBend", + "directions": 4 + }, + { + "name": "pipeFourway", + "directions": 4 + }, + { + "name": "pipeStraight", + "directions": 4 + }, + { + "name": "pipeConnector", + "directions": 4 + }, + { + "name": "pipeUnaryConnectors", + "directions": 4 + }, + { + "name": "pipeBinaryConnectors", + "directions": 4 + }, + { + "name": "pipeTrinaryConnectors", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeBend.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeBend.png new file mode 100644 index 0000000000..fc371f495c Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeBend.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeBinaryConnectors.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeBinaryConnectors.png new file mode 100644 index 0000000000..3573b28923 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeBinaryConnectors.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeBroken.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeBroken.png new file mode 100644 index 0000000000..8a54fed66d Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeBroken.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeConnector.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeConnector.png new file mode 100644 index 0000000000..5310c113da Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeConnector.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeFourway.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeFourway.png new file mode 100644 index 0000000000..f879717da3 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeFourway.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeHalf.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeHalf.png new file mode 100644 index 0000000000..227a31c2b0 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeHalf.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeStraight.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeStraight.png new file mode 100644 index 0000000000..5fb9c344f3 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeStraight.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeTJunction.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeTJunction.png new file mode 100644 index 0000000000..6ff306dc02 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeTJunction.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeTrinaryConnectors.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeTrinaryConnectors.png new file mode 100644 index 0000000000..4049d71d46 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeTrinaryConnectors.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeUnaryConnectors.png b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeUnaryConnectors.png new file mode 100644 index 0000000000..8eb130bbed Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pipe_alt2.rsi/pipeUnaryConnectors.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/meta.json new file mode 100644 index 0000000000..ef75896795 --- /dev/null +++ b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/meta.json @@ -0,0 +1,157 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from https://github.com/tgstation/tgstation at commit 57cd1d59ca019dd0e7811ac451f295f818e573da. Signal valve is a digital valve modified by deltanedas. Manual valve modified by Deerstop at https://github.com/space-wizards/space-station-14/pull/34378. Modified by chromiumboy.", + "states": [ + { + "name": "pumpDigitalValve", + "directions": 4 + }, + { + "name": "pumpManualValve", + "directions": 4 + }, + { + "name": "pumpManualValveOn", + "directions": 4 + }, + { + "name": "pumpSignalValve", + "directions": 4 + }, + { + "name": "pumpSignalValveOn", + "directions": 4 + }, + { + "name": "pumpPassiveGate", + "directions": 4 + }, + { + "name": "pumpPassiveGateOn", + "directions": 4 + }, + { + "name": "pumpPressure", + "directions": 4 + }, + { + "name": "pumpPressureOn", + "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": "pumpVolume", + "directions": 4 + }, + { + "name": "pumpVolumeOn", + "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 + ], + [ + 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": "pumpVolumeBlocked", + "directions": 4, + "delays": [ + [ + 1.0, + 1.0 + ], + [ + 1.0, + 1.0 + ], + [ + 1.0, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + ] +} diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpDigitalValve.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpDigitalValve.png new file mode 100644 index 0000000000..ec8e261f2b Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpDigitalValve.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpManualValve.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpManualValve.png new file mode 100644 index 0000000000..2bae097010 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpManualValve.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpManualValveOn.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpManualValveOn.png new file mode 100644 index 0000000000..f889124d18 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpManualValveOn.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpPassiveGate.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpPassiveGate.png new file mode 100644 index 0000000000..0d205491ec Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpPassiveGate.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpPassiveGateOn.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpPassiveGateOn.png new file mode 100644 index 0000000000..e899d0ed0c Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpPassiveGateOn.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpPressure.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpPressure.png new file mode 100644 index 0000000000..3a634fc929 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpPressure.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpPressureOn.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpPressureOn.png new file mode 100644 index 0000000000..117ff9c8fb Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpPressureOn.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpSignalValve.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpSignalValve.png new file mode 100644 index 0000000000..53656aafaf Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpSignalValve.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpSignalValveOn.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpSignalValveOn.png new file mode 100644 index 0000000000..a2549e268c Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpSignalValveOn.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpVolume.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpVolume.png new file mode 100644 index 0000000000..55708b37dd Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpVolume.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpVolumeBlocked.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpVolumeBlocked.png new file mode 100644 index 0000000000..bf41bf2adb Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpVolumeBlocked.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpVolumeOn.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpVolumeOn.png new file mode 100644 index 0000000000..6a5efbff37 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt1.rsi/pumpVolumeOn.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/meta.json new file mode 100644 index 0000000000..ef75896795 --- /dev/null +++ b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/meta.json @@ -0,0 +1,157 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA-3.0", + "copyright": "Taken from https://github.com/tgstation/tgstation at commit 57cd1d59ca019dd0e7811ac451f295f818e573da. Signal valve is a digital valve modified by deltanedas. Manual valve modified by Deerstop at https://github.com/space-wizards/space-station-14/pull/34378. Modified by chromiumboy.", + "states": [ + { + "name": "pumpDigitalValve", + "directions": 4 + }, + { + "name": "pumpManualValve", + "directions": 4 + }, + { + "name": "pumpManualValveOn", + "directions": 4 + }, + { + "name": "pumpSignalValve", + "directions": 4 + }, + { + "name": "pumpSignalValveOn", + "directions": 4 + }, + { + "name": "pumpPassiveGate", + "directions": 4 + }, + { + "name": "pumpPassiveGateOn", + "directions": 4 + }, + { + "name": "pumpPressure", + "directions": 4 + }, + { + "name": "pumpPressureOn", + "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": "pumpVolume", + "directions": 4 + }, + { + "name": "pumpVolumeOn", + "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 + ], + [ + 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": "pumpVolumeBlocked", + "directions": 4, + "delays": [ + [ + 1.0, + 1.0 + ], + [ + 1.0, + 1.0 + ], + [ + 1.0, + 1.0 + ], + [ + 1.0, + 1.0 + ] + ] + } + ] +} diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpDigitalValve.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpDigitalValve.png new file mode 100644 index 0000000000..4b43b4304e Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpDigitalValve.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpManualValve.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpManualValve.png new file mode 100644 index 0000000000..c83d71fb70 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpManualValve.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpManualValveOn.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpManualValveOn.png new file mode 100644 index 0000000000..2adedbc95f Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpManualValveOn.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpPassiveGate.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpPassiveGate.png new file mode 100644 index 0000000000..668c626712 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpPassiveGate.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpPassiveGateOn.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpPassiveGateOn.png new file mode 100644 index 0000000000..38ff9270e7 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpPassiveGateOn.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpPressure.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpPressure.png new file mode 100644 index 0000000000..cb5286e46c Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpPressure.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpPressureOn.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpPressureOn.png new file mode 100644 index 0000000000..114ed9a627 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpPressureOn.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpSignalValve.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpSignalValve.png new file mode 100644 index 0000000000..ba0a3ed350 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpSignalValve.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpSignalValveOn.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpSignalValveOn.png new file mode 100644 index 0000000000..181c6f2ace Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpSignalValveOn.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpVolume.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpVolume.png new file mode 100644 index 0000000000..0e9f52f6e6 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpVolume.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpVolumeBlocked.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpVolumeBlocked.png new file mode 100644 index 0000000000..0d267ff178 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpVolumeBlocked.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpVolumeOn.png b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpVolumeOn.png new file mode 100644 index 0000000000..85e33e7b7b Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/pump_alt2.rsi/pumpVolumeOn.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/thermomachine.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/thermomachine.rsi/meta.json index 4cbb72e1ac..3ba53e431c 100644 --- a/Resources/Textures/Structures/Piping/Atmospherics/thermomachine.rsi/meta.json +++ b/Resources/Textures/Structures/Piping/Atmospherics/thermomachine.rsi/meta.json @@ -1,38 +1,67 @@ { - "version":1, - "size":{"x":32,"y":32}, - "copyright":"Base sprites taken from tgstation, splitted to display on two layers (machinebody/panel) by Menshin, for SS14", - "license":"CC-BY-SA-3.0", - "states":[ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "copyright": "Base sprites taken from tgstation, splitted to display on two layers (machinebody/panel) by Menshin, for SS14, edited by chromiumboy", + "license": "CC-BY-SA-3.0", + "states": [ { - "name":"freezerOff", - "directions":1 + "name": "freezerOff", + "directions": 1 }, { - "name":"freezerPanelOpen", - "directions":1 + "name": "freezerPanelOpen", + "directions": 1 }, { - "name":"freezerOn", - "directions":1, - "delays":[ [ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1] ] + "name": "freezerOn", + "directions": 1, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] }, { - "name":"heaterOff", - "directions":1 + "name": "heaterOff", + "directions": 1 }, { - "name":"heaterPanelOpen", - "directions":1 + "name": "heaterPanelOpen", + "directions": 1 }, { - "name":"heaterOn", - "directions":1, - "delays":[ [ 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1] ] + "name": "heaterOn", + "directions": 1, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] }, { - "name":"pipe", - "directions":4 + "name": "pipe", + "directions": 4 } ] -} \ No newline at end of file +} diff --git a/Resources/Textures/Structures/Piping/Atmospherics/thermomachine.rsi/pipe.png b/Resources/Textures/Structures/Piping/Atmospherics/thermomachine.rsi/pipe.png index 620ba905be..e0209a7bc8 100644 Binary files a/Resources/Textures/Structures/Piping/Atmospherics/thermomachine.rsi/pipe.png and b/Resources/Textures/Structures/Piping/Atmospherics/thermomachine.rsi/pipe.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/thermomachine_alt1.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/thermomachine_alt1.rsi/meta.json new file mode 100644 index 0000000000..f8a645528c --- /dev/null +++ b/Resources/Textures/Structures/Piping/Atmospherics/thermomachine_alt1.rsi/meta.json @@ -0,0 +1,15 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "copyright": "Base sprites taken from tgstation, splitted to display on two layers (machinebody/panel) by Menshin, for SS14, edited by chromiumboy", + "license": "CC-BY-SA-3.0", + "states": [ + { + "name": "pipe", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Structures/Piping/Atmospherics/thermomachine_alt1.rsi/pipe.png b/Resources/Textures/Structures/Piping/Atmospherics/thermomachine_alt1.rsi/pipe.png new file mode 100644 index 0000000000..cb6fc36c97 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/thermomachine_alt1.rsi/pipe.png differ diff --git a/Resources/Textures/Structures/Piping/Atmospherics/thermomachine_alt2.rsi/meta.json b/Resources/Textures/Structures/Piping/Atmospherics/thermomachine_alt2.rsi/meta.json new file mode 100644 index 0000000000..f8a645528c --- /dev/null +++ b/Resources/Textures/Structures/Piping/Atmospherics/thermomachine_alt2.rsi/meta.json @@ -0,0 +1,15 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "copyright": "Base sprites taken from tgstation, splitted to display on two layers (machinebody/panel) by Menshin, for SS14, edited by chromiumboy", + "license": "CC-BY-SA-3.0", + "states": [ + { + "name": "pipe", + "directions": 4 + } + ] +} diff --git a/Resources/Textures/Structures/Piping/Atmospherics/thermomachine_alt2.rsi/pipe.png b/Resources/Textures/Structures/Piping/Atmospherics/thermomachine_alt2.rsi/pipe.png new file mode 100644 index 0000000000..4a52081bc8 Binary files /dev/null and b/Resources/Textures/Structures/Piping/Atmospherics/thermomachine_alt2.rsi/pipe.png differ