From 40d6f690dd0ba9e27eda7022e20cde5c234dd4e3 Mon Sep 17 00:00:00 2001
From: Rane <60792108+Elijahrane@users.noreply.github.com>
Date: Fri, 3 Jun 2022 06:08:09 -0400
Subject: [PATCH] Floor tile ECS (#8577)
---
Content.Server/Tiles/FloorTileComponent.cs | 20 ++++
.../Tiles/FloorTileItemComponent.cs | 104 ------------------
Content.Server/Tiles/FloorTileSystem.cs | 91 +++++++++++++++
3 files changed, 111 insertions(+), 104 deletions(-)
create mode 100644 Content.Server/Tiles/FloorTileComponent.cs
delete mode 100644 Content.Server/Tiles/FloorTileItemComponent.cs
create mode 100644 Content.Server/Tiles/FloorTileSystem.cs
diff --git a/Content.Server/Tiles/FloorTileComponent.cs b/Content.Server/Tiles/FloorTileComponent.cs
new file mode 100644
index 0000000000..05cdc6c309
--- /dev/null
+++ b/Content.Server/Tiles/FloorTileComponent.cs
@@ -0,0 +1,20 @@
+using Content.Shared.Maps;
+using Content.Shared.Sound;
+using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
+
+namespace Content.Server.Tiles
+{
+ ///
+ /// This gives items floor tile behavior, but it doesn't have to be a literal floor tile.
+ /// A lot of materials use this too. Note that the AfterInteract will fail without a stack component on the item.
+ ///
+ [RegisterComponent]
+ public sealed class FloorTileComponent : Component
+ {
+ [DataField("outputs", customTypeSerializer: typeof(PrototypeIdListSerializer))]
+ public List? OutputTiles;
+
+ [DataField("placeTileSound")]
+ public SoundSpecifier PlaceTileSound = new SoundPathSpecifier("/Audio/Items/genhit.ogg");
+ }
+}
diff --git a/Content.Server/Tiles/FloorTileItemComponent.cs b/Content.Server/Tiles/FloorTileItemComponent.cs
deleted file mode 100644
index b70ed17560..0000000000
--- a/Content.Server/Tiles/FloorTileItemComponent.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-using System.Threading.Tasks;
-using Content.Server.Stack;
-using Content.Shared.Audio;
-using Content.Shared.Interaction;
-using Content.Shared.Maps;
-using Content.Shared.Sound;
-using Robust.Shared.Audio;
-using Robust.Shared.Map;
-using Robust.Shared.Player;
-using Robust.Shared.Random;
-using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
-
-namespace Content.Server.Tiles
-{
- [RegisterComponent]
- [ComponentProtoName("FloorTile")]
- public sealed class FloorTileItemComponent : Component, IAfterInteract
- {
- [Dependency] private readonly IEntityManager _entMan = default!;
- [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!;
- [Dependency] private readonly IRobustRandom _random = default!;
-
- [DataField("outputs", customTypeSerializer: typeof(PrototypeIdListSerializer))]
- private List? _outputTiles;
-
- [DataField("placeTileSound")] SoundSpecifier _placeTileSound = new SoundPathSpecifier("/Audio/Items/genhit.ogg");
-
- protected override void Initialize()
- {
- base.Initialize();
- Owner.EnsureComponent();
- }
-
- private bool HasBaseTurf(ContentTileDefinition tileDef, string baseTurf)
- {
- foreach (var tileBaseTurf in tileDef.BaseTurfs)
- {
- if (baseTurf == tileBaseTurf)
- {
- return true;
- }
- }
-
- return false;
- }
-
- private void PlaceAt(IMapGrid mapGrid, EntityCoordinates location, ushort tileId, float offset = 0)
- {
- var variant = _random.Pick(((ContentTileDefinition) _tileDefinitionManager[tileId]).PlacementVariants);
- mapGrid.SetTile(location.Offset(new Vector2(offset, offset)), new Tile(tileId, 0, variant));
- SoundSystem.Play(Filter.Pvs(location), _placeTileSound.GetSound(), location, AudioHelpers.WithVariation(0.125f));
- }
-
- async Task IAfterInteract.AfterInteract(AfterInteractEventArgs eventArgs)
- {
- if (!eventArgs.CanReach)
- return true;
-
- if (!_entMan.TryGetComponent(Owner, out StackComponent? stack))
- return true;
-
- var mapManager = IoCManager.Resolve();
-
- var location = eventArgs.ClickLocation.AlignWithClosestGridTile();
- var locationMap = location.ToMap(_entMan);
- if (locationMap.MapId == MapId.Nullspace)
- return true;
- mapManager.TryGetGrid(location.GetGridId(_entMan), out var mapGrid);
-
- if (_outputTiles == null)
- return true;
-
- foreach (var currentTile in _outputTiles)
- {
- var currentTileDefinition = (ContentTileDefinition) _tileDefinitionManager[currentTile];
-
- if (mapGrid != null)
- {
- var tile = mapGrid.GetTileRef(location);
- var baseTurf = (ContentTileDefinition) _tileDefinitionManager[tile.Tile.TypeId];
-
- if (HasBaseTurf(currentTileDefinition, baseTurf.ID))
- {
- if (!EntitySystem.Get().Use(Owner, 1, stack))
- continue;
-
- PlaceAt(mapGrid, location, currentTileDefinition.TileId);
- break;
- }
- }
- else if (HasBaseTurf(currentTileDefinition, "space"))
- {
- mapGrid = mapManager.CreateGrid(locationMap.MapId);
- mapGrid.WorldPosition = locationMap.Position;
- location = new EntityCoordinates(mapGrid.GridEntityId, Vector2.Zero);
- PlaceAt(mapGrid, location, _tileDefinitionManager[_outputTiles[0]].TileId, mapGrid.TileSize / 2f);
- break;
- }
- }
-
- return true;
- }
- }
-}
diff --git a/Content.Server/Tiles/FloorTileSystem.cs b/Content.Server/Tiles/FloorTileSystem.cs
new file mode 100644
index 0000000000..effd6d63d7
--- /dev/null
+++ b/Content.Server/Tiles/FloorTileSystem.cs
@@ -0,0 +1,91 @@
+using Content.Server.Stack;
+using Content.Shared.Audio;
+using Content.Shared.Interaction;
+using Content.Shared.Maps;
+using Content.Shared.Sound;
+using Robust.Shared.Audio;
+using Robust.Shared.Map;
+using Robust.Shared.Player;
+using Robust.Shared.Random;
+
+namespace Content.Server.Tiles
+{
+ public sealed class FloorTileSystem : EntitySystem
+ {
+ [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!;
+ [Dependency] private readonly IMapManager _mapManager = default!;
+ [Dependency] private readonly IRobustRandom _random = default!;
+ [Dependency] private readonly StackSystem _stackSystem = default!;
+
+ public override void Initialize()
+ {
+ base.Initialize();
+ SubscribeLocalEvent(OnAfterInteract);
+ }
+
+ private void OnAfterInteract(EntityUid uid, FloorTileComponent component, AfterInteractEvent args)
+ {
+ if (!args.CanReach)
+ return;
+
+ if (!TryComp(uid, out var stack))
+ return;
+
+ if (component.OutputTiles == null)
+ return;
+
+ // this looks a bit sussy but it might be because it needs to be able to place off of grids and expand them
+ var location = args.ClickLocation.AlignWithClosestGridTile();
+ var locationMap = location.ToMap(EntityManager);
+ if (locationMap.MapId == MapId.Nullspace)
+ return;
+ _mapManager.TryGetGrid(location.GetGridId(EntityManager), out var mapGrid);
+
+ foreach (var currentTile in component.OutputTiles)
+ {
+ var currentTileDefinition = (ContentTileDefinition) _tileDefinitionManager[currentTile];
+
+ if (mapGrid != null)
+ {
+ var tile = mapGrid.GetTileRef(location);
+ var baseTurf = (ContentTileDefinition) _tileDefinitionManager[tile.Tile.TypeId];
+
+ if (HasBaseTurf(currentTileDefinition, baseTurf.ID))
+ {
+ if (!_stackSystem.Use(uid, 1, stack))
+ continue;
+
+ PlaceAt(mapGrid, location, currentTileDefinition.TileId, component.PlaceTileSound);
+ return;
+ }
+ }
+ if (HasBaseTurf(currentTileDefinition, "space"))
+ {
+ mapGrid = _mapManager.CreateGrid(locationMap.MapId);
+ mapGrid.WorldPosition = locationMap.Position;
+ location = new EntityCoordinates(mapGrid.GridEntityId, Vector2.Zero);
+ PlaceAt(mapGrid, location, _tileDefinitionManager[component.OutputTiles[0]].TileId, component.PlaceTileSound, mapGrid.TileSize / 2f);
+ return;
+ }
+ }
+ }
+
+ public bool HasBaseTurf(ContentTileDefinition tileDef, string baseTurf)
+ {
+ foreach (var tileBaseTurf in tileDef.BaseTurfs)
+ {
+ if (baseTurf == tileBaseTurf)
+ return true;
+ }
+
+ return false;
+ }
+
+ private void PlaceAt(IMapGrid mapGrid, EntityCoordinates location, ushort tileId, SoundSpecifier placeSound, float offset = 0)
+ {
+ var variant = _random.Pick(((ContentTileDefinition) _tileDefinitionManager[tileId]).PlacementVariants);
+ mapGrid.SetTile(location.Offset(new Vector2(offset, offset)), new Tile(tileId, 0, variant));
+ SoundSystem.Play(Filter.Pvs(location), placeSound.GetSound(), location, AudioHelpers.WithVariation(0.125f, _random));
+ }
+ }
+}