Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ghost visibility #34474

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions Content.Client/Ghost/GhostSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -32,9 +32,9 @@ private bool GhostVisibility
_ghostVisibility = value;

var query = AllEntityQuery<GhostComponent, SpriteComponent>();
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));
}
}
}
Expand Down Expand Up @@ -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<GhostComponent?, SpriteComponent?> 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)
Expand Down Expand Up @@ -130,7 +137,9 @@ private void OnGhostPlayerAttach(EntityUid uid, GhostComponent component, LocalP
private void OnGhostState(EntityUid uid, GhostComponent component, ref AfterAutoHandleStateEvent args)
{
if (TryComp<SpriteComponent>(uid, out var sprite))
sprite.LayerSetColor(0, component.color);
sprite.LayerSetColor(0, component.Color);

UpdateVisibility((uid, component, null));

if (uid != _playerManager.LocalEntity)
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,7 @@ public void Execute(IConsoleShell shell, string argStr, string[] args)
return;
}

var ghostSys = _entities.EntitySysManager.GetEntitySystem<GhostSystem>();
var revSys = _entities.EntitySysManager.GetEntitySystem<RevenantSystem>();

ghostSys.MakeVisible(visible);
revSys.MakeVisible(visible);
_entities.System<GhostSystem>().MakeVisible(visible);
}
}
}
59 changes: 34 additions & 25 deletions Content.Server/Ghost/GhostSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,33 @@ private void OnGhostHearingAction(EntityUid uid, GhostComponent component, Toggl
Dirty(uid, component);
}

public override void SetVisible(Entity<GhostComponent?> 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)
Expand Down Expand Up @@ -178,7 +205,7 @@ private void OnGhostStartup(EntityUid uid, GhostComponent component, ComponentSt
// Allow this entity to be seen by other ghosts.
var visibility = EnsureComp<VisibilityComponent>(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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -398,20 +417,10 @@ private void OnToggleGhostVisibilityToAll(ToggleGhostVisibilityToAllEvent ev)
/// </summary>
public void MakeVisible(bool visible)
{
var entityQuery = EntityQueryEnumerator<GhostComponent, VisibilityComponent>();
while (entityQuery.MoveNext(out var uid, out _, out var vis))
var entityQuery = EntityQueryEnumerator<GhostComponent>();
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);
}
}

Expand Down
29 changes: 0 additions & 29 deletions Content.Server/Revenant/EntitySystems/CorporealSystem.cs
Original file line number Diff line number Diff line change
@@ -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<VisibilityComponent>(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<VisibilityComponent>(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);
}
}
}
33 changes: 0 additions & 33 deletions Content.Server/Revenant/EntitySystems/RevenantSystem.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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!;
Expand All @@ -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<EntityPrototype>]
private const string RevenantShopId = "ActionRevenantShop";
Expand All @@ -61,7 +57,6 @@ public override void Initialize()
SubscribeLocalEvent<RevenantComponent, ExaminedEvent>(OnExamine);
SubscribeLocalEvent<RevenantComponent, StatusEffectAddedEvent>(OnStatusAdded);
SubscribeLocalEvent<RevenantComponent, StatusEffectEndedEvent>(OnStatusEnded);
SubscribeLocalEvent<RoundEndTextAppendEvent>(_ => MakeVisible(true));

InitializeAbilities();
}
Expand All @@ -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<VisibilityComponent>(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)
Expand Down Expand Up @@ -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<RevenantComponent, VisibilityComponent>();
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);
Expand Down
11 changes: 9 additions & 2 deletions Content.Shared/Ghost/GhostComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,19 @@ public bool CanReturnToBody
}
}

/// <summary>
/// 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.
/// </summary>
[DataField, AutoNetworkedField]
public bool Visible;

/// <summary>
/// Ghost color
/// </summary>
/// <remarks>Used to allow admins to change ghost colors. Should be removed if the capability to edit existing sprite colors is ever added back.</remarks>
[DataField("color"), ViewVariables(VVAccess.ReadWrite), AutoNetworkedField]
public Color color = Color.White;
[DataField, AutoNetworkedField]
public Color Color = Color.White;

[DataField("canReturnToBody"), AutoNetworkedField]
private bool _canReturnToBody;
Expand Down
9 changes: 9 additions & 0 deletions Content.Shared/Ghost/SharedGhostSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ public void SetCanReturnToBody(GhostComponent component, bool value)
{
component.CanReturnToBody = value;
}

public virtual void SetVisible(Entity<GhostComponent?> ghost, bool visible)
{
if (!Resolve(ghost.Owner, ref ghost.Comp))
return;

ghost.Comp.Visible = visible;
Dirty(ghost);
}
}

/// <summary>
Expand Down
7 changes: 7 additions & 0 deletions Content.Shared/Revenant/Components/CorporealComponent.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
using Content.Shared.Eye;

namespace Content.Shared.Revenant.Components;

// TODO separate component
// Visibility, collision, and slowdown should be separate components
/// <summary>
/// Makes the target solid, visible, and applies a slowdown.
/// Meant to be used in conjunction with statusEffectSystem
Expand All @@ -12,4 +16,7 @@ public sealed partial class CorporealComponent : Component
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float MovementSpeedDebuff = 0.66f;

[DataField]
public bool MadeVisible;
}
12 changes: 12 additions & 0 deletions Content.Shared/Revenant/EntitySystems/SharedCorporealSystem.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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()
{
Expand Down Expand Up @@ -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)
Expand All @@ -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);
}
}
Loading