diff --git a/Content.Client/Eye/EyeLerpingSystem.cs b/Content.Client/Eye/EyeLerpingSystem.cs index 8e9679afbd..8a5a6586aa 100644 --- a/Content.Client/Eye/EyeLerpingSystem.cs +++ b/Content.Client/Eye/EyeLerpingSystem.cs @@ -1,3 +1,4 @@ +using Content.Shared.Follower.Components; using Content.Shared.Movement.Components; using Content.Shared.Movement.Systems; using Robust.Client.GameObjects; @@ -25,8 +26,9 @@ public sealed class EyeLerpingSystem : EntitySystem SubscribeLocalEvent(OnEyeStartup); SubscribeLocalEvent(OnEyeShutdown); - SubscribeLocalEvent(HandleMapChange); SubscribeLocalEvent(OnAttached); + + SubscribeLocalEvent(HandleMapChange); SubscribeLocalEvent(OnDetached); UpdatesAfter.Add(typeof(TransformSystem)); diff --git a/Content.Shared/Follower/Components/FollowedComponent.cs b/Content.Shared/Follower/Components/FollowedComponent.cs index 63a71106bb..259af7c484 100644 --- a/Content.Shared/Follower/Components/FollowedComponent.cs +++ b/Content.Shared/Follower/Components/FollowedComponent.cs @@ -7,8 +7,9 @@ namespace Content.Shared.Follower.Components; /// Attached to entities that are currently being followed by a ghost. /// [RegisterComponent, Access(typeof(FollowerSystem))] -[NetworkedComponent] -public sealed class FollowedComponent : Component +[NetworkedComponent, AutoGenerateComponentState] +public sealed partial class FollowedComponent : Component { + [AutoNetworkedField(true), DataField("following")] public HashSet Following = new(); } diff --git a/Content.Shared/Follower/Components/FollowerComponent.cs b/Content.Shared/Follower/Components/FollowerComponent.cs index 040bab4df1..15d23a7037 100644 --- a/Content.Shared/Follower/Components/FollowerComponent.cs +++ b/Content.Shared/Follower/Components/FollowerComponent.cs @@ -4,8 +4,9 @@ namespace Content.Shared.Follower.Components; [RegisterComponent] [Access(typeof(FollowerSystem))] -[NetworkedComponent] -public sealed class FollowerComponent : Component +[NetworkedComponent, AutoGenerateComponentState] +public sealed partial class FollowerComponent : Component { + [AutoNetworkedField, DataField("following")] public EntityUid Following; } diff --git a/Content.Shared/Follower/FollowerSystem.cs b/Content.Shared/Follower/FollowerSystem.cs index 4e5f0931a7..1493ce4445 100644 --- a/Content.Shared/Follower/FollowerSystem.cs +++ b/Content.Shared/Follower/FollowerSystem.cs @@ -2,6 +2,7 @@ using Content.Shared.Database; using Content.Shared.Follower.Components; using Content.Shared.Ghost; using Content.Shared.Movement.Events; +using Content.Shared.Movement.Systems; using Content.Shared.Verbs; using Robust.Shared.Map; using Robust.Shared.Utility; @@ -71,12 +72,12 @@ public sealed class FollowerSystem : EntitySystem followerComp.Following = entity; var followedComp = EnsureComp(entity); - followedComp.Following.Add(follower); + + if (!followedComp.Following.Add(follower)) + return; var xform = Transform(follower); - _transform.SetParent(follower, xform, entity); - xform.LocalPosition = Vector2.Zero; - xform.LocalRotation = Angle.Zero; + _transform.SetCoordinates(follower, xform, new EntityCoordinates(entity, Vector2.Zero), Angle.Zero); EnsureComp(follower); @@ -85,6 +86,7 @@ public sealed class FollowerSystem : EntitySystem RaiseLocalEvent(follower, followerEv, true); RaiseLocalEvent(entity, entityEv, false); + Dirty(followedComp); } /// @@ -105,10 +107,10 @@ public sealed class FollowerSystem : EntitySystem RemComp(uid); var xform = Transform(uid); - xform.AttachToGridOrMap(); + _transform.AttachToGridOrMap(uid, xform); if (xform.MapID == MapId.Nullspace) { - Del(uid); + QueueDel(uid); return; } @@ -119,6 +121,7 @@ public sealed class FollowerSystem : EntitySystem RaiseLocalEvent(uid, uidEv, true); RaiseLocalEvent(target, targetEv, false); + Dirty(followed); } /// diff --git a/Content.Shared/Movement/Systems/SharedMoverController.Input.cs b/Content.Shared/Movement/Systems/SharedMoverController.Input.cs index d1da217a3d..186c4f8756 100644 --- a/Content.Shared/Movement/Systems/SharedMoverController.Input.cs +++ b/Content.Shared/Movement/Systems/SharedMoverController.Input.cs @@ -1,4 +1,5 @@ using Content.Shared.CCVar; +using Content.Shared.Follower.Components; using Content.Shared.Input; using Content.Shared.Movement.Components; using Content.Shared.Movement.Events; @@ -51,6 +52,8 @@ namespace Content.Shared.Movement.Systems SubscribeLocalEvent(OnInputHandleState); SubscribeLocalEvent(OnInputParentChange); + SubscribeLocalEvent(OnFollowedParentChange); + _configManager.OnValueChanged(CCVars.CameraRotationLocked, SetCameraRotationLocked, true); _configManager.OnValueChanged(CCVars.GameDiagonalMovement, SetDiagonalMovement, true); } @@ -145,6 +148,21 @@ namespace Content.Shared.Movement.Systems return rotation; } + private void OnFollowedParentChange(EntityUid uid, FollowedComponent component, ref EntParentChangedMessage args) + { + var moverQuery = GetEntityQuery(); + var xformQuery = GetEntityQuery(); + + foreach (var foll in component.Following) + { + if (!moverQuery.TryGetComponent(foll, out var mover)) + continue; + + var ev = new EntParentChangedMessage(foll, null, args.OldMapId, xformQuery.GetComponent(foll)); + OnInputParentChange(foll, mover, ref ev); + } + } + private void OnInputParentChange(EntityUid uid, InputMoverComponent component, ref EntParentChangedMessage args) { // If we change our grid / map then delay updating our LastGridAngle.