From 46a3076ecb89359d7c642bed635af42350a44cd5 Mon Sep 17 00:00:00 2001 From: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Date: Tue, 24 Oct 2023 00:20:33 +1100 Subject: [PATCH] Predict tile-prying (#21167) --- Content.Client/Tools/ToolSystem.cs | 1 + .../Commands/VariantizeCommand.cs | 12 ++-- .../Atmos/EntitySystems/AtmosphereSystem.cs | 1 + .../Construction/ConstructionSystem.cs | 1 + Content.Server/Construction/RefiningSystem.cs | 1 + Content.Server/Decals/DecalSystem.cs | 4 +- .../DeviceLinking/Systems/LogicGateSystem.cs | 1 + Content.Server/Interaction/TilePryCommand.cs | 3 +- Content.Server/Medical/CryoPodSystem.cs | 1 + .../Power/EntitySystems/CableSystem.cs | 2 + Content.Server/Repairable/RepairableSystem.cs | 1 + .../EntitySystems/RevenantSystem.Abilities.cs | 1 + Content.Server/Toilet/ToiletSystem.cs | 1 + .../Tools/Components/TilePryingComponent.cs | 25 --------- .../Tools/ToolSystem.LatticeCutting.cs | 6 +- Content.Server/Tools/ToolSystem.cs | 3 +- Content.Server/Wires/WiresSystem.cs | 1 + .../Debris/BlobFloorPlanBuilderSystem.cs | 5 +- .../Debris/DebrisFeaturePlacerSystem.cs | 2 +- .../EntitySystems/AnchorableSystem.cs | 1 + Content.Shared/Decals/SharedDecalSystem.cs | 13 +++++ .../Maps/TileSystem.cs | 56 ++++++++++++++----- Content.Shared/Maps/TurfHelpers.cs | 24 -------- .../EntitySystems/EncryptionKeySystem.cs | 1 + .../Tools/Components/TilePryingComponent.cs | 26 +++++++++ .../Systems/SharedToolSystem.MultipleTool.cs | 4 +- .../Systems/SharedToolSystem.TilePrying.cs | 36 ++++++------ .../Tools/Systems/SharedToolSystem.cs | 23 ++++++-- 28 files changed, 154 insertions(+), 102 deletions(-) delete mode 100644 Content.Server/Tools/Components/TilePryingComponent.cs rename {Content.Server => Content.Shared}/Maps/TileSystem.cs (68%) create mode 100644 Content.Shared/Tools/Components/TilePryingComponent.cs rename Content.Server/Tools/ToolSystem.TilePrying.cs => Content.Shared/Tools/Systems/SharedToolSystem.TilePrying.cs (66%) diff --git a/Content.Client/Tools/ToolSystem.cs b/Content.Client/Tools/ToolSystem.cs index f4dc480b41..966f37146e 100644 --- a/Content.Client/Tools/ToolSystem.cs +++ b/Content.Client/Tools/ToolSystem.cs @@ -5,6 +5,7 @@ using Content.Shared.Tools; using Content.Shared.Tools.Components; using Robust.Client.GameObjects; using Robust.Shared.GameStates; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Client.Tools { diff --git a/Content.Server/Administration/Commands/VariantizeCommand.cs b/Content.Server/Administration/Commands/VariantizeCommand.cs index 1b5cbbd4d5..7aabd76335 100644 --- a/Content.Server/Administration/Commands/VariantizeCommand.cs +++ b/Content.Server/Administration/Commands/VariantizeCommand.cs @@ -12,6 +12,7 @@ public sealed class VariantizeCommand : IConsoleCommand { [Dependency] private readonly IEntityManager _entManager = default!; [Dependency] private readonly IRobustRandom _random = default!; + [Dependency] private readonly ITileDefinitionManager _tileDefManager = default!; public string Command => "variantize"; @@ -39,11 +40,14 @@ public sealed class VariantizeCommand : IConsoleCommand return; } - foreach (var tile in gridComp.GetAllTiles()) + var mapsSystem = _entManager.System(); + var tileSystem = _entManager.System(); + + foreach (var tile in mapsSystem.GetAllTiles(euid.Value, gridComp)) { - var def = tile.GetContentTileDefinition(); - var newTile = new Tile(tile.Tile.TypeId, tile.Tile.Flags, def.PickVariant(_random)); - gridComp.SetTile(tile.GridIndices, newTile); + var def = tile.GetContentTileDefinition(_tileDefManager); + var newTile = new Tile(tile.Tile.TypeId, tile.Tile.Flags, tileSystem.PickVariant(def)); + mapsSystem.SetTile(euid.Value, gridComp, tile.GridIndices, newTile); } } } diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs index 91634de8d7..d8364b652b 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs @@ -4,6 +4,7 @@ using Content.Server.Body.Systems; using Content.Server.Maps; using Content.Server.NodeContainer.EntitySystems; using Content.Shared.Atmos.EntitySystems; +using Content.Shared.Maps; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Containers; diff --git a/Content.Server/Construction/ConstructionSystem.cs b/Content.Server/Construction/ConstructionSystem.cs index 76d37432cb..6e40b7b856 100644 --- a/Content.Server/Construction/ConstructionSystem.cs +++ b/Content.Server/Construction/ConstructionSystem.cs @@ -7,6 +7,7 @@ using JetBrains.Annotations; using Robust.Server.Containers; using Robust.Shared.Prototypes; using Robust.Shared.Random; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Server.Construction { diff --git a/Content.Server/Construction/RefiningSystem.cs b/Content.Server/Construction/RefiningSystem.cs index 40f69c51f8..b9d80c7170 100644 --- a/Content.Server/Construction/RefiningSystem.cs +++ b/Content.Server/Construction/RefiningSystem.cs @@ -6,6 +6,7 @@ using Content.Shared.Interaction; using Content.Shared.Stacks; using Content.Shared.Tools; using Robust.Shared.Serialization; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Server.Construction { diff --git a/Content.Server/Decals/DecalSystem.cs b/Content.Server/Decals/DecalSystem.cs index d5a5bf9aff..ed281e05ba 100644 --- a/Content.Server/Decals/DecalSystem.cs +++ b/Content.Server/Decals/DecalSystem.cs @@ -305,10 +305,10 @@ namespace Content.Server.Decals return true; } - public bool RemoveDecal(EntityUid gridId, uint decalId, DecalGridComponent? component = null) + public override bool RemoveDecal(EntityUid gridId, uint decalId, DecalGridComponent? component = null) => RemoveDecalInternal(gridId, decalId, out _, component); - public HashSet<(uint Index, Decal Decal)> GetDecalsInRange(EntityUid gridId, Vector2 position, float distance = 0.75f, Func? validDelegate = null) + public override HashSet<(uint Index, Decal Decal)> GetDecalsInRange(EntityUid gridId, Vector2 position, float distance = 0.75f, Func? validDelegate = null) { var decalIds = new HashSet<(uint, Decal)>(); var chunkCollection = ChunkCollection(gridId); diff --git a/Content.Server/DeviceLinking/Systems/LogicGateSystem.cs b/Content.Server/DeviceLinking/Systems/LogicGateSystem.cs index 360f86eebe..5641b0b4ae 100644 --- a/Content.Server/DeviceLinking/Systems/LogicGateSystem.cs +++ b/Content.Server/DeviceLinking/Systems/LogicGateSystem.cs @@ -5,6 +5,7 @@ using Content.Shared.Examine; using Content.Shared.Interaction; using Content.Shared.Tools; using Content.Shared.Popups; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; using SignalReceivedEvent = Content.Server.DeviceLinking.Events.SignalReceivedEvent; namespace Content.Server.DeviceLinking.Systems; diff --git a/Content.Server/Interaction/TilePryCommand.cs b/Content.Server/Interaction/TilePryCommand.cs index 157fa2cc80..4fe3599df9 100644 --- a/Content.Server/Interaction/TilePryCommand.cs +++ b/Content.Server/Interaction/TilePryCommand.cs @@ -3,6 +3,7 @@ using Content.Server.Administration; using Content.Server.Tools.Components; using Content.Shared.Administration; using Content.Shared.Maps; +using Content.Shared.Tools.Components; using Robust.Server.Player; using Robust.Shared.Console; using Robust.Shared.Map; @@ -10,7 +11,7 @@ using Robust.Shared.Map; namespace Content.Server.Interaction { /// - /// + /// /// [AdminCommand(AdminFlags.Debug)] sealed class TilePryCommand : IConsoleCommand diff --git a/Content.Server/Medical/CryoPodSystem.cs b/Content.Server/Medical/CryoPodSystem.cs index b94d6de6de..82f7b9cb0a 100644 --- a/Content.Server/Medical/CryoPodSystem.cs +++ b/Content.Server/Medical/CryoPodSystem.cs @@ -32,6 +32,7 @@ using Content.Shared.Tools; using Content.Shared.Verbs; using Robust.Server.GameObjects; using Robust.Shared.Timing; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Server.Medical; diff --git a/Content.Server/Power/EntitySystems/CableSystem.cs b/Content.Server/Power/EntitySystems/CableSystem.cs index 8dd09fab35..a5c9591d9a 100644 --- a/Content.Server/Power/EntitySystems/CableSystem.cs +++ b/Content.Server/Power/EntitySystems/CableSystem.cs @@ -8,6 +8,8 @@ using Content.Shared.Interaction; using Content.Shared.Tools; using Content.Shared.Tools.Components; using Robust.Shared.Map; +using CableCuttingFinishedEvent = Content.Shared.Tools.Systems.CableCuttingFinishedEvent; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Server.Power.EntitySystems; diff --git a/Content.Server/Repairable/RepairableSystem.cs b/Content.Server/Repairable/RepairableSystem.cs index 486ac756e3..5bd580756d 100644 --- a/Content.Server/Repairable/RepairableSystem.cs +++ b/Content.Server/Repairable/RepairableSystem.cs @@ -5,6 +5,7 @@ using Content.Shared.Interaction; using Content.Shared.Popups; using Content.Shared.Repairable; using Content.Shared.Tools; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Server.Repairable { diff --git a/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs b/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs index b3caced0da..cb20a1b868 100644 --- a/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs +++ b/Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs @@ -21,6 +21,7 @@ using Content.Shared.DoAfter; using Content.Shared.Emag.Systems; using Content.Shared.FixedPoint; using Content.Shared.Humanoid; +using Content.Shared.Maps; using Content.Shared.Mobs; using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Systems; diff --git a/Content.Server/Toilet/ToiletSystem.cs b/Content.Server/Toilet/ToiletSystem.cs index 57467397c6..b10feae453 100644 --- a/Content.Server/Toilet/ToiletSystem.cs +++ b/Content.Server/Toilet/ToiletSystem.cs @@ -19,6 +19,7 @@ using Content.Shared.Verbs; using Robust.Shared.Audio; using Robust.Shared.Player; using Robust.Shared.Random; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Server.Toilet { diff --git a/Content.Server/Tools/Components/TilePryingComponent.cs b/Content.Server/Tools/Components/TilePryingComponent.cs deleted file mode 100644 index 99d7144b68..0000000000 --- a/Content.Server/Tools/Components/TilePryingComponent.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Threading; -using Content.Shared.Tools; -using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; - -namespace Content.Server.Tools.Components -{ - [RegisterComponent] - public sealed partial class TilePryingComponent : Component - { - [DataField("toolComponentNeeded")] - public bool ToolComponentNeeded = true; - - [DataField("qualityNeeded", customTypeSerializer:typeof(PrototypeIdSerializer))] - public string QualityNeeded = "Prying"; - - /// - /// Whether this tool can pry tiles with CanAxe. - /// - [DataField("advanced")] - public bool Advanced = false; - - [DataField("delay")] - public float Delay = 1f; - } -} diff --git a/Content.Server/Tools/ToolSystem.LatticeCutting.cs b/Content.Server/Tools/ToolSystem.LatticeCutting.cs index 674a810239..ab289c1ae2 100644 --- a/Content.Server/Tools/ToolSystem.LatticeCutting.cs +++ b/Content.Server/Tools/ToolSystem.LatticeCutting.cs @@ -62,14 +62,14 @@ public sealed partial class ToolSystem var coordinates = mapGrid.GridTileToLocal(tile.GridIndices); - if (!_interactionSystem.InRangeUnobstructed(user, coordinates, popup: false)) + if (!InteractionSystem.InRangeUnobstructed(user, coordinates, popup: false)) return false; if (_tileDefinitionManager[tile.Tile.TypeId] is not ContentTileDefinition tileDef || !tileDef.CanWirecutter || string.IsNullOrEmpty(tileDef.BaseTurf) - || _tileDefinitionManager[tileDef.BaseTurf] is not ContentTileDefinition newDef - || tile.IsBlockedTurf(true)) + || _tileDefinitionManager[tileDef.BaseTurf] is not ContentTileDefinition || + tile.IsBlockedTurf(true)) { return false; } diff --git a/Content.Server/Tools/ToolSystem.cs b/Content.Server/Tools/ToolSystem.cs index 63642338f3..88a96dc1e8 100644 --- a/Content.Server/Tools/ToolSystem.cs +++ b/Content.Server/Tools/ToolSystem.cs @@ -6,6 +6,7 @@ using Content.Shared.Maps; using Content.Shared.Tools; using Robust.Server.GameObjects; using Robust.Shared.Map; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Server.Tools { @@ -21,13 +22,11 @@ namespace Content.Server.Tools [Dependency] private readonly SharedPointLightSystem _light = default!; [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!; [Dependency] private readonly TransformSystem _transformSystem = default!; - [Dependency] private readonly TurfSystem _turf = default!; public override void Initialize() { base.Initialize(); - InitializeTilePrying(); InitializeLatticeCutting(); InitializeWelders(); } diff --git a/Content.Server/Wires/WiresSystem.cs b/Content.Server/Wires/WiresSystem.cs index df61e89d4d..e75ad0a9ef 100644 --- a/Content.Server/Wires/WiresSystem.cs +++ b/Content.Server/Wires/WiresSystem.cs @@ -19,6 +19,7 @@ using Robust.Server.GameObjects; using Robust.Server.Player; using Robust.Shared.Prototypes; using Robust.Shared.Random; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Server.Wires; diff --git a/Content.Server/Worldgen/Systems/Debris/BlobFloorPlanBuilderSystem.cs b/Content.Server/Worldgen/Systems/Debris/BlobFloorPlanBuilderSystem.cs index a90faef995..a09416e593 100644 --- a/Content.Server/Worldgen/Systems/Debris/BlobFloorPlanBuilderSystem.cs +++ b/Content.Server/Worldgen/Systems/Debris/BlobFloorPlanBuilderSystem.cs @@ -14,6 +14,7 @@ public sealed class BlobFloorPlanBuilderSystem : BaseWorldSystem { [Dependency] private readonly IRobustRandom _random = default!; [Dependency] private readonly ITileDefinitionManager _tileDefinition = default!; + [Dependency] private readonly TileSystem _tiles = default!; /// public override void Initialize() @@ -30,6 +31,8 @@ public sealed class BlobFloorPlanBuilderSystem : BaseWorldSystem private void PlaceFloorplanTiles(BlobFloorPlanBuilderComponent comp, MapGridComponent grid) { // NO MORE THAN TWO ALLOCATIONS THANK YOU VERY MUCH. + // TODO: Just put these on a field instead then? + // Also the end of the method has a big LINQ which is gonna blow this out the water. var spawnPoints = new HashSet(comp.FloorPlacements * 6); var taken = new Dictionary(comp.FloorPlacements * 5); @@ -56,7 +59,7 @@ public sealed class BlobFloorPlanBuilderSystem : BaseWorldSystem spawnPoints.Add(west); var tileDef = _tileDefinition[_random.Pick(comp.FloorTileset)]; - taken.Add(point, new Tile(tileDef.TileId, 0, ((ContentTileDefinition)tileDef).PickVariant(_random))); + taken.Add(point, new Tile(tileDef.TileId, 0, _tiles.PickVariant((ContentTileDefinition) tileDef))); } PlaceTile(Vector2i.Zero); diff --git a/Content.Server/Worldgen/Systems/Debris/DebrisFeaturePlacerSystem.cs b/Content.Server/Worldgen/Systems/Debris/DebrisFeaturePlacerSystem.cs index b2d8df4de9..65af0b68cb 100644 --- a/Content.Server/Worldgen/Systems/Debris/DebrisFeaturePlacerSystem.cs +++ b/Content.Server/Worldgen/Systems/Debris/DebrisFeaturePlacerSystem.cs @@ -46,7 +46,7 @@ public sealed class DebrisFeaturePlacerSystem : BaseWorldSystem return; // Redundant logic, prolly needs it's own handler for your custom system. var placer = Comp(component.OwningController); - var xform = Transform(uid); + var xform = args.Component; var ownerXform = Transform(component.OwningController); if (xform.MapUid is null || ownerXform.MapUid is null) return; // not our problem diff --git a/Content.Shared/Construction/EntitySystems/AnchorableSystem.cs b/Content.Shared/Construction/EntitySystems/AnchorableSystem.cs index 3e1cf5584c..b40c049562 100644 --- a/Content.Shared/Construction/EntitySystems/AnchorableSystem.cs +++ b/Content.Shared/Construction/EntitySystems/AnchorableSystem.cs @@ -18,6 +18,7 @@ using Content.Shared.Tag; using Robust.Shared.Player; using Robust.Shared.Serialization; using Robust.Shared.Utility; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Shared.Construction.EntitySystems; diff --git a/Content.Shared/Decals/SharedDecalSystem.cs b/Content.Shared/Decals/SharedDecalSystem.cs index 79bf826eed..02f73bdacb 100644 --- a/Content.Shared/Decals/SharedDecalSystem.cs +++ b/Content.Shared/Decals/SharedDecalSystem.cs @@ -1,3 +1,4 @@ +using System.Collections; using System.Diagnostics.CodeAnalysis; using System.Numerics; using Robust.Shared.GameStates; @@ -107,6 +108,18 @@ namespace Content.Shared.Decals { // used by client-side overlay code } + + public virtual HashSet<(uint Index, Decal Decal)> GetDecalsInRange(EntityUid gridId, Vector2 position, float distance = 0.75f, Func? validDelegate = null) + { + // NOOP on client atm. + return new HashSet<(uint Index, Decal Decal)>(); + } + + public virtual bool RemoveDecal(EntityUid gridId, uint decalId, DecalGridComponent? component = null) + { + // NOOP on client atm. + return true; + } } // TODO: Pretty sure paul was moving this somewhere but just so people know diff --git a/Content.Server/Maps/TileSystem.cs b/Content.Shared/Maps/TileSystem.cs similarity index 68% rename from Content.Server/Maps/TileSystem.cs rename to Content.Shared/Maps/TileSystem.cs index 1423f76d97..2c09375d59 100644 --- a/Content.Server/Maps/TileSystem.cs +++ b/Content.Shared/Maps/TileSystem.cs @@ -1,13 +1,13 @@ +using System.Linq; using System.Numerics; -using Content.Server.Decals; using Content.Shared.Coordinates.Helpers; using Content.Shared.Decals; -using Content.Shared.Maps; using Robust.Shared.Map; using Robust.Shared.Map.Components; using Robust.Shared.Random; +using Robust.Shared.Utility; -namespace Content.Server.Maps; +namespace Content.Shared.Maps; /// /// Handles server-side tile manipulation like prying/deconstructing tiles. @@ -15,15 +15,39 @@ namespace Content.Server.Maps; public sealed class TileSystem : EntitySystem { [Dependency] private readonly IMapManager _mapManager = default!; - [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; [Dependency] private readonly IRobustRandom _robustRandom = default!; - [Dependency] private readonly DecalSystem _decal = default!; + [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; + [Dependency] private readonly SharedDecalSystem _decal = default!; + [Dependency] private readonly SharedMapSystem _maps = default!; [Dependency] private readonly TurfSystem _turf = default!; + /// + /// Returns a weighted pick of a tile variant. + /// + public byte PickVariant(ContentTileDefinition tile) + { + var variants = tile.PlacementVariants; + + var sum = variants.Sum(); + var accumulated = 0f; + var rand = _robustRandom.NextFloat() * sum; + + for (byte i = 0; i < variants.Length; ++i) + { + accumulated += variants[i]; + + if (accumulated >= rand) + return i; + } + + // Shouldn't happen + throw new InvalidOperationException($"Invalid weighted variantize tile pick for {tile.ID}!"); + } + public bool PryTile(Vector2i indices, EntityUid gridId) { - var grid = _mapManager.GetGrid(gridId); - var tileRef = grid.GetTileRef(indices); + var grid = Comp(gridId); + var tileRef = _maps.GetTileRef(gridId, grid, indices); return PryTile(tileRef); } @@ -71,16 +95,20 @@ public sealed class TileSystem : EntitySystem public bool ReplaceTile(TileRef tileref, ContentTileDefinition replacementTile, EntityUid grid, MapGridComponent? component = null) { + DebugTools.Assert(tileref.GridUid == grid); + if (!Resolve(grid, ref component)) return false; - var variant = replacementTile.PickVariant(); + + var variant = PickVariant(replacementTile); var decals = _decal.GetDecalsInRange(tileref.GridUid, _turf.GetTileCenter(tileref).Position, 0.5f); foreach (var (id, _) in decals) { _decal.RemoveDecal(tileref.GridUid, id); } - component.SetTile(tileref.GridIndices, new Tile(replacementTile.TileId, 0, variant)); + + _maps.SetTile(grid, component, tileref.GridIndices, new Tile(replacementTile.TileId, 0, variant)); return true; } @@ -94,12 +122,13 @@ public sealed class TileSystem : EntitySystem if (string.IsNullOrEmpty(tileDef.BaseTurf)) return false; - var mapGrid = _mapManager.GetGrid(tileRef.GridUid); + var gridUid = tileRef.GridUid; + var mapGrid = Comp(gridUid); const float margin = 0.1f; var bounds = mapGrid.TileSize - margin * 2; var indices = tileRef.GridIndices; - var coordinates = mapGrid.GridTileToLocal(indices) + var coordinates = _maps.GridTileToLocal(gridUid, mapGrid, indices) .Offset(new Vector2( (_robustRandom.NextFloat() - 0.5f) * bounds, (_robustRandom.NextFloat() - 0.5f) * bounds)); @@ -109,15 +138,14 @@ public sealed class TileSystem : EntitySystem Transform(tileItem).LocalRotation = _robustRandom.NextDouble() * Math.Tau; // Destroy any decals on the tile - var decals = _decal.GetDecalsInRange(tileRef.GridUid, coordinates.SnapToGrid(EntityManager, _mapManager).Position, 0.5f); + var decals = _decal.GetDecalsInRange(gridUid, coordinates.SnapToGrid(EntityManager, _mapManager).Position, 0.5f); foreach (var (id, _) in decals) { _decal.RemoveDecal(tileRef.GridUid, id); } var plating = _tileDefinitionManager[tileDef.BaseTurf]; - - mapGrid.SetTile(tileRef.GridIndices, new Tile(plating.TileId)); + _maps.SetTile(gridUid, mapGrid, tileRef.GridIndices, new Tile(plating.TileId)); return true; } diff --git a/Content.Shared/Maps/TurfHelpers.cs b/Content.Shared/Maps/TurfHelpers.cs index 857244d658..a87b8c97d1 100644 --- a/Content.Shared/Maps/TurfHelpers.cs +++ b/Content.Shared/Maps/TurfHelpers.cs @@ -86,30 +86,6 @@ namespace Content.Shared.Maps return tile.Tile.IsSpace(tileDefinitionManager); } - /// - /// Returns a weighted pick of a tile variant. - /// - public static byte PickVariant(this ContentTileDefinition tile, IRobustRandom? random = null) - { - IoCManager.Resolve(ref random); - var variants = tile.PlacementVariants; - - var sum = variants.Sum(); - var accumulated = 0f; - var rand = random.NextFloat() * sum; - - for (byte i = 0; i < variants.Length; ++i) - { - accumulated += variants[i]; - - if (accumulated >= rand) - return i; - } - - // Shouldn't happen - throw new InvalidOperationException($"Invalid weighted variantize tile pick for {tile.ID}!"); - } - /// /// Helper that returns all entities in a turf. /// diff --git a/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs b/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs index 3d2ce2fd00..eb97fe4113 100644 --- a/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs +++ b/Content.Shared/Radio/EntitySystems/EncryptionKeySystem.cs @@ -14,6 +14,7 @@ using Robust.Shared.Network; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; using Robust.Shared.Timing; +using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem; namespace Content.Shared.Radio.EntitySystems; diff --git a/Content.Shared/Tools/Components/TilePryingComponent.cs b/Content.Shared/Tools/Components/TilePryingComponent.cs new file mode 100644 index 0000000000..4c123ca1ed --- /dev/null +++ b/Content.Shared/Tools/Components/TilePryingComponent.cs @@ -0,0 +1,26 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; + +namespace Content.Shared.Tools.Components; + +/// +/// Allows prying tiles up on a grid. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class TilePryingComponent : Component +{ + [DataField("toolComponentNeeded"), AutoNetworkedField] + public bool ToolComponentNeeded = true; + + [DataField("qualityNeeded", customTypeSerializer:typeof(PrototypeIdSerializer)), AutoNetworkedField] + public string QualityNeeded = "Prying"; + + /// + /// Whether this tool can pry tiles with CanAxe. + /// + [DataField("advanced"), AutoNetworkedField] + public bool Advanced = false; + + [DataField("delay"), AutoNetworkedField] + public float Delay = 1f; +} diff --git a/Content.Shared/Tools/Systems/SharedToolSystem.MultipleTool.cs b/Content.Shared/Tools/Systems/SharedToolSystem.MultipleTool.cs index 39a1dc50f3..cb8830060a 100644 --- a/Content.Shared/Tools/Systems/SharedToolSystem.MultipleTool.cs +++ b/Content.Shared/Tools/Systems/SharedToolSystem.MultipleTool.cs @@ -1,9 +1,9 @@ using System.Linq; using Content.Shared.Interaction; -using Content.Shared.Tools.Components; using Content.Shared.Prying.Components; +using Content.Shared.Tools.Components; -namespace Content.Shared.Tools; +namespace Content.Shared.Tools.Systems; public abstract partial class SharedToolSystem : EntitySystem { diff --git a/Content.Server/Tools/ToolSystem.TilePrying.cs b/Content.Shared/Tools/Systems/SharedToolSystem.TilePrying.cs similarity index 66% rename from Content.Server/Tools/ToolSystem.TilePrying.cs rename to Content.Shared/Tools/Systems/SharedToolSystem.TilePrying.cs index faaed6abb8..81592f5a98 100644 --- a/Content.Server/Tools/ToolSystem.TilePrying.cs +++ b/Content.Shared/Tools/Systems/SharedToolSystem.TilePrying.cs @@ -1,17 +1,15 @@ -using Content.Server.Tools.Components; using Content.Shared.Database; using Content.Shared.Fluids.Components; using Content.Shared.Interaction; using Content.Shared.Maps; using Content.Shared.Tools.Components; using Robust.Shared.Map; +using Robust.Shared.Map.Components; -namespace Content.Server.Tools; +namespace Content.Shared.Tools.Systems; -public sealed partial class ToolSystem +public abstract partial class SharedToolSystem { - [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!; - private void InitializeTilePrying() { SubscribeLocalEvent(OnTilePryingAfterInteract); @@ -20,7 +18,8 @@ public sealed partial class ToolSystem private void OnTilePryingAfterInteract(EntityUid uid, TilePryingComponent component, AfterInteractEvent args) { - if (args.Handled || !args.CanReach || (args.Target != null && !HasComp(args.Target))) return; + if (args.Handled || !args.CanReach || args.Target != null && !HasComp(args.Target)) + return; if (TryPryTile(uid, args.User, component, args.ClickLocation)) args.Handled = true; @@ -33,26 +32,28 @@ public sealed partial class ToolSystem var coords = GetCoordinates(args.Coordinates); var gridUid = coords.GetGridUid(EntityManager); - if (!_mapManager.TryGetGrid(gridUid, out var grid)) + if (!TryComp(gridUid, out MapGridComponent? grid)) { Log.Error("Attempted to pry from a non-existent grid?"); return; } - var tile = grid.GetTileRef(coords); - var center = _turf.GetTileCenter(tile); + var tile = _maps.GetTileRef(gridUid.Value, grid, coords); + var center = _turfs.GetTileCenter(tile); + if (args.Used != null) { _adminLogger.Add(LogType.Tile, LogImpact.Low, - $"{ToPrettyString(args.User):actor} used {ToPrettyString(args.Used.Value):tool} to pry {_tileDefinitionManager[tile.Tile.TypeId].Name} at {center}"); + $"{ToPrettyString(args.User):actor} used {ToPrettyString(args.Used.Value):tool} to pry {_tileDefManager[tile.Tile.TypeId].Name} at {center}"); } else { _adminLogger.Add(LogType.Tile, LogImpact.Low, - $"{ToPrettyString(args.User):actor} pried {_tileDefinitionManager[tile.Tile.TypeId].Name} at {center}"); + $"{ToPrettyString(args.User):actor} pried {_tileDefManager[tile.Tile.TypeId].Name} at {center}"); } - _tile.PryTile(tile, component.Advanced); + if (_netManager.IsServer) + _tiles.PryTile(tile, component.Advanced); } private bool TryPryTile(EntityUid toolEntity, EntityUid user, TilePryingComponent component, EntityCoordinates clickLocation) @@ -60,17 +61,16 @@ public sealed partial class ToolSystem if (!TryComp(toolEntity, out var tool) && component.ToolComponentNeeded) return false; - if (!_mapManager.TryFindGridAt(clickLocation.ToMap(EntityManager, _transformSystem), out _, out var mapGrid)) + if (!_mapManager.TryFindGridAt(clickLocation.ToMap(EntityManager, _transformSystem), out var gridUid, out var mapGrid)) return false; - var tile = mapGrid.GetTileRef(clickLocation); - - var coordinates = mapGrid.GridTileToLocal(tile.GridIndices); + var tile = _maps.GetTileRef(gridUid, mapGrid, clickLocation); + var coordinates = _maps.GridTileToLocal(gridUid, mapGrid, tile.GridIndices); - if (!_interactionSystem.InRangeUnobstructed(user, coordinates, popup: false)) + if (!InteractionSystem.InRangeUnobstructed(user, coordinates, popup: false)) return false; - var tileDef = (ContentTileDefinition)_tileDefinitionManager[tile.Tile.TypeId]; + var tileDef = (ContentTileDefinition) _tileDefManager[tile.Tile.TypeId]; if (!tileDef.CanCrowbar && !(tileDef.CanAxe && component.Advanced)) return false; diff --git a/Content.Shared/Tools/Systems/SharedToolSystem.cs b/Content.Shared/Tools/Systems/SharedToolSystem.cs index 716a9332d0..c1a2bdc2dd 100644 --- a/Content.Shared/Tools/Systems/SharedToolSystem.cs +++ b/Content.Shared/Tools/Systems/SharedToolSystem.cs @@ -1,22 +1,35 @@ +using Content.Shared.Administration.Logs; using Content.Shared.DoAfter; +using Content.Shared.Interaction; +using Content.Shared.Maps; using Content.Shared.Tools.Components; using Robust.Shared.Map; +using Robust.Shared.Network; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; -using Robust.Shared.Timing; using Robust.Shared.Utility; -namespace Content.Shared.Tools; +namespace Content.Shared.Tools.Systems; public abstract partial class SharedToolSystem : EntitySystem { - [Dependency] private readonly IPrototypeManager _protoMan = default!; - [Dependency] private readonly SharedAudioSystem _audioSystem = default!; - [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; + [Dependency] private readonly IMapManager _mapManager = default!; + [Dependency] private readonly INetManager _netManager = default!; + [Dependency] private readonly IPrototypeManager _protoMan = default!; + [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; + [Dependency] private readonly ITileDefinitionManager _tileDefManager = default!; + [Dependency] private readonly SharedAudioSystem _audioSystem = default!; + [Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!; + [Dependency] protected readonly SharedInteractionSystem InteractionSystem = default!; + [Dependency] private readonly SharedMapSystem _maps = default!; + [Dependency] private readonly SharedTransformSystem _transformSystem = default!; + [Dependency] private readonly TileSystem _tiles = default!; + [Dependency] private readonly TurfSystem _turfs = default!; public override void Initialize() { InitializeMultipleTool(); + InitializeTilePrying(); SubscribeLocalEvent(OnDoAfter); } -- 2.51.2