diff --git a/Content.Client/GameObjects/EntitySystems/ConstructionSystem.cs b/Content.Client/GameObjects/EntitySystems/ConstructionSystem.cs index 57537e8a5b..700393b9c5 100644 --- a/Content.Client/GameObjects/EntitySystems/ConstructionSystem.cs +++ b/Content.Client/GameObjects/EntitySystems/ConstructionSystem.cs @@ -153,6 +153,11 @@ namespace Content.Client.GameObjects.EntitySystems /// public void SpawnGhost(ConstructionPrototype prototype, GridCoordinates loc, Direction dir) { + if (GhostPresent(loc)) + { + return; + } + var ghost = _entityManager.SpawnEntity("constructionghost", loc); var comp = ghost.GetComponent(); comp.Prototype = prototype; @@ -167,6 +172,22 @@ namespace Content.Client.GameObjects.EntitySystems sprite.LayerSetVisible(0, true); } + /// + /// Checks if any construction ghosts are present at the given position + /// + private bool GhostPresent(GridCoordinates loc) + { + foreach (KeyValuePair ghost in _ghosts) + { + if (ghost.Value.Owner.Transform.GridPosition.Equals(loc)) + { + return true; + } + } + + return false; + } + private void TryStartConstruction(int ghostId) { var ghost = _ghosts[ghostId]; diff --git a/Content.Server/GameTicking/GameTickerCommands.cs b/Content.Server/GameTicking/GameTickerCommands.cs index 839dddf891..c2878dbd40 100644 --- a/Content.Server/GameTicking/GameTickerCommands.cs +++ b/Content.Server/GameTicking/GameTickerCommands.cs @@ -6,10 +6,15 @@ using Content.Server.Interfaces.GameTicking; using Content.Server.Players; using Content.Shared.BodySystem; using Content.Shared.Jobs; +using Content.Shared.Maps; using Robust.Server.Interfaces.Console; using Robust.Server.Interfaces.Player; +using Robust.Shared.GameObjects.Components.Transform; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Map; using Robust.Shared.Interfaces.Random; using Robust.Shared.IoC; +using Robust.Shared.Map; using Robust.Shared.Network; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -377,7 +382,7 @@ namespace Content.Server.GameTicking { if (player == null) { - shell.SendText(player, "Only a player can run this command."); + shell.SendText((IPlayerSession) null, "Only a player can run this command."); return; } @@ -400,4 +405,102 @@ namespace Content.Server.GameTicking } } } + + class TileWallsCommand : IClientCommand + { + // ReSharper disable once StringLiteralTypo + public string Command => "tilewalls"; + public string Description => "Puts an underplating tile below every wall on a grid."; + public string Help => $"Usage: {Command} | {Command}"; + + public void Execute(IConsoleShell shell, IPlayerSession player, string[] args) + { + GridId gridId; + + switch (args.Length) + { + case 0: + if (player?.AttachedEntity == null) + { + shell.SendText((IPlayerSession) null, "Only a player can run this command."); + return; + } + + gridId = player.AttachedEntity.Transform.GridID; + break; + case 1: + if (!int.TryParse(args[0], out var id)) + { + shell.SendText(player, $"{args[0]} is not a valid integer."); + return; + } + + gridId = new GridId(id); + break; + default: + shell.SendText(player, Help); + return; + } + + var mapManager = IoCManager.Resolve(); + if (!mapManager.TryGetGrid(gridId, out var grid)) + { + shell.SendText(player, $"No grid exists with id {gridId}"); + return; + } + + var entityManager = IoCManager.Resolve(); + if (!entityManager.TryGetEntity(grid.GridEntityId, out var gridEntity)) + { + shell.SendText(player, $"Grid {gridId} doesn't have an associated grid entity."); + return; + } + + var tileDefinitionManager = IoCManager.Resolve(); + var underplating = tileDefinitionManager["underplating"]; + var underplatingTile = new Tile(underplating.TileId); + var changed = 0; + foreach (var childUid in gridEntity.Transform.ChildEntityUids) + { + if (!entityManager.TryGetEntity(childUid, out var childEntity)) + { + continue; + } + + var prototype = childEntity.Prototype; + while (true) + { + if (prototype?.Parent == null) + { + break; + } + + prototype = prototype.Parent; + } + + if (prototype?.ID != "base_wall") + { + continue; + } + + if (!childEntity.TryGetComponent(out SnapGridComponent snapGrid)) + { + continue; + } + + var tile = grid.GetTileRef(childEntity.Transform.GridPosition); + var tileDef = (ContentTileDefinition) tileDefinitionManager[tile.Tile.TypeId]; + + if (tileDef.Name == "underplating") + { + continue; + } + + grid.SetTile(childEntity.Transform.GridPosition, underplatingTile); + changed++; + } + + shell.SendText(player, $"Changed {changed} tiles."); + } + } } diff --git a/Content.Shared/Maps/TurfHelpers.cs b/Content.Shared/Maps/TurfHelpers.cs index 549a1517dd..1f81bc6f8f 100644 --- a/Content.Shared/Maps/TurfHelpers.cs +++ b/Content.Shared/Maps/TurfHelpers.cs @@ -1,4 +1,7 @@ -using Content.Shared.Physics; +#nullable enable +using System.Collections.Generic; +using Content.Shared.Physics; +using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Map; using Robust.Shared.Interfaces.Physics; using Robust.Shared.IoC; @@ -9,6 +12,35 @@ namespace Content.Shared.Maps { public static class TurfHelpers { + /// + /// Attempts to get the turf at a certain coordinates or null if no such turf is found. + /// + public static TileRef? GetTileRef(this GridCoordinates coordinates) + { + if (!coordinates.GridID.IsValid()) + return null; + + var mapManager = IoCManager.Resolve(); + + if (!mapManager.TryGetGrid(coordinates.GridID, out var grid)) + return null; + + if (!grid.TryGetTileRef(coordinates.ToMapIndices(mapManager), out var tile)) + return null; + + return tile; + } + + /// + /// Helper that returns all entities in a turf. + /// + public static IEnumerable GetEntitiesInTile(this TileRef turf, bool approximate = false) + { + var entityManager = IoCManager.Resolve(); + + return entityManager.GetEntitiesIntersecting(turf.MapIndex, GetWorldTileBox(turf), approximate); + } + /// /// Checks if a turf has something dense on it. /// diff --git a/Resources/Groups/groups.yml b/Resources/Groups/groups.yml index 0649f13c13..ce1885473a 100644 --- a/Resources/Groups/groups.yml +++ b/Resources/Groups/groups.yml @@ -92,6 +92,7 @@ - anchor - unanchor - tubeconnections + - tilewalls CanViewVar: true CanAdminPlace: true @@ -179,6 +180,7 @@ - clearatmos - settemp - setatmostemp + - tilewalls CanViewVar: true CanAdminPlace: true CanScript: true diff --git a/Resources/Prototypes/Catalog/VendingMachines/soviet.yml b/Resources/Prototypes/Catalog/VendingMachines/soviet.yml deleted file mode 100644 index 65373a505e..0000000000 --- a/Resources/Prototypes/Catalog/VendingMachines/soviet.yml +++ /dev/null @@ -1,5 +0,0 @@ -- type: vendingMachineInventory - id: soviet - name: товарищ-vend - description: Rodina-mat' zovyot! - spriteName: soviet diff --git a/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml b/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml index 642895efc1..c53aa0cc93 100644 --- a/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml +++ b/Resources/Prototypes/Entities/Constructible/Power/vending_machines.yml @@ -52,18 +52,6 @@ - type: Anchorable - type: Pullable -- type: entity - parent: VendingMachine - id: VendingMachineAmmo - name: AmmoVend - components: - - type: VendingMachine - pack: AmmoVend - - type: Icon - sprite: Constructible/Power/VendingMachines/ammo.rsi - - type: Sprite - sprite: Constructible/Power/VendingMachines/ammo.rsi - - type: entity parent: VendingMachine id: VendingMachineBooze @@ -324,18 +312,6 @@ - type: Sprite sprite: Constructible/Power/VendingMachines/snack.rsi -- type: entity - parent: VendingMachine - id: VendingMachineSoviet - name: Товарищ-vend - components: - - type: VendingMachine - pack: soviet - - type: Icon - sprite: Constructible/Power/VendingMachines/soviet.rsi - - type: Sprite - sprite: Constructible/Power/VendingMachines/soviet.rsi - - type: entity parent: VendingMachine id: VendingMachineSovietSoda diff --git a/Resources/Prototypes/Entities/Objects/Consumable/food.yml b/Resources/Prototypes/Entities/Objects/Consumable/food.yml index e078357d06..5a1c3e677e 100644 --- a/Resources/Prototypes/Entities/Objects/Consumable/food.yml +++ b/Resources/Prototypes/Entities/Objects/Consumable/food.yml @@ -3047,3 +3047,22 @@ sprite: Objects/Consumable/Food/banana.rsi - type: Icon sprite: Objects/Consumable/Food/banana.rsi + +- type: entity + name: memory leek + parent: FoodBase + id: FoodMemoryLeek + description: It makes you irrationally angry just looking at it. + components: + - type: Food + - type: Solution + contents: + reagents: + - ReagentId: chem.Nutriment + Quantity: 9999999999 + - type: Sprite + sprite: Objects/Consumable/Food/memoryleek.rsi + state: memoryLeek + - type: Icon + sprite: Objects/Consumable/Food/memoryleek.rsi + state: memoryLeek diff --git a/Resources/Textures/Constructible/Power/VendingMachines/ammo.rsi/broken.png b/Resources/Textures/Constructible/Power/VendingMachines/ammo.rsi/broken.png deleted file mode 100644 index 129cdb87e8..0000000000 Binary files a/Resources/Textures/Constructible/Power/VendingMachines/ammo.rsi/broken.png and /dev/null differ diff --git a/Resources/Textures/Constructible/Power/VendingMachines/ammo.rsi/meta.json b/Resources/Textures/Constructible/Power/VendingMachines/ammo.rsi/meta.json deleted file mode 100644 index 8288f2c29d..0000000000 --- a/Resources/Textures/Constructible/Power/VendingMachines/ammo.rsi/meta.json +++ /dev/null @@ -1 +0,0 @@ -{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "broken", "directions": 1, "delays": [[1.0]]}, {"name": "normal", "directions": 1, "delays": [[1.0]]}, {"name": "off", "directions": 1, "delays": [[1.0]]}]} \ No newline at end of file diff --git a/Resources/Textures/Constructible/Power/VendingMachines/ammo.rsi/normal.png b/Resources/Textures/Constructible/Power/VendingMachines/ammo.rsi/normal.png deleted file mode 100644 index 5016f81e86..0000000000 Binary files a/Resources/Textures/Constructible/Power/VendingMachines/ammo.rsi/normal.png and /dev/null differ diff --git a/Resources/Textures/Constructible/Power/VendingMachines/ammo.rsi/off.png b/Resources/Textures/Constructible/Power/VendingMachines/ammo.rsi/off.png deleted file mode 100644 index 129cdb87e8..0000000000 Binary files a/Resources/Textures/Constructible/Power/VendingMachines/ammo.rsi/off.png and /dev/null differ diff --git a/Resources/Textures/Constructible/Power/VendingMachines/soviet.rsi/broken.png b/Resources/Textures/Constructible/Power/VendingMachines/soviet.rsi/broken.png deleted file mode 100644 index 5d084d925d..0000000000 Binary files a/Resources/Textures/Constructible/Power/VendingMachines/soviet.rsi/broken.png and /dev/null differ diff --git a/Resources/Textures/Constructible/Power/VendingMachines/soviet.rsi/dangermode.png b/Resources/Textures/Constructible/Power/VendingMachines/soviet.rsi/dangermode.png deleted file mode 100644 index cd13f3d419..0000000000 Binary files a/Resources/Textures/Constructible/Power/VendingMachines/soviet.rsi/dangermode.png and /dev/null differ diff --git a/Resources/Textures/Constructible/Power/VendingMachines/soviet.rsi/meta.json b/Resources/Textures/Constructible/Power/VendingMachines/soviet.rsi/meta.json deleted file mode 100644 index ee16cfe604..0000000000 --- a/Resources/Textures/Constructible/Power/VendingMachines/soviet.rsi/meta.json +++ /dev/null @@ -1 +0,0 @@ -{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "broken", "directions": 1, "delays": [[1.0]]}, {"name": "dangermode", "directions": 1, "delays": [[0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08, 0.08]]}, {"name": "normal", "directions": 1, "delays": [[0.5, 0.5]]}, {"name": "off", "directions": 1, "delays": [[1.0]]}]} \ No newline at end of file diff --git a/Resources/Textures/Constructible/Power/VendingMachines/soviet.rsi/normal.png b/Resources/Textures/Constructible/Power/VendingMachines/soviet.rsi/normal.png deleted file mode 100644 index 768870dc78..0000000000 Binary files a/Resources/Textures/Constructible/Power/VendingMachines/soviet.rsi/normal.png and /dev/null differ diff --git a/Resources/Textures/Constructible/Power/VendingMachines/soviet.rsi/off.png b/Resources/Textures/Constructible/Power/VendingMachines/soviet.rsi/off.png deleted file mode 100644 index 7b93a0ce6a..0000000000 Binary files a/Resources/Textures/Constructible/Power/VendingMachines/soviet.rsi/off.png and /dev/null differ diff --git a/Resources/Textures/Objects/Consumable/Food/memoryleek.rsi/memoryLeek.png b/Resources/Textures/Objects/Consumable/Food/memoryleek.rsi/memoryLeek.png new file mode 100644 index 0000000000..531fb82799 Binary files /dev/null and b/Resources/Textures/Objects/Consumable/Food/memoryleek.rsi/memoryLeek.png differ diff --git a/Resources/Textures/Objects/Consumable/Food/memoryleek.rsi/meta.json b/Resources/Textures/Objects/Consumable/Food/memoryleek.rsi/meta.json new file mode 100644 index 0000000000..bbdf977682 --- /dev/null +++ b/Resources/Textures/Objects/Consumable/Food/memoryleek.rsi/meta.json @@ -0,0 +1,24 @@ +{ + "version": 1, + "size": { + "x": 32, + "y": 32 + }, + "license": "CC-BY-SA 3.0", + "copyright": "Yeeye", + "states": [ + { + "name": "memoryLeek", + "directions": 1, + "delays": [ + [ + 0.1, + 0.1, + 0.1, + 0.1, + 0.1 + ] + ] + } + ] +}