]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fix followers getting sent to nullspace when target is polymorphed (#33878)
authorTayrtahn <tayrtahn@gmail.com>
Tue, 11 Feb 2025 21:34:24 +0000 (16:34 -0500)
committerGitHub <noreply@github.com>
Tue, 11 Feb 2025 21:34:24 +0000 (22:34 +0100)
* Add an event for polymorph actions

* Subscribe FollowerSystem to the event

* Add check that unfollow target is actually current target.

* Make followers try to follow on state update; Dirty follower on follow.

Content.Server/Polymorph/Systems/PolymorphSystem.cs
Content.Shared/Follower/Components/FollowerComponent.cs
Content.Shared/Follower/FollowerSystem.cs
Content.Shared/Polymorph/PolymorphEvents.cs [new file with mode: 0644]

index 1514d580dda093fc77c645afa4032d887af4d098..2c06ba3be9738f071fb81ef0005010e9355b7f28 100644 (file)
@@ -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))),
index 15d23a7037ddd4e041d85faeb148ab79e67db2c4..ede810293ff427e05d8bee3d3d9f406fc3c08196 100644 (file)
@@ -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")]
index 0c7bc99c4648b968cccd1e62a77401c4cf059d47..d1adaa014a0f75c5d6e85d776c48813bde8e742f 100644 (file)
@@ -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<FollowerComponent, MoveInputEvent>(OnFollowerMove);
         SubscribeLocalEvent<FollowerComponent, PullStartedMessage>(OnPullStarted);
         SubscribeLocalEvent<FollowerComponent, EntityTerminatingEvent>(OnFollowerTerminating);
+        SubscribeLocalEvent<FollowerComponent, AfterAutoHandleStateEvent>(OnAfterHandleState);
 
         SubscribeLocalEvent<FollowedComponent, ComponentGetStateAttemptEvent>(OnFollowedAttempt);
         SubscribeLocalEvent<FollowerComponent, GotEquippedHandEvent>(OnGotEquippedHand);
         SubscribeLocalEvent<FollowedComponent, EntityTerminatingEvent>(OnFollowedTerminating);
+        SubscribeLocalEvent<FollowedComponent, PolymorphedEvent>(OnFollowedPolymorphed);
         SubscribeLocalEvent<BeforeSaveEvent>(OnBeforeSave);
     }
 
@@ -135,6 +138,11 @@ public sealed class FollowerSystem : EntitySystem
         StopFollowingEntity(uid, component.Following, deparent: false);
     }
 
+    private void OnAfterHandleState(Entity<FollowerComponent> 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<FollowedComponent> 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);
+        }
+    }
+
     /// <summary>
     ///     Makes an entity follow another entity, by parenting to it.
     /// </summary>
@@ -202,6 +219,7 @@ public sealed class FollowerSystem : EntitySystem
         RaiseLocalEvent(follower, followerEv);
         RaiseLocalEvent(entity, entityEv);
         Dirty(entity, followedComp);
+        Dirty(follower, followerComp);
     }
 
     /// <summary>
@@ -213,7 +231,7 @@ public sealed class FollowerSystem : EntitySystem
         if (!Resolve(target, ref followed, false))
             return;
 
-        if (!HasComp<FollowerComponent>(uid))
+        if (!TryComp<FollowerComponent>(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 (file)
index 0000000..f2a478c
--- /dev/null
@@ -0,0 +1,10 @@
+namespace Content.Shared.Polymorph;
+
+/// <summary>
+/// Raised locally on an entity when it polymorphs into another entity
+/// </summary>
+/// <param name="OldEntity">EntityUid of the entity before the polymorph</param>
+/// <param name="NewEntity">EntityUid of the entity after the polymorph</param>
+/// <param name="IsRevert">Whether this polymorph event was a revert back to the original entity</param>
+[ByRefEvent]
+public record struct PolymorphedEvent(EntityUid OldEntity, EntityUid NewEntity, bool IsRevert);