diff --git a/Content.Client/Ghost/GhostSystem.cs b/Content.Client/Ghost/GhostSystem.cs index f4f7e3459fb981..f2c5f958e56fb4 100644 --- a/Content.Client/Ghost/GhostSystem.cs +++ b/Content.Client/Ghost/GhostSystem.cs @@ -17,7 +17,7 @@ public sealed class GhostSystem : SharedGhostSystem public int AvailableGhostRoleCount { get; private set; } - private bool _ghostVisibility = true; + private bool _ghostVisibility; private bool GhostVisibility { @@ -32,9 +32,9 @@ private bool GhostVisibility _ghostVisibility = value; var query = AllEntityQuery(); - while (query.MoveNext(out var uid, out _, out var sprite)) + while (query.MoveNext(out var uid, out var ghost, out var sprite)) { - sprite.Visible = value || uid == _playerManager.LocalEntity; + UpdateVisibility((uid, ghost, sprite)); } } } @@ -70,8 +70,15 @@ public override void Initialize() private void OnStartup(EntityUid uid, GhostComponent component, ComponentStartup args) { - if (TryComp(uid, out SpriteComponent? sprite)) - sprite.Visible = GhostVisibility || uid == _playerManager.LocalEntity; + UpdateVisibility((uid, component)); + } + + private void UpdateVisibility(Entity ghost) + { + if (!Resolve(ghost.Owner, ref ghost.Comp1, ref ghost.Comp2)) + return; + + ghost.Comp2.Visible = GhostVisibility || ghost.Comp1.Visible || ghost.Owner == _playerManager.LocalEntity; } private void OnToggleLighting(EntityUid uid, EyeComponent component, ToggleLightingActionEvent args) @@ -130,7 +137,9 @@ private void OnGhostPlayerAttach(EntityUid uid, GhostComponent component, LocalP private void OnGhostState(EntityUid uid, GhostComponent component, ref AfterAutoHandleStateEvent args) { if (TryComp(uid, out var sprite)) - sprite.LayerSetColor(0, component.color); + sprite.LayerSetColor(0, component.Color); + + UpdateVisibility((uid, component, null)); if (uid != _playerManager.LocalEntity) return; diff --git a/Content.Server/Administration/Commands/ShowGhostsCommand.cs b/Content.Server/Administration/Commands/ShowGhostsCommand.cs index 2f8bf79e6980a0..e1fb5e7a02e064 100644 --- a/Content.Server/Administration/Commands/ShowGhostsCommand.cs +++ b/Content.Server/Administration/Commands/ShowGhostsCommand.cs @@ -28,11 +28,7 @@ public void Execute(IConsoleShell shell, string argStr, string[] args) return; } - var ghostSys = _entities.EntitySysManager.GetEntitySystem(); - var revSys = _entities.EntitySysManager.GetEntitySystem(); - - ghostSys.MakeVisible(visible); - revSys.MakeVisible(visible); + _entities.System().MakeVisible(visible); } } } diff --git a/Content.Server/Ghost/GhostSystem.cs b/Content.Server/Ghost/GhostSystem.cs index 25319557ae165b..937d02be037e8e 100644 --- a/Content.Server/Ghost/GhostSystem.cs +++ b/Content.Server/Ghost/GhostSystem.cs @@ -124,6 +124,33 @@ private void OnGhostHearingAction(EntityUid uid, GhostComponent component, Toggl Dirty(uid, component); } + public override void SetVisible(Entity ghost, bool visible) + { + if (!Resolve(ghost.Owner, ref ghost.Comp)) + return; + + if (ghost.Comp.Visible == visible) + return; + + base.SetVisible(ghost, visible); + + if (!TryComp(ghost.Owner, out VisibilityComponent? visibility)) + return; + + if (visible) + { + _visibilitySystem.RemoveLayer((ghost.Owner, visibility), (int)VisibilityFlags.Ghost, false); + _visibilitySystem.AddLayer((ghost.Owner, visibility), (int)VisibilityFlags.Normal, false); + _visibilitySystem.RefreshVisibility(ghost.Owner, visibility); + } + else + { + _visibilitySystem.AddLayer((ghost.Owner, visibility), (int)VisibilityFlags.Ghost, false); + _visibilitySystem.RemoveLayer((ghost.Owner, visibility), (int)VisibilityFlags.Normal, false); + _visibilitySystem.RefreshVisibility(ghost.Owner, visibility); + } + } + private void OnActionPerform(EntityUid uid, GhostComponent component, BooActionEvent args) { if (args.Handled) @@ -178,7 +205,7 @@ private void OnGhostStartup(EntityUid uid, GhostComponent component, ComponentSt // Allow this entity to be seen by other ghosts. var visibility = EnsureComp(uid); - if (_gameTicker.RunLevel != GameRunLevel.PostRound) + if (_gameTicker.RunLevel != GameRunLevel.PostRound && !component.Visible) { _visibilitySystem.AddLayer((uid, visibility), (int) VisibilityFlags.Ghost, false); _visibilitySystem.RemoveLayer((uid, visibility), (int) VisibilityFlags.Normal, false); @@ -198,7 +225,7 @@ private void OnGhostShutdown(EntityUid uid, GhostComponent component, ComponentS return; // Entity can't be seen by ghosts anymore. - if (TryComp(uid, out VisibilityComponent? visibility)) + if (TryComp(uid, out VisibilityComponent? visibility) && !component.Visible) { _visibilitySystem.RemoveLayer((uid, visibility), (int) VisibilityFlags.Ghost, false); _visibilitySystem.AddLayer((uid, visibility), (int) VisibilityFlags.Normal, false); @@ -244,24 +271,16 @@ private void OnGhostExamine(EntityUid uid, GhostComponent component, ExaminedEve private void OnMindRemovedMessage(EntityUid uid, GhostComponent component, MindRemovedMessage args) { - DeleteEntity(uid); + QueueDel(uid); } private void OnMindUnvisitedMessage(EntityUid uid, GhostComponent component, MindUnvisitedMessage args) { - DeleteEntity(uid); + QueueDel(uid); } private void OnPlayerDetached(EntityUid uid, GhostComponent component, PlayerDetachedEvent args) { - DeleteEntity(uid); - } - - private void DeleteEntity(EntityUid uid) - { - if (Deleted(uid) || Terminating(uid)) - return; - QueueDel(uid); } @@ -398,20 +417,10 @@ private void OnToggleGhostVisibilityToAll(ToggleGhostVisibilityToAllEvent ev) /// public void MakeVisible(bool visible) { - var entityQuery = EntityQueryEnumerator(); - while (entityQuery.MoveNext(out var uid, out _, out var vis)) + var entityQuery = EntityQueryEnumerator(); + while (entityQuery.MoveNext(out var uid, out var ghost)) { - if (visible) - { - _visibilitySystem.AddLayer((uid, vis), (int) VisibilityFlags.Normal, false); - _visibilitySystem.RemoveLayer((uid, vis), (int) VisibilityFlags.Ghost, false); - } - else - { - _visibilitySystem.AddLayer((uid, vis), (int) VisibilityFlags.Ghost, false); - _visibilitySystem.RemoveLayer((uid, vis), (int) VisibilityFlags.Normal, false); - } - _visibilitySystem.RefreshVisibility(uid, visibilityComponent: vis); + SetVisible((uid, ghost), visible); } } diff --git a/Content.Server/Revenant/EntitySystems/CorporealSystem.cs b/Content.Server/Revenant/EntitySystems/CorporealSystem.cs index 5f31a2f280a5a6..056174d012c39c 100644 --- a/Content.Server/Revenant/EntitySystems/CorporealSystem.cs +++ b/Content.Server/Revenant/EntitySystems/CorporealSystem.cs @@ -1,37 +1,8 @@ -using Content.Server.GameTicking; -using Content.Shared.Eye; -using Content.Shared.Revenant.Components; using Content.Shared.Revenant.EntitySystems; -using Robust.Server.GameObjects; namespace Content.Server.Revenant.EntitySystems; public sealed class CorporealSystem : SharedCorporealSystem { - [Dependency] private readonly VisibilitySystem _visibilitySystem = default!; - [Dependency] private readonly GameTicker _ticker = default!; - public override void OnStartup(EntityUid uid, CorporealComponent component, ComponentStartup args) - { - base.OnStartup(uid, component, args); - - if (TryComp(uid, out var visibility)) - { - _visibilitySystem.RemoveLayer((uid, visibility), (int) VisibilityFlags.Ghost, false); - _visibilitySystem.AddLayer((uid, visibility), (int) VisibilityFlags.Normal, false); - _visibilitySystem.RefreshVisibility(uid, visibility); - } - } - - public override void OnShutdown(EntityUid uid, CorporealComponent component, ComponentShutdown args) - { - base.OnShutdown(uid, component, args); - - if (TryComp(uid, out var visibility) && _ticker.RunLevel != GameRunLevel.PostRound) - { - _visibilitySystem.AddLayer((uid, visibility), (int) VisibilityFlags.Ghost, false); - _visibilitySystem.RemoveLayer((uid, visibility), (int) VisibilityFlags.Normal, false); - _visibilitySystem.RefreshVisibility(uid, visibility); - } - } } diff --git a/Content.Server/Revenant/EntitySystems/RevenantSystem.cs b/Content.Server/Revenant/EntitySystems/RevenantSystem.cs index 4cfceaf2974777..fdcceaa37a7854 100644 --- a/Content.Server/Revenant/EntitySystems/RevenantSystem.cs +++ b/Content.Server/Revenant/EntitySystems/RevenantSystem.cs @@ -1,7 +1,5 @@ using System.Numerics; using Content.Server.Actions; -using Content.Server.GameTicking; -using Content.Server.Store.Components; using Content.Server.Store.Systems; using Content.Shared.Alert; using Content.Shared.Damage; @@ -33,7 +31,6 @@ public sealed partial class RevenantSystem : EntitySystem [Dependency] private readonly AlertsSystem _alerts = default!; [Dependency] private readonly DamageableSystem _damage = default!; [Dependency] private readonly EntityLookupSystem _lookup = default!; - [Dependency] private readonly GameTicker _ticker = default!; [Dependency] private readonly MobStateSystem _mobState = default!; [Dependency] private readonly PhysicsSystem _physics = default!; [Dependency] private readonly SharedDoAfterSystem _doAfter = default!; @@ -44,7 +41,6 @@ public sealed partial class RevenantSystem : EntitySystem [Dependency] private readonly SharedStunSystem _stun = default!; [Dependency] private readonly StoreSystem _store = default!; [Dependency] private readonly TagSystem _tag = default!; - [Dependency] private readonly VisibilitySystem _visibility = default!; [ValidatePrototypeId] private const string RevenantShopId = "ActionRevenantShop"; @@ -61,7 +57,6 @@ public override void Initialize() SubscribeLocalEvent(OnExamine); SubscribeLocalEvent(OnStatusAdded); SubscribeLocalEvent(OnStatusEnded); - SubscribeLocalEvent(_ => MakeVisible(true)); InitializeAbilities(); } @@ -76,18 +71,9 @@ private void OnStartup(EntityUid uid, RevenantComponent component, ComponentStar _appearance.SetData(uid, RevenantVisuals.Harvesting, false); _appearance.SetData(uid, RevenantVisuals.Stunned, false); - if (_ticker.RunLevel == GameRunLevel.PostRound && TryComp(uid, out var visibility)) - { - _visibility.AddLayer((uid, visibility), (int) VisibilityFlags.Ghost, false); - _visibility.RemoveLayer((uid, visibility), (int) VisibilityFlags.Normal, false); - _visibility.RefreshVisibility(uid, visibility); - } - //ghost vision if (TryComp(uid, out EyeComponent? eye)) - { _eye.SetVisibilityMask(uid, eye.VisibilityMask | (int) (VisibilityFlags.Ghost), eye); - } } private void OnMapInit(EntityUid uid, RevenantComponent component, MapInitEvent args) @@ -185,25 +171,6 @@ private void OnShop(EntityUid uid, RevenantComponent component, RevenantShopActi _store.ToggleUi(uid, uid, store); } - public void MakeVisible(bool visible) - { - var query = EntityQueryEnumerator(); - while (query.MoveNext(out var uid, out _, out var vis)) - { - if (visible) - { - _visibility.AddLayer((uid, vis), (int) VisibilityFlags.Normal, false); - _visibility.RemoveLayer((uid, vis), (int) VisibilityFlags.Ghost, false); - } - else - { - _visibility.AddLayer((uid, vis), (int) VisibilityFlags.Ghost, false); - _visibility.RemoveLayer((uid, vis), (int) VisibilityFlags.Normal, false); - } - _visibility.RefreshVisibility(uid, vis); - } - } - public override void Update(float frameTime) { base.Update(frameTime); diff --git a/Content.Shared/Ghost/GhostComponent.cs b/Content.Shared/Ghost/GhostComponent.cs index 96e9b717b90084..53b1a298892100 100644 --- a/Content.Shared/Ghost/GhostComponent.cs +++ b/Content.Shared/Ghost/GhostComponent.cs @@ -82,12 +82,19 @@ public bool CanReturnToBody } } + /// + /// Whether or not the ghost should be visible by default. + /// The ghost will still always be visible if global ghost visibility is enabled in the ghost system. + /// + [DataField, AutoNetworkedField] + public bool Visible; + /// /// Ghost color /// /// Used to allow admins to change ghost colors. Should be removed if the capability to edit existing sprite colors is ever added back. - [DataField("color"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField] - public Color color = Color.White; + [DataField, AutoNetworkedField] + public Color Color = Color.White; [DataField("canReturnToBody"), AutoNetworkedField] private bool _canReturnToBody; diff --git a/Content.Shared/Ghost/SharedGhostSystem.cs b/Content.Shared/Ghost/SharedGhostSystem.cs index 6e62bee1310175..c5942b38482cba 100644 --- a/Content.Shared/Ghost/SharedGhostSystem.cs +++ b/Content.Shared/Ghost/SharedGhostSystem.cs @@ -57,6 +57,15 @@ public void SetCanReturnToBody(GhostComponent component, bool value) { component.CanReturnToBody = value; } + + public virtual void SetVisible(Entity ghost, bool visible) + { + if (!Resolve(ghost.Owner, ref ghost.Comp)) + return; + + ghost.Comp.Visible = visible; + Dirty(ghost); + } } /// diff --git a/Content.Shared/Revenant/Components/CorporealComponent.cs b/Content.Shared/Revenant/Components/CorporealComponent.cs index ee9c4924e9cd89..580f140d732068 100644 --- a/Content.Shared/Revenant/Components/CorporealComponent.cs +++ b/Content.Shared/Revenant/Components/CorporealComponent.cs @@ -1,5 +1,9 @@ +using Content.Shared.Eye; + namespace Content.Shared.Revenant.Components; +// TODO separate component +// Visibility, collision, and slowdown should be separate components /// /// Makes the target solid, visible, and applies a slowdown. /// Meant to be used in conjunction with statusEffectSystem @@ -12,4 +16,7 @@ public sealed partial class CorporealComponent : Component /// [ViewVariables(VVAccess.ReadWrite)] public float MovementSpeedDebuff = 0.66f; + + [DataField] + public bool MadeVisible; } diff --git a/Content.Shared/Revenant/EntitySystems/SharedCorporealSystem.cs b/Content.Shared/Revenant/EntitySystems/SharedCorporealSystem.cs index e86fdb8e80f334..6d329ca104731f 100644 --- a/Content.Shared/Revenant/EntitySystems/SharedCorporealSystem.cs +++ b/Content.Shared/Revenant/EntitySystems/SharedCorporealSystem.cs @@ -1,6 +1,8 @@ using Content.Shared.Physics; using Robust.Shared.Physics; using System.Linq; +using Content.Shared.Eye; +using Content.Shared.Ghost; using Content.Shared.Movement.Systems; using Content.Shared.Revenant.Components; using Robust.Shared.Physics.Systems; @@ -17,6 +19,7 @@ public abstract class SharedCorporealSystem : EntitySystem [Dependency] private readonly SharedAppearanceSystem _appearance = default!; [Dependency] private readonly MovementSpeedModifierSystem _movement = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!; + [Dependency] private readonly SharedGhostSystem _ghost = default!; public override void Initialize() { @@ -44,6 +47,12 @@ public virtual void OnStartup(EntityUid uid, CorporealComponent component, Compo _physics.SetCollisionLayer(uid, fixture.Key, fixture.Value, (int) CollisionGroup.SmallMobLayer, fixtures); } _movement.RefreshMovementSpeedModifiers(uid); + + if (!TryComp(uid, out GhostComponent? ghost) || ghost.Visible) + return; + + component.MadeVisible = true; + _ghost.SetVisible((uid, ghost), true); } public virtual void OnShutdown(EntityUid uid, CorporealComponent component, ComponentShutdown args) @@ -59,5 +68,8 @@ public virtual void OnShutdown(EntityUid uid, CorporealComponent component, Comp } component.MovementSpeedDebuff = 1; //just so we can avoid annoying code elsewhere _movement.RefreshMovementSpeedModifiers(uid); + + if (component.MadeVisible && TryComp(uid, out GhostComponent? ghost)) + _ghost.SetVisible((uid, ghost), false); } }