]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fixes obsolete Transform warnings in Content. (#25256)
authorTemporalOroboros <TemporalOroboros@gmail.com>
Tue, 27 Feb 2024 01:06:20 +0000 (17:06 -0800)
committerGitHub <noreply@github.com>
Tue, 27 Feb 2024 01:06:20 +0000 (12:06 +1100)
* Fix TransformComponent.MapPosition warnings in Content.Client

* Fix TransformComponent.MapPosition warnings in Content.IntegrationTests

* Fix TransformComponent.MapPosition warnings in Content.Shared

* Fix TransformComponent.MapPosition warnings in Content.Server

* Fix TransformComponent.WorldPosition warnings in Content.Shared

* Fix TransformComponent.WorldPosition warnings in Content.Client
Excepts ClickableComponent b/c that needs to be ECS'd entirely later

* Fix TransformComponent.WorldPosition warnings in Content.Server

* Fix TransformComponent.WorldRotation warnings in Content.*

* Fix TransformComponent.MapPosition warnings I missed

* Fix TransformComponent.WorldMatrix warnings in Content.*

* Fix TransformComponent.InvWorldMatrix warnings in Content.*

* Fix TransformComponent.GetWorldPositionRotationMatrixWithInv warnings in Content.*

* Fix TransformComponent.GetWorldPositionRotationMatrix warnings in Content.*

* Fix TransformComponent.GetWorldPositionRotation warnings in Content.*

* Fix TransformComponent.Anchored.set warnings in Content.*

* Fix TransformComponent.Coordinates.set warnings in Content.*

* Fix TransformComponent.LocalPosition.set warnings in Content.*

* Fix TransformComponent.AttachToGridOrMap warnings in Content.*

* Fix TransformComponent.AttachParent warnings in Content.*

* Preempt TransformComponent.LocalRotation.set warnings in Content.Shared

* Preempt TransformComponent.LocalRotation.set warnings in Content.Client

* Preempt TransformComponent.LocalRotation.set warnings in Content.IntegrationTests

* Preempt TransformComponent.LocalRotation.set warnings in Content.Server

* Fix/Preempt the remaining obsolete TransformComponent properties/methods in Content.*

* ECS ClickableComponent

* Fix obsolete SharedTransformSystem methods in Content.*

* Fix ExplosionOverlay `SharedTransformSystem` dependency

* Maybe fix null eye position breaking tests

* MGS requested changes

154 files changed:
Content.Client/Administration/UI/SpawnExplosion/SpawnExplosionWindow.xaml.cs
Content.Client/Atmos/Overlays/GasTileOverlay.cs
Content.Client/CardboardBox/CardboardBoxSystem.cs
Content.Client/Chat/UI/SpeechBubble.cs
Content.Client/Clickable/ClickableComponent.cs
Content.Client/Clickable/ClickableSystem.cs [new file with mode: 0644]
Content.Client/Construction/ConstructionSystem.cs
Content.Client/Explosion/ExplosionOverlay.cs
Content.Client/Fluids/PuddleOverlay.cs
Content.Client/GPS/UI/HandheldGpsStatusControl.cs
Content.Client/Gameplay/GameplayStateBase.cs
Content.Client/Guidebook/GuidebookSystem.cs
Content.Client/HotPotato/HotPotatoSystem.cs
Content.Client/Interaction/DragDropSystem.cs
Content.Client/Maps/GridDraggingSystem.cs
Content.Client/MouseRotator/MouseRotatorSystem.cs
Content.Client/NPC/HTN/HTNOverlay.cs
Content.Client/NPC/NPCSteeringSystem.cs
Content.Client/NPC/PathfindingSystem.cs
Content.Client/NetworkConfigurator/NetworkConfiguratorLinkOverlay.cs
Content.Client/NodeContainer/NodeVisualizationOverlay.cs
Content.Client/Outline/TargetOutlineSystem.cs
Content.Client/Pinpointer/NavMapSystem.cs
Content.Client/Radiation/Overlays/RadiationPulseOverlay.cs
Content.Client/Replay/Spectator/ReplaySpectatorSystem.Position.cs
Content.Client/Replay/Spectator/ReplaySpectatorSystem.Spectate.cs
Content.Client/Shuttles/Systems/ShuttleSystem.EmergencyConsole.cs
Content.Client/Shuttles/UI/DockingControl.cs
Content.Client/Shuttles/UI/ShuttleConsoleWindow.xaml.cs
Content.Client/Sprite/SpriteFadeSystem.cs
Content.Client/Stealth/StealthSystem.cs
Content.Client/Tabletop/TabletopSystem.cs
Content.Client/UserInterface/Systems/Chat/ChatUIController.cs
Content.Client/UserInterface/Systems/Viewport/ViewportUIController.cs
Content.Client/Verbs/VerbSystem.cs
Content.Client/Weapons/Melee/MeleeArcOverlay.cs
Content.Client/Weapons/Melee/MeleeWeaponSystem.Effects.cs
Content.Client/Weapons/Melee/MeleeWeaponSystem.cs
Content.Client/Weapons/Ranged/GunSpreadOverlay.cs
Content.Client/Weapons/Ranged/Systems/GunSystem.cs
Content.IntegrationTests/Tests/ClickableTest.cs
Content.IntegrationTests/Tests/Disposal/DisposalUnitTest.cs
Content.IntegrationTests/Tests/Hands/HandTests.cs
Content.IntegrationTests/Tests/Interaction/InRangeUnobstructed.cs
Content.IntegrationTests/Tests/Power/PowerTest.cs
Content.IntegrationTests/Tests/Shuttle/DockTest.cs
Content.Server/Administration/Commands/AGhost.cs
Content.Server/Administration/Commands/ExplosionCommand.cs
Content.Server/Administration/Commands/WarpCommand.cs
Content.Server/Administration/Systems/AdminVerbSystem.Smites.cs
Content.Server/Anomaly/Effects/BluespaceAnomalySystem.cs
Content.Server/Anomaly/Effects/ElectricityAnomalySystem.cs
Content.Server/Anomaly/Effects/InjectionAnomalySystem.cs
Content.Server/Atmos/EntitySystems/AirFilterSystem.cs
Content.Server/Atmos/EntitySystems/AirtightSystem.cs
Content.Server/Atmos/EntitySystems/AtmosphereSystem.HighPressureDelta.cs
Content.Server/Beam/BeamSystem.cs
Content.Server/Botany/Systems/LogSystem.cs
Content.Server/Chemistry/EntitySystems/RehydratableSystem.cs
Content.Server/Chemistry/EntitySystems/VaporSystem.cs
Content.Server/Chemistry/ReactionEffects/AreaReactionEffect.cs
Content.Server/Chemistry/ReactionEffects/CreateEntityReactionEffect.cs
Content.Server/Chemistry/ReactionEffects/EmpReactionEffect.cs
Content.Server/Cloning/CloningSystem.cs
Content.Server/Commands/CommandUtils.cs
Content.Server/Construction/Commands/FixRotationsCommand.cs
Content.Server/Construction/Completions/SetAnchor.cs
Content.Server/Construction/Completions/SnapToGrid.cs
Content.Server/Construction/ConstructionSystem.Graph.cs
Content.Server/Construction/ConstructionSystem.Initial.cs
Content.Server/Destructible/DestructibleSystem.cs
Content.Server/Destructible/Thresholds/Behaviors/DumpRestockInventory.cs
Content.Server/Destructible/Thresholds/Behaviors/SpawnEntitiesBehavior.cs
Content.Server/DeviceNetwork/Systems/WirelessNetworkSystem.cs
Content.Server/Disposal/Tube/DisposalTubeSystem.cs
Content.Server/Dragon/DragonSystem.cs
Content.Server/Emp/EmpSystem.cs
Content.Server/Explosion/EntitySystems/ExplosionGridTileFlood.cs
Content.Server/Explosion/EntitySystems/ExplosionSystem.GridMap.cs
Content.Server/Explosion/EntitySystems/ExplosionSystem.TileFill.cs
Content.Server/Explosion/EntitySystems/ExplosionSystem.cs
Content.Server/Explosion/EntitySystems/SmokeOnTriggerSystem.cs
Content.Server/Explosion/EntitySystems/TriggerSystem.cs
Content.Server/Flash/FlashSystem.cs
Content.Server/Fluids/EntitySystems/DrainSystem.cs
Content.Server/Fluids/EntitySystems/PuddleDebugDebugOverlaySystem.cs
Content.Server/GameTicking/GameTicker.Spawning.cs
Content.Server/GameTicking/Rules/DeathMatchRuleSystem.cs
Content.Server/GameTicking/Rules/PiratesRuleSystem.cs
Content.Server/GameTicking/Rules/VariationPass/BaseEntityReplaceVariationPassSystem.cs
Content.Server/Gatherable/GatherableSystem.cs
Content.Server/Guardian/GuardianSystem.cs
Content.Server/Hands/Systems/HandsSystem.cs
Content.Server/ImmovableRod/ImmovableRodSystem.cs
Content.Server/Kitchen/EntitySystems/SharpSystem.cs
Content.Server/Lightning/LightningSystem.cs
Content.Server/Lightning/LightningTargetSystem.cs
Content.Server/Magic/MagicSystem.cs
Content.Server/Maps/GridDraggingSystem.cs
Content.Server/Mech/Equipment/EntitySystems/MechGrabberSystem.cs
Content.Server/NPC/Pathfinding/PathfindingSystem.Distance.cs
Content.Server/NPC/Pathfinding/PathfindingSystem.cs
Content.Server/NPC/Systems/NPCSteeringSystem.cs
Content.Server/NPC/Systems/NPCUtilitySystem.cs
Content.Server/NPC/Systems/NpcFactionSystem.cs
Content.Server/Nuke/NukeSystem.cs
Content.Server/Nutrition/EntitySystems/FoodSystem.cs
Content.Server/PDA/Ringer/RingerSystem.cs
Content.Server/Parallax/BiomeSystem.cs
Content.Server/Payload/EntitySystems/PayloadSystem.cs
Content.Server/Physics/Controllers/PullController.cs
Content.Server/Pointing/EntitySystems/PointingSystem.cs
Content.Server/Pointing/EntitySystems/RoguePointingSystem.cs
Content.Server/Procedural/DungeonSystem.Rooms.cs
Content.Server/Respawn/SpecialRespawnSystem.cs
Content.Server/Revenant/EntitySystems/RevenantSystem.Abilities.cs
Content.Server/Rotatable/RotatableSystem.cs
Content.Server/Shuttles/Systems/ShuttleSystem.FasterThanLight.cs
Content.Server/Shuttles/Systems/ShuttleSystem.GridFill.cs
Content.Server/Shuttles/Systems/ShuttleSystem.Impact.cs
Content.Server/Singularity/EntitySystems/ContainmentFieldGeneratorSystem.cs
Content.Server/Singularity/EntitySystems/ContainmentFieldSystem.cs
Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs
Content.Server/Solar/EntitySystems/PowerSolarSystem.cs
Content.Server/Standing/StandingStateSystem.cs
Content.Server/Worldgen/Systems/BaseWorldSystem.cs
Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/EmpArtifactSystem.cs
Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/SpawnArtifactSystem.cs
Content.Server/Xenoarchaeology/XenoArtifacts/Effects/Systems/ThrowArtifactSystem.cs
Content.Shared/Buckle/SharedBuckleSystem.Buckle.cs
Content.Shared/Construction/Conditions/WallmountCondition.cs
Content.Shared/Construction/EntitySystems/AnchorableSystem.cs
Content.Shared/Containers/ContainerFillSystem.cs
Content.Shared/DeviceLinking/SharedDeviceLinkSystem.cs
Content.Shared/Examine/ExamineSystemShared.cs
Content.Shared/Hands/EntitySystems/SharedHandsSystem.Drop.cs
Content.Shared/Hands/EntitySystems/SharedHandsSystem.Pickup.cs
Content.Shared/Interaction/RotateToFaceSystem.cs
Content.Shared/Interaction/SharedInteractionSystem.cs
Content.Shared/Maps/TileSystem.cs
Content.Shared/Maps/TurfHelpers.cs
Content.Shared/Movement/Systems/SharedMoverController.cs
Content.Shared/Ninja/Systems/DashAbilitySystem.cs
Content.Shared/Physics/Controllers/SharedConveyorController.cs
Content.Shared/Placeable/PlaceableSurfaceSystem.cs
Content.Shared/RCD/Systems/RCDSystem.cs
Content.Shared/Random/RandomHelperSystem.cs
Content.Shared/Stealth/SharedStealthSystem.cs
Content.Shared/Storage/EntitySystems/MagnetPickupSystem.cs
Content.Shared/Tabletop/SharedTabletopSystem.cs
Content.Shared/Throwing/ThrowingSystem.cs
Content.Shared/Weapons/Misc/SharedTetherGunSystem.cs
Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.Ballistic.cs
Content.Shared/Weapons/Ranged/Systems/SharedGunSystem.cs

index 5f187cad794efe8df987aef0db7c698cefd520a9..f90637a649e272ac56af452dd2695730872e9a7f 100644 (file)
@@ -22,6 +22,7 @@ public sealed partial class SpawnExplosionWindow : DefaultWindow
     [Dependency] private readonly IPlayerManager _playerManager = default!;
     [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
     [Dependency] private readonly IEntityManager _entMan = default!;
+    private SharedTransformSystem? _xformSystem = null;
 
 
     private readonly SpawnExplosionEui _eui;
@@ -102,9 +103,13 @@ public sealed partial class SpawnExplosionWindow : DefaultWindow
         if (!_entMan.TryGetComponent(_playerManager.LocalEntity, out TransformComponent? transform))
             return;
 
+        _xformSystem ??= _entMan.SystemOrNull<SharedTransformSystem>();
+        if (_xformSystem is null)
+            return;
+
         _pausePreview = true;
         MapOptions.Select(_mapData.IndexOf(transform.MapID));
-        (MapX.Value, MapY.Value) = transform.MapPosition.Position;
+        (MapX.Value, MapY.Value) = _xformSystem.GetWorldPosition(transform);
         _pausePreview = false;
 
         UpdatePreview();
index ef65d43fe85ecaa019955524eb1013323b61de9b..4bbc4654fb4e087e251bed51f9dfbd3cc0eec0f3 100644 (file)
@@ -22,6 +22,7 @@ namespace Content.Client.Atmos.Overlays
     {
         private readonly IEntityManager _entManager;
         private readonly IMapManager _mapManager;
+        private readonly SharedTransformSystem _xformSystem;
 
         public override OverlaySpace Space => OverlaySpace.WorldSpaceEntities;
         private readonly ShaderInstance _shader;
@@ -51,6 +52,7 @@ namespace Content.Client.Atmos.Overlays
         {
             _entManager = entManager;
             _mapManager = IoCManager.Resolve<IMapManager>();
+            _xformSystem = _entManager.System<SharedTransformSystem>();
             _shader = protoMan.Index<ShaderPrototype>("unshaded").Instance();
             ZIndex = GasOverlayZIndex;
 
@@ -156,7 +158,8 @@ namespace Content.Client.Atmos.Overlays
                 _fireFrameCounter,
                 _shader,
                 overlayQuery,
-                xformQuery);
+                xformQuery,
+                _xformSystem);
 
             var mapUid = _mapManager.GetMapEntityId(args.MapId);
 
@@ -194,7 +197,8 @@ namespace Content.Client.Atmos.Overlays
                         int[] fireFrameCounter,
                         ShaderInstance shader,
                         EntityQuery<GasTileOverlayComponent> overlayQuery,
-                        EntityQuery<TransformComponent> xformQuery) state) =>
+                        EntityQuery<TransformComponent> xformQuery,
+                        SharedTransformSystem xformSystem) state) =>
                 {
                     if (!state.overlayQuery.TryGetComponent(uid, out var comp) ||
                         !state.xformQuery.TryGetComponent(uid, out var gridXform))
@@ -202,7 +206,7 @@ namespace Content.Client.Atmos.Overlays
                             return true;
                         }
 
-                    var (_, _, worldMatrix, invMatrix) = gridXform.GetWorldPositionRotationMatrixWithInv();
+                    var (_, _, worldMatrix, invMatrix) = state.xformSystem.GetWorldPositionRotationMatrixWithInv(gridXform);
                     state.drawHandle.SetTransform(worldMatrix);
                     var floatBounds = invMatrix.TransformBox(in state.WorldBounds).Enlarged(grid.TileSize);
                     var localBounds = new Box2i(
index 50f9de239d5209f2c9adc2c32dee98dd2cde62f7..fc4f1e079caf6ccf93add6a9f6552b37bf60f4ef 100644 (file)
@@ -30,7 +30,7 @@ public sealed class CardboardBoxSystem : SharedCardboardBoxSystem
         if (!xformQuery.TryGetComponent(source, out var xform))
             return;
 
-        var sourcePos = _transform.GetMapCoordinates(source, xform);
+        var sourcePos = _transform.GetMapCoordinates((source, xform));
 
         //Any mob that can move should be surprised?
         //God mind rework needs to come faster so it can just check for mind
index 82eccbcec84b4f49b39c2f8ca5c22c081fcd5794..48b1c9dc42eba3468850070e098f9f3fc5105226 100644 (file)
@@ -15,6 +15,7 @@ namespace Content.Client.Chat.UI
     {
         [Dependency] private readonly IEyeManager _eyeManager = default!;
         [Dependency] private readonly IEntityManager _entityManager = default!;
+        [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
         [Dependency] protected readonly IConfigurationManager ConfigManager = default!;
 
         public enum SpeechType : byte
@@ -82,6 +83,7 @@ namespace Content.Client.Chat.UI
         public SpeechBubble(ChatMessage message, EntityUid senderEntity, string speechStyleClass, Color? fontColor = null)
         {
             IoCManager.InjectDependencies(this);
+            _xformSystem = _entityManager.System<SharedTransformSystem>();
             _senderEntity = senderEntity;
 
             // Use text clipping so new messages don't overlap old ones being pushed up.
@@ -140,7 +142,7 @@ namespace Content.Client.Chat.UI
             }
 
             var offset = (-_eyeManager.CurrentEye.Rotation).ToWorldVec() * -EntityVerticalOffset;
-            var worldPos = xform.WorldPosition + offset;
+            var worldPos = _xformSystem.GetWorldPosition(xform) + offset;
 
             var lowerCenter = _eyeManager.WorldToScreen(worldPos) / UIScale;
             var screenPos = lowerCenter - new Vector2(ContentSize.X / 2, ContentSize.Y + _verticalOffsetAchieved);
index cfbd1a99d69b40eda42e3de022e5d1436a7ef455..27b3437a2f570a044761c6998c3fb6d38f459819 100644 (file)
-using System.Numerics;
-using Robust.Client.GameObjects;
-using Robust.Client.Graphics;
-using Robust.Client.Utility;
-using Robust.Shared.Graphics;
-using static Robust.Client.GameObjects.SpriteComponent;
-using Direction = Robust.Shared.Maths.Direction;
+namespace Content.Client.Clickable;
 
-namespace Content.Client.Clickable
+/// <summary>
+/// Makes it possible to click the associated entity.
+/// </summary>
+[RegisterComponent]
+public sealed partial class ClickableComponent : Component
 {
-    [RegisterComponent]
-    public sealed partial class ClickableComponent : Component
+    /// <summary>
+    /// A set of AABBs used as an approximate check for whether a click could hit this entity.
+    /// </summary>
+    [DataField("bounds")]
+    public DirBoundData? Bounds;
+
+    /// <summary>
+    /// A set of AABBs associated with the cardinal directions used for approximate click intersection calculations.
+    /// </summary>
+    [DataDefinition]
+    public sealed partial class DirBoundData
     {
-        [Dependency] private readonly IClickMapManager _clickMapManager = default!;
-
-        [DataField("bounds")] public DirBoundData? Bounds;
-
-        /// <summary>
-        /// Used to check whether a click worked. Will first check if the click falls inside of some explicit bounding
-        /// boxes (see <see cref="Bounds"/>). If that fails, attempts to use automatically generated click maps.
-        /// </summary>
-        /// <param name="worldPos">The world position that was clicked.</param>
-        /// <param name="drawDepth">
-        /// The draw depth for the sprite that captured the click.
-        /// </param>
-        /// <returns>True if the click worked, false otherwise.</returns>
-        public bool CheckClick(SpriteComponent sprite, TransformComponent transform, EntityQuery<TransformComponent> xformQuery, Vector2 worldPos, IEye eye, out int drawDepth, out uint renderOrder, out float bottom)
-        {
-            if (!sprite.Visible)
-            {
-                drawDepth = default;
-                renderOrder = default;
-                bottom = default;
-                return false;
-            }
-
-            drawDepth = sprite.DrawDepth;
-            renderOrder = sprite.RenderOrder;
-            var (spritePos, spriteRot) = transform.GetWorldPositionRotation(xformQuery);
-            var spriteBB = sprite.CalculateRotatedBoundingBox(spritePos, spriteRot, eye.Rotation);
-            bottom = Matrix3.CreateRotation(eye.Rotation).TransformBox(spriteBB).Bottom;
-
-            var invSpriteMatrix = Matrix3.Invert(sprite.GetLocalMatrix());
-
-            // This should have been the rotation of the sprite relative to the screen, but this is not the case with no-rot or directional sprites.
-            var relativeRotation = (spriteRot + eye.Rotation).Reduced().FlipPositive();
-
-            Angle cardinalSnapping = sprite.SnapCardinals ? relativeRotation.GetCardinalDir().ToAngle() : Angle.Zero;
-
-            // First we get `localPos`, the clicked location in the sprite-coordinate frame.
-            var entityXform = Matrix3.CreateInverseTransform(transform.WorldPosition, sprite.NoRotation ? -eye.Rotation : spriteRot - cardinalSnapping);
-            var localPos = invSpriteMatrix.Transform(entityXform.Transform(worldPos));
-
-            // Check explicitly defined click-able bounds
-            if (CheckDirBound(sprite, relativeRotation, localPos))
-                return true;
-
-            // Next check each individual sprite layer using automatically computed click maps.
-            foreach (var spriteLayer in sprite.AllLayers)
-            {
-                if (!spriteLayer.Visible || spriteLayer is not Layer layer)
-                    continue;
-
-                // Check the layer's texture, if it has one
-                if (layer.Texture != null)
-                {
-                    // Convert to image coordinates
-                    var imagePos = (Vector2i) (localPos * EyeManager.PixelsPerMeter * new Vector2(1, -1) + layer.Texture.Size / 2f);
-
-                    if (_clickMapManager.IsOccluding(layer.Texture, imagePos))
-                        return true;
-                }
-
-                // Either we weren't clicking on the texture, or there wasn't one. In which case: check the RSI next
-                if (layer.ActualRsi is not { } rsi || !rsi.TryGetState(layer.State, out var rsiState))
-                    continue;
-
-                var dir = Layer.GetDirection(rsiState.RsiDirections, relativeRotation);
-
-                // convert to layer-local coordinates
-                layer.GetLayerDrawMatrix(dir, out var matrix);
-                var inverseMatrix = Matrix3.Invert(matrix);
-                var layerLocal = inverseMatrix.Transform(localPos);
-
-                // Convert to image coordinates
-                var layerImagePos = (Vector2i) (layerLocal * EyeManager.PixelsPerMeter * new Vector2(1, -1) + rsiState.Size / 2f);
-
-                // Next, to get the right click map we need the "direction" of this layer that is actually being used to draw the sprite on the screen.
-                // This **can** differ from the dir defined before, but can also just be the same.
-                if (sprite.EnableDirectionOverride)
-                    dir = sprite.DirectionOverride.Convert(rsiState.RsiDirections);
-                dir = dir.OffsetRsiDir(layer.DirOffset);
-
-                if (_clickMapManager.IsOccluding(layer.ActualRsi!, layer.State, dir, layer.AnimationFrame, layerImagePos))
-                    return true;
-            }
-
-            drawDepth = default;
-            renderOrder = default;
-            bottom = default;
-            return false;
-        }
-
-        public bool CheckDirBound(SpriteComponent sprite, Angle relativeRotation, Vector2 localPos)
-        {
-            if (Bounds == null)
-                return false;
-
-            // These explicit bounds only work for either 1 or 4 directional sprites.
-
-            // This would be the orientation of a 4-directional sprite.
-            var direction = relativeRotation.GetCardinalDir();
-
-            var modLocalPos = sprite.NoRotation
-                ? localPos
-                : direction.ToAngle().RotateVec(localPos);
-
-            // First, check the bounding box that is valid for all orientations
-            if (Bounds.All.Contains(modLocalPos))
-                return true;
-
-            // Next, get and check the appropriate bounding box for the current sprite orientation
-            var boundsForDir = (sprite.EnableDirectionOverride ? sprite.DirectionOverride : direction) switch
-            {
-                Direction.East => Bounds.East,
-                Direction.North => Bounds.North,
-                Direction.South => Bounds.South,
-                Direction.West => Bounds.West,
-                _ => throw new InvalidOperationException()
-            };
-
-            return boundsForDir.Contains(modLocalPos);
-        }
-
-        [DataDefinition]
-        public sealed partial class DirBoundData
-        {
-            [DataField("all")] public Box2 All;
-            [DataField("north")] public Box2 North;
-            [DataField("south")] public Box2 South;
-            [DataField("east")] public Box2 East;
-            [DataField("west")] public Box2 West;
-        }
+        [DataField("all")] public Box2 All;
+        [DataField("north")] public Box2 North;
+        [DataField("south")] public Box2 South;
+        [DataField("east")] public Box2 East;
+        [DataField("west")] public Box2 West;
     }
 }
diff --git a/Content.Client/Clickable/ClickableSystem.cs b/Content.Client/Clickable/ClickableSystem.cs
new file mode 100644 (file)
index 0000000..9a96aef
--- /dev/null
@@ -0,0 +1,144 @@
+using Robust.Client.GameObjects;
+using Robust.Client.Graphics;
+using static Robust.Client.GameObjects.SpriteComponent;
+using Robust.Client.Utility;
+using Robust.Shared.Graphics;
+using Direction = Robust.Shared.Maths.Direction;
+using System.Numerics;
+
+namespace Content.Client.Clickable;
+
+public sealed partial class ClickableSystem : EntitySystem
+{
+    [Dependency] private readonly IClickMapManager _clickMapManager = default!;
+    [Dependency] private readonly SharedTransformSystem _transformSystem = default!;
+
+    /// <summary>
+    /// Used to check whether a click worked. Will first check if the click falls inside of some explicit bounding
+    /// boxes (see <see cref="Bounds"/>). If that fails, attempts to use automatically generated click maps.
+    /// </summary>
+    /// <param name="entity">The entity that we are trying to click.</param>
+    /// <param name="worldPos">The world position that was clicked.</param>
+    /// <param name="eye">The PoV the click is originating from.</param>
+    /// <param name="drawDepth">The draw depth for the sprite that captured the click.</param>
+    /// <param name="renderOrder">The render order for the sprite that captured the click.</param>
+    /// <param name="bottom">The bottom of the sprite AABB from the perspective of the eye doing the click.</param>
+    /// <returns>True if the click worked, false otherwise.</returns>
+    public bool CheckClick(Entity<ClickableComponent, SpriteComponent, TransformComponent> entity, Vector2 worldPos, IEye eye, out int drawDepth, out uint renderOrder, out float bottom)
+    {
+        var (uid, clickable, sprite, xform) = entity;
+
+        if (!sprite.Visible)
+        {
+            drawDepth = default;
+            renderOrder = default;
+            bottom = default;
+            return false;
+        }
+
+        drawDepth = sprite.DrawDepth;
+        renderOrder = sprite.RenderOrder;
+        var (spritePos, spriteRot) = _transformSystem.GetWorldPositionRotation(xform);
+        var spriteBB = sprite.CalculateRotatedBoundingBox(spritePos, spriteRot, eye.Rotation);
+        bottom = Matrix3.CreateRotation(eye.Rotation).TransformBox(spriteBB).Bottom;
+
+        var invSpriteMatrix = Matrix3.Invert(sprite.GetLocalMatrix());
+
+        // This should have been the rotation of the sprite relative to the screen, but this is not the case with no-rot or directional sprites.
+        var relativeRotation = (spriteRot + eye.Rotation).Reduced().FlipPositive();
+
+        Angle cardinalSnapping = sprite.SnapCardinals ? relativeRotation.GetCardinalDir().ToAngle() : Angle.Zero;
+
+        // First we get `localPos`, the clicked location in the sprite-coordinate frame.
+        var entityXform = Matrix3.CreateInverseTransform(_transformSystem.GetWorldPosition(xform), sprite.NoRotation ? -eye.Rotation : spriteRot - cardinalSnapping);
+        var localPos = invSpriteMatrix.Transform(entityXform.Transform(worldPos));
+
+        // Check explicitly defined click-able bounds
+        if (CheckDirBound((uid, clickable, sprite), relativeRotation, localPos))
+            return true;
+
+        // Next check each individual sprite layer using automatically computed click maps.
+        foreach (var spriteLayer in sprite.AllLayers)
+        {
+            if (!spriteLayer.Visible || spriteLayer is not Layer layer)
+                continue;
+
+            // Check the layer's texture, if it has one
+            if (layer.Texture != null)
+            {
+                // Convert to image coordinates
+                var imagePos = (Vector2i) (localPos * EyeManager.PixelsPerMeter * new Vector2(1, -1) + layer.Texture.Size / 2f);
+
+                if (_clickMapManager.IsOccluding(layer.Texture, imagePos))
+                    return true;
+            }
+
+            // Either we weren't clicking on the texture, or there wasn't one. In which case: check the RSI next
+            if (layer.ActualRsi is not { } rsi || !rsi.TryGetState(layer.State, out var rsiState))
+                continue;
+
+            var dir = Layer.GetDirection(rsiState.RsiDirections, relativeRotation);
+
+            // convert to layer-local coordinates
+            layer.GetLayerDrawMatrix(dir, out var matrix);
+            var inverseMatrix = Matrix3.Invert(matrix);
+            var layerLocal = inverseMatrix.Transform(localPos);
+
+            // Convert to image coordinates
+            var layerImagePos = (Vector2i) (layerLocal * EyeManager.PixelsPerMeter * new Vector2(1, -1) + rsiState.Size / 2f);
+
+            // Next, to get the right click map we need the "direction" of this layer that is actually being used to draw the sprite on the screen.
+            // This **can** differ from the dir defined before, but can also just be the same.
+            if (sprite.EnableDirectionOverride)
+                dir = sprite.DirectionOverride.Convert(rsiState.RsiDirections);
+            dir = dir.OffsetRsiDir(layer.DirOffset);
+
+            if (_clickMapManager.IsOccluding(layer.ActualRsi!, layer.State, dir, layer.AnimationFrame, layerImagePos))
+                return true;
+        }
+
+        drawDepth = default;
+        renderOrder = default;
+        bottom = default;
+        return false;
+    }
+
+    /// <summary>
+    /// Used to check whether a click worked lands inside of the AABB for the current sprite for a clickable entity.
+    /// </summary>
+    /// <param name="localPos">The world position that was clicked.</param>
+    /// <param name="relativeRotation">The angle of the entity to check relative to the PoV that the click is coming from.</param>
+    /// <returns>True if the click lands inside the relevant AABB.</returns>
+    public bool CheckDirBound(Entity<ClickableComponent, SpriteComponent> entity, Angle relativeRotation, Vector2 localPos)
+    {
+        var (uid, clickable, sprite) = entity;
+
+        if (clickable.Bounds == null)
+            return false;
+
+        // These explicit bounds only work for either 1 or 4 directional sprites.
+
+        // This would be the orientation of a 4-directional sprite.
+        var direction = relativeRotation.GetCardinalDir();
+
+        var modLocalPos = sprite.NoRotation
+            ? localPos
+            : direction.ToAngle().RotateVec(localPos);
+
+        // First, check the bounding box that is valid for all orientations
+        if (clickable.Bounds.All.Contains(modLocalPos))
+            return true;
+
+        // Next, get and check the appropriate bounding box for the current sprite orientation
+        var boundsForDir = (sprite.EnableDirectionOverride ? sprite.DirectionOverride : direction) switch
+        {
+            Direction.East => clickable.Bounds.East,
+            Direction.North => clickable.Bounds.North,
+            Direction.South => clickable.Bounds.South,
+            Direction.West => clickable.Bounds.West,
+            _ => throw new InvalidOperationException()
+        };
+
+        return boundsForDir.Contains(modLocalPos);
+    }
+}
index ae1724c3bf63c58f4dff4627fcfc209dd402de97..cd76778ac6c0445f12bd6e3a87e99531a10aa8d7 100644 (file)
@@ -27,6 +27,7 @@ namespace Content.Client.Construction
         [Dependency] private readonly IPlayerManager _playerManager = default!;
         [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
         [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
+        [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
         [Dependency] private readonly PopupSystem _popupSystem = default!;
 
         private readonly Dictionary<int, EntityUid> _ghosts = new();
@@ -205,7 +206,7 @@ namespace Content.Client.Construction
             ghost = EntityManager.SpawnEntity("constructionghost", loc);
             var comp = EntityManager.GetComponent<ConstructionGhostComponent>(ghost.Value);
             comp.Prototype = prototype;
-            EntityManager.GetComponent<TransformComponent>(ghost.Value).LocalRotation = dir.ToAngle();
+            _xformSystem.SetLocalRotation(ghost.Value, dir.ToAngle());
             _ghosts.Add(ghost.GetHashCode(), ghost.Value);
             var sprite = EntityManager.GetComponent<SpriteComponent>(ghost.Value);
             sprite.Color = new Color(48, 255, 48, 128);
index 2d8c15f1b9f9ff3340e2c7d8acacbd706a8a824c..a8ffcd98bbc0bb6e47ed984dc2130633ab7a9600 100644 (file)
@@ -16,6 +16,7 @@ public sealed class ExplosionOverlay : Overlay
     [Dependency] private readonly IRobustRandom _robustRandom = default!;
     [Dependency] private readonly IEntityManager _entMan = default!;
     [Dependency] private readonly IPrototypeManager _proto = default!;
+    private SharedTransformSystem _xformSystem = default!;
 
     public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowFOV;
 
@@ -24,6 +25,7 @@ public sealed class ExplosionOverlay : Overlay
     public ExplosionOverlay()
     {
         IoCManager.InjectDependencies(this);
+        _xformSystem = _entMan.System<SharedTransformSystem>();
         _shader = _proto.Index<ShaderPrototype>("unshaded").Instance();
     }
 
@@ -67,7 +69,7 @@ public sealed class ExplosionOverlay : Overlay
                 continue;
 
             var xform = xforms.GetComponent(gridId);
-            var (_, _, worldMatrix, invWorldMatrix) = xform.GetWorldPositionRotationMatrixWithInv(xforms);
+            var (_, _, worldMatrix, invWorldMatrix) = _xformSystem.GetWorldPositionRotationMatrixWithInv(xform);
 
             gridBounds = invWorldMatrix.TransformBox(worldBounds).Enlarged(grid.TileSize * 2);
             drawHandle.SetTransform(worldMatrix);
index ac6661cfdd839ecb596751c0be1c466d2a9da8d3..612ea42a251ee9523b42a9bec059a9a9b30b795c 100644 (file)
@@ -13,6 +13,7 @@ public sealed class PuddleOverlay : Overlay
     [Dependency] private readonly IEntityManager _entityManager = default!;
     [Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
     private readonly PuddleDebugOverlaySystem _debugOverlaySystem;
+    private readonly SharedTransformSystem _xformSystem;
 
     private readonly Color _heavyPuddle = new(0, 255, 255, 50);
     private readonly Color _mediumPuddle = new(0, 150, 255, 50);
@@ -26,6 +27,7 @@ public sealed class PuddleOverlay : Overlay
     {
         IoCManager.InjectDependencies(this);
         _debugOverlaySystem = _entitySystemManager.GetEntitySystem<PuddleDebugOverlaySystem>();
+        _xformSystem = _entitySystemManager.GetEntitySystem<SharedTransformSystem>();
         var cache = IoCManager.Resolve<IResourceCache>();
         _font = new VectorFont(cache.GetResource<FontResource>("/Fonts/NotoSans/NotoSans-Regular.ttf"), 8);
     }
@@ -55,7 +57,7 @@ public sealed class PuddleOverlay : Overlay
                 continue;
 
             var gridXform = xformQuery.GetComponent(gridId);
-            var (_, _, worldMatrix, invWorldMatrix) = gridXform.GetWorldPositionRotationMatrixWithInv(xformQuery);
+            var (_, _, worldMatrix, invWorldMatrix) = _xformSystem.GetWorldPositionRotationMatrixWithInv(gridXform);
             gridBounds = invWorldMatrix.TransformBox(args.WorldBounds).Enlarged(mapGrid.TileSize * 2);
             drawHandle.SetTransform(worldMatrix);
 
@@ -88,7 +90,7 @@ public sealed class PuddleOverlay : Overlay
                 continue;
 
             var gridXform = xformQuery.GetComponent(gridId);
-            var (_, _, matrix, invMatrix) = gridXform.GetWorldPositionRotationMatrixWithInv(xformQuery);
+            var (_, _, matrix, invMatrix) = _xformSystem.GetWorldPositionRotationMatrixWithInv(gridXform);
             var gridBounds = invMatrix.TransformBox(args.WorldBounds).Enlarged(mapGrid.TileSize * 2);
 
             foreach (var debugOverlayData in _debugOverlaySystem.GetData(gridId))
index de6a1031bad0070f475409d4bd7aa11f01e88893..8e5aac92f7d940876f747d6dc7d1ee7c7c110977 100644 (file)
@@ -13,11 +13,13 @@ public sealed class HandheldGpsStatusControl : Control
     private readonly RichTextLabel _label;
     private float _updateDif;
     private readonly IEntityManager _entMan;
+    private readonly SharedTransformSystem _xformSystem;
 
     public HandheldGpsStatusControl(Entity<HandheldGPSComponent> parent)
     {
         _parent = parent;
         _entMan = IoCManager.Resolve<IEntityManager>();
+        _xformSystem = _entMan.System<SharedTransformSystem>();
         _label = new RichTextLabel { StyleClasses = { StyleNano.StyleClassItemStatus } };
         AddChild(_label);
         UpdateGpsDetails();
@@ -41,7 +43,7 @@ public sealed class HandheldGpsStatusControl : Control
         var posText = "Error";
         if (_entMan.TryGetComponent(_parent, out TransformComponent? transComp))
         {
-            var pos =  transComp.MapPosition;
+            var pos = _xformSystem.GetMapCoordinates((_parent, transComp));
             var x = (int) pos.X;
             var y = (int) pos.Y;
             posText = $"({x}, {y})";
index bdbd69d108636d526734e02d2754a44d13280902..e44adcfb2f3cc2e0404c2ae0b84f79cc627c6442 100644 (file)
@@ -116,7 +116,7 @@ namespace Content.Client.Gameplay
             // Check the entities against whether or not we can click them
             var foundEntities = new List<(EntityUid, int, uint, float)>(entities.Count);
             var clickQuery = _entityManager.GetEntityQuery<ClickableComponent>();
-            var xformQuery = _entityManager.GetEntityQuery<TransformComponent>();
+            var clickSystem = _entityManager.System<ClickableSystem>();
 
             // TODO: Smelly
             var eye = _eyeManager.CurrentEye;
@@ -124,7 +124,7 @@ namespace Content.Client.Gameplay
             foreach (var entity in entities)
             {
                 if (clickQuery.TryGetComponent(entity.Uid, out var component) &&
-                    component.CheckClick(entity.Component, entity.Transform, xformQuery, coordinates.Position, eye,  out var drawDepthClicked, out var renderOrder, out var bottom))
+                    clickSystem.CheckClick((entity.Uid, component, entity.Component, entity.Transform), coordinates.Position, eye,  out var drawDepthClicked, out var renderOrder, out var bottom))
                 {
                     foundEntities.Add((entity.Uid, drawDepthClicked, renderOrder, bottom));
                 }
index cb13d4ca6e5bcef858a9759031e43f3629d12f2f..fabdd47ed35c295da0f366faf2ca518488efe502 100644 (file)
@@ -30,6 +30,7 @@ public sealed class GuidebookSystem : EntitySystem
     [Dependency] private readonly RgbLightControllerSystem _rgbLightControllerSystem = default!;
     [Dependency] private readonly SharedPointLightSystem _pointLightSystem = default!;
     [Dependency] private readonly TagSystem _tags = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public event Action<List<string>, List<string>?, string?, bool, string?>? OnGuidebookOpen;
     public const string GuideEmbedTag = "GuideEmbeded";
@@ -98,8 +99,9 @@ public sealed class GuidebookSystem : EntitySystem
         {
             Act = () =>
             {
-                if (Transform(uid).LocalRotation != Angle.Zero)
-                    Transform(uid).LocalRotation -= Angle.FromDegrees(90);
+                var xform = Transform(uid);
+                if (xform.LocalRotation != Angle.Zero)
+                    _xformSystem.SetLocalRotation(uid, xform.LocalRotation - Angle.FromDegrees(90), xform);
             },
             Text = Loc.GetString("guidebook-monkey-unspin"),
             Priority = -9999,
@@ -130,7 +132,8 @@ public sealed class GuidebookSystem : EntitySystem
 
     private void OnGuidebookControlsTestActivateInWorld(EntityUid uid, GuidebookControlsTestComponent component, ActivateInWorldEvent args)
     {
-        Transform(uid).LocalRotation += Angle.FromDegrees(90);
+        var xform = Transform(uid);
+        _xformSystem.SetLocalRotation(uid, xform.LocalRotation + Angle.FromDegrees(90), xform);
     }
 
     private void OnGuidebookControlsTestInteractHand(EntityUid uid, GuidebookControlsTestComponent component, InteractHandEvent args)
index 028a3b70d9f42ac2511bb9d2fddaa797a28a3634..a9ded70accab7952add0172cf9c06e3cb283cc60 100644 (file)
@@ -22,6 +22,7 @@ public sealed class HotPotatoSystem : SharedHotPotatoSystem
         {
             if (_timing.CurTime < comp.TargetTime)
                 continue;
+
             comp.TargetTime = _timing.CurTime + TimeSpan.FromSeconds(comp.EffectCooldown);
             Spawn("HotPotatoEffect", _transform.GetMapCoordinates(uid).Offset(_random.NextVector2(0.25f)));
         }
index 8baa4d15fe4b229d82a66cdab52de69334b857c8..18b3381ba59001d0586397cf63e30007fba3b551 100644 (file)
@@ -42,6 +42,7 @@ public sealed class DragDropSystem : SharedDragDropSystem
     [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!;
     [Dependency] private readonly EntityLookupSystem _lookup = default!;
     [Dependency] private readonly SharedPopupSystem _popup = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     // how often to recheck possible targets (prevents calling expensive
     // check logic each update)
@@ -250,7 +251,7 @@ public sealed class DragDropSystem : SharedDragDropSystem
             dragSprite.DrawDepth = (int) DrawDepth.Overlays;
             if (!dragSprite.NoRotation)
             {
-                Transform(_dragShadow.Value).WorldRotation = Transform(_draggedEntity.Value).WorldRotation;
+                _xformSystem.SetWorldRotation(_dragShadow.Value, _xformSystem.GetWorldRotation(_draggedEntity.Value));
             }
 
             // drag initiated
@@ -551,7 +552,7 @@ public sealed class DragDropSystem : SharedDragDropSystem
         if (Exists(_dragShadow))
         {
             var mousePos = _eyeManager.PixelToMap(_inputManager.MouseScreenPosition);
-            Transform(_dragShadow.Value).WorldPosition = mousePos.Position;
+            _xformSystem.SetWorldPosition(_dragShadow.Value, mousePos.Position);
         }
     }
 }
index 16357c8983872092f2c89212b8b3c092fba6c10d..a5fa9743711f7480bec9c1a124bef5dd979b0191 100644 (file)
@@ -18,6 +18,7 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem
     [Dependency] private readonly IInputManager _inputManager = default!;
     [Dependency] private readonly IMapManager _mapManager = default!;
     [Dependency] private readonly InputSystem _inputSystem = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public bool Enabled { get; set; }
 
@@ -66,7 +67,7 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem
             xform.MapID == _lastMousePosition.Value.MapId)
         {
             var tickTime = _gameTiming.TickPeriod;
-            var distance = _lastMousePosition.Value.Position - xform.WorldPosition;
+            var distance = _lastMousePosition.Value.Position - _xformSystem.GetWorldPosition(xform);
             RaiseNetworkEvent(new GridDragVelocityRequest()
             {
                 Grid = GetNetEntity(_dragging.Value),
@@ -101,7 +102,7 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem
             if (!_mapManager.TryFindGridAt(mousePos, out var gridUid, out var grid))
                 return;
 
-            StartDragging(gridUid, Transform(gridUid).InvWorldMatrix.Transform(mousePos.Position));
+            StartDragging(gridUid, _xformSystem.GetInvWorldMatrix(gridUid).Transform(mousePos.Position));
         }
 
         if (!TryComp<TransformComponent>(_dragging, out var xform))
@@ -116,11 +117,11 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem
             return;
         }
 
-        var localToWorld = xform.WorldMatrix.Transform(_localPosition);
+        var localToWorld = _xformSystem.GetWorldMatrix(xform).Transform(_localPosition);
 
         if (localToWorld.EqualsApprox(mousePos.Position, 0.01f)) return;
 
-        var requestedGridOrigin = mousePos.Position - xform.WorldRotation.RotateVec(_localPosition);
+        var requestedGridOrigin = mousePos.Position - _xformSystem.GetWorldRotation(xform).RotateVec(_localPosition);
         _lastMousePosition = new MapCoordinates(requestedGridOrigin, mousePos.MapId);
 
         RaiseNetworkEvent(new GridDragRequestPosition()
index 44e82053554184e4aba78967b24ca91f564bc0b8..7e70477bb0659a7ea5b387c8fc327e51f9dcbb8f 100644 (file)
@@ -37,7 +37,7 @@ public sealed class MouseRotatorSystem : SharedMouseRotatorSystem
         if (mapPos.MapId == MapId.Nullspace)
             return;
 
-        var angle = (mapPos.Position - xform.MapPosition.Position).ToWorldAngle();
+        var angle = (mapPos.Position - _transform.GetMapCoordinates((player.Value, xform)).Position).ToWorldAngle();
 
         var curRot = _transform.GetWorldRotation(xform);
 
index ad173f3b29c760b7bcefbde76979efbdc93a23ca..55b98046c8102b8bd876a6ce8892aa275eed5ae5 100644 (file)
@@ -9,6 +9,7 @@ public sealed class HTNOverlay : Overlay
 {
     private readonly IEntityManager _entManager = default!;
     private readonly Font _font = default!;
+    private SharedTransformSystem? _xformSystem = null;
 
     public override OverlaySpace Space => OverlaySpace.ScreenSpace;
 
@@ -23,6 +24,10 @@ public sealed class HTNOverlay : Overlay
         if (args.ViewportControl == null)
             return;
 
+        _xformSystem ??= _entManager.SystemOrNull<SharedTransformSystem>();
+        if (_xformSystem is null)
+            return;
+
         var handle = args.ScreenHandle;
 
         foreach (var (comp, xform) in _entManager.EntityQuery<HTNComponent, TransformComponent>(true))
@@ -30,7 +35,7 @@ public sealed class HTNOverlay : Overlay
             if (string.IsNullOrEmpty(comp.DebugText) || xform.MapID != args.MapId)
                 continue;
 
-            var worldPos = xform.WorldPosition;
+            var worldPos = _xformSystem.GetWorldPosition(xform);
 
             if (!args.WorldAABB.Contains(worldPos))
                 continue;
index bb2145bce0c92bc8d22d0a4c7f3d313484ea0ac5..4f4663e8c3498e09b56a1bbc555f4c0ea856d2f7 100644 (file)
@@ -89,6 +89,10 @@ public sealed class NPCSteeringOverlay : Overlay
 
     protected override void Draw(in OverlayDrawArgs args)
     {
+        var xformSystem = _entManager.SystemOrNull<SharedTransformSystem>();
+        if (xformSystem is null)
+            return;
+
         foreach (var (comp, mover, xform) in _entManager.EntityQuery<NPCSteeringComponent, InputMoverComponent, TransformComponent>(true))
         {
             if (xform.MapID != args.MapId)
@@ -96,7 +100,7 @@ public sealed class NPCSteeringOverlay : Overlay
                 continue;
             }
 
-            var (worldPos, worldRot) = xform.GetWorldPositionRotation();
+            var (worldPos, worldRot) = xformSystem.GetWorldPositionRotation(xform);
 
             if (!args.WorldAABB.Contains(worldPos))
                 continue;
index 548edd601ce871bcd133d033e3aa5f949228feb2..6ff9e8d249d3b63de0f0d0ab5e5830d6c880d377 100644 (file)
@@ -140,6 +140,7 @@ namespace Content.Client.NPC
         private readonly IMapManager _mapManager;
         private readonly PathfindingSystem _system;
         private readonly MapSystem _mapSystem;
+        private readonly SharedTransformSystem _xformSystem;
 
         public override OverlaySpace Space => OverlaySpace.ScreenSpace | OverlaySpace.WorldSpace;
 
@@ -161,6 +162,7 @@ namespace Content.Client.NPC
             _mapManager = mapManager;
             _system = system;
             _mapSystem = mapSystem;
+            _xformSystem = _entManager.System<SharedTransformSystem>();
             _font = new VectorFont(cache.GetResource<FontResource>("/Fonts/NotoSans/NotoSans-Regular.ttf"), 10);
         }
 
@@ -199,7 +201,7 @@ namespace Content.Client.NPC
                     if (found || !_system.Breadcrumbs.TryGetValue(netGrid, out var crumbs) || !xformQuery.TryGetComponent(grid, out var gridXform))
                         continue;
 
-                    var (_, _, worldMatrix, invWorldMatrix) = gridXform.GetWorldPositionRotationMatrixWithInv();
+                    var (_, _, worldMatrix, invWorldMatrix) = _xformSystem.GetWorldPositionRotationMatrixWithInv(gridXform);
                     var localAABB = invWorldMatrix.TransformBox(aabb.Enlarged(float.Epsilon - SharedPathfindingSystem.ChunkSize));
 
                     foreach (var chunk in crumbs)
@@ -283,7 +285,7 @@ namespace Content.Client.NPC
                     return;
                 }
 
-                var invGridMatrix = gridXform.InvWorldMatrix;
+                var invGridMatrix = _xformSystem.GetInvWorldMatrix(gridXform);
                 DebugPathPoly? nearest = null;
                 var nearestDistance = float.MaxValue;
 
@@ -356,7 +358,7 @@ namespace Content.Client.NPC
                         continue;
                     }
 
-                    var (_, _, worldMatrix, invWorldMatrix) = gridXform.GetWorldPositionRotationMatrixWithInv();
+                    var (_, _, worldMatrix, invWorldMatrix) = _xformSystem.GetWorldPositionRotationMatrixWithInv(gridXform);
                     worldHandle.SetTransform(worldMatrix);
                     var localAABB = invWorldMatrix.TransformBox(aabb);
 
@@ -416,7 +418,7 @@ namespace Content.Client.NPC
                         !xformQuery.TryGetComponent(grid, out var gridXform))
                         continue;
 
-                    var (_, _, worldMatrix, invWorldMatrix) = gridXform.GetWorldPositionRotationMatrixWithInv();
+                    var (_, _, worldMatrix, invWorldMatrix) = _xformSystem.GetWorldPositionRotationMatrixWithInv(gridXform);
                     worldHandle.SetTransform(worldMatrix);
                     var localAABB = invWorldMatrix.TransformBox(aabb);
 
@@ -455,7 +457,7 @@ namespace Content.Client.NPC
                         !xformQuery.TryGetComponent(grid, out var gridXform))
                         continue;
 
-                    var (_, _, worldMatrix, invMatrix) = gridXform.GetWorldPositionRotationMatrixWithInv();
+                    var (_, _, worldMatrix, invMatrix) = _xformSystem.GetWorldPositionRotationMatrixWithInv(gridXform);
                     worldHandle.SetTransform(worldMatrix);
                     var localAABB = invMatrix.TransformBox(aabb);
 
@@ -514,7 +516,7 @@ namespace Content.Client.NPC
                         !xformQuery.TryGetComponent(grid, out var gridXform))
                         continue;
 
-                    var (_, _, worldMatrix, invWorldMatrix) = gridXform.GetWorldPositionRotationMatrixWithInv();
+                    var (_, _, worldMatrix, invWorldMatrix) = _xformSystem.GetWorldPositionRotationMatrixWithInv(gridXform);
                     worldHandle.SetTransform(worldMatrix);
                     var localAABB = invWorldMatrix.TransformBox(args.WorldBounds);
 
@@ -541,7 +543,7 @@ namespace Content.Client.NPC
                         if (!_entManager.TryGetComponent<TransformComponent>(_entManager.GetEntity(node.GraphUid), out var graphXform))
                             continue;
 
-                        worldHandle.SetTransform(graphXform.WorldMatrix);
+                        worldHandle.SetTransform(_xformSystem.GetWorldMatrix(graphXform));
                         worldHandle.DrawRect(node.Box, Color.Orange.WithAlpha(0.10f));
                     }
                 }
@@ -565,7 +567,7 @@ namespace Content.Client.NPC
                                 continue;
 
                             matrix = graph;
-                            worldHandle.SetTransform(graphXform.WorldMatrix);
+                            worldHandle.SetTransform(_xformSystem.GetWorldMatrix(graphXform));
                         }
 
                         worldHandle.DrawRect(node.Box, new Color(0f, cost / highestGScore, 1f - (cost / highestGScore), 0.10f));
index 4fcdada86842ec8842d5e11d422513f9ee25c4d0..1cc66e2eac3c2413107b09e2a02a911ab5fb4e5d 100644 (file)
@@ -12,6 +12,7 @@ public sealed class NetworkConfiguratorLinkOverlay : Overlay
     [Dependency] private readonly IEntityManager _entityManager = default!;
     [Dependency] private readonly IRobustRandom _random = default!;
     private readonly DeviceListSystem _deviceListSystem;
+    private readonly SharedTransformSystem _xformSystem;
 
     public Dictionary<EntityUid, Color> Colors = new();
     public EntityUid? Action;
@@ -23,6 +24,7 @@ public sealed class NetworkConfiguratorLinkOverlay : Overlay
         IoCManager.InjectDependencies(this);
 
         _deviceListSystem = _entityManager.System<DeviceListSystem>();
+        _xformSystem = _entityManager.System<SharedTransformSystem>();
     }
 
     protected override void Draw(in OverlayDrawArgs args)
@@ -66,7 +68,7 @@ public sealed class NetworkConfiguratorLinkOverlay : Overlay
                     continue;
                 }
 
-                args.WorldHandle.DrawLine(sourceTransform.WorldPosition, linkTransform.WorldPosition, Colors[uid]);
+                args.WorldHandle.DrawLine(_xformSystem.GetWorldPosition(sourceTransform), _xformSystem.GetWorldPosition(linkTransform), Colors[uid]);
             }
         }
     }
index f10eb9ed8b14e0d75ad8862ab7bd026bd20b2787..b43b7542e6223ef442238dfa5a6a4ec0064637d4 100644 (file)
@@ -20,6 +20,7 @@ namespace Content.Client.NodeContainer
         private readonly IMapManager _mapManager;
         private readonly IInputManager _inputManager;
         private readonly IEntityManager _entityManager;
+        private readonly SharedTransformSystem _xformSystem;
 
         private readonly Dictionary<(int, int), NodeRenderData> _nodeIndex = new();
         private readonly Dictionary<EntityUid, Dictionary<Vector2i, List<(GroupData, NodeDatum)>>> _gridIndex = new ();
@@ -46,6 +47,7 @@ namespace Content.Client.NodeContainer
             _mapManager = mapManager;
             _inputManager = inputManager;
             _entityManager = entityManager;
+            _xformSystem = _entityManager.System<SharedTransformSystem>();
 
             _font = cache.GetFont("/Fonts/NotoSans/NotoSans-Regular.ttf", 12);
         }
@@ -146,7 +148,7 @@ namespace Content.Client.NodeContainer
             foreach (var (gridId, gridDict) in _gridIndex)
             {
                 var grid = _mapManager.GetGrid(gridId);
-                var (_, _, worldMatrix, invMatrix) = _entityManager.GetComponent<TransformComponent>(gridId).GetWorldPositionRotationMatrixWithInv();
+                var (_, _, worldMatrix, invMatrix) = _xformSystem.GetWorldPositionRotationMatrixWithInv(gridId);
 
                 var lCursorBox = invMatrix.TransformBox(cursorBox);
                 foreach (var (pos, list) in gridDict)
index 2a6867f51f55c92d5c5d38fd5c1725c39daaf00d..b6cb06091ac8c937a01cf3c71f37294fd4360fd9 100644 (file)
@@ -22,6 +22,7 @@ public sealed class TargetOutlineSystem : EntitySystem
     [Dependency] private readonly IPlayerManager _playerManager = default!;
     [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
     [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     private bool _enabled = false;
 
@@ -164,8 +165,8 @@ public sealed class TargetOutlineSystem : EntitySystem
                 valid = _interactionSystem.InRangeUnobstructed(player, entity, Range);
             else if (Range >= 0)
             {
-                var origin = Transform(player).WorldPosition;
-                var target = Transform(entity).WorldPosition;
+                var origin = _xformSystem.GetWorldPosition(player);
+                var target = _xformSystem.GetWorldPosition(entity);
                 valid = (origin - target).LengthSquared() <= Range;
             }
 
index bd7dfc1117fb6c5e9b37432602cfc2381e9f48ce..b15c1add30889e3a85896a9856eb00851d3d0e3e 100644 (file)
@@ -58,6 +58,7 @@ public sealed class NavMapOverlay : Overlay
     {
         var query = _entManager.GetEntityQuery<NavMapComponent>();
         var xformQuery = _entManager.GetEntityQuery<TransformComponent>();
+        var xformSystem = _entManager.System<SharedTransformSystem>();
         var scale = Matrix3.CreateScale(new Vector2(1f, 1f));
 
         _grids.Clear();
@@ -69,7 +70,7 @@ public sealed class NavMapOverlay : Overlay
                 continue;
 
             // TODO: Faster helper method
-            var (_, _, matrix, invMatrix) = xform.GetWorldPositionRotationMatrixWithInv();
+            var (_, _, matrix, invMatrix) = xformSystem.GetWorldPositionRotationMatrixWithInv(xform);
 
             var localAABB = invMatrix.TransformBox(args.WorldBounds);
             Matrix3.Multiply(in scale, in matrix, out var matty);
index adc535b2684b4fc2b57bb5a10851a659263bde84..57840f55e79d875cde139067f2b1a72a9caccc5d 100644 (file)
@@ -14,6 +14,7 @@ namespace Content.Client.Radiation.Overlays
         [Dependency] private readonly IEntityManager _entityManager = default!;
         [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
         [Dependency] private readonly IGameTiming _gameTiming = default!;
+        private SharedTransformSystem? _xformSystem = null;
 
         private const float MaxDist = 15.0f;
 
@@ -72,7 +73,9 @@ namespace Content.Client.Radiation.Overlays
         //Queries all pulses on the map and either adds or removes them from the list of rendered pulses based on whether they should be drawn (in range? on the same z-level/map? pulse entity still exists?)
         private void RadiationQuery(IEye? currentEye)
         {
-            if (currentEye == null)
+            _xformSystem ??= _entityManager.SystemOrNull<SharedTransformSystem>();
+
+            if (_xformSystem is null || currentEye is null)
             {
                 _pulses.Clear();
                 return;
@@ -91,7 +94,7 @@ namespace Content.Client.Radiation.Overlays
                             (
                                 _baseShader.Duplicate(),
                                 new RadiationShaderInstance(
-                                    _entityManager.GetComponent<TransformComponent>(pulseEntity).MapPosition,
+                                    _xformSystem.GetMapCoordinates(pulseEntity),
                                     pulse.VisualRange,
                                     pulse.StartTime,
                                     pulse.VisualDuration
@@ -109,7 +112,7 @@ namespace Content.Client.Radiation.Overlays
                     _entityManager.TryGetComponent(pulseEntity, out RadiationPulseComponent? pulse))
                 {
                     var shaderInstance = _pulses[pulseEntity];
-                    shaderInstance.instance.CurrentMapCoords = _entityManager.GetComponent<TransformComponent>(pulseEntity).MapPosition;
+                    shaderInstance.instance.CurrentMapCoords = _xformSystem.GetMapCoordinates(pulseEntity);
                     shaderInstance.instance.Range = pulse.VisualRange;
                 } else {
                     _pulses[pulseEntity].shd.Dispose();
index 2ee7e30ec9a239e5d32021c912fd633743f16459..9baec2eb58a79941c9a61444db64c9608e8147ec 100644 (file)
@@ -126,18 +126,18 @@ public sealed partial class ReplaySpectatorSystem
 
         if (data.Local != null && data.Local.Value.Coords.IsValid(EntityManager))
         {
-            var newXform = SpawnSpectatorGhost(data.Local.Value.Coords, false);
-            newXform.LocalRotation = data.Local.Value.Rot;
+            var (newUid, newXform) = SpawnSpectatorGhost(data.Local.Value.Coords, false);
+            _transform.SetLocalRotation(newUid, data.Local.Value.Rot, newXform);
         }
         else if (data.World != null && data.World.Value.Coords.IsValid(EntityManager))
         {
-            var newXform = SpawnSpectatorGhost(data.World.Value.Coords, true);
-            newXform.LocalRotation = data.World.Value.Rot;
+            var (newUid, newXform) = SpawnSpectatorGhost(data.World.Value.Coords, true);
+            _transform.SetLocalRotation(newUid, data.World.Value.Rot, newXform);
         }
         else if (TryFindFallbackSpawn(out var coords))
         {
-            var newXform = SpawnSpectatorGhost(coords, true);
-            newXform.LocalRotation = 0;
+            var (newUid, newXform) = SpawnSpectatorGhost(coords, true);
+            _transform.SetLocalRotation(newUid, 0, newXform);
         }
         else
         {
index 27b33b84c528c4cb4149793d5fb91f1e82b5cb9d..1bab04363548d90bfaa00ed28a8f103f52f03a13 100644 (file)
@@ -55,7 +55,7 @@ public sealed partial class ReplaySpectatorSystem
             RemComp<ReplaySpectatorComponent>(old.Value);
     }
 
-    public TransformComponent SpawnSpectatorGhost(EntityCoordinates coords, bool gridAttach)
+    public Entity<TransformComponent> SpawnSpectatorGhost(EntityCoordinates coords, bool gridAttach)
     {
         var old = _player.LocalEntity;
         var session = _player.GetSessionById(DefaultUser);
@@ -83,7 +83,7 @@ public sealed partial class ReplaySpectatorSystem
         _stateMan.RequestStateChange<ReplayGhostState>();
 
         _spectatorData = GetSpectatorData();
-        return xform;
+        return (ent, xform);
     }
 
     private void SpectateCommand(IConsoleShell shell, string argStr, string[] args)
index 7086fd05411f10d218bc9b785c9fb3b0388039bb..9e6c475176ca38b16a1b86912cd0b9b4a558f7d6 100644 (file)
@@ -58,6 +58,7 @@ public sealed partial class ShuttleSystem : SharedShuttleSystem
 public sealed class EmergencyShuttleOverlay : Overlay
 {
     private IEntityManager _entManager;
+    private SharedTransformSystem _xformSystem;
 
     public override OverlaySpace Space => OverlaySpace.WorldSpace;
 
@@ -67,13 +68,14 @@ public sealed class EmergencyShuttleOverlay : Overlay
     public EmergencyShuttleOverlay(IEntityManager entManager)
     {
         _entManager = entManager;
+        _xformSystem = _entManager.System<SharedTransformSystem>();
     }
 
     protected override void Draw(in OverlayDrawArgs args)
     {
         if (Position == null || !_entManager.TryGetComponent<TransformComponent>(StationUid, out var xform)) return;
 
-        args.WorldHandle.SetTransform(xform.WorldMatrix);
+        args.WorldHandle.SetTransform(_xformSystem.GetWorldMatrix(xform));
         args.WorldHandle.DrawRect(Position.Value, Color.Red.WithAlpha(100));
         args.WorldHandle.SetTransform(Matrix3.Identity);
     }
index c0ddeff86c23bee5b4abf5c4c94d685126f90f21..245eaba454ea5fc14ed3f19c92f7fed908bb1b38 100644 (file)
@@ -18,6 +18,7 @@ public class DockingControl : Control
 {
     private readonly IEntityManager _entManager;
     private readonly IMapManager _mapManager;
+    private readonly SharedTransformSystem _xformSystem;
 
     private float _range = 8f;
     private float _rangeSquared = 0f;
@@ -50,6 +51,7 @@ public class DockingControl : Control
     {
         _entManager = IoCManager.Resolve<IEntityManager>();
         _mapManager = IoCManager.Resolve<IMapManager>();
+        _xformSystem = _entManager.System<SharedTransformSystem>();
         _rangeSquared = _range * _range;
         MinSize = new Vector2(SizeFull, SizeFull);
     }
@@ -143,8 +145,8 @@ public class DockingControl : Control
             ScalePosition(rotation.Transform(new Vector2(0.5f, -0.5f)))), Color.Green);
 
         // Draw nearby grids
-        var worldPos = gridXform.WorldMatrix.Transform(Coordinates.Value.Position);
-        var gridInvMatrix = gridXform.InvWorldMatrix;
+        var worldPos = _xformSystem.GetWorldMatrix(gridXform).Transform(Coordinates.Value.Position);
+        var gridInvMatrix = _xformSystem.GetInvWorldMatrix(gridXform);
         Matrix3.Multiply(in gridInvMatrix, in matrix, out var invMatrix);
 
         // TODO: Getting some overdraw so need to fix that.
@@ -162,7 +164,7 @@ public class DockingControl : Control
             if (!_entManager.TryGetComponent<FixturesComponent>(grid, out var gridFixtures))
                 continue;
 
-            var gridMatrix = xformQuery.GetComponent(grid).WorldMatrix;
+            var gridMatrix = _xformSystem.GetWorldMatrix(grid);
 
             Matrix3.Multiply(in gridMatrix, in invMatrix, out var matty);
 
index d67227549a9071e5244be20ccf15ea81a9f372c4..4e1a2662f398021cfbc4f3b40dd7dcfeacc11fc1 100644 (file)
@@ -21,6 +21,7 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
 {
     private readonly IEntityManager _entManager;
     private readonly IGameTiming _timing;
+    private SharedTransformSystem? _xformSystem = null;
 
     private EntityUid? _shuttleEntity;
 
@@ -309,7 +310,9 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
     {
         base.Draw(handle);
 
-        if (!_entManager.TryGetComponent<PhysicsComponent>(_shuttleEntity, out var gridBody) ||
+        _xformSystem ??= _entManager.SystemOrNull<SharedTransformSystem>();
+        if (_xformSystem is null ||
+            !_entManager.TryGetComponent<PhysicsComponent>(_shuttleEntity, out var gridBody) ||
             !_entManager.TryGetComponent<TransformComponent>(_shuttleEntity, out var gridXform))
         {
             return;
@@ -322,7 +325,7 @@ public sealed partial class ShuttleConsoleWindow : FancyWindow,
 
         FTLTimer.Text = GetFTLText();
 
-        var (_, worldRot, worldMatrix) = gridXform.GetWorldPositionRotationMatrix();
+        var (_, worldRot, worldMatrix) = _xformSystem.GetWorldPositionRotationMatrix(gridXform);
         var worldPos = worldMatrix.Transform(gridBody.LocalCenter);
 
         // Get the positive reduced angle.
index dda3a6c948ee518e5f63cef4a230c716be14160e..011a7cd9491a1b12e5477bee29c4525027a55124 100644 (file)
@@ -15,6 +15,7 @@ public sealed class SpriteFadeSystem : EntitySystem
 
     [Dependency] private readonly IPlayerManager _playerManager = default!;
     [Dependency] private readonly IStateManager _stateManager = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     private readonly HashSet<FadingSpriteComponent> _comps = new();
 
@@ -48,7 +49,7 @@ public sealed class SpriteFadeSystem : EntitySystem
             spriteQuery.TryGetComponent(player, out var playerSprite))
         {
             var fadeQuery = GetEntityQuery<SpriteFadeComponent>();
-            var mapPos = playerXform.MapPosition;
+            var mapPos = _xformSystem.GetMapCoordinates((player.Value, playerXform));
 
             // Also want to handle large entities even if they may not be clickable.
             foreach (var ent in state.GetClickableEntities(mapPos))
index b60ffc2a4089645dac8da5e2060de539ac767aed..b34de23c26c47473de6516a21f8663877cb9fea7 100644 (file)
@@ -10,6 +10,7 @@ namespace Content.Client.Stealth;
 public sealed class StealthSystem : SharedStealthSystem
 {
     [Dependency] private readonly IPrototypeManager _protoMan = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     private ShaderInstance _shader = default!;
 
@@ -79,7 +80,7 @@ public sealed class StealthSystem : SharedStealthSystem
         if (!parent.IsValid())
             return; // should never happen, but lets not kill the client.
         var parentXform = Transform(parent);
-        var reference = args.Viewport.WorldToLocal(parentXform.WorldPosition);
+        var reference = args.Viewport.WorldToLocal(_xformSystem.GetWorldPosition(parentXform));
         reference.X = -reference.X;
         var visibility = GetVisibility(uid, component);
 
index 696c1455e0c1bf609eb3ece64520b626300a2050..1002bbe6174e3eb5c27d2b3356307334b6307e3e 100644 (file)
@@ -27,6 +27,7 @@ namespace Content.Client.Tabletop
         [Dependency] private readonly IPlayerManager _playerManager = default!;
         [Dependency] private readonly IGameTiming _gameTiming = default!;
         [Dependency] private readonly AppearanceSystem _appearance = default!;
+        [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
         // Time in seconds to wait until sending the location of a dragged entity to the server again
         private const float Delay = 1f / 10; // 10 Hz
@@ -100,7 +101,7 @@ namespace Content.Client.Tabletop
             if (clampedCoords.Equals(MapCoordinates.Nullspace)) return;
 
             // Move the entity locally every update
-            EntityManager.GetComponent<TransformComponent>(_draggedEntity.Value).WorldPosition = clampedCoords.Position;
+            _xformSystem.SetWorldPosition(_draggedEntity.Value, clampedCoords.Position);
 
             // Increment total time passed
             _timePassed += frameTime;
@@ -258,7 +259,7 @@ namespace Content.Client.Tabletop
             // Set the dragging player on the component to noone
             if (broadcast && _draggedEntity != null && EntityManager.HasComponent<TabletopDraggableComponent>(_draggedEntity.Value))
             {
-                RaisePredictiveEvent(new TabletopMoveEvent(GetNetEntity(_draggedEntity.Value), Transform(_draggedEntity.Value).MapPosition, GetNetEntity(_table!.Value)));
+                RaisePredictiveEvent(new TabletopMoveEvent(GetNetEntity(_draggedEntity.Value), Transforms.GetMapCoordinates(_draggedEntity.Value), GetNetEntity(_table!.Value)));
                 RaisePredictiveEvent(new TabletopDraggingPlayerChangedEvent(GetNetEntity(_draggedEntity.Value), false));
             }
 
index 1adf9ae59bd570e03ef1ef66362fb32f58e9f6a5..da153f269779e3ac6e315c8e3951af024dc27a33 100644 (file)
@@ -60,6 +60,7 @@ public sealed class ChatUIController : UIController
     [UISystemDependency] private readonly GhostSystem? _ghost = default;
     [UISystemDependency] private readonly TypingIndicatorSystem? _typingIndicator = default;
     [UISystemDependency] private readonly ChatSystem? _chatSys = default;
+    [UISystemDependency] private readonly SharedTransformSystem? _xformSystem = default!;
 
     [ValidatePrototypeId<ColorPalettePrototype>]
     private const string ChatNamePalette = "ChatNames";
@@ -553,7 +554,7 @@ public sealed class ChatUIController : UIController
     private void UpdateQueuedSpeechBubbles(FrameEventArgs delta)
     {
         // Update queued speech bubbles.
-        if (_queuedSpeechBubbles.Count == 0 || _examine == null)
+        if (_queuedSpeechBubbles.Count == 0 || _examine is null || _xformSystem is null)
         {
             return;
         }
@@ -591,7 +592,7 @@ public sealed class ChatUIController : UIController
         var predicate = static (EntityUid uid, (EntityUid compOwner, EntityUid? attachedEntity) data)
             => uid == data.compOwner || uid == data.attachedEntity;
         var playerPos = player != null
-            ? EntityManager.GetComponent<TransformComponent>(player.Value).MapPosition
+            ? _xformSystem.GetMapCoordinates(player.Value)
             : MapCoordinates.Nullspace;
 
         var occluded = player != null && _examine.IsOccluded(player.Value);
@@ -610,7 +611,7 @@ public sealed class ChatUIController : UIController
                 continue;
             }
 
-            var otherPos = EntityManager.GetComponent<TransformComponent>(ent).MapPosition;
+            var otherPos = _xformSystem.GetMapCoordinates(ent);
 
             if (occluded && !ExamineSystemShared.InRangeUnOccluded(
                     playerPos,
index d117043f425f27c31d5cdc07ba6f80e0195bf270..2358e87a7e74ae95b7ddb520a31a88c0d1582c71 100644 (file)
@@ -3,6 +3,7 @@ using Content.Client.UserInterface.Systems.Gameplay;
 using Content.Shared.CCVar;
 using Robust.Client.Graphics;
 using Robust.Client.Player;
+using Robust.Client.UserInterface;
 using Robust.Client.UserInterface.Controllers;
 using Robust.Shared.Configuration;
 using Robust.Shared.Timing;
@@ -15,6 +16,7 @@ public sealed class ViewportUIController : UIController
     [Dependency] private readonly IPlayerManager _playerMan = default!;
     [Dependency] private readonly IEntityManager _entMan = default!;
     [Dependency] private readonly IConfigurationManager _configurationManager = default!;
+    [UISystemDependency] private readonly SharedTransformSystem? _xformSystem = default!;
 
     public static readonly Vector2i ViewportSize = (EyeManager.PixelsPerMeter * 21, EyeManager.PixelsPerMeter * 15);
     public const int ViewportHeight = 15;
@@ -87,7 +89,7 @@ public sealed class ViewportUIController : UIController
         _entMan.TryGetComponent(ent, out EyeComponent? eye);
 
         if (eye?.Eye == _eyeManager.CurrentEye
-            && _entMan.GetComponent<TransformComponent>(ent.Value).WorldPosition == default)
+            && (_xformSystem is null || _xformSystem.GetWorldPosition(ent.Value) == default))
             return; // nothing to worry about, the player is just in null space... actually that is probably a problem?
 
         // Currently, this shouldn't happen. This likely happened because the main eye was set to null. When this
index 329a8977a68438e60dd8fb241510c2958be237c5..d515006cd1f2e3805af6185e5e964e8091200947 100644 (file)
@@ -25,6 +25,7 @@ namespace Content.Client.Verbs
         [Dependency] private readonly IStateManager _stateManager = default!;
         [Dependency] private readonly EntityLookupSystem _entityLookup = default!;
         [Dependency] private readonly IPlayerManager _playerManager = default!;
+        [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
         /// <summary>
         ///     When a user right clicks somewhere, how large is the box we use to get entities for the context menu?
@@ -140,8 +141,7 @@ namespace Content.Client.Verbs
             // Remove any entities that do not have LOS
             if ((visibility & MenuVisibility.NoFov) == 0)
             {
-                var xformQuery = GetEntityQuery<TransformComponent>();
-                var playerPos = xformQuery.GetComponent(player.Value).MapPosition;
+                var playerPos = _xformSystem.GetMapCoordinates(player.Value);
 
                 for (var i = entities.Count - 1; i >= 0; i--)
                 {
@@ -149,7 +149,7 @@ namespace Content.Client.Verbs
 
                     if (!ExamineSystemShared.InRangeUnOccluded(
                         playerPos,
-                        xformQuery.GetComponent(entity).MapPosition,
+                        _xformSystem.GetMapCoordinates(entity),
                         ExamineSystemShared.ExamineRange,
                         null))
                     {
index dbd68c15e247a87580c3eb0aa141e240c2e0b949..e25242d7295b7a07726f350f5b7ec2f5c44322a2 100644 (file)
@@ -20,6 +20,7 @@ public sealed class MeleeArcOverlay : Overlay
     private readonly IPlayerManager _playerManager;
     private readonly MeleeWeaponSystem _melee;
     private readonly SharedCombatModeSystem _combatMode;
+    private readonly SharedTransformSystem _xformSystem;
 
     public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowFOV;
 
@@ -31,6 +32,7 @@ public sealed class MeleeArcOverlay : Overlay
         _playerManager = playerManager;
         _melee = melee;
         _combatMode = combatMode;
+        _xformSystem = _entManager.System<SharedTransformSystem>();
     }
 
     protected override void Draw(in OverlayDrawArgs args)
@@ -52,7 +54,7 @@ public sealed class MeleeArcOverlay : Overlay
         if (mapPos.MapId != args.MapId)
             return;
 
-        var playerPos = xform.MapPosition;
+        var playerPos = _xformSystem.GetMapCoordinates((player.Value, xform));
 
         if (mapPos.MapId != playerPos.MapId)
             return;
index 0f2f98e76408e901565ef488be0dfd2e72a6be51..132ec0a9b97c4d5686cda16e3e5736232b2080ef 100644 (file)
@@ -80,7 +80,7 @@ public sealed partial class MeleeWeaponSystem
                 TransformSystem.AttachToGridOrMap(animationUid, xform);
                 var worldPos = mapPos + (mapRot - userXform.LocalRotation).RotateVec(localPos);
                 var newLocalPos = TransformSystem.GetInvWorldMatrix(xform.ParentUid).Transform(worldPos);
-                TransformSystem.SetLocalPositionNoLerp(xform, newLocalPos);
+                TransformSystem.SetLocalPositionNoLerp(animationUid, newLocalPos, xform);
                 if (arcComponent.Fadeout)
                     _animation.Play(animationUid, GetFadeAnimation(sprite, 0f, 0.15f), FadeAnimationKey);
                 break;
index 641d56d3d14beb37adc76a19805a3e80c59a71f8..4c5b5cad0270a21476b73ba767a49bed239840da 100644 (file)
@@ -136,7 +136,7 @@ public sealed partial class MeleeWeaponSystem : SharedMeleeWeaponSystem
         // Light attack
         if (useDown == BoundKeyState.Down)
         {
-            var attackerPos = Transform(entity).MapPosition;
+            var attackerPos = TransformSystem.GetMapCoordinates(entity);
 
             if (mousePos.MapId != attackerPos.MapId ||
                 (attackerPos.Position - mousePos.Position).Length() > weapon.Range)
index 62df764ae50c590c7c5a615602f0bef87268045b..c7f8cf647b9682e2f05ca4df12879180778bdc14 100644 (file)
@@ -18,6 +18,7 @@ public sealed class GunSpreadOverlay : Overlay
     private readonly IInputManager _input;
     private readonly IPlayerManager _player;
     private readonly GunSystem _guns;
+    private readonly SharedTransformSystem _xforms;
 
     public GunSpreadOverlay(IEntityManager entManager, IEyeManager eyeManager, IGameTiming timing, IInputManager input, IPlayerManager player, GunSystem system)
     {
@@ -27,6 +28,7 @@ public sealed class GunSpreadOverlay : Overlay
         _timing = timing;
         _player = player;
         _guns = system;
+        _xforms = entManager.System<SharedTransformSystem>();
     }
 
     protected override void Draw(in OverlayDrawArgs args)
@@ -41,7 +43,7 @@ public sealed class GunSpreadOverlay : Overlay
             return;
         }
 
-        var mapPos = xform.MapPosition;
+        var mapPos = _xforms.GetMapCoordinates((player.Value, xform));
 
         if (mapPos.MapId == MapId.Nullspace)
             return;
index 9e50cab3e10f0e0a6068a95bc2124d60af181486..84205fb005a8ada9866796a80613d849f7629c98 100644 (file)
@@ -99,8 +99,7 @@ public sealed partial class GunSystem : SharedGunSystem
 
             var ent = Spawn(HitscanProto, coords);
             var sprite = Comp<SpriteComponent>(ent);
-            var xform = Transform(ent);
-            xform.LocalRotation = a.angle;
+            TransformSystem.SetLocalRotation(ent, a.angle);
             sprite[EffectLayers.Unshaded].AutoAnimated = false;
             sprite.LayerSetSprite(EffectLayers.Unshaded, rsi);
             sprite.LayerSetState(EffectLayers.Unshaded, rsi.RsiState);
@@ -278,9 +277,11 @@ public sealed partial class GunSystem : SharedGunSystem
         var ent = Spawn(message.Prototype, coordinates);
 
         var effectXform = Transform(ent);
-        TransformSystem.SetLocalPositionRotation(effectXform,
+        TransformSystem.SetLocalPositionRotation(ent,
             effectXform.LocalPosition + new Vector2(0f, -0.5f),
-            effectXform.LocalRotation - MathF.PI / 2);
+            effectXform.LocalRotation - MathF.PI / 2,
+            effectXform
+        );
 
         var lifetime = 0.4f;
 
index 76085381852df7ee155c77965a5a99c80f8e75b5..16860931e1e4db393965f7901c7f02aae5d9abc6 100644 (file)
@@ -53,6 +53,7 @@ namespace Content.IntegrationTests.Tests
             var eyeManager = client.ResolveDependency<IEyeManager>();
             var spriteQuery = clientEntManager.GetEntityQuery<SpriteComponent>();
             var xformQuery = clientEntManager.GetEntityQuery<TransformComponent>();
+            var clickSystem = clientEntManager.System<ClickableSystem>();
             var eye = client.ResolveDependency<IEyeManager>().CurrentEye;
 
             var testMap = await pair.CreateTestMap();
@@ -82,7 +83,7 @@ namespace Content.IntegrationTests.Tests
                 var pos = clientEntManager.System<SharedTransformSystem>().GetWorldPosition(clientEnt);
                 var clickable = clientEntManager.GetComponent<ClickableComponent>(clientEnt);
 
-                hit = clickable.CheckClick(sprite, xformQuery.GetComponent(clientEnt), xformQuery, new Vector2(clickPosX, clickPosY) + pos, eye, out _, out _, out _);
+                hit = clickSystem.CheckClick((clientEnt, clickable, sprite, xformQuery.GetComponent(clientEnt)), new Vector2(clickPosX, clickPosY) + pos, eye, out _, out _, out _);
             });
 
             await server.WaitPost(() =>
index 976fc2eceb5aaa981a7857650cc337a30147f5f5..cc66f9369fc93063c1efe6453075f9afa2c78188 100644 (file)
@@ -171,8 +171,7 @@ namespace Content.IntegrationTests.Tests.Disposal
                 human = entityManager.SpawnEntity("HumanDisposalDummy", coordinates);
                 wrench = entityManager.SpawnEntity("WrenchDummy", coordinates);
                 disposalUnit = entityManager.SpawnEntity("DisposalUnitDummy", coordinates);
-                disposalTrunk = entityManager.SpawnEntity("DisposalTrunkDummy",
-                    entityManager.GetComponent<TransformComponent>(disposalUnit).MapPosition);
+                disposalTrunk = entityManager.SpawnEntity("DisposalTrunkDummy", xformSystem.GetMapCoordinates(disposalUnit));
 
                 // Test for components existing
                 unitUid = disposalUnit;
index fdcd7f9096ff354f002b0cf9ee04eaec96fafbef..874fd1c3dcc3249e28ef15b9bbc29f049ecb74f9 100644 (file)
@@ -24,6 +24,7 @@ public sealed class HandTests
         var playerMan = server.ResolveDependency<IPlayerManager>();
         var mapMan = server.ResolveDependency<IMapManager>();
         var sys = entMan.System<SharedHandsSystem>();
+        var xfm = entMan.System<SharedTransformSystem>();
 
         var data = await pair.CreateTestMap();
         await pair.RunTicksSync(5);
@@ -35,7 +36,7 @@ public sealed class HandTests
         {
             player = playerMan.Sessions.First().AttachedEntity!.Value;
             var xform = entMan.GetComponent<TransformComponent>(player);
-            item = entMan.SpawnEntity("Crowbar", xform.MapPosition);
+            item = entMan.SpawnEntity("Crowbar", xfm.GetMapCoordinates(xform));
             hands = entMan.GetComponent<HandsComponent>(player);
             sys.TryPickup(player, item, hands.ActiveHand!);
         });
index b8828763a23094d30befef3eb93eb5d0b557e80c..04ee98f81068a219189808629ab4e31a7b3ad09e 100644 (file)
@@ -32,6 +32,7 @@ namespace Content.IntegrationTests.Tests.Interaction
             var sEntities = server.ResolveDependency<IEntityManager>();
             var mapManager = server.ResolveDependency<IMapManager>();
             var conSystem = sEntities.EntitySysManager.GetEntitySystem<SharedContainerSystem>();
+            var xfmSystem = sEntities.EntitySysManager.GetEntitySystem<SharedTransformSystem>();
 
             EntityUid origin = default;
             EntityUid other = default;
@@ -45,7 +46,7 @@ namespace Content.IntegrationTests.Tests.Interaction
                 origin = sEntities.SpawnEntity(HumanId, coordinates);
                 other = sEntities.SpawnEntity(HumanId, coordinates);
                 conSystem.EnsureContainer<Container>(other, "InRangeUnobstructedTestOtherContainer");
-                mapCoordinates = sEntities.GetComponent<TransformComponent>(other).MapPosition;
+                mapCoordinates = xfmSystem.GetMapCoordinates(other);
             });
 
             await server.WaitIdleAsync();
index d4e2cde9b0d541712986c60fbc651336f53b29be..c18e12e16eaa5910d8fee827c49bd8a8cbb91ee9 100644 (file)
@@ -626,6 +626,7 @@ namespace Content.IntegrationTests.Tests.Power
             var entityManager = server.ResolveDependency<IEntityManager>();
             var gameTiming = server.ResolveDependency<IGameTiming>();
             var batterySys = entityManager.System<BatterySystem>();
+            var xformSys = entityManager.System<SharedTransformSystem>();
             PowerConsumerComponent consumer = default!;
             PowerSupplierComponent supplier = default!;
             PowerNetworkBatteryComponent netBattery = default!;
@@ -644,7 +645,7 @@ namespace Content.IntegrationTests.Tests.Power
                 }
 
                 var terminal = entityManager.SpawnEntity("CableTerminal", grid.ToCoordinates(0, 1));
-                entityManager.GetComponent<TransformComponent>(terminal).LocalRotation = Angle.FromDegrees(180);
+                xformSys.SetLocalRotation(terminal, Angle.FromDegrees(180));
 
                 var batteryEnt = entityManager.SpawnEntity("FullBatteryDummy", grid.ToCoordinates(0, 2));
                 var supplyEnt = entityManager.SpawnEntity("GeneratorDummy", grid.ToCoordinates(0, 0));
@@ -703,6 +704,7 @@ namespace Content.IntegrationTests.Tests.Power
             var entityManager = server.ResolveDependency<IEntityManager>();
             var gameTiming = server.ResolveDependency<IGameTiming>();
             var batterySys = entityManager.System<BatterySystem>();
+            var xformSys = entityManager.System<SharedTransformSystem>();
             PowerConsumerComponent consumer = default!;
             PowerSupplierComponent supplier = default!;
             PowerNetworkBatteryComponent netBattery = default!;
@@ -721,7 +723,7 @@ namespace Content.IntegrationTests.Tests.Power
                 }
 
                 var terminal = entityManager.SpawnEntity("CableTerminal", grid.ToCoordinates(0, 1));
-                entityManager.GetComponent<TransformComponent>(terminal).LocalRotation = Angle.FromDegrees(180);
+                xformSys.SetLocalRotation(terminal, Angle.FromDegrees(180));
 
                 var batteryEnt = entityManager.SpawnEntity("FullBatteryDummy", grid.ToCoordinates(0, 2));
                 var supplyEnt = entityManager.SpawnEntity("GeneratorDummy", grid.ToCoordinates(0, 0));
@@ -779,6 +781,7 @@ namespace Content.IntegrationTests.Tests.Power
             var mapManager = server.ResolveDependency<IMapManager>();
             var entityManager = server.ResolveDependency<IEntityManager>();
             var batterySys = entityManager.System<BatterySystem>();
+            var xformSys = entityManager.System<SharedTransformSystem>();
             PowerConsumerComponent consumer1 = default!;
             PowerConsumerComponent consumer2 = default!;
             PowerSupplierComponent supplier = default!;
@@ -805,7 +808,7 @@ namespace Content.IntegrationTests.Tests.Power
 
                 entityManager.SpawnEntity("CableTerminal", grid.ToCoordinates(0, 2));
                 var terminal = entityManager.SpawnEntity("CableTerminal", grid.ToCoordinates(0, 2));
-                entityManager.GetComponent<TransformComponent>(terminal).LocalRotation = Angle.FromDegrees(180);
+                xformSys.SetLocalRotation(terminal, Angle.FromDegrees(180));
 
                 var batteryEnt1 = entityManager.SpawnEntity("FullBatteryDummy", grid.ToCoordinates(0, 1));
                 var batteryEnt2 = entityManager.SpawnEntity("FullBatteryDummy", grid.ToCoordinates(0, 3));
@@ -973,6 +976,7 @@ namespace Content.IntegrationTests.Tests.Power
             var mapManager = server.ResolveDependency<IMapManager>();
             var entityManager = server.ResolveDependency<IEntityManager>();
             var batterySys = entityManager.System<BatterySystem>();
+            var xformSys = entityManager.System<SharedTransformSystem>();
             PowerConsumerComponent consumer1 = default!;
             PowerConsumerComponent consumer2 = default!;
             PowerSupplierComponent supplier = default!;
@@ -999,7 +1003,7 @@ namespace Content.IntegrationTests.Tests.Power
 
                 entityManager.SpawnEntity("CableTerminal", grid.ToCoordinates(0, 2));
                 var terminal = entityManager.SpawnEntity("CableTerminal", grid.ToCoordinates(0, 2));
-                entityManager.GetComponent<TransformComponent>(terminal).LocalRotation = Angle.FromDegrees(180);
+                xformSys.SetLocalRotation(terminal, Angle.FromDegrees(180));
 
                 var batteryEnt1 = entityManager.SpawnEntity("FullBatteryDummy", grid.ToCoordinates(0, 1));
                 var batteryEnt2 = entityManager.SpawnEntity("FullBatteryDummy", grid.ToCoordinates(0, 3));
@@ -1060,6 +1064,7 @@ namespace Content.IntegrationTests.Tests.Power
             var mapManager = server.ResolveDependency<IMapManager>();
             var entityManager = server.ResolveDependency<IEntityManager>();
             var batterySys = entityManager.System<BatterySystem>();
+            var xformSys = entityManager.System<SharedTransformSystem>();
             PowerConsumerComponent consumer = default!;
             PowerSupplierComponent supplier = default!;
             PowerNetworkBatteryComponent netBattery = default!;
@@ -1077,7 +1082,7 @@ namespace Content.IntegrationTests.Tests.Power
                 }
 
                 var terminal = entityManager.SpawnEntity("CableTerminal", grid.ToCoordinates(0, 1));
-                entityManager.GetComponent<TransformComponent>(terminal).LocalRotation = Angle.FromDegrees(180);
+                xformSys.SetLocalRotation(terminal, Angle.FromDegrees(180));
 
                 var batteryEnt = entityManager.SpawnEntity("FullBatteryDummy", grid.ToCoordinates(0, 2));
                 var supplyEnt = entityManager.SpawnEntity("GeneratorDummy", grid.ToCoordinates(0, 0));
@@ -1144,6 +1149,7 @@ namespace Content.IntegrationTests.Tests.Power
             var mapManager = server.ResolveDependency<IMapManager>();
             var entityManager = server.ResolveDependency<IEntityManager>();
             var nodeContainer = entityManager.System<NodeContainerSystem>();
+            var xformSys = entityManager.System<SharedTransformSystem>();
             CableNode leftNode = default!;
             CableNode rightNode = default!;
             Node batteryInput = default!;
@@ -1166,7 +1172,7 @@ namespace Content.IntegrationTests.Tests.Power
                 var rightEnt = entityManager.SpawnEntity("CableHV", grid.ToCoordinates(0, 3));
 
                 var terminal = entityManager.SpawnEntity("CableTerminal", grid.ToCoordinates(0, 1));
-                entityManager.GetComponent<TransformComponent>(terminal).LocalRotation = Angle.FromDegrees(180);
+                xformSys.SetLocalRotation(terminal, Angle.FromDegrees(180));
 
                 var battery = entityManager.SpawnEntity("FullBatteryDummy", grid.ToCoordinates(0, 2));
                 var batteryNodeContainer = entityManager.GetComponent<NodeContainerComponent>(battery);
index b6fc273570a151b51ca1990e8720e1488ab28420..bf90ccc8ef881d08d505fc0eb75165508cb9feb1 100644 (file)
@@ -60,8 +60,7 @@ public sealed class DockTest : ContentUnitTest
 
             mapSystem.SetTiles(grid1.Owner, grid1.Comp, tiles1);
             var dock1 = entManager.SpawnEntity("AirlockShuttle", new EntityCoordinates(grid1Ent, dock1Pos));
-            var dock1Xform = entManager.GetComponent<TransformComponent>(dock1);
-            dock1Xform.LocalRotation = dock1Angle;
+            xformSystem.SetLocalRotation(dock1, dock1Angle);
 
             var tiles2 = new List<(Vector2i Index, Tile Tile)>()
             {
@@ -74,8 +73,7 @@ public sealed class DockTest : ContentUnitTest
 
             mapSystem.SetTiles(grid2.Owner, grid2.Comp, tiles2);
             var dock2 = entManager.SpawnEntity("AirlockShuttle", new EntityCoordinates(grid2Ent, dock2Pos));
-            var dock2Xform = entManager.GetComponent<TransformComponent>(dock2);
-            dock2Xform.LocalRotation = dock2Angle;
+            xformSystem.SetLocalRotation(dock2, dock2Angle);
 
             var config = dockingSystem.GetDockingConfig(grid1Ent, grid2Ent);
 
index d541b1c8840a5ea59dd625679ca51e40f655eed6..ed9b211ca98a003291699daf29b09e5d64e1cfcc 100644 (file)
@@ -47,7 +47,7 @@ namespace Content.Server.Administration.Commands
                 ? _entities.GetComponent<TransformComponent>(player.AttachedEntity.Value).Coordinates
                 : EntitySystem.Get<GameTicker>().GetObserverSpawnPoint();
             var ghost = _entities.SpawnEntity(GameTicker.AdminObserverPrototypeName, coordinates);
-            _entities.GetComponent<TransformComponent>(ghost).AttachToGridOrMap();
+            _entities.System<SharedTransformSystem>().AttachToGridOrMap(ghost);
 
             if (canReturn)
             {
index 56ed78b2e2e3909ecd87b902a10a65ecd915450e..94185a0248cf72b3dc4e01e87df80b87b66f0894 100644 (file)
@@ -105,7 +105,7 @@ public sealed class ExplosionCommand : IConsoleCommand
             if (args.Length > 4)
                 coords = new MapCoordinates(new Vector2(x, y), xform.MapID);
             else
-                coords = xform.MapPosition;
+                coords = entMan.System<SharedTransformSystem>().GetMapCoordinates(xform);
         }
 
         ExplosionPrototype? type;
index 0d6da0d993735f65ab6248e96f3b92144f354710..0b15b2687ae5f7b0ef4c8a2280e639b5c82eb359 100644 (file)
@@ -118,8 +118,10 @@ namespace Content.Server.Administration.Commands
                 }
 
                 var xform = _entManager.GetComponent<TransformComponent>(playerEntity);
-                xform.Coordinates = coords;
-                xform.AttachToGridOrMap();
+                var xformSystem = _entManager.System<SharedTransformSystem>();
+
+                xformSystem.SetCoordinates((playerEntity, xform, _entManager.GetComponent<MetaDataComponent>(playerEntity)), coords);
+                xformSystem.AttachToGridOrMap(playerEntity, xform);
                 if (_entManager.TryGetComponent(playerEntity, out PhysicsComponent? physics))
                 {
                     _entManager.System<SharedPhysicsSystem>().SetLinearVelocity(playerEntity, Vector2.Zero, body: physics);
index 8a819f59420c97e49714ce139a91c31a9c053ce5..075ea0b71cd1101ae66cf3efe4aa8d32d766ea32 100644 (file)
@@ -103,7 +103,7 @@ public sealed partial class AdminVerbSystem
             Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/smite.svg.192dpi.png")),
             Act = () =>
             {
-                var coords = Transform(args.Target).MapPosition;
+                var coords = _transformSystem.GetMapCoordinates(args.Target);
                 Timer.Spawn(_gameTiming.TickPeriod,
                     () => _explosionSystem.QueueExplosion(coords, ExplosionSystem.DefaultExplosionPrototypeId,
                         4, 1, 2, maxTileBreak: 0), // it gibs, damage doesn't need to be high.
@@ -134,8 +134,8 @@ public sealed partial class AdminVerbSystem
                     Filter.PvsExcept(args.Target), true, PopupType.MediumCaution);
                 var board = Spawn("ChessBoard", xform.Coordinates);
                 var session = _tabletopSystem.EnsureSession(Comp<TabletopGameComponent>(board));
-                xform.Coordinates = EntityCoordinates.FromMap(_mapManager, session.Position);
-                xform.WorldRotation = Angle.Zero;
+                _transformSystem.SetCoordinates((args.Target, xform, MetaData(args.Target)), EntityCoordinates.FromMap(_mapManager, session.Position));
+                _transformSystem.SetWorldRotation(xform, Angle.Zero);
             },
             Impact = LogImpact.Extreme,
             Message = Loc.GetString("admin-smite-chess-dimension-description")
@@ -407,7 +407,7 @@ public sealed partial class AdminVerbSystem
                 {
                     var xform = Transform(args.Target);
                     var fixtures = Comp<FixturesComponent>(args.Target);
-                    xform.Anchored = false; // Just in case.
+                    _xformSystem.Unanchor(args.Target, xform); // Just in case.
                     _physics.SetBodyType(args.Target, BodyType.Dynamic, manager: fixtures, body: physics);
                     _physics.SetBodyStatus(physics, BodyStatus.InAir);
                     _physics.WakeBody(args.Target, manager: fixtures, body: physics);
@@ -441,7 +441,7 @@ public sealed partial class AdminVerbSystem
                 {
                     var xform = Transform(args.Target);
                     var fixtures = Comp<FixturesComponent>(args.Target);
-                    xform.Anchored = false; // Just in case.
+                    _xformSystem.Unanchor(args.Target, xform); // Just in case.
 
                     _physics.SetBodyType(args.Target, BodyType.Dynamic, body: physics);
                     _physics.SetBodyStatus(physics, BodyStatus.InAir);
index 87c0ba4a4eedd742933e90a8e14fb655bc05de97..8919822228af05838356cd35f95ceb66ec40f14e 100644 (file)
@@ -40,7 +40,7 @@ public sealed class BluespaceAnomalySystem : EntitySystem
         foreach (var ent in allEnts)
         {
             if (xformQuery.TryGetComponent(ent, out var xf))
-                coords.Add(xf.MapPosition.Position);
+                coords.Add(_xform.GetWorldPosition(xf));
         }
 
         _random.Shuffle(coords);
index 8b5a72449f348d2027ab86bb8ed7fb91ac748ac7..85470d17b1a735834a929c081d74bdc6f7f3e293 100644 (file)
@@ -61,7 +61,7 @@ public sealed class ElectricityAnomalySystem : EntitySystem
             var damage = (int) (elec.MaxElectrocuteDamage * anom.Severity);
             var duration = elec.MaxElectrocuteDuration * anom.Severity;
 
-            foreach (var (ent, comp) in _lookup.GetEntitiesInRange<StatusEffectsComponent>(xform.MapPosition, range))
+            foreach (var (ent, comp) in _lookup.GetEntitiesInRange<StatusEffectsComponent>(_transform.GetMapCoordinates((uid, xform)), range))
             {
                 _electrocution.TryDoElectrocution(ent, uid, damage, duration, true, statusEffects: comp, ignoreInsulation: true);
             }
index 2bef32e322816733c67427feb91bc25e1f2f70dc..721f23c3aee8d8cb00c62de0a55b0cb5194a5143 100644 (file)
@@ -16,6 +16,7 @@ public sealed class InjectionAnomalySystem : EntitySystem
 {
     [Dependency] private readonly EntityLookupSystem _lookup = default!;
     [Dependency] private readonly SolutionContainerSystem _solutionContainer = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     private EntityQuery<InjectableSolutionComponent> _injectableQuery;
 
@@ -45,7 +46,7 @@ public sealed class InjectionAnomalySystem : EntitySystem
         //We get all the entity in the radius into which the reagent will be injected.
         var xformQuery = GetEntityQuery<TransformComponent>();
         var xform = xformQuery.GetComponent(entity);
-        var allEnts = _lookup.GetEntitiesInRange<InjectableSolutionComponent>(xform.MapPosition, injectRadius)
+        var allEnts = _lookup.GetEntitiesInRange<InjectableSolutionComponent>(_xformSystem.GetMapCoordinates((entity.Owner, xform)), injectRadius)
             .Select(x => x.Owner).ToList();
 
         //for each matching entity found
index 416045fc5ed9fc395bf00168ad491b2f1c78236b..2c4123ee9ed26f078b8dd63622fcb07a2979877e 100644 (file)
@@ -66,7 +66,7 @@ public sealed class AirFilterSystem : EntitySystem
         var oxygen = air.GetMoles(filter.Oxygen) / air.TotalMoles;
         var gases = oxygen >= filter.TargetOxygen ? filter.Gases : filter.OverflowGases;
 
-        var coordinates = Transform(uid).MapPosition;
+        var coordinates = _transform.GetMapCoordinates(uid);
         GasMixture? destination = null;
         if (_map.TryFindGridAt(coordinates, out _, out var grid))
         {
index 97dccbaabb7317ab834994805c0f81dabbef9571..7462ab1d8f16bc6258d84930b61fefd4a8282945 100644 (file)
@@ -29,7 +29,7 @@ namespace Content.Server.Atmos.EntitySystems
 
             if (airtight.Comp.FixAirBlockedDirectionInitialize)
             {
-                var moveEvent = new MoveEvent(airtight, default, default, Angle.Zero, xform.LocalRotation, xform, false);
+                var moveEvent = new MoveEvent((airtight, xform, MetaData(airtight)), default, default, Angle.Zero, xform.LocalRotation);
                 if (AirtightMove(airtight, ref moveEvent))
                     return;
             }
index 53035e1ed3c5555df7225031cad7c0f7cb82794c..fdc4568d04bc4583fb2cffcac51d0e73a7fd85eb 100644 (file)
@@ -119,7 +119,7 @@ namespace Content.Server.Atmos.EntitySystems
                 return;
 
             // Used by ExperiencePressureDifference to correct push/throw directions from tile-relative to physics world.
-            var gridWorldRotation = xforms.GetComponent(gridAtmosphere).WorldRotation;
+            var gridWorldRotation = _transformSystem.GetWorldRotation(gridAtmosphere);
 
             // If we're using monstermos, smooth out the yeet direction to follow the flow
             if (MonstermosEqualization)
@@ -238,7 +238,7 @@ namespace Content.Server.Atmos.EntitySystems
                     // TODO: Technically these directions won't be correct but uhh I'm just here for optimisations buddy not to fix my old bugs.
                     if (throwTarget != EntityCoordinates.Invalid)
                     {
-                        var pos = ((throwTarget.ToMap(EntityManager).Position - xform.WorldPosition).Normalized() + dirVec).Normalized();
+                        var pos = ((throwTarget.ToMap(EntityManager).Position - _transformSystem.GetWorldPosition(xform)).Normalized() + dirVec).Normalized();
                         _physics.ApplyLinearImpulse(uid, pos * moveForce, body: physics);
                     }
                     else
index 33f2f252d90dd31180c77772d763de1d722d8b93..4a8a0e40b3bbfb39a50334460b38f146139cfa9c 100644 (file)
@@ -19,6 +19,7 @@ public sealed class BeamSystem : SharedBeamSystem
     [Dependency] private readonly SharedAudioSystem _audio = default!;
     [Dependency] private readonly SharedBroadphaseSystem _broadphase = default!;
     [Dependency] private readonly SharedPhysicsSystem _physics = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public override void Initialize()
     {
@@ -144,8 +145,8 @@ public sealed class BeamSystem : SharedBeamSystem
         if (Deleted(user) || Deleted(target))
             return;
 
-        var userMapPos = Transform(user).MapPosition;
-        var targetMapPos = Transform(target).MapPosition;
+        var userMapPos = _xformSystem.GetMapCoordinates(user);
+        var targetMapPos = _xformSystem.GetMapCoordinates(target);
 
         //The distance between the target and the user.
         var calculatedDistance = targetMapPos.Position - userMapPos.Position;
index a0639e3708cc1b7a66383b80e2859380f6a77c8d..5c96e533ec9b89b0bc4ec6eb0b8e0dd50878319c 100644 (file)
@@ -12,6 +12,7 @@ public sealed class LogSystem : EntitySystem
     [Dependency] private readonly SharedHandsSystem _handsSystem = default!;
     [Dependency] private readonly SharedContainerSystem _containerSystem = default!;
     [Dependency] private readonly RandomHelperSystem _randomHelper = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public override void Initialize()
     {
@@ -39,7 +40,7 @@ public sealed class LogSystem : EntitySystem
             {
                 var xform = Transform(plank);
                 _containerSystem.AttachParentToContainerOrGrid((plank, xform));
-                xform.LocalRotation = 0;
+                _xformSystem.SetLocalRotation(plank, 0, xform);
                 _randomHelper.RandomOffset(plank, 0.25f);
             }
         }
index e1cdfd2066092b4176ceaa58fd3511b8870780fa..0f81a79cd3b0184eea5e049a9f87f3bac02ec927 100644 (file)
@@ -11,6 +11,7 @@ public sealed class RehydratableSystem : EntitySystem
 {
     [Dependency] private readonly SharedPopupSystem _popups = default!;
     [Dependency] private readonly SolutionContainerSystem _solutions = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
     [Dependency] private readonly IRobustRandom _random = default!;
 
     public override void Initialize()
@@ -40,7 +41,7 @@ public sealed class RehydratableSystem : EntitySystem
 
         var target = Spawn(randomMob, Transform(uid).Coordinates);
 
-        Transform(target).AttachToGridOrMap();
+        _xformSystem.AttachToGridOrMap(target);
         var ev = new GotRehydratedEvent(target);
         RaiseLocalEvent(uid, ref ev);
 
index 2c23b8f0390074f37df0834abac813caad0c35a3..7a2ac44984b85c0bf145828f6c99750231e966d2 100644 (file)
@@ -28,6 +28,7 @@ namespace Content.Server.Chemistry.EntitySystems
         [Dependency] private readonly SolutionContainerSystem _solutionContainerSystem = default!;
         [Dependency] private readonly ThrowingSystem _throwing = default!;
         [Dependency] private readonly ReactiveSystem _reactive = default!;
+        [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
         private const float ReactTime = 0.125f;
 
@@ -71,7 +72,7 @@ namespace Content.Server.Chemistry.EntitySystems
 
                 _throwing.TryThrow(vapor, dir, speed, user: user);
 
-                var distance = (target.Position - vaporXform.WorldPosition).Length();
+                var distance = (target.Position - _xformSystem.GetWorldPosition(vaporXform)).Length();
                 var time = (distance / physics.LinearVelocity.Length());
                 despawn.Lifetime = MathF.Min(aliveTime, time);
             }
index 024558f8de34959f4dd0f4b67594cff8c047aa13..93d7f6062865dd18211b5dbcc859401d910e752a 100644 (file)
@@ -57,16 +57,18 @@ namespace Content.Server.Chemistry.ReactionEffects
             var spreadAmount = (int) Math.Max(0, Math.Ceiling((args.Quantity / OverflowThreshold).Float()));
             var splitSolution = args.Source.SplitSolution(args.Source.Volume);
             var transform = args.EntityManager.GetComponent<TransformComponent>(args.SolutionEntity);
+            var xformSystem = args.EntityManager.System<SharedTransformSystem>();
             var mapManager = IoCManager.Resolve<IMapManager>();
 
-            if (!mapManager.TryFindGridAt(transform.MapPosition, out _, out var grid) ||
+            var mapCoordinates = xformSystem.GetMapCoordinates((args.SolutionEntity, transform));
+            if (!mapManager.TryFindGridAt(mapCoordinates, out _, out var grid) ||
                 !grid.TryGetTileRef(transform.Coordinates, out var tileRef) ||
                 tileRef.Tile.IsSpace())
             {
                 return;
             }
 
-            var coords = grid.MapToGrid(transform.MapPosition);
+            var coords = grid.MapToGrid(mapCoordinates);
             var ent = args.EntityManager.SpawnEntity(_prototypeId, coords.SnapToGrid());
 
             var smoke = args.EntityManager.System<SmokeSystem>();
index f8c0378452bf1b450be7dc6264e321dab7638014..db89d52696dfe0d81a383b7402e3f8e7154cfb27 100644 (file)
@@ -34,7 +34,7 @@ public sealed partial class CreateEntityReactionEffect : ReagentEffect
 
         for (var i = 0; i < quantity; i++)
         {
-            var uid = args.EntityManager.SpawnEntity(Entity, transform.MapPosition);
+            var uid = args.EntityManager.SpawnEntity(Entity, transformSystem.GetMapCoordinates((args.SolutionEntity, transform)));
             transformSystem.AttachToGridOrMap(uid);
 
             // TODO figure out how to properly spawn inside of containers
index b6714ca28d0f4c6265c3bf8e058c744a9348a8a3..cc81ddff1646c73148be8b5cc519815a8ae4fb0b 100644 (file)
@@ -41,7 +41,7 @@ public sealed partial class EmpReactionEffect : ReagentEffect
         var range = MathF.Min((float) (args.Quantity*EmpRangePerUnit), EmpMaxRange);
 
         args.EntityManager.System<EmpSystem>().EmpPulse(
-            transform.MapPosition,
+            args.EntityManager.System<SharedTransformSystem>().GetMapCoordinates((args.SolutionEntity, transform)),
             range,
             EnergyConsumption,
             DisableDuration);
index def9950d9049f609ada4f2093fea23b197e452de..3893f31d25d755067bbde4aa3892107ab663fadc 100644 (file)
@@ -210,7 +210,7 @@ namespace Content.Server.Cloning
             }
             // end of genetic damage checks
 
-            var mob = Spawn(speciesPrototype.Prototype, Transform(uid).MapPosition);
+            var mob = Spawn(speciesPrototype.Prototype, _transformSystem.GetMapCoordinates(uid));
             _humanoidSystem.CloneAppearance(bodyToClone, mob);
 
             var ev = new CloningEvent(bodyToClone, mob);
index 172f3324e35d8ba09bc673f36efceba68aaeece8..09736a4eac1d8d216d27ef2c97d4b9a5c02ac7ae 100644 (file)
@@ -54,18 +54,16 @@ namespace Content.Server.Commands
         public static string SubstituteEntityDetails(IConsoleShell shell, EntityUid ent, string ruleString)
         {
             var entMan = IoCManager.Resolve<IEntityManager>();
+            var xfmSys = entMan.System<SharedTransformSystem>();
             var transform = entMan.GetComponent<TransformComponent>(ent);
+            var worldPosition = xfmSys.GetWorldPosition(transform);
 
             // gross, is there a better way to do this?
             ruleString = ruleString.Replace("$ID", ent.ToString());
-            ruleString = ruleString.Replace("$WX",
-                transform.WorldPosition.X.ToString(CultureInfo.InvariantCulture));
-            ruleString = ruleString.Replace("$WY",
-                transform.WorldPosition.Y.ToString(CultureInfo.InvariantCulture));
-            ruleString = ruleString.Replace("$LX",
-                transform.LocalPosition.X.ToString(CultureInfo.InvariantCulture));
-            ruleString = ruleString.Replace("$LY",
-                transform.LocalPosition.Y.ToString(CultureInfo.InvariantCulture));
+            ruleString = ruleString.Replace("$WX", worldPosition.X.ToString(CultureInfo.InvariantCulture));
+            ruleString = ruleString.Replace("$WY", worldPosition.Y.ToString(CultureInfo.InvariantCulture));
+            ruleString = ruleString.Replace("$LX", transform.LocalPosition.X.ToString(CultureInfo.InvariantCulture));
+            ruleString = ruleString.Replace("$LY", transform.LocalPosition.Y.ToString(CultureInfo.InvariantCulture));
             ruleString = ruleString.Replace("$NAME", entMan.GetComponent<MetaDataComponent>(ent).EntityName);
 
             if (shell.Player is { } player)
@@ -73,16 +71,13 @@ namespace Content.Server.Commands
                 if (player.AttachedEntity is {Valid: true} p)
                 {
                     var pTransform = entMan.GetComponent<TransformComponent>(p);
+                    var pPosition = xfmSys.GetWorldPosition(pTransform);
 
                     ruleString = ruleString.Replace("$PID", ent.ToString());
-                    ruleString = ruleString.Replace("$PWX",
-                        pTransform.WorldPosition.X.ToString(CultureInfo.InvariantCulture));
-                    ruleString = ruleString.Replace("$PWY",
-                        pTransform.WorldPosition.Y.ToString(CultureInfo.InvariantCulture));
-                    ruleString = ruleString.Replace("$PLX",
-                        pTransform.LocalPosition.X.ToString(CultureInfo.InvariantCulture));
-                    ruleString = ruleString.Replace("$PLY",
-                        pTransform.LocalPosition.Y.ToString(CultureInfo.InvariantCulture));
+                    ruleString = ruleString.Replace("$PWX", pPosition.X.ToString(CultureInfo.InvariantCulture));
+                    ruleString = ruleString.Replace("$PWY", pPosition.Y.ToString(CultureInfo.InvariantCulture));
+                    ruleString = ruleString.Replace("$PLX", pTransform.LocalPosition.X.ToString(CultureInfo.InvariantCulture));
+                    ruleString = ruleString.Replace("$PLY", pTransform.LocalPosition.Y.ToString(CultureInfo.InvariantCulture));
                 }
             }
             return ruleString;
index 9c99035573ab818cdb95fa5525eb8cd7ab9466e3..0a37c2f4440aa639f84b4eaf227f716aaaf3dd3c 100644 (file)
@@ -63,6 +63,7 @@ namespace Content.Server.Construction.Commands
 
             var changed = 0;
             var tagSystem = _entManager.EntitySysManager.GetEntitySystem<TagSystem>();
+            var xformSystem = _entManager.System<SharedTransformSystem>();
 
 
             var enumerator = xformQuery.GetComponent(gridId.Value).ChildEnumerator;
@@ -97,7 +98,7 @@ namespace Content.Server.Construction.Commands
 
                 if (childXform.LocalRotation != Angle.Zero)
                 {
-                    childXform.LocalRotation = Angle.Zero;
+                    xformSystem.SetLocalRotation(child, Angle.Zero, childXform);
                     changed++;
                 }
             }
index 989ecc99bda6299e2ff85d31dca9b749faeeb1cb..737f07b91da450dff26a2b77802269724e7b7a1e 100644 (file)
@@ -12,7 +12,14 @@ namespace Content.Server.Construction.Completions
         public void PerformAction(EntityUid uid, EntityUid? userUid, IEntityManager entityManager)
         {
             var transform = entityManager.GetComponent<TransformComponent>(uid);
-            transform.Anchored = Value;
+            if (Value == transform.Anchored)
+                return;
+
+            var xformSystem = entityManager.System<SharedTransformSystem>();
+            if (Value)
+                xformSystem.AnchorEntity((uid, transform));
+            else
+                xformSystem.Unanchor(uid, transform);
         }
     }
 }
index 47941108f539747cccdfb056f237f7334c4d1a82..dfba91b7cf111d8504463f8a3a63fc0772b43380 100644 (file)
@@ -14,13 +14,12 @@ namespace Content.Server.Construction.Completions
         {
             var transform = entityManager.GetComponent<TransformComponent>(uid);
 
+            var xformSystem = entityManager.System<SharedTransformSystem>();
             if (!transform.Anchored)
-                transform.Coordinates = transform.Coordinates.SnapToGrid(entityManager);
+                xformSystem.SetCoordinates((uid, transform, entityManager.GetComponent<MetaDataComponent>(uid)), transform.Coordinates.SnapToGrid(entityManager));
 
             if (SouthRotation)
-            {
-                transform.LocalRotation = Angle.Zero;
-            }
+                xformSystem.SetLocalRotation(uid, Angle.Zero, transform);
         }
     }
 }
index 570360bf09a31f7b5df38609b332a1f43a450169..ec5e71e14537a5f314dfca2cac05c54e27e15965 100644 (file)
@@ -362,9 +362,12 @@ namespace Content.Server.Construction
 
             // Transform transferring.
             var newTransform = Transform(newUid);
-            newTransform.AttachToGridOrMap(); // in case in hands or a container
-            newTransform.LocalRotation = transform.LocalRotation;
-            newTransform.Anchored = transform.Anchored;
+            _xformSystem.AttachToGridOrMap(newUid, newTransform); // in case in hands or a container
+            _xformSystem.SetLocalRotation(newUid, transform.LocalRotation, newTransform);
+            if (transform.Anchored)
+                _xformSystem.AnchorEntity((newUid, newTransform));
+            else
+                _xformSystem.Unanchor(newUid, newTransform);
 
             // Container transferring.
             if (containerManager != null)
index e0bdf096296f6d7d44810954807e93d3f5eb7fc3..708fa5a543886ea144d223ebd0b723e1a3c83847 100644 (file)
@@ -32,6 +32,7 @@ namespace Content.Server.Construction
         [Dependency] private readonly EntityLookupSystem _lookupSystem = default!;
         [Dependency] private readonly StorageSystem _storageSystem = default!;
         [Dependency] private readonly TagSystem _tagSystem = default!;
+        [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
         // --- WARNING! LEGACY CODE AHEAD! ---
         // This entire file contains the legacy code for initial construction.
@@ -82,7 +83,7 @@ namespace Content.Server.Construction
                 }
             }
 
-            var pos = Transform(user).MapPosition;
+            var pos = _xformSystem.GetMapCoordinates(user);
 
             foreach (var near in _lookupSystem.GetEntitiesInRange(pos, 2f, LookupFlags.Contained | LookupFlags.Dynamic | LookupFlags.Sundries | LookupFlags.Approximate))
             {
@@ -527,10 +528,12 @@ namespace Content.Server.Construction
             // ikr
             var xform = Transform(structure);
             var wasAnchored = xform.Anchored;
-            xform.Anchored = false;
-            xform.Coordinates = GetCoordinates(ev.Location);
-            xform.LocalRotation = constructionPrototype.CanRotate ? ev.Angle : Angle.Zero;
-            xform.Anchored = wasAnchored;
+            if (wasAnchored)
+                _xformSystem.Unanchor(structure, xform);
+            _xformSystem.SetCoordinates((structure, xform, MetaData(structure)), GetCoordinates(ev.Location));
+            _xformSystem.SetLocalRotation(structure, constructionPrototype.CanRotate ? ev.Angle : Angle.Zero, xform);
+            if (wasAnchored)
+                _xformSystem.AnchorEntity((structure, xform));
 
             RaiseNetworkEvent(new AckStructureConstructionMessage(ev.Ack, GetNetEntity(structure)));
             _adminLogger.Add(LogType.Construction, LogImpact.Low, $"{ToPrettyString(user):player} has turned a {ev.PrototypeName} construction ghost into {ToPrettyString(structure)} at {Transform(structure).Coordinates}");
index 16c54fd3b02af0d39518858647cd65483ea83d1e..e1bbe5bf1ae394180349f010cf3a95f345dd67cc 100644 (file)
@@ -42,6 +42,7 @@ namespace Content.Server.Destructible
         [Dependency] public readonly IPrototypeManager PrototypeManager = default!;
         [Dependency] public readonly IComponentFactory ComponentFactory = default!;
         [Dependency] public readonly IAdminLogManager _adminLogger = default!;
+        [Dependency] public readonly SharedTransformSystem TransformSystem = default!;
 
         public override void Initialize()
         {
index e13fd5e05beb60658132da7f29223454ed6e90eb..1d28666ea6f7c6cfdd0e46b5d8c019b8e085c67b 100644 (file)
@@ -44,14 +44,14 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
                 {
                     var spawned = system.EntityManager.SpawnEntity(entityId, xform.Coordinates.Offset(system.Random.NextVector2(-Offset, Offset)));
                     system.StackSystem.SetCount(spawned, toSpawn);
-                    system.EntityManager.GetComponent<TransformComponent>(spawned).LocalRotation = system.Random.NextAngle();
+                    system.TransformSystem.SetLocalRotation(spawned, system.Random.NextAngle());
                 }
                 else
                 {
                     for (var i = 0; i < toSpawn; i++)
                     {
                         var spawned = system.EntityManager.SpawnEntity(entityId, xform.Coordinates.Offset(system.Random.NextVector2(-Offset, Offset)));
-                        system.EntityManager.GetComponent<TransformComponent>(spawned).LocalRotation = system.Random.NextAngle();
+                        system.TransformSystem.SetLocalRotation(spawned, system.Random.NextAngle());
                     }
                 }
             }
index ed5777c42aa99632ec216f8d58550bf4bae11b69..43204da8d2ef2febdb1f88db2e693b406d744e8f 100644 (file)
@@ -27,7 +27,7 @@ namespace Content.Server.Destructible.Thresholds.Behaviors
 
         public void Execute(EntityUid owner, DestructibleSystem system, EntityUid? cause = null)
         {
-            var position = system.EntityManager.GetComponent<TransformComponent>(owner).MapPosition;
+            var position = system.TransformSystem.GetMapCoordinates(owner);
 
             var getRandomVector = () => new Vector2(system.Random.NextFloat(-Offset, Offset), system.Random.NextFloat(-Offset, Offset));
 
index b27ef52eca60ccda5dcf98b229a02d75433849bd..30ffc2d1d2c2e005fdf8df2df01f19209fa9d935 100644 (file)
@@ -6,6 +6,8 @@ namespace Content.Server.DeviceNetwork.Systems
     [UsedImplicitly]
     public sealed class WirelessNetworkSystem : EntitySystem
     {
+        [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
+
         public override void Initialize()
         {
             base.Initialize();
@@ -25,7 +27,7 @@ namespace Content.Server.DeviceNetwork.Systems
                 return;
 
             if (xform.MapID != args.SenderTransform.MapID
-                || (ownPosition - xform.WorldPosition).Length() > sendingComponent.Range)
+                || (ownPosition - _xformSystem.GetWorldPosition(xform)).Length() > sendingComponent.Range)
             {
                 args.Cancel();
             }
index b7d8455d85e07bb4075ed205294bfd53969b93fb..9e69b3d7e9c775029f5b40ea6aecd611c15dc3ba 100644 (file)
@@ -37,6 +37,8 @@ namespace Content.Server.Disposal.Tube
         [Dependency] private readonly DisposableSystem _disposableSystem = default!;
         [Dependency] private readonly SharedContainerSystem _containerSystem = default!;
         [Dependency] private readonly AtmosphereSystem _atmosSystem = default!;
+        [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
+
         public override void Initialize()
         {
             base.Initialize();
@@ -430,8 +432,7 @@ namespace Content.Server.Disposal.Tube
             if (!Resolve(uid, ref entry))
                 return false;
 
-            var xform = Transform(uid);
-            var holder = Spawn(DisposalEntryComponent.HolderPrototypeId, xform.MapPosition);
+            var holder = Spawn(DisposalEntryComponent.HolderPrototypeId, _xformSystem.GetMapCoordinates(uid));
             var holderComponent = Comp<DisposalHolderComponent>(holder);
 
             foreach (var entity in from.Container.ContainedEntities.ToArray())
index 93d6bc8db0b3a97c376f4837129b2e7c0d5a7e07..0d996aa281f75fafae268ac7f00bc6462ab5e206 100644 (file)
@@ -28,6 +28,7 @@ public sealed partial class DragonSystem : EntitySystem
     [Dependency] private readonly RoleSystem _role = default!;
     [Dependency] private readonly SharedActionsSystem _actions = default!;
     [Dependency] private readonly SharedAudioSystem _audio = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     private EntityQuery<CarpRiftsConditionComponent> _objQuery;
 
@@ -154,7 +155,7 @@ public sealed partial class DragonSystem : EntitySystem
         }
 
         // cant put a rift on solars
-        foreach (var tile in grid.GetTilesIntersecting(new Circle(xform.WorldPosition, RiftTileRadius), false))
+        foreach (var tile in grid.GetTilesIntersecting(new Circle(_xformSystem.GetWorldPosition(xform), RiftTileRadius), false))
         {
             if (!tile.IsSpace(_tileDef))
                 continue;
@@ -163,7 +164,7 @@ public sealed partial class DragonSystem : EntitySystem
             return;
         }
 
-        var carpUid = Spawn(component.RiftPrototype, xform.MapPosition);
+        var carpUid = Spawn(component.RiftPrototype, _xformSystem.GetMapCoordinates((uid, xform)));
         component.Rifts.Add(carpUid);
         Comp<DragonRiftComponent>(carpUid).Dragon = uid;
     }
index 7c1a6f9b5db0cfeed29f219165e8e576facf1adb..fc79961f6d24c503402af3c3c66bd14560271ad2 100644 (file)
@@ -11,6 +11,7 @@ namespace Content.Server.Emp;
 public sealed class EmpSystem : SharedEmpSystem
 {
     [Dependency] private readonly EntityLookupSystem _lookup = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public const string EmpPulseEffectPrototype = "EffectEmpPulse";
 
@@ -102,7 +103,7 @@ public sealed class EmpSystem : SharedEmpSystem
 
     private void HandleEmpTrigger(EntityUid uid, EmpOnTriggerComponent comp, TriggerEvent args)
     {
-        EmpPulse(Transform(uid).MapPosition, comp.Range, comp.EnergyConsumption, comp.DisableDuration);
+        EmpPulse(_xformSystem.GetMapCoordinates(uid), comp.Range, comp.EnergyConsumption, comp.DisableDuration);
         args.Handled = true;
     }
 
index 8d2a699de270b634d936ddb4046b1b60506f5df8..73b546bcdf70884e191fcd4a5b6bb7e7d3fb97ed 100644 (file)
@@ -69,13 +69,15 @@ public sealed class ExplosionGridTileFlood : ExplosionTileFlood
             return;
 
         _needToTransform = true;
+        var entMan = IoCManager.Resolve<IEntityManager>();
+        var xfmSys = entMan.System<SharedTransformSystem>();
         var transform = IoCManager.Resolve<IEntityManager>().GetComponent<TransformComponent>(Grid.Owner);
         var size = (float) Grid.TileSize;
 
         _matrix.R0C2 = size / 2;
         _matrix.R1C2 = size / 2;
-        _matrix *= transform.WorldMatrix * Matrix3.Invert(spaceMatrix);
-        var relativeAngle = transform.WorldRotation - spaceAngle;
+        _matrix *= xfmSys.GetWorldMatrix(transform) * Matrix3.Invert(spaceMatrix);
+        var relativeAngle = xfmSys.GetWorldRotation(transform) - spaceAngle;
         _offset = relativeAngle.RotateVec(new Vector2(size / 4, size / 4));
     }
 
index b04642a8db000d991277a2b5fc93242664a68abc..6f5b94f63e40ad132f560e9012a73dc766d6bceb 100644 (file)
@@ -70,8 +70,8 @@ public sealed partial class ExplosionSystem : EntitySystem
         {
             var targetGrid = Comp<MapGridComponent>(referenceGrid.Value);
             var xform = Transform(referenceGrid.Value);
-            targetAngle = xform.WorldRotation;
-            targetMatrix = xform.InvWorldMatrix;
+            targetAngle = _transformSystem.GetWorldRotation(xform);
+            targetMatrix = _transformSystem.GetInvWorldMatrix(xform);
             tileSize = targetGrid.TileSize;
         }
 
@@ -104,7 +104,7 @@ public sealed partial class ExplosionSystem : EntitySystem
 
             var xforms = EntityManager.GetEntityQuery<TransformComponent>();
             var xform = xforms.GetComponent(gridToTransform);
-            var  (_, gridWorldRotation, gridWorldMatrix, invGridWorldMatrid) = xform.GetWorldPositionRotationMatrixWithInv(xforms);
+            var  (_, gridWorldRotation, gridWorldMatrix, invGridWorldMatrid) = _transformSystem.GetWorldPositionRotationMatrixWithInv(xform);
 
             var localEpicentre = (Vector2i) invGridWorldMatrid.Transform(epicentre.Position);
             var matrix = offsetMatrix * gridWorldMatrix * targetMatrix;
index 1b324d924bc0484dacb59da303543e205d38a48b..d5f756ca7496bbc67c5c55c707742737a9b583b1 100644 (file)
@@ -88,8 +88,8 @@ public sealed partial class ExplosionSystem : EntitySystem
         if (referenceGrid != null)
         {
             var xform = Transform(_mapManager.GetGrid(referenceGrid.Value).Owner);
-            spaceMatrix = xform.WorldMatrix;
-            spaceAngle = xform.WorldRotation;
+            spaceMatrix = _transformSystem.GetWorldMatrix(xform);
+            spaceAngle = _transformSystem.GetWorldRotation(xform);
         }
 
         // is the explosion starting on a grid?
index 7495ecbb3490e905be553eccc28a6629ea62aa90..8de622f1b514c0fb00088f85bd45f2ee8eb9569f 100644 (file)
@@ -382,7 +382,7 @@ public sealed partial class ExplosionSystem : EntitySystem
             if (player.AttachedEntity is not EntityUid uid)
                 continue;
 
-            var playerPos = Transform(player.AttachedEntity!.Value).WorldPosition;
+            var playerPos = _transformSystem.GetWorldPosition(player.AttachedEntity!.Value);
             var delta = epicenter.Position - playerPos;
 
             if (delta.EqualsApprox(Vector2.Zero))
index c0775947ba44d560abcaf3d9d8d7dc3d60881392..fc563d51461af176c8f3b9d720d744f2bbae4bf8 100644 (file)
@@ -15,6 +15,7 @@ public sealed class SmokeOnTriggerSystem : SharedSmokeOnTriggerSystem
 {
     [Dependency] private readonly IMapManager _mapMan = default!;
     [Dependency] private readonly SmokeSystem _smoke = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public override void Initialize()
     {
@@ -26,14 +27,15 @@ public sealed class SmokeOnTriggerSystem : SharedSmokeOnTriggerSystem
     private void OnTrigger(EntityUid uid, SmokeOnTriggerComponent comp, TriggerEvent args)
     {
         var xform = Transform(uid);
-        if (!_mapMan.TryFindGridAt(xform.MapPosition, out _, out var grid) ||
+        var mapCoords = _xformSystem.GetMapCoordinates((uid, xform));
+        if (!_mapMan.TryFindGridAt(mapCoords, out _, out var grid) ||
             !grid.TryGetTileRef(xform.Coordinates, out var tileRef) ||
             tileRef.Tile.IsSpace())
         {
             return;
         }
 
-        var coords = grid.MapToGrid(xform.MapPosition);
+        var coords = grid.MapToGrid(mapCoords);
         var ent = Spawn(comp.SmokePrototype, coords.SnapToGrid());
         if (!TryComp<SmokeComponent>(ent, out var smoke))
         {
index 9b9a042641f17f5ae516b2063d27bf2cf1473cdc..494caeab04f175913e26291bc3f353c913b6864f 100644 (file)
@@ -186,7 +186,7 @@ namespace Content.Server.Explosion.EntitySystems
 
             // Gets location of the implant
             var ownerXform = Transform(uid);
-            var pos = ownerXform.MapPosition;
+            var pos = _transformSystem.GetMapCoordinates((uid, ownerXform));
             var x = (int) pos.X;
             var y = (int) pos.Y;
             var posText = $"({x}, {y})";
index fe7eb81d1e132f3a984da8223aca2c1f66133129..64f7add4e8603723e53f3039caebd3ce8ded1ee1 100644 (file)
@@ -37,6 +37,7 @@ namespace Content.Server.Flash
         [Dependency] private readonly PopupSystem _popup = default!;
         [Dependency] private readonly StunSystem _stun = default!;
         [Dependency] private readonly TagSystem _tag = default!;
+        [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
         public override void Initialize()
         {
index 19cb650db7cb9fae213c88c66dbed8e488c8c843..846eac078b703848c479d27483c079e936a62513 100644 (file)
@@ -33,6 +33,7 @@ public sealed class DrainSystem : SharedDrainSystem
     [Dependency] private readonly PuddleSystem _puddleSystem = default!;
     [Dependency] private readonly IRobustRandom _random = default!;
     [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public override void Initialize()
     {
@@ -155,7 +156,7 @@ public sealed class DrainSystem : SharedDrainSystem
 
             puddles.Clear();
 
-            foreach (var entity in _lookup.GetEntitiesInRange(xform.MapPosition, drain.Range))
+            foreach (var entity in _lookup.GetEntitiesInRange(_xformSystem.GetMapCoordinates((uid, xform)), drain.Range))
             {
                 // No InRangeUnobstructed because there's no collision group that fits right now
                 // and these are placed by mappers and not buildable/movable so shouldnt really be a problem...
index ac967b3c201b9d510c3aad8f13fa004e1b5d4947..974b2d62208f03a8b72b5ad5efad79eae15fdaf4 100644 (file)
@@ -13,6 +13,7 @@ public sealed class PuddleDebugDebugOverlaySystem : SharedPuddleDebugOverlaySyst
     [Dependency] private readonly IGameTiming _timing = default!;
     [Dependency] private readonly IMapManager _mapManager = default!;
     [Dependency] private readonly PuddleSystem _puddle = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     private readonly HashSet<ICommonSession> _playerObservers = new();
     private List<Entity<MapGridComponent>> _grids = new();
@@ -55,7 +56,7 @@ public sealed class PuddleDebugDebugOverlaySystem : SharedPuddleDebugOverlaySyst
 
             var transform = EntityManager.GetComponent<TransformComponent>(entity);
 
-            var worldBounds = Box2.CenteredAround(transform.WorldPosition,
+            var worldBounds = Box2.CenteredAround(_xformSystem.GetWorldPosition(transform),
                 new Vector2(LocalViewRange, LocalViewRange));
 
             _grids.Clear();
index 882d5e37d8dfe64803afa377fed7ad844ec9bb60..75c2eb543a4e1b8c30c779dcee112e8112e574f8 100644 (file)
@@ -392,7 +392,7 @@ namespace Content.Server.GameTicking
                     var gridXform = Transform(gridUid);
 
                     return new EntityCoordinates(gridUid,
-                        gridXform.InvWorldMatrix.Transform(toMap.Position));
+                        _transform.GetInvWorldMatrix(gridXform).Transform(toMap.Position));
                 }
 
                 return spawn;
index 82ac755592e6c8dc623914f38f77ecb790da99f3..9c863effee33aaa4f0047a6139470f216c6e2a50 100644 (file)
@@ -24,6 +24,7 @@ public sealed class DeathMatchRuleSystem : GameRuleSystem<DeathMatchRuleComponen
     [Dependency] private readonly RespawnRuleSystem _respawn = default!;
     [Dependency] private readonly RoundEndSystem _roundEnd = default!;
     [Dependency] private readonly StationSpawningSystem _stationSpawning = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public override void Initialize()
     {
@@ -97,7 +98,7 @@ public sealed class DeathMatchRuleSystem : GameRuleSystem<DeathMatchRuleComponen
                 _point.AdjustPointValue(assist.PlayerId, 1, uid, point);
 
             var spawns = EntitySpawnCollection.GetSpawns(dm.RewardSpawns).Cast<string?>().ToList();
-            EntityManager.SpawnEntities(Transform(ev.Entity).MapPosition, spawns);
+            EntityManager.SpawnEntities(_xformSystem.GetMapCoordinates(ev.Entity), spawns);
         }
     }
 
index eb22ba9ead6db9ac30223b8eba3bd7e4b95efaa9..5603591825aa93ac8264d410af222bc67407aae8 100644 (file)
@@ -50,6 +50,8 @@ public sealed class PiratesRuleSystem : GameRuleSystem<PiratesRuleComponent>
     [Dependency] private readonly SharedMindSystem _mindSystem = default!;
     [Dependency] private readonly SharedAudioSystem _audioSystem = default!;
     [Dependency] private readonly MetaDataSystem _metaData = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
+
 
     [ValidatePrototypeId<EntityPrototype>]
     private const string GameRuleId = "Pirates";
@@ -180,7 +182,7 @@ public sealed class PiratesRuleSystem : GameRuleSystem<PiratesRuleComponent>
 
             var aabbs = EntityQuery<StationDataComponent>().SelectMany(x =>
                     x.Grids.Select(x =>
-                        xformQuery.GetComponent(x).WorldMatrix.TransformBox(_mapManager.GetGridComp(x).LocalAABB)))
+                        _xformSystem.GetWorldMatrix(x).TransformBox(_mapManager.GetGridComp(x).LocalAABB)))
                 .ToArray();
 
             var aabb = aabbs[0];
index 00b2546e785b16ef81c50d9c27383bb70d8540c2..cf8621f4a7c96cb7373f8701be9a9df749820546 100644 (file)
@@ -19,6 +19,8 @@ public abstract class BaseEntityReplaceVariationPassSystem<TEntComp, TGameRuleCo
     where TEntComp: IComponent
     where TGameRuleComp: IComponent
 {
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
+
     /// <summary>
     ///     Used so we don't modify while enumerating
     ///     if the replaced entity also has <see cref="TEntComp"/>.
@@ -55,7 +57,7 @@ public abstract class BaseEntityReplaceVariationPassSystem<TEntComp, TGameRuleCo
         {
             var (spawn, coords, rot) = tup;
             var newEnt = Spawn(spawn, coords);
-            Transform(newEnt).LocalRotation = rot;
+            _xformSystem.SetLocalRotation(newEnt, rot);
         }
 
         Log.Debug($"Entity replacement took {stopwatch.Elapsed} with {Stations.GetTileCount(args.Station)} tiles");
index 7fbbf7f4f649a6d1d727d32b42c722707f12f3c3..0ee7f207dd75f953b3f424d77e4a27001e206cb4 100644 (file)
@@ -18,6 +18,7 @@ public sealed partial class GatherableSystem : EntitySystem
     [Dependency] private readonly DestructibleSystem _destructible = default!;
     [Dependency] private readonly SharedAudioSystem _audio = default!;
     [Dependency] private readonly TagSystem _tagSystem = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public override void Initialize()
     {
@@ -61,7 +62,7 @@ public sealed partial class GatherableSystem : EntitySystem
         if (component.MappedLoot == null)
             return;
 
-        var pos = Transform(gatheredUid).MapPosition;
+        var pos = _xformSystem.GetMapCoordinates(gatheredUid);
 
         foreach (var (tag, table) in component.MappedLoot)
         {
index 627c336a36bb6a75d5ba2fd647552954d56c7aa2..b2ab78f987cd03003c1d16f92f41e1b4dcabb791 100644 (file)
@@ -34,6 +34,7 @@ namespace Content.Server.Guardian
         [Dependency] private readonly SharedAudioSystem _audio = default!;
         [Dependency] private readonly BodySystem _bodySystem = default!;
         [Dependency] private readonly SharedContainerSystem _container = default!;
+        [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
         public override void Initialize()
         {
@@ -211,7 +212,7 @@ namespace Content.Server.Guardian
             var hostXform = Transform(args.Args.Target.Value);
             var host = EnsureComp<GuardianHostComponent>(args.Args.Target.Value);
             // Use map position so it's not inadvertantly parented to the host + if it's in a container it spawns outside I guess.
-            var guardian = Spawn(component.GuardianProto, hostXform.MapPosition);
+            var guardian = Spawn(component.GuardianProto, _xformSystem.GetMapCoordinates(hostXform));
 
             _container.Insert(guardian, host.GuardianContainer);
             host.HostedGuardian = guardian;
index 62278064b685a2478cf09eedd5bd11a71e6961fd..2610f4fd5c6ac4812ea53ba7e1f190115783fa53 100644 (file)
@@ -38,6 +38,7 @@ namespace Content.Server.Hands.Systems
         [Dependency] private readonly SharedHandsSystem _handsSystem = default!;
         [Dependency] private readonly PullingSystem _pullingSystem = default!;
         [Dependency] private readonly ThrowingSystem _throwingSystem = default!;
+        [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
         public override void Initialize()
         {
@@ -198,7 +199,7 @@ namespace Content.Server.Hands.Systems
                 throwEnt = splitStack.Value;
             }
 
-            var direction = coordinates.ToMapPos(EntityManager) - Transform(player).WorldPosition;
+            var direction = coordinates.ToMapPos(EntityManager) - _xformSystem.GetWorldPosition(player);
             if (direction == Vector2.Zero)
                 return true;
 
index 0fa8f7d292f2cd6b52f562d7a28e8ce3b6953d64..c0da749ab1f77c30f046f6ee6e0f592d19747355 100644 (file)
@@ -22,6 +22,7 @@ public sealed class ImmovableRodSystem : EntitySystem
     [Dependency] private readonly PopupSystem _popup = default!;
     [Dependency] private readonly SharedPhysicsSystem _physics = default!;
     [Dependency] private readonly SharedAudioSystem _audio = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public override void Update(float frameTime)
     {
@@ -64,11 +65,11 @@ public sealed class ImmovableRodSystem : EntitySystem
             var vel = component.DirectionOverride.Degrees switch
             {
                 0f => _random.NextVector2(component.MinSpeed, component.MaxSpeed),
-                _ => xform.WorldRotation.RotateVec(component.DirectionOverride.ToVec()) * _random.NextFloat(component.MinSpeed, component.MaxSpeed)
+                _ => _xformSystem.GetWorldRotation(xform).RotateVec(component.DirectionOverride.ToVec()) * _random.NextFloat(component.MinSpeed, component.MaxSpeed)
             };
 
             _physics.ApplyLinearImpulse(uid, vel, body: phys);
-            xform.LocalRotation = (vel - xform.WorldPosition).ToWorldAngle() + MathHelper.PiOver2;
+            _xformSystem.SetLocalRotation(uid, (vel - _xformSystem.GetWorldPosition(xform)).ToWorldAngle() + MathHelper.PiOver2, xform);
         }
     }
 
index f270fe76d2cc168259d40250a69f50f4c1167c86..2e336a717fbd5545312680db3ea6590ef34f4837 100644 (file)
@@ -26,6 +26,7 @@ public sealed class SharpSystem : EntitySystem
     [Dependency] private readonly ContainerSystem _containerSystem = default!;
     [Dependency] private readonly MobStateSystem _mobStateSystem = default!;
     [Dependency] private readonly IRobustRandom _robustRandom = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public override void Initialize()
     {
@@ -97,7 +98,7 @@ public sealed class SharpSystem : EntitySystem
         }
 
         var spawnEntities = EntitySpawnCollection.GetSpawns(butcher.SpawnedEntities, _robustRandom);
-        var coords = Transform(args.Args.Target.Value).MapPosition;
+        var coords = _xformSystem.GetMapCoordinates(args.Args.Target.Value);
         EntityUid popupEnt = default!;
         foreach (var proto in spawnEntities)
         {
index 4f975a60fdab392b24ee1f5232a070cfc95f7428..e67d42227e29752100ebab614771a55e87e3aa61 100644 (file)
@@ -20,6 +20,7 @@ public sealed class LightningSystem : SharedLightningSystem
     [Dependency] private readonly BeamSystem _beam = default!;
     [Dependency] private readonly IRobustRandom _random = default!;
     [Dependency] private readonly EntityLookupSystem _lookup = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public override void Initialize()
     {
@@ -74,7 +75,7 @@ public sealed class LightningSystem : SharedLightningSystem
         //To Do: This is still pretty bad for perf but better than before and at least it doesn't re-allocate
         // several hashsets every time
 
-        var targets = _lookup.GetComponentsInRange<LightningTargetComponent>(Transform(user).MapPosition, range).ToList();
+        var targets = _lookup.GetComponentsInRange<LightningTargetComponent>(_xformSystem.GetMapCoordinates(user), range).ToList();
         _random.Shuffle(targets);
         targets.Sort((x, y) => y.Priority.CompareTo(x.Priority));
 
index ccaa74e9e262c8d91d554837e717c609e4639559..b100c4c2238738d2c5d7c8943360ef23d11d9a8f 100644 (file)
@@ -12,6 +12,7 @@ public sealed class LightningTargetSystem : EntitySystem
 {
     [Dependency] private readonly DamageableSystem _damageable = default!;
     [Dependency] private readonly ExplosionSystem _explosionSystem = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public override void Initialize()
     {
@@ -29,7 +30,7 @@ public sealed class LightningTargetSystem : EntitySystem
         if (uid.Comp.LightningExplode)
         {
             _explosionSystem.QueueExplosion(
-                Transform(uid).MapPosition,
+                _xformSystem.GetMapCoordinates(uid),
                 uid.Comp.ExplosionPrototype,
                 uid.Comp.TotalIntensity, uid.Comp.Dropoff,
                 uid.Comp.MaxTileIntensity,
index 2c9b11dbd3dc76e253192c084e35776eabfc6895..f97d17d6f43329b29e2570a5485203daa40d8309 100644 (file)
@@ -278,7 +278,7 @@ public sealed class MagicSystem : EntitySystem
         if (transform.MapID != args.Target.GetMapId(EntityManager)) return;
 
         _transformSystem.SetCoordinates(args.Performer, args.Target);
-        transform.AttachToGridOrMap();
+        _transformSystem.AttachToGridOrMap(args.Performer, transform);
         _audio.PlayPvs(args.BlinkSound, args.Performer, AudioParams.Default.WithVolume(args.BlinkVolume));
         Speak(args);
         args.Handled = true;
@@ -321,7 +321,7 @@ public sealed class MagicSystem : EntitySystem
         ev.Handled = true;
         Speak(ev);
 
-        var direction = Transform(ev.Target).MapPosition.Position - Transform(ev.Performer).MapPosition.Position;
+        var direction = _transformSystem.GetWorldPosition(ev.Target) - _transformSystem.GetWorldPosition(ev.Performer);
         var impulseVector = direction * 10000;
 
         _physics.ApplyLinearImpulse(ev.Target, impulseVector);
index 76b2e29dea0fd270dbaec2fd0f8150f4f5e2afef..2ad126c10da6286637c06863b632b5122ee566ee 100644 (file)
@@ -12,6 +12,7 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem
 {
     [Dependency] private readonly IConGroupController _admin = default!;
     [Dependency] private readonly SharedPhysicsSystem _physics = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     private readonly HashSet<ICommonSession> _draggers = new();
 
@@ -78,6 +79,6 @@ public sealed class GridDraggingSystem : SharedGridDraggingSystem
 
         var gridXform = Transform(grid);
 
-        gridXform.WorldPosition = msg.WorldPosition;
+        _xformSystem.SetWorldPosition(gridXform, msg.WorldPosition);
     }
 }
index fa46792d2af91c86b94f4ca3864d617a6e9ac492..b1a2de61d5c58b4e5e92eb1ec7a3ddfdaa0375c8 100644 (file)
@@ -85,7 +85,7 @@ public sealed class MechGrabberSystem : EntitySystem
         var (mechPos, mechRot) = _transform.GetWorldPositionRotation(mechxform);
 
         var offset = mechPos + mechRot.RotateVec(component.DepositOffset);
-        _transform.SetWorldPositionRotation(xform, offset, Angle.Zero);
+        _transform.SetWorldPositionRotation(toRemove, offset, Angle.Zero, xform);
         _mech.UpdateUserInterface(mech);
     }
 
index 95d5c9c46510330603a1c97c4b8f8860115df7b1..fb650ec2cdc350cf927747ec3fc5fa6a749cd324 100644 (file)
@@ -36,7 +36,7 @@ public sealed partial class PathfindingSystem
                 return Vector2.Zero;
             }
 
-            endPos = startXform.InvWorldMatrix.Transform(endXform.WorldMatrix.Transform(endPos));
+            endPos = _transform.GetInvWorldMatrix(startXform).Transform(_transform.GetWorldMatrix(endXform).Transform(endPos));
         }
 
         // TODO: Numerics when we changeover.
index 95f931cdd6a693f4069bd0e5b2f0c798c7763782..201189220a74111c058960b8a90bd34d22f864a8 100644 (file)
@@ -405,7 +405,7 @@ namespace Content.Server.NPC.Pathfinding
                 return null;
             }
 
-            var localPos = xform.InvWorldMatrix.Transform(coordinates.ToMapPos(EntityManager));
+            var localPos = _transform.GetInvWorldMatrix(xform).Transform(coordinates.ToMapPos(EntityManager));
             var origin = GetOrigin(localPos);
 
             if (!TryGetChunk(origin, comp, out var chunk))
index aca2411d8a08213a4773e1c3df0c03e755408382..1d8822d0e62d77aa7f0d70ef723c0faa6e20b7dc 100644 (file)
@@ -462,7 +462,7 @@ public sealed partial class NPCSteeringSystem : SharedNPCSteeringSystem
         }
 
         var targetPos = steering.Coordinates.ToMap(EntityManager, _transform);
-        var ourPos = xform.MapPosition;
+        var ourPos = _transform.GetMapCoordinates((uid, xform));
 
         PrunePath(uid, ourPos, targetPos.Position - ourPos.Position, result.Path);
         steering.CurrentPath = new Queue<PathPoly>(result.Path);
index fc483f68c3be72ecda6b2191939a9b0f09cab826..69735f1d8c855dad945461d561c631c99430beed 100644 (file)
@@ -369,7 +369,7 @@ public sealed class NPCUtilitySystem : EntitySystem
                 if (compQuery.Components.Count == 0)
                     return;
 
-                var mapPos = _xformQuery.GetComponent(owner).MapPosition;
+                var mapPos = _transform.GetMapCoordinates(owner);
                 _compTypes.Clear();
                 var i = -1;
                 EntityPrototype.ComponentRegistryEntry compZero = default!;
index 0657ab4af917a7d9fb3425057207967bf601609a..81b34c2a9dde12c6ed43ef5b3ab65251d7abb18d 100644 (file)
@@ -12,6 +12,7 @@ namespace Content.Server.NPC.Systems;
 public sealed partial class NpcFactionSystem : EntitySystem
 {
     [Dependency] private readonly EntityLookupSystem _lookup = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
     [Dependency] private readonly IPrototypeManager _protoManager = default!;
 
     private ISawmill _sawmill = default!;
@@ -153,7 +154,7 @@ public sealed partial class NpcFactionSystem : EntitySystem
         if (!xformQuery.TryGetComponent(entity, out var entityXform))
             yield break;
 
-        foreach (var ent in _lookup.GetEntitiesInRange<NpcFactionMemberComponent>(entityXform.MapPosition, range))
+        foreach (var ent in _lookup.GetEntitiesInRange<NpcFactionMemberComponent>(_xformSystem.GetMapCoordinates((entity, entityXform)), range))
         {
             if (ent.Owner == entity)
                 continue;
index 652852ece288d3514d22de5067903f9201cf72a2..fa80749211a3e8156acb96feb4832a4d096646b7 100644 (file)
@@ -452,7 +452,7 @@ public sealed class NukeSystem : EntitySystem
         if (stationUid != null)
             _alertLevel.SetLevel(stationUid.Value, component.AlertLevelOnActivate, true, true, true, true);
 
-        var pos = nukeXform.MapPosition;
+        var pos = _transform.GetMapCoordinates(nukeXform);
         var x = (int) pos.X;
         var y = (int) pos.Y;
         var posText = $"({x}, {y})";
index 2b627151339b9d59f87ab7378847db1e1688b9f0..ec31d1710aea846aa5c0e78a6dfc034c1f8edc83 100644 (file)
@@ -54,6 +54,7 @@ public sealed class FoodSystem : EntitySystem
     [Dependency] private readonly StackSystem _stack = default!;
     [Dependency] private readonly StomachSystem _stomach = default!;
     [Dependency] private readonly UtensilSystem _utensil = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public const float MaxFeedDistance = 1.0f;
 
@@ -149,7 +150,7 @@ public sealed class FoodSystem : EntitySystem
             return (false, true);
 
         // TODO make do-afters account for fixtures in the range check.
-        if (!Transform(user).MapPosition.InRange(Transform(target).MapPosition, MaxFeedDistance))
+        if (!_xformSystem.GetMapCoordinates(user).InRange(_xformSystem.GetMapCoordinates(target), MaxFeedDistance))
         {
             var message = Loc.GetString("interaction-system-user-interaction-cannot-reach");
             _popup.PopupEntity(message, user, user);
@@ -325,7 +326,7 @@ public sealed class FoodSystem : EntitySystem
         }
 
         //We're empty. Become trash.
-        var position = Transform(food).MapPosition;
+        var position = _xformSystem.GetMapCoordinates(food);
         var finisher = Spawn(component.Trash, position);
 
         // If the user is holding the item
index 885503713f8308622dbb29c9b67c5dcae3d6381c..6e703f9c944f90bd0221abaaefb7d8d81d87d40d 100644 (file)
@@ -25,6 +25,7 @@ namespace Content.Server.PDA.Ringer
         [Dependency] private readonly UserInterfaceSystem _ui = default!;
         [Dependency] private readonly AudioSystem _audio = default!;
         [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
+        [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
         private readonly Dictionary<NetUserId, TimeSpan> _lastSetRingtoneAt = new();
 
@@ -206,7 +207,7 @@ namespace Content.Server.PDA.Ringer
 
                 _audio.PlayEntity(
                     GetSound(ringer.Ringtone[ringer.NoteCount]),
-                    Filter.Empty().AddInRange(ringerXform.MapPosition, ringer.Range),
+                    Filter.Empty().AddInRange(_xformSystem.GetMapCoordinates(ringerXform), ringer.Range),
                     uid,
                     true,
                     AudioParams.Default.WithMaxDistance(ringer.Range).WithVolume(ringer.Volume)
index c4c2300870d71678d635fe720b3f3ed12bcf0879..ff08e90f8cdb0516e2cc67399b6935c3305e8ab5 100644 (file)
@@ -797,7 +797,7 @@ public sealed partial class BiomeSystem : SharedBiomeSystem
                 // At least for now unless we do lookups or smth, only work with anchoring.
                 if (_xformQuery.TryGetComponent(ent, out var xform) && !xform.Anchored)
                 {
-                    _transform.AnchorEntity(ent, xform, gridUid, grid, indices);
+                    _transform.AnchorEntity((ent, xform), (gridUid, grid), indices);
                 }
 
                 loadedEntities.Add(ent, indices);
index 85cf303d5d73cf59718a88f309b79cc4fb2dcdc1..c282032bb23b121d97731905ea20f66116a2fb34 100644 (file)
@@ -20,6 +20,7 @@ public sealed class PayloadSystem : EntitySystem
     [Dependency] private readonly IAdminLogManager _adminLogger = default!;
     [Dependency] private readonly IComponentFactory _componentFactory = default!;
     [Dependency] private readonly ISerializationManager _serializationManager = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public override void Initialize()
     {
@@ -158,7 +159,7 @@ public sealed class PayloadSystem : EntitySystem
         var solStringB = SolutionContainerSystem.ToPrettyString(solutionB);
 
         _adminLogger.Add(LogType.ChemicalReaction,
-            $"Chemical bomb payload {ToPrettyString(entity.Owner):payload} at {Transform(entity.Owner).MapPosition:location} is combining two solutions: {solStringA:solutionA} and {solStringB:solutionB}");
+            $"Chemical bomb payload {ToPrettyString(entity.Owner):payload} at {_xformSystem.GetMapCoordinates(entity.Owner):location} is combining two solutions: {solStringA:solutionA} and {solStringB:solutionB}");
 
         solutionA.MaxVolume += solutionB.MaxVolume;
         _solutionContainerSystem.TryAddSolution(solnA.Value, solutionB);
index 8f58f807aaee536a8f02fb49e7ee2ffa384ceb37..c575f2a8fa5bf408fcf5b0d79f5f8c5f41e9188d 100644 (file)
@@ -116,7 +116,7 @@ namespace Content.Server.Physics.Controllers
                     var baseRotation = pulledData.WorldRotation - pulledXform.LocalRotation;
                     var localRotation = newAngle - baseRotation;
                     var localRotationSnapped = Angle.FromDegrees(Math.Floor((localRotation.Degrees / ThresholdRotAngle) + 0.5f) * ThresholdRotAngle);
-                    TransformSystem.SetLocalRotation(pulledXform, localRotationSnapped);
+                    TransformSystem.SetLocalRotation(pulled, localRotationSnapped, pulledXform);
                 }
             }
         }
@@ -146,7 +146,7 @@ namespace Content.Server.Physics.Controllers
 
                 // Now that's over with...
 
-                var pullerPosition = pullerXform.MapPosition;
+                var pullerPosition = TransformSystem.GetMapCoordinates((puller, pullerXform));
                 var movingTo = pullable.MovingTo.Value.ToMap(EntityManager, _transform);
                 if (movingTo.MapId != pullerPosition.MapId)
                 {
@@ -163,7 +163,7 @@ namespace Content.Server.Physics.Controllers
                 }
 
                 var movingPosition = movingTo.Position;
-                var ownerPosition = pullableXform.MapPosition.Position;
+                var ownerPosition = TransformSystem.GetWorldPosition(pullableXform);
 
                 var diff = movingPosition - ownerPosition;
                 var diffLength = diff.Length();
index a7c455e6a5d3c89e317ad64c0f5fc38343dda8c9..bc3132e54f337c3b648bec3ee9e7dcb6c75a9432 100644 (file)
@@ -37,6 +37,7 @@ namespace Content.Server.Pointing.EntitySystems
         [Dependency] private readonly VisibilitySystem _visibilitySystem = default!;
         [Dependency] private readonly SharedMindSystem _minds = default!;
         [Dependency] private readonly IAdminLogManager _adminLogger = default!;
+        [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
         private static readonly TimeSpan PointDelay = TimeSpan.FromSeconds(0.5f);
 
@@ -181,7 +182,7 @@ namespace Content.Server.Pointing.EntitySystems
                     (eyeComp.VisibilityMask & layer) == 0)
                     return false;
 
-                return Transform(ent).MapPosition.InRange(Transform(player).MapPosition, PointingRange);
+                return _xformSystem.GetMapCoordinates(ent).InRange(_xformSystem.GetMapCoordinates(player), PointingRange);
             }
 
             var viewers = Filter.Empty()
index be3ceb3b08625a6c4cc5d7361166406a9e968da1..dac6c5ff8fc5bf908b788c0f7450be295e479f4d 100644 (file)
@@ -12,6 +12,7 @@ namespace Content.Server.Pointing.EntitySystems
         [Dependency] private readonly IRobustRandom _random = default!;
         [Dependency] private readonly ExplosionSystem _explosion = default!;
         [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
+        [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
         private EntityUid? RandomNearbyPlayer(EntityUid uid, RoguePointingArrowComponent? component = null, TransformComponent? transform = null)
         {
@@ -69,24 +70,25 @@ namespace Content.Server.Pointing.EntitySystems
 
                 if (component.TurningDelay > 0)
                 {
-                    var difference = Comp<TransformComponent>(chasing).WorldPosition - transform.WorldPosition;
+                    var difference = _xformSystem.GetWorldPosition(chasing) - _xformSystem.GetWorldPosition(transform);
                     var angle = difference.ToAngle();
                     var adjusted = angle.Degrees + 90;
                     var newAngle = Angle.FromDegrees(adjusted);
 
-                    transform.WorldRotation = newAngle;
+                    _xformSystem.SetWorldRotation(transform, newAngle);
 
                     UpdateAppearance(uid, component, transform);
                     continue;
                 }
 
-                transform.WorldRotation += Angle.FromDegrees(20);
+                _xformSystem.SetWorldRotation(transform, _xformSystem.GetWorldRotation(transform) + Angle.FromDegrees(20));
 
                 UpdateAppearance(uid, component, transform);
 
-                var toChased = Comp<TransformComponent>(chasing).WorldPosition - transform.WorldPosition;
+                var worldPosition = _xformSystem.GetWorldPosition(transform);
+                var toChased = _xformSystem.GetWorldPosition(chasing) - worldPosition;
 
-                transform.WorldPosition += toChased * frameTime * component.ChasingSpeed;
+                _xformSystem.SetWorldPosition(transform, worldPosition + toChased * frameTime * component.ChasingSpeed);
 
                 component.ChasingTime -= frameTime;
 
index 03bcc2b4b13de9852f45c2ff33d5975fc24d841e..648a7b7b15f6378cafdefd5efe8a8d8229e0cad4 100644 (file)
@@ -177,7 +177,7 @@ public sealed partial class DungeonSystem
 
             // If the templated entity was anchored then anchor us too.
             if (anchored && !childXform.Anchored)
-                _transform.AnchorEntity(ent, childXform, grid);
+                _transform.AnchorEntity((ent, childXform), (gridUid, grid));
             else if (!anchored && childXform.Anchored)
                 _transform.Unanchor(ent, childXform);
         }
index 51c092be18b36d5b804fa7c6807da7d0aa21a512..92b6a95fdf74376ad6face085ab3870ddb8b703e 100644 (file)
@@ -22,6 +22,7 @@ public sealed class SpecialRespawnSystem : SharedSpecialRespawnSystem
     [Dependency] private readonly IRobustRandom _random = default!;
     [Dependency] private readonly TurfSystem _turf = default!;
     [Dependency] private readonly IChatManager _chat = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public override void Initialize()
     {
@@ -94,7 +95,7 @@ public sealed class SpecialRespawnSystem : SharedSpecialRespawnSystem
         {
             var xform = Transform(entityGridUid.Value);
             var pos = xform.Coordinates;
-            var mapPos = xform.MapPosition;
+            var mapPos = _xformSystem.GetMapCoordinates((entityGridUid.Value, xform));
             var circle = new Circle(mapPos.Position, 2);
 
             var found = false;
@@ -156,7 +157,7 @@ public sealed class SpecialRespawnSystem : SharedSpecialRespawnSystem
         var tile = tileRef.GridIndices;
 
         var found = false;
-        var (gridPos, _, gridMatrix) = xform.GetWorldPositionRotationMatrix();
+        var (gridPos, _, gridMatrix) = _xformSystem.GetWorldPositionRotationMatrix(xform);
         var gridBounds = gridMatrix.TransformBox(grid.LocalAABB);
 
         //Obviously don't put anything ridiculous in here
index eb6eb5a426f2a881ab9b3dd7fdd61cc6aad77c3a..c904393100739e2d2f7d07882fc0fb577baeddf4 100644 (file)
@@ -41,6 +41,7 @@ public sealed partial class RevenantSystem
     [Dependency] private readonly MobThresholdSystem _mobThresholdSystem = default!;
     [Dependency] private readonly GhostSystem _ghost = default!;
     [Dependency] private readonly TileSystem _tile = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     private void InitializeAbilities()
     {
@@ -215,7 +216,7 @@ public sealed partial class RevenantSystem
         var xform = Transform(uid);
         if (!_mapManager.TryGetGrid(xform.GridUid, out var map))
             return;
-        var tiles = map.GetTilesIntersecting(Box2.CenteredAround(xform.WorldPosition,
+        var tiles = map.GetTilesIntersecting(Box2.CenteredAround(_xformSystem.GetWorldPosition(xform),
             new Vector2(component.DefileRadius * 2, component.DefileRadius))).ToArray();
 
         _random.Shuffle(tiles);
index a9df60c45b716e72ed26569889087c24f412cc16..5d2b1a48ae7812d3aa249f54a3330b7e0c32375d 100644 (file)
@@ -14,6 +14,7 @@ namespace Content.Server.Rotatable
     public sealed class RotatableSystem : EntitySystem
     {
         [Dependency] private readonly PopupSystem _popup = default!;
+        [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
         public override void Initialize()
         {
@@ -54,7 +55,7 @@ namespace Content.Server.Rotatable
             Verb resetRotation = new ()
             {
                 DoContactInteraction = true,
-                Act = () => EntityManager.GetComponent<TransformComponent>(uid).LocalRotation = Angle.Zero,
+                Act = () => _xformSystem.SetLocalRotation(uid, Angle.Zero),
                 Category = VerbCategory.Rotate,
                 Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/refresh.svg.192dpi.png")),
                 Text = "Reset",
@@ -66,7 +67,11 @@ namespace Content.Server.Rotatable
             // rotate clockwise
             Verb rotateCW = new()
             {
-                Act = () => EntityManager.GetComponent<TransformComponent>(uid).LocalRotation -= component.Increment,
+                Act = () =>
+                {
+                    var xform = Transform(uid);
+                    _xformSystem.SetLocalRotation(uid, xform.LocalRotation - component.Increment, xform);
+                },
                 Category = VerbCategory.Rotate,
                 Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/rotate_cw.svg.192dpi.png")),
                 Priority = -1,
@@ -77,7 +82,11 @@ namespace Content.Server.Rotatable
             // rotate counter-clockwise
             Verb rotateCCW = new()
             {
-                Act = () => EntityManager.GetComponent<TransformComponent>(uid).LocalRotation += component.Increment,
+                Act = () =>
+                {
+                    var xform = Transform(uid);
+                    _xformSystem.SetLocalRotation(uid, xform.LocalRotation + component.Increment, xform);
+                },
                 Category = VerbCategory.Rotate,
                 Icon = new SpriteSpecifier.Texture(new ("/Textures/Interface/VerbIcons/rotate_ccw.svg.192dpi.png")),
                 Priority = 0,
@@ -101,8 +110,8 @@ namespace Content.Server.Rotatable
             var oldTransform = EntityManager.GetComponent<TransformComponent>(uid);
             var entity = EntityManager.SpawnEntity(component.MirrorEntity, oldTransform.Coordinates);
             var newTransform = EntityManager.GetComponent<TransformComponent>(entity);
-            newTransform.LocalRotation = oldTransform.LocalRotation;
-            newTransform.Anchored = false;
+            _xformSystem.SetLocalRotation(entity, oldTransform.LocalRotation, newTransform);
+            _xformSystem.Unanchor(entity, newTransform);
             EntityManager.DeleteEntity(uid);
         }
     }
index d976b634d5bda94ab710fd9263dda5b304eebbf1..3373122d76b368da63bdbd6cfe91714f47a727c2 100644 (file)
@@ -275,9 +275,9 @@ public sealed partial class ShuttleSystem
                     var fromRotation = _transform.GetWorldRotation(xform);
 
                     var width = Comp<MapGridComponent>(uid).LocalAABB.Width;
-                    xform.Coordinates = new EntityCoordinates(_mapManager.GetMapEntityId(_hyperSpaceMap!.Value),
-                        new Vector2(_index + width / 2f, 0f));
-                    xform.LocalRotation = Angle.Zero;
+                    _transform.SetCoordinates((uid, xform, MetaData(uid)), new EntityCoordinates(_mapManager.GetMapEntityId(_hyperSpaceMap!.Value),
+                        new Vector2(_index + width / 2f, 0f)));
+                    _transform.SetLocalRotation(uid, Angle.Zero, xform);
                     _index += width + Buffer;
                     comp.Accumulator += comp.TravelTime - DefaultArrivalTime;
 
@@ -372,7 +372,7 @@ public sealed partial class ShuttleSystem
                     }
                     else
                     {
-                        xform.Coordinates = comp.TargetCoordinates;
+                        _transform.SetCoordinates((uid, xform, MetaData(uid)), comp.TargetCoordinates);
                         mapId = comp.TargetCoordinates.GetMapId(EntityManager);
                     }
 
@@ -574,7 +574,7 @@ public sealed partial class ShuttleSystem
 
         if (config != null)
         {
-            FTLDock(config, shuttleXform);
+            FTLDock((shuttleUid, shuttleXform), config);
             return true;
         }
 
@@ -585,11 +585,11 @@ public sealed partial class ShuttleSystem
     /// <summary>
     /// Forces an FTL dock.
     /// </summary>
-    public void FTLDock(DockingConfig config, TransformComponent shuttleXform)
+    public void FTLDock(Entity<TransformComponent> shuttle, DockingConfig config)
     {
         // Set position
-        shuttleXform.Coordinates = config.Coordinates;
-        _transform.SetWorldRotation(shuttleXform, config.Angle);
+        _transform.SetCoordinates((shuttle.Owner, shuttle.Comp, MetaData(shuttle)), config.Coordinates);
+        _transform.SetWorldRotation(shuttle.Comp, config.Angle);
 
         // Connect everything
         foreach (var (dockAUid, dockBUid, dockA, dockB) in config.Docks)
@@ -702,15 +702,15 @@ public sealed partial class ShuttleSystem
             spawnPos = _transform.GetWorldPosition(targetXform, xformQuery);
         }
 
-        xform.Coordinates = new EntityCoordinates(targetXform.MapUid.Value, spawnPos);
+        _transform.SetCoordinates((shuttleUid, xform, MetaData(shuttleUid)), new EntityCoordinates(targetXform.MapUid.Value, spawnPos));
 
         if (!HasComp<MapComponent>(targetXform.GridUid))
         {
-            _transform.SetLocalRotation(xform, _random.NextAngle());
+            _transform.SetLocalRotation(shuttleUid, _random.NextAngle(), xform);
         }
         else
         {
-            _transform.SetLocalRotation(xform, Angle.Zero);
+            _transform.SetLocalRotation(shuttleUid, Angle.Zero, xform);
         }
 
         return true;
index 71e02200766515fb1a837c1f3ed581ccd243e8d9..a4871a2dd11b93b22f6f9ebfec21681fac0cb2a3 100644 (file)
@@ -206,7 +206,7 @@ public sealed partial class ShuttleSystem
 
                 if (config != null)
                 {
-                    FTLDock(config, shuttleXform);
+                    FTLDock((ent[0], shuttleXform), config);
 
                     if (TryComp<StationMemberComponent>(xform.GridUid, out var stationMember))
                     {
index f346398cdaaab3c3efacef785a71908194fcb526..2f9c0f8a57de86b309970253ba7a52a08f6e2ab0 100644 (file)
@@ -38,8 +38,8 @@ public sealed partial class ShuttleSystem
 
         var otherXform = Transform(args.OtherEntity);
 
-        var ourPoint = ourXform.InvWorldMatrix.Transform(args.WorldPoint);
-        var otherPoint = otherXform.InvWorldMatrix.Transform(args.WorldPoint);
+        var ourPoint = _transform.GetInvWorldMatrix(ourXform).Transform(args.WorldPoint);
+        var otherPoint = _transform.GetInvWorldMatrix(otherXform).Transform(args.WorldPoint);
 
         var ourVelocity = _physics.GetLinearVelocity(uid, ourPoint, ourBody, ourXform);
         var otherVelocity = _physics.GetLinearVelocity(args.OtherEntity, otherPoint, otherBody, otherXform);
index d58458527f6f48ed868104f554c77f1d4109c1c9..f30e4d3f1640c897bfbfc22c2ca72cbf3aa50dde 100644 (file)
@@ -23,6 +23,7 @@ public sealed class ContainmentFieldGeneratorSystem : EntitySystem
     [Dependency] private readonly PopupSystem _popupSystem = default!;
     [Dependency] private readonly SharedPointLightSystem _light = default!;
     [Dependency] private readonly TagSystem _tags = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public override void Initialize()
     {
@@ -233,7 +234,7 @@ public sealed class ContainmentFieldGeneratorSystem : EntitySystem
         if (!gen1XForm.Anchored)
             return false;
 
-        var genWorldPosRot = gen1XForm.GetWorldPositionRotation();
+        var genWorldPosRot = _xformSystem.GetWorldPositionRotation(gen1XForm);
         var dirRad = dir.ToAngle() + genWorldPosRot.WorldRotation; //needs to be like this for the raycast to work properly
 
         var ray = new CollisionRay(genWorldPosRot.WorldPosition, dirRad.ToVec(), component.CollisionMask);
@@ -310,14 +311,14 @@ public sealed class ContainmentFieldGeneratorSystem : EntitySystem
             var newField = Spawn(firstGen.Comp.CreatedField, currentCoords);
 
             var fieldXForm = Transform(newField);
-            fieldXForm.AttachParent(firstGen);
+            _xformSystem.SetParent(newField, fieldXForm, firstGen);
             if (dirVec.GetDir() == Direction.East || dirVec.GetDir() == Direction.West)
             {
                 var angle = fieldXForm.LocalPosition.ToAngle();
                 var rotateBy90 = angle.Degrees + 90;
                 var rotatedAngle = Angle.FromDegrees(rotateBy90);
 
-                fieldXForm.LocalRotation = rotatedAngle;
+                _xformSystem.SetLocalRotation(newField, rotatedAngle, fieldXForm);
             }
 
             fieldList.Add(newField);
index 561db76a470f0b625040eac61cf94688051afed9..47661167770d9283f0388701d8b6ad7309d2de9e 100644 (file)
@@ -13,6 +13,7 @@ public sealed class ContainmentFieldSystem : EntitySystem
 {
     [Dependency] private readonly ThrowingSystem _throwing = default!;
     [Dependency] private readonly PopupSystem _popupSystem = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public override void Initialize()
     {
@@ -34,8 +35,8 @@ public sealed class ContainmentFieldSystem : EntitySystem
 
         if (TryComp<PhysicsComponent>(otherBody, out var physics) && physics.Mass <= component.MaxMass && physics.Hard)
         {
-            var fieldDir = Transform(uid).WorldPosition;
-            var playerDir = Transform(otherBody).WorldPosition;
+            var fieldDir = _xformSystem.GetWorldPosition(uid);
+            var playerDir = _xformSystem.GetWorldPosition(otherBody);
 
             _throwing.TryThrow(otherBody, playerDir-fieldDir, strength: component.ThrowForce);
         }
index e346ae93007921e680eb2b3958003a1dd825a485..4914b4d44d67d9d9b2628c46f927b5a7d4693306 100644 (file)
@@ -165,7 +165,7 @@ public sealed class EventHorizonSystem : SharedEventHorizonSystem
         var range2 = range * range;
         var xformQuery = EntityManager.GetEntityQuery<TransformComponent>();
         var epicenter = _xformSystem.GetWorldPosition(xform, xformQuery);
-        foreach (var entity in _lookup.GetEntitiesInRange(xform.MapPosition, range, flags: LookupFlags.Uncontained))
+        foreach (var entity in _lookup.GetEntitiesInRange(_xformSystem.GetMapCoordinates((uid, xform)), range, flags: LookupFlags.Uncontained))
         {
             if (entity == uid)
                 continue;
@@ -295,7 +295,7 @@ public sealed class EventHorizonSystem : SharedEventHorizonSystem
         if (!Resolve(uid, ref xform) || !Resolve(uid, ref eventHorizon))
             return;
 
-        var mapPos = xform.MapPosition;
+        var mapPos = _xformSystem.GetMapCoordinates((uid, xform));
         var box = Box2.CenteredAround(mapPos.Position, new Vector2(range, range));
         var circle = new Circle(mapPos.Position, range);
         var grids = new List<Entity<MapGridComponent>>();
index 6a8fc68d976bd72d2f1151a5026bdd658dfd2c79..d80187688d9123d614837f24225e91f694af4582 100644 (file)
@@ -18,6 +18,7 @@ namespace Content.Server.Solar.EntitySystems
     {
         [Dependency] private readonly IRobustRandom _robustRandom = default!;
         [Dependency] private readonly SharedPhysicsSystem _physicsSystem = default!;
+        [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
         /// <summary>
         /// Maximum panel angular velocity range - used to stop people rotating panels fast enough that the lag prevention becomes noticable
@@ -112,7 +113,7 @@ namespace Content.Server.Solar.EntitySystems
                 while (query.MoveNext(out var uid, out var panel, out var xform))
                 {
                     TotalPanelPower += panel.MaxSupply * panel.Coverage;
-                    xform.WorldRotation = TargetPanelRotation;
+                    _xformSystem.SetWorldRotation(xform, TargetPanelRotation);
                     _updateQueue.Enqueue((uid, panel));
                 }
             }
@@ -135,7 +136,7 @@ namespace Content.Server.Solar.EntitySystems
             // directly downwards (abs(theta) = pi) = coverage -1
             // as TowardsSun + = CCW,
             // panelRelativeToSun should - = CW
-            var panelRelativeToSun = xform.WorldRotation - TowardsSun;
+            var panelRelativeToSun = _xformSystem.GetWorldRotation(xform) - TowardsSun;
             // essentially, given cos = X & sin = Y & Y is 'downwards',
             // then for the first 90 degrees of rotation in either direction,
             // this plots the lower-right quadrant of a circle.
@@ -153,7 +154,7 @@ namespace Content.Server.Solar.EntitySystems
             if (coverage > 0)
             {
                 // Determine if the solar panel is occluded, and zero out coverage if so.
-                var ray = new CollisionRay(xform.WorldPosition, TowardsSun.ToWorldVec(), (int) CollisionGroup.Opaque);
+                var ray = new CollisionRay(_xformSystem.GetWorldPosition(xform), TowardsSun.ToWorldVec(), (int) CollisionGroup.Opaque);
                 var rayCastResults = _physicsSystem.IntersectRayWithPredicate(
                     xform.MapID,
                     ray,
index e2b64958446d2e523b4ce2ca33f33ba441a1402b..87a25f9e1680059e806437f32bae91a1a4c4c455 100644 (file)
@@ -13,6 +13,7 @@ public sealed class StandingStateSystem : EntitySystem
     [Dependency] private readonly IRobustRandom _random = default!;
     [Dependency] private readonly SharedHandsSystem _handsSystem = default!;
     [Dependency] private readonly ThrowingSystem _throwingSystem = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     private void FallOver(EntityUid uid, StandingStateComponent component, DropHandItemsEvent args)
     {
@@ -25,7 +26,7 @@ public sealed class StandingStateSystem : EntitySystem
         if (!TryComp(uid, out HandsComponent? handsComp))
             return;
 
-        var worldRotation = EntityManager.GetComponent<TransformComponent>(uid).WorldRotation.ToVec();
+        var worldRotation = _xformSystem.GetWorldRotation(uid).ToVec();
         foreach (var hand in handsComp.Hands.Values)
         {
             if (hand.HeldEntity is not EntityUid held)
index 78326651c9c0aa3f9ac8d673d3f8dc1d1682a63c..21e125e708409a715371a75cd2c2531d15595615 100644 (file)
@@ -12,6 +12,7 @@ namespace Content.Server.Worldgen.Systems;
 public abstract class BaseWorldSystem : EntitySystem
 {
     [Dependency] private readonly WorldControllerSystem _worldController = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     /// <summary>
     ///     Gets a chunk's coordinates in chunk space as an integer value.
@@ -25,7 +26,7 @@ public abstract class BaseWorldSystem : EntitySystem
         if (!Resolve(ent, ref xform))
             throw new Exception("Failed to resolve transform, somehow.");
 
-        return WorldGen.WorldToChunkCoords(xform.WorldPosition).Floored();
+        return WorldGen.WorldToChunkCoords(_xformSystem.GetWorldPosition(xform)).Floored();
     }
 
     /// <summary>
@@ -40,7 +41,7 @@ public abstract class BaseWorldSystem : EntitySystem
         if (!Resolve(ent, ref xform))
             throw new Exception("Failed to resolve transform, somehow.");
 
-        return WorldGen.WorldToChunkCoords(xform.WorldPosition);
+        return WorldGen.WorldToChunkCoords(_xformSystem.GetWorldPosition(xform));
     }
 
     /// <summary>
index d4ed8272aa3c27d3486fb6aa733192e002b15ec2..f292be7c087ed1608353d62fe6756b62bcf238a6 100644 (file)
@@ -7,6 +7,7 @@ namespace Content.Server.Xenoarchaeology.XenoArtifacts.Effects.Systems;
 public sealed class EmpArtifactSystem : EntitySystem
 {
     [Dependency] private readonly EmpSystem _emp = default!;
+    [Dependency] private readonly SharedTransformSystem _xform = default!;
 
     /// <inheritdoc/>
     public override void Initialize()
@@ -16,6 +17,6 @@ public sealed class EmpArtifactSystem : EntitySystem
 
     private void OnActivate(EntityUid uid, EmpArtifactComponent component, ArtifactActivatedEvent args)
     {
-        _emp.EmpPulse(Transform(uid).MapPosition, component.Range, component.EnergyConsumption, component.DisableDuration);
+        _emp.EmpPulse(_xform.GetMapCoordinates(uid), component.Range, component.EnergyConsumption, component.DisableDuration);
     }
 }
\ No newline at end of file
index fcb33ae41fdb00022cf791bb08a83633ca84bf12..c2622837872e9e5737ebeea30e013394d429d912 100644 (file)
@@ -32,7 +32,7 @@ public sealed class SpawnArtifactSystem : EntitySystem
         if (component.Spawns is not {} spawns)
             return;
 
-        var artifactCord = Transform(uid).MapPosition;
+        var artifactCord = _transform.GetMapCoordinates(uid);
         foreach (var spawn in EntitySpawnCollection.GetSpawns(spawns, _random))
         {
             var dx = _random.NextFloat(-component.Range, component.Range);
index 85783b552daf917d6accc50972b623ae5cfcf22c..683957865df89062c13a470defd1e67e35090c97 100644 (file)
@@ -19,6 +19,7 @@ public sealed class ThrowArtifactSystem : EntitySystem
     [Dependency] private readonly EntityLookupSystem _lookup = default!;
     [Dependency] private readonly ThrowingSystem _throwing = default!;
     [Dependency] private readonly TileSystem _tile = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     /// <inheritdoc/>
     public override void Initialize()
@@ -32,7 +33,7 @@ public sealed class ThrowArtifactSystem : EntitySystem
         if (_map.TryGetGrid(xform.GridUid, out var grid))
         {
             var tiles = grid.GetTilesIntersecting(
-                Box2.CenteredAround(xform.WorldPosition, new Vector2(component.Range * 2, component.Range)));
+                Box2.CenteredAround(_xformSystem.GetWorldPosition(xform), new Vector2(component.Range * 2, component.Range)));
 
             foreach (var tile in tiles)
             {
@@ -51,9 +52,7 @@ public sealed class ThrowArtifactSystem : EntitySystem
                 && (phys.CollisionMask & (int) CollisionGroup.GhostImpassable) != 0)
                 continue;
 
-            var tempXform = Transform(ent);
-
-            var foo = tempXform.MapPosition.Position - xform.MapPosition.Position;
+            var foo = _xformSystem.GetWorldPosition(ent) - _xformSystem.GetWorldPosition(xform);
             _throwing.TryThrow(ent, foo*2, component.ThrowStrength, uid, 0);
         }
     }
index 731b2892aa87bcebfeb540a50db7347206f76f82..76fc7bcdd2f46d27694f2f869fa0de8f491de2cf 100644 (file)
@@ -451,7 +451,7 @@ public abstract partial class SharedBuckleSystem
             _transform.SetWorldRotation(buckleXform, oldBuckledToWorldRot);
 
             if (strapComp.UnbuckleOffset != Vector2.Zero)
-                buckleXform.Coordinates = oldBuckledXform.Coordinates.Offset(strapComp.UnbuckleOffset);
+                _transform.SetCoordinates((buckleUid, buckleXform, MetaData(buckleUid)), oldBuckledXform.Coordinates.Offset(strapComp.UnbuckleOffset));
         }
 
         if (TryComp(buckleUid, out AppearanceComponent? appearance))
index bf3016d49740118650ce185f843ed3373a6ebdf1..fbb280bd0c7fcd832601b18c27bb6a122dc2004f 100644 (file)
@@ -17,15 +17,16 @@ namespace Content.Shared.Construction.Conditions
         public bool Condition(EntityUid user, EntityCoordinates location, Direction direction)
         {
             var entManager = IoCManager.Resolve<IEntityManager>();
+            var xfmSystem = entManager.System<SharedTransformSystem>();
 
             // get blueprint and user position
-            var userWorldPosition = entManager.GetComponent<TransformComponent>(user).WorldPosition;
+            var userWorldPosition = xfmSystem.GetWorldPosition(user);
             var objWorldPosition = location.ToMap(entManager).Position;
 
             // find direction from user to blueprint
             var userToObject = (objWorldPosition - userWorldPosition);
             // get direction of the grid being placed on as an offset.
-            var gridRotation = entManager.GetComponent<TransformComponent>(location.EntityId).WorldRotation;
+            var gridRotation = xfmSystem.GetWorldRotation(location.EntityId);
             var directionWithOffset = gridRotation.RotateVec(direction.ToVec());
 
             // dot product will be positive if user direction and blueprint are co-directed
index b40c04956228211d16b0dff5a3b1d5cb1cd8876a..64faec38d2693091952924d57613c9574a3f1302 100644 (file)
@@ -127,7 +127,7 @@ public sealed partial class AnchorableSystem : EntitySystem
 
         // Snap rotation to cardinal (multiple of 90)
         var rot = xform.LocalRotation;
-        xform.LocalRotation = Math.Round(rot / (Math.PI / 2)) * (Math.PI / 2);
+        _transformSystem.SetLocalRotation(uid, Math.Round(rot / (Math.PI / 2)) * (Math.PI / 2), xform);
 
         if (TryComp<SharedPullableComponent>(uid, out var pullable) && pullable.Puller != null)
         {
index e120b6bc8838ce30dc0fd4ed08ae666f8d251088..27517c68b2f7f9828d363689cb1eb87513a95788 100644 (file)
@@ -7,6 +7,7 @@ namespace Content.Shared.Containers;
 public sealed class ContainerFillSystem : EntitySystem
 {
     [Dependency] private readonly SharedContainerSystem _containerSystem = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     public override void Initialize()
     {
@@ -36,7 +37,7 @@ public sealed class ContainerFillSystem : EntitySystem
                 if (!_containerSystem.Insert(ent, container, containerXform: xform))
                 {
                     Log.Error($"Entity {ToPrettyString(uid)} with a {nameof(ContainerFillComponent)} failed to insert an entity: {ToPrettyString(ent)}.");
-                    Transform(ent).AttachToGridOrMap();
+                    _xformSystem.AttachToGridOrMap(ent);
                     break;
                 }
             }
index 2ac525d154dd977af90acdf86d10fd6ec71fb026..495b7c3415ec35365afe4883a23192033ac9d45a 100644 (file)
@@ -13,6 +13,8 @@ public abstract class SharedDeviceLinkSystem : EntitySystem
     [Dependency] private readonly IPrototypeManager _prototypeManager = default!;
     [Dependency] private readonly SharedPopupSystem _popupSystem = default!;
     [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
+
     private ISawmill _sawmill = default!;
 
     public const string InvokedPort = "link_port";
@@ -531,7 +533,7 @@ public abstract class SharedDeviceLinkSystem : EntitySystem
     private bool InRange(EntityUid sourceUid, EntityUid sinkUid, float range)
     {
         // TODO: This should be using an existing method and also coordinates inrange instead.
-        return Transform(sourceUid).MapPosition.InRange(Transform(sinkUid).MapPosition, range);
+        return _xformSystem.GetMapCoordinates(sourceUid).InRange(_xformSystem.GetMapCoordinates(sinkUid), range);
     }
 
     private void SendNewLinkEvent(EntityUid? user, EntityUid sourceUid, string source, EntityUid sinkUid, string sink)
index 5a3fb8722933f9357cc00472883055b11df77ecf..7e616829c9496430c80b9e98e7c6bd01b7a3be70 100644 (file)
@@ -20,6 +20,7 @@ namespace Content.Shared.Examine
         [Dependency] private readonly SharedTransformSystem _transform = default!;
         [Dependency] private readonly SharedContainerSystem _containerSystem = default!;
         [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
+        [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
         [Dependency] protected readonly MobStateSystem MobStateSystem = default!;
 
         public const float MaxRaycastRange = 100;
@@ -186,6 +187,7 @@ namespace Content.Shared.Examine
 
             if (!ignoreInsideBlocker) return false;
 
+            var xfmSys = entMan.System<SharedTransformSystem>();
             foreach (var result in rayResults)
             {
                 if (!entMan.TryGetComponent(result.HitEntity, out OccluderComponent? o))
@@ -194,7 +196,7 @@ namespace Content.Shared.Examine
                 }
 
                 var bBox = o.BoundingBox;
-                bBox = bBox.Translated(entMan.GetComponent<TransformComponent>(result.HitEntity).WorldPosition);
+                bBox = bBox.Translated(xfmSys.GetWorldPosition(result.HitEntity));
 
                 if (bBox.Contains(origin.Position) || bBox.Contains(other.Position))
                 {
@@ -210,8 +212,10 @@ namespace Content.Shared.Examine
         public static bool InRangeUnOccluded(EntityUid origin, EntityUid other, float range = ExamineRange, Ignored? predicate = null, bool ignoreInsideBlocker = true)
         {
             var entMan = IoCManager.Resolve<IEntityManager>();
-            var originPos = entMan.GetComponent<TransformComponent>(origin).MapPosition;
-            var otherPos = entMan.GetComponent<TransformComponent>(other).MapPosition;
+            var xfmSys = entMan.System<SharedTransformSystem>();
+
+            var originPos = xfmSys.GetMapCoordinates(origin);
+            var otherPos = xfmSys.GetMapCoordinates(other);
 
             return InRangeUnOccluded(originPos, otherPos, range, predicate, ignoreInsideBlocker);
         }
@@ -219,8 +223,10 @@ namespace Content.Shared.Examine
         public static bool InRangeUnOccluded(EntityUid origin, EntityCoordinates other, float range = ExamineRange, Ignored? predicate = null, bool ignoreInsideBlocker = true)
         {
             var entMan = IoCManager.Resolve<IEntityManager>();
-            var originPos = entMan.GetComponent<TransformComponent>(origin).MapPosition;
-            var otherPos = other.ToMap(entMan);
+            var xfmSys = entMan.System<SharedTransformSystem>();
+
+            var originPos = xfmSys.GetMapCoordinates(origin);
+            var otherPos = other.ToMap(entMan, xfmSys);
 
             return InRangeUnOccluded(originPos, otherPos, range, predicate, ignoreInsideBlocker);
         }
@@ -228,7 +234,9 @@ namespace Content.Shared.Examine
         public static bool InRangeUnOccluded(EntityUid origin, MapCoordinates other, float range = ExamineRange, Ignored? predicate = null, bool ignoreInsideBlocker = true)
         {
             var entMan = IoCManager.Resolve<IEntityManager>();
-            var originPos = entMan.GetComponent<TransformComponent>(origin).MapPosition;
+            var xfmSys = entMan.System<SharedTransformSystem>();
+
+            var originPos = xfmSys.GetMapCoordinates(origin);
 
             return InRangeUnOccluded(originPos, other, range, predicate, ignoreInsideBlocker);
         }
index e071cdc69380c4f58e589a79ab4f2c5b827d3016..8382e7d2ee123c3ea6ffcd559bd16005315cb4c9 100644 (file)
@@ -135,7 +135,7 @@ public abstract partial class SharedHandsSystem
         }
 
         var target = targetDropLocation.Value.ToMap(EntityManager, TransformSystem);
-        TransformSystem.SetWorldPosition(itemXform, GetFinalDropCoordinates(uid, userXform.MapPosition, target));
+        TransformSystem.SetWorldPosition(itemXform, GetFinalDropCoordinates(uid, TransformSystem.GetMapCoordinates((uid, userXform)), target));
         return true;
     }
 
index bbae03e45b3d34d8bbde4fc163fb80619b0019e6..821f36697be8307a20335c785b35cc5bdb02fd1a 100644 (file)
@@ -108,10 +108,10 @@ public abstract partial class SharedHandsSystem : EntitySystem
             var xform = Transform(uid);
             var coordinateEntity = xform.ParentUid.IsValid() ? xform.ParentUid : uid;
             var itemXform = Transform(entity);
-            var itemPos = itemXform.MapPosition;
+            var itemPos = TransformSystem.GetMapCoordinates((entity, itemXform));
 
             if (itemPos.MapId == xform.MapID
-                && (itemPos.Position - xform.MapPosition.Position).Length() <= MaxAnimationRange
+                && (itemPos.Position - TransformSystem.GetMapCoordinates((uid, xform)).Position).Length() <= MaxAnimationRange
                 && MetaData(entity).VisibilityMask == MetaData(uid).VisibilityMask) // Don't animate aghost pickups.
             {
                 var initialPosition = EntityCoordinates.FromMap(coordinateEntity, itemPos, EntityManager);
index 01dc572a73d08ae9ff37e8c0ffcad536e5bc7bde..7644727aec9662bdb5f2f95a8205bd731127d0da 100644 (file)
@@ -70,7 +70,7 @@ namespace Content.Shared.Interaction
             if (!Resolve(user, ref xform))
                 return false;
 
-            var diff = coordinates - xform.MapPosition.Position;
+            var diff = coordinates - _transform.GetMapCoordinates((user, xform)).Position;
             if (diff.LengthSquared() <= 0.01f)
                 return true;
 
index 75063c55503fcd51fddbd2171cffad0c6336dd1f..94d486de391dfa19793144a15f8e138fc7051b4c 100644 (file)
@@ -630,7 +630,7 @@ namespace Content.Shared.Interaction
                 fixtureB.FixtureCount > 0 &&
                 TryComp<TransformComponent>(origin, out var xformA))
             {
-                var (worldPosA, worldRotA) = xformA.GetWorldPositionRotation();
+                var (worldPosA, worldRotA) = _transform.GetWorldPositionRotation(xformA);
                 var xfA = new Transform(worldPosA, worldRotA);
                 var parentRotB = _transform.GetWorldRotation(otherCoordinates.EntityId);
                 var xfB = new Transform(targetPos.Position, parentRotB + otherAngle);
@@ -660,14 +660,14 @@ namespace Content.Shared.Interaction
                 else
                 {
                     // We'll still do the raycast from the centres but we'll bump the range as we know they're in range.
-                    originPos = xformA.MapPosition;
+                    originPos = _transform.GetMapCoordinates(xformA);
                     range = (originPos.Position - targetPos.Position).Length();
                 }
             }
             // No fixtures, e.g. wallmounts.
             else
             {
-                originPos = Transform(origin).MapPosition;
+                originPos = _transform.GetMapCoordinates(origin);
                 var otherParent = Transform(other).ParentUid;
                 targetRot = otherParent.IsValid() ? Transform(otherParent).LocalRotation + otherAngle : otherAngle;
             }
@@ -696,7 +696,7 @@ namespace Content.Shared.Interaction
             Ignored? predicate = null)
         {
             var transform = Transform(target);
-            var (position, rotation) = transform.GetWorldPositionRotation();
+            var (position, rotation) = _transform.GetWorldPositionRotation(transform);
             var mapPos = new MapCoordinates(position, transform.MapID);
             var combinedPredicate = GetPredicate(origin, target, mapPos, rotation, collisionMask, predicate);
 
@@ -821,7 +821,7 @@ namespace Content.Shared.Interaction
             bool popup = false)
         {
             Ignored combinedPredicate = e => e == origin || (predicate?.Invoke(e) ?? false);
-            var originPosition = Transform(origin).MapPosition;
+            var originPosition = _transform.GetMapCoordinates(origin);
             var inRange = InRangeUnobstructed(originPosition, other, range, collisionMask, combinedPredicate, ShouldCheckAccess(origin));
 
             if (!inRange && popup && _gameTiming.IsFirstTimePredicted)
@@ -1057,7 +1057,7 @@ namespace Content.Shared.Interaction
                 rotation = mover.TargetRelativeRotation;
             }
 
-            Transform(item).LocalRotation = rotation;
+            _transform.SetLocalRotation(item, rotation);
         }
         #endregion
 
index d87b3ca50d542abcf232a0ca86ed6d55c61da760..4b5a0cb860f0ef8c29bc2ac95ced748d2aa2dd1d 100644 (file)
@@ -20,6 +20,7 @@ public sealed class TileSystem : EntitySystem
     [Dependency] private readonly SharedDecalSystem _decal = default!;
     [Dependency] private readonly SharedMapSystem _maps = default!;
     [Dependency] private readonly TurfSystem _turf = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     /// <summary>
     ///     Returns a weighted pick of a tile variant.
@@ -154,7 +155,7 @@ public sealed class TileSystem : EntitySystem
 
         //Actually spawn the relevant tile item at the right position and give it some random offset.
         var tileItem = Spawn(tileDef.ItemDropPrototypeName, coordinates);
-        Transform(tileItem).LocalRotation = _robustRandom.NextDouble() * Math.Tau;
+        _xformSystem.SetLocalRotation(tileItem, _robustRandom.NextDouble() * Math.Tau);
 
         // Destroy any decals on the tile
         var decals = _decal.GetDecalsInRange(gridUid, coordinates.SnapToGrid(EntityManager, _mapManager).Position, 0.5f);
index a87b8c97d159945389b321e022a002ca41744022..a0afe184081b0e510f18cbe5b28eeac3f5e8aa29 100644 (file)
@@ -144,11 +144,12 @@ namespace Content.Shared.Maps
         private static bool GetWorldTileBox(TileRef turf, out Box2Rotated res)
         {
             var entManager = IoCManager.Resolve<IEntityManager>();
+            var xfmSystem = entManager.System<SharedTransformSystem>();
             var map = IoCManager.Resolve<IMapManager>();
 
             if (map.TryGetGrid(turf.GridUid, out var tileGrid))
             {
-                var gridRot = entManager.GetComponent<TransformComponent>(turf.GridUid).WorldRotation;
+                var gridRot = xfmSystem.GetWorldRotation(turf.GridUid);
 
                 // This is scaled to 90 % so it doesn't encompass walls on other tiles.
                 var tileBox = Box2.UnitCentered.Scale(0.9f);
index 2c03507f6174a4067e443de1292610de007ffa30..d854d5544a67af234278504b108052c885e19988 100644 (file)
@@ -248,7 +248,7 @@ namespace Content.Shared.Movement.Systems
                     // TODO apparently this results in a duplicate move event because "This should have its event run during
                     // island solver"??. So maybe SetRotation needs an argument to avoid raising an event?
                     var worldRot = _transform.GetWorldRotation(xform);
-                    _transform.SetLocalRotation(xform, xform.LocalRotation + worldTotal.ToWorldAngle() - worldRot);
+                    _transform.SetLocalRotation(physicsUid, xform.LocalRotation + worldTotal.ToWorldAngle() - worldRot, xform);
                 }
 
                 if (!weightless && MobMoverQuery.TryGetComponent(uid, out var mobMover) &&
index f9e5d4a1f63d2691445b05e085701fa29571918d..cce0b2917579b34cfee5d6d6441fd99969b31d5a 100644 (file)
@@ -80,7 +80,7 @@ public sealed class DashAbilitySystem : EntitySystem
             return;
         }
 
-        var origin = Transform(user).MapPosition;
+        var origin = _transform.GetMapCoordinates(user);
         var target = args.Target.ToMap(EntityManager, _transform);
         // prevent collision with the user duh
         if (!_interaction.InRangeUnobstructed(origin, target, 0f, CollisionGroup.Opaque, uid => uid == user))
index ec17df7a24f8c5d8cfee2cf94ba641c4cc3497db..eea646295357aeebcf4302ff9f9874600c44e2d3 100644 (file)
@@ -97,7 +97,7 @@ public abstract class SharedConveyorController : VirtualController
             var itemRelative = conveyorPos - localPos;
 
             localPos += Convey(direction, speed, frameTime, itemRelative);
-            transform.LocalPosition = localPos;
+            TransformSystem.SetLocalPosition(entity, localPos, transform);
 
             // Force it awake for collisionwake reasons.
             Physics.SetAwake(entity, body, true);
index b0031cfa33f24c6d03a2ae69d41241ee126d69fd..eb098d762bb6684a6e6f23922192aec0b88983df 100644 (file)
@@ -8,6 +8,7 @@ namespace Content.Shared.Placeable
     public sealed class PlaceableSurfaceSystem : EntitySystem
     {
         [Dependency] private readonly SharedHandsSystem _handsSystem = default!;
+        [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
         public override void Initialize()
         {
@@ -60,9 +61,11 @@ namespace Content.Shared.Placeable
                 return;
 
             if (surface.PlaceCentered)
-                Transform(args.Used).LocalPosition = Transform(uid).LocalPosition + surface.PositionOffset;
+            {
+                _xformSystem.SetLocalPosition(args.Used, Transform(uid).LocalPosition + surface.PositionOffset);
+            }
             else
-                Transform(args.Used).Coordinates = args.ClickLocation;
+                _xformSystem.SetCoordinates(args.Used, args.ClickLocation);
 
             args.Handled = true;
         }
index 187c8d8a9d847572eaf21274152b075593da7190..830f4ca1b538e6e9c70ba56e37c38f8573e69001 100644 (file)
@@ -38,6 +38,7 @@ public sealed class RCDSystem : EntitySystem
     [Dependency] private readonly TagSystem _tag = default!;
     [Dependency] private readonly TurfSystem _turf = default!;
     [Dependency] private readonly IGameTiming _gameTiming = default!;
+    [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
 
     private readonly int RcdModeCount = Enum.GetValues(typeof(RcdMode)).Length;
 
@@ -198,7 +199,7 @@ public sealed class RCDSystem : EntitySystem
                 if (_net.IsServer)
                 {
                     var ent = Spawn("WallSolid", mapGrid.GridTileToLocal(snapPos));
-                    Transform(ent).LocalRotation = Angle.Zero; // Walls always need to point south.
+                    _xformSystem.SetLocalRotation(ent, Angle.Zero); // Walls always need to point south.
                     _adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(args.User):user} used RCD to spawn {ToPrettyString(ent)} at {snapPos} on grid {tile.GridUid}");
                 }
                 break;
@@ -207,7 +208,7 @@ public sealed class RCDSystem : EntitySystem
                 if (_net.IsServer)
                 {
                     var airlock = Spawn("Airlock", mapGrid.GridTileToLocal(snapPos));
-                    Transform(airlock).LocalRotation = Transform(uid).LocalRotation; //Now apply icon smoothing.
+                    _xformSystem.SetLocalRotation(airlock, Transform(uid).LocalRotation); //Now apply icon smoothing.
                     _adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(args.User):user} used RCD to spawn {ToPrettyString(airlock)} at {snapPos} on grid {tile.GridUid}");
                 }
                 break;
index 66ebcc3f78bdd0d7b9ef05d0bb5c77a654b0aef8..553e28cd659643db3e0e5f2bdd62d2f7d653a7d5 100644 (file)
@@ -20,7 +20,7 @@ public sealed class RandomHelperSystem : EntitySystem
         var offset = new Vector2(randomX, randomY);
 
         var xform = Transform(entity);
-        _transform.SetLocalPosition(xform, xform.LocalPosition + offset);
+        _transform.SetLocalPosition(entity, xform.LocalPosition + offset, xform);
     }
 
     public void RandomOffset(EntityUid entity, float min, float max)
index d0ea8045347f900ae1464e60b3de0a56fc510941..1bab55589fd2f6245749931e6491bbe2a91b1ce7 100644 (file)
@@ -113,7 +113,7 @@ public abstract class SharedStealthSystem : EntitySystem
 
     private void OnMove(EntityUid uid, StealthOnMoveComponent component, ref MoveEvent args)
     {
-        if (args.FromStateHandling)
+        if (_timing.ApplyingState)
             return;
 
         if (args.NewPosition.EntityId != args.OldPosition.EntityId)
index 21861f57dab20ad713b3fb4dce92c4df06b5ae02..a47488b24fa8cfb08f8be3b2e55d11464368d712 100644 (file)
@@ -77,7 +77,7 @@ public sealed class MagnetPickupSystem : EntitySystem
                 // the problem is that stack pickups delete the original entity, which is fine, but due to
                 // game state handling we can't show a lerp animation for it.
                 var nearXform = Transform(near);
-                var nearMap = nearXform.MapPosition;
+                var nearMap = _transform.GetMapCoordinates(nearXform);
                 var nearCoords = EntityCoordinates.FromMap(moverCoords.EntityId, nearMap, _transform, EntityManager);
 
                 if (!_storage.Insert(uid, near, out var stacked, storageComp: storage, playSound: !playedSound))
index 7bfd9d345729a07496c884962b3772e1765ce046..351fe04174c73335180a24da5568b67311499fb3 100644 (file)
@@ -14,9 +14,9 @@ namespace Content.Shared.Tabletop
     public abstract class SharedTabletopSystem : EntitySystem
     {
         [Dependency] protected readonly ActionBlockerSystem ActionBlockerSystem = default!;
+        [Dependency] protected readonly SharedTransformSystem Transforms = default!;
         [Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
         [Dependency] private readonly SharedAppearanceSystem _appearance = default!;
-        [Dependency] private readonly SharedTransformSystem _transforms = default!;
         [Dependency] private readonly IMapManager _mapMan = default!;
 
         public override void Initialize()
@@ -41,8 +41,8 @@ namespace Content.Shared.Tabletop
 
             // Move the entity and dirty it (we use the map ID from the entity so noone can try to be funny and move the item to another map)
             var transform = EntityManager.GetComponent<TransformComponent>(moved);
-            _transforms.SetParent(moved, transform, _mapMan.GetMapEntityId(transform.MapID));
-            _transforms.SetLocalPositionNoLerp(transform, msg.Coordinates.Position);
+            var coordinates = new EntityCoordinates(_mapMan.GetMapEntityId(transform.MapID), msg.Coordinates.Position);
+            Transforms.SetCoordinates(moved, transform, coordinates);
         }
 
         private void OnDraggingPlayerChanged(TabletopDraggingPlayerChangedEvent msg, EntitySessionEventArgs args)
index 54294318315053a3caee9017d861e95d76d5dfdd..2ac71e35f46730135b2172bf2d840f9d7fc2c599 100644 (file)
@@ -44,7 +44,7 @@ public sealed class ThrowingSystem : EntitySystem
         float pushbackRatio = PushbackDefault,
         bool playSound = true)
     {
-        var thrownPos = Transform(uid).MapPosition;
+        var thrownPos = _transform.GetMapCoordinates(uid);
         var mapPos = coordinates.ToMap(EntityManager, _transform);
 
         if (mapPos.MapId != thrownPos.MapId)
index 177cb310d18a5bfd896ac8f68fac9105973b38ac..4d3b0b802bc308319f52f3e74cae74a3ee270da9 100644 (file)
@@ -220,7 +220,7 @@ public abstract partial class SharedTetherGunSystem : EntitySystem
         _blocker.UpdateCanMove(target);
 
         // Invisible tether entity
-        var tether = Spawn("TetherEntity", Transform(target).MapPosition);
+        var tether = Spawn("TetherEntity", TransformSystem.GetMapCoordinates(target));
         var tetherPhysics = Comp<PhysicsComponent>(tether);
         component.TetherEntity = tether;
         _physics.WakeBody(tether);
index a8f7ee23956c41f36ac9830b6b90db4e4eb8f909..3de5ae3144ae7f65e6df2896c254110eac9f8d14 100644 (file)
@@ -35,7 +35,7 @@ public abstract partial class SharedGunSystem
         if (args.Handled)
             return;
 
-        ManualCycle(uid, component, Transform(uid).MapPosition, args.User);
+        ManualCycle(uid, component, TransformSystem.GetMapCoordinates(uid), args.User);
         args.Handled = true;
     }
 
@@ -162,7 +162,7 @@ public abstract partial class SharedGunSystem
             {
                 Text = Loc.GetString("gun-ballistic-cycle"),
                 Disabled = GetBallisticShots(component) == 0,
-                Act = () => ManualCycle(uid, component, Transform(uid).MapPosition, args.User),
+                Act = () => ManualCycle(uid, component, TransformSystem.GetMapCoordinates(uid), args.User),
             });
 
         }
index 71e3e80764f002485e68bcc8c727faeba54f16bb..2ad63ad096589c0bd033d048fed4f69d89ce1da6 100644 (file)
@@ -431,8 +431,7 @@ public abstract partial class SharedGunSystem : EntitySystem
         var coordinates = xform.Coordinates;
         coordinates = coordinates.Offset(offsetPos);
 
-        TransformSystem.SetLocalRotation(xform, Random.NextAngle());
-        TransformSystem.SetCoordinates(entity, xform, coordinates);
+        TransformSystem.SetCoordinates(entity, xform, coordinates, Random.NextAngle());
 
         // decides direction the casing ejects and only when not cycling
         if (angle != null)