diff --git a/Content.Server/Polymorph/Systems/PolymorphSystem.cs b/Content.Server/Polymorph/Systems/PolymorphSystem.cs index 1514d580dd..2c06ba3be9 100644 --- a/Content.Server/Polymorph/Systems/PolymorphSystem.cs +++ b/Content.Server/Polymorph/Systems/PolymorphSystem.cs @@ -267,6 +267,10 @@ public sealed partial class PolymorphSystem : EntitySystem if (PausedMap != null) _transform.SetParent(uid, targetTransformComp, PausedMap.Value); + // Raise an event to inform anything that wants to know about the entity swap + var ev = new PolymorphedEvent(uid, child, false); + RaiseLocalEvent(uid, ref ev); + return child; } @@ -339,6 +343,10 @@ public sealed partial class PolymorphSystem : EntitySystem // if an item polymorph was picked up, put it back down after reverting _transform.AttachToGridOrMap(parent, parentXform); + // Raise an event to inform anything that wants to know about the entity swap + var ev = new PolymorphedEvent(uid, parent, true); + RaiseLocalEvent(uid, ref ev); + _popup.PopupEntity(Loc.GetString("polymorph-revert-popup-generic", ("parent", Identity.Entity(uid, EntityManager)), ("child", Identity.Entity(parent, EntityManager))), diff --git a/Content.Shared/Follower/Components/FollowerComponent.cs b/Content.Shared/Follower/Components/FollowerComponent.cs index 15d23a7037..ede810293f 100644 --- a/Content.Shared/Follower/Components/FollowerComponent.cs +++ b/Content.Shared/Follower/Components/FollowerComponent.cs @@ -4,7 +4,7 @@ namespace Content.Shared.Follower.Components; [RegisterComponent] [Access(typeof(FollowerSystem))] -[NetworkedComponent, AutoGenerateComponentState] +[NetworkedComponent, AutoGenerateComponentState(RaiseAfterAutoHandleState = true)] public sealed partial class FollowerComponent : Component { [AutoNetworkedField, DataField("following")] diff --git a/Content.Shared/Follower/FollowerSystem.cs b/Content.Shared/Follower/FollowerSystem.cs index 0c7bc99c46..d1adaa014a 100644 --- a/Content.Shared/Follower/FollowerSystem.cs +++ b/Content.Shared/Follower/FollowerSystem.cs @@ -6,6 +6,7 @@ using Content.Shared.Ghost; using Content.Shared.Hands; using Content.Shared.Movement.Events; using Content.Shared.Movement.Pulling.Events; +using Content.Shared.Polymorph; using Content.Shared.Tag; using Content.Shared.Verbs; using Robust.Shared.Containers; @@ -38,10 +39,12 @@ public sealed class FollowerSystem : EntitySystem SubscribeLocalEvent(OnFollowerMove); SubscribeLocalEvent(OnPullStarted); SubscribeLocalEvent(OnFollowerTerminating); + SubscribeLocalEvent(OnAfterHandleState); SubscribeLocalEvent(OnFollowedAttempt); SubscribeLocalEvent(OnGotEquippedHand); SubscribeLocalEvent(OnFollowedTerminating); + SubscribeLocalEvent(OnFollowedPolymorphed); SubscribeLocalEvent(OnBeforeSave); } @@ -135,6 +138,11 @@ public sealed class FollowerSystem : EntitySystem StopFollowingEntity(uid, component.Following, deparent: false); } + private void OnAfterHandleState(Entity entity, ref AfterAutoHandleStateEvent args) + { + StartFollowingEntity(entity, entity.Comp.Following); + } + // Since we parent our observer to the followed entity, we need to detach // before they get deleted so that we don't get recursively deleted too. private void OnFollowedTerminating(EntityUid uid, FollowedComponent component, ref EntityTerminatingEvent args) @@ -142,6 +150,15 @@ public sealed class FollowerSystem : EntitySystem StopAllFollowers(uid, component); } + private void OnFollowedPolymorphed(Entity entity, ref PolymorphedEvent args) + { + foreach (var follower in entity.Comp.Following) + { + // Stop following the target's old entity and start following the new one + StartFollowingEntity(follower, args.NewEntity); + } + } + /// /// Makes an entity follow another entity, by parenting to it. /// @@ -202,6 +219,7 @@ public sealed class FollowerSystem : EntitySystem RaiseLocalEvent(follower, followerEv); RaiseLocalEvent(entity, entityEv); Dirty(entity, followedComp); + Dirty(follower, followerComp); } /// @@ -213,7 +231,7 @@ public sealed class FollowerSystem : EntitySystem if (!Resolve(target, ref followed, false)) return; - if (!HasComp(uid)) + if (!TryComp(uid, out var followerComp) || followerComp.Following != target) return; followed.Following.Remove(uid); diff --git a/Content.Shared/Polymorph/PolymorphEvents.cs b/Content.Shared/Polymorph/PolymorphEvents.cs new file mode 100644 index 0000000000..f2a478c34f --- /dev/null +++ b/Content.Shared/Polymorph/PolymorphEvents.cs @@ -0,0 +1,10 @@ +namespace Content.Shared.Polymorph; + +/// +/// Raised locally on an entity when it polymorphs into another entity +/// +/// EntityUid of the entity before the polymorph +/// EntityUid of the entity after the polymorph +/// Whether this polymorph event was a revert back to the original entity +[ByRefEvent] +public record struct PolymorphedEvent(EntityUid OldEntity, EntityUid NewEntity, bool IsRevert);