diff --git a/Content.Server/Ghost/GhostSystem.cs b/Content.Server/Ghost/GhostSystem.cs index af1a433d1a..3486e2024b 100644 --- a/Content.Server/Ghost/GhostSystem.cs +++ b/Content.Server/Ghost/GhostSystem.cs @@ -333,7 +333,8 @@ namespace Content.Server.Ghost if (_followerSystem.GetMostGhostFollowed() is not {} target) return; - WarpTo(uid, target); + // If there is a ghostnado happening you almost definitely wanna join it, so we automatically follow instead of just warping. + _followerSystem.StartFollowingEntity(uid, target); } private void WarpTo(EntityUid uid, EntityUid target) diff --git a/Content.Shared/Follower/FollowerSystem.cs b/Content.Shared/Follower/FollowerSystem.cs index 07639a1790..8357b0106f 100644 --- a/Content.Shared/Follower/FollowerSystem.cs +++ b/Content.Shared/Follower/FollowerSystem.cs @@ -35,6 +35,7 @@ public sealed class FollowerSystem : EntitySystem [Dependency] private readonly ISharedAdminManager _adminManager = default!; private static readonly ProtoId ForceableFollowTag = "ForceableFollow"; + private static readonly ProtoId PreventGhostnadoWarpTag = "NotGhostnadoWarpable"; public override void Initialize() { @@ -320,11 +321,17 @@ public sealed class FollowerSystem : EntitySystem var query = EntityQueryEnumerator(); while (query.MoveNext(out _, out var follower, out _, out var actor)) { - // Exclude admins + // Don't count admin followers so that players cannot notice if admins are in stealth mode and following someone. if (_adminManager.IsAdmin(actor.PlayerSession)) continue; var followed = follower.Following; + + // If the followed entity cannot be ghostnado'd to, we don't count it. + // Used for making admins not warpable to, but IsAdmin isn't used for cases where the admin wants to be followed, for example during events. + if (_tagSystem.HasTag(followed, PreventGhostnadoWarpTag)) + continue; + // Add new entry or increment existing followedEnts.TryGetValue(followed, out var currentValue); followedEnts[followed] = currentValue + 1; diff --git a/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml b/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml index 7c1bb7ef16..e5fdfe7336 100644 --- a/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml +++ b/Resources/Prototypes/Entities/Mobs/Player/admin_ghost.yml @@ -16,6 +16,7 @@ - SilentStorageUser - PreventAccessLogging - AllowBiomeLoading + - NotGhostnadoWarpable - type: Input context: "aghost" - type: Ghost diff --git a/Resources/Prototypes/tags.yml b/Resources/Prototypes/tags.yml index 3b3d11e612..44b636495c 100644 --- a/Resources/Prototypes/tags.yml +++ b/Resources/Prototypes/tags.yml @@ -973,7 +973,7 @@ - type: Tag id: Mouse # CargoBounty: BountyMouse - + - type: Tag id: Multitool # Storage whitelist: BaseClothingBeltEngineering. ItemMapper: BaseClothingBeltEngineering. ConstructionGraph: LogicGate @@ -987,6 +987,9 @@ - type: Tag id: NoConsoleSound # Blacklist on BaseComputer, StationMap. Tagged entity will not make sound when opening the UI. +- type: Tag + id: NotGhostnadoWarpable # Prevents the entity from being selected via "Warp to most followed" ghost warp + - type: Tag id: NozzleBackTank # Used by WeaponSprayNozzle to find a tagged entity for supplying ammo.