CatStation/Content.Client/Wall/Systems/WallMountVisibilitySystem.cs
B_Kirill 6938064aa5
Directional visibility for wall-mounted entities 2 (#44801)
* Directional visibility for wall-mounted entities (#43476)

* Directional visibility for wall-mounted entities

* Fix cache

* Revert

* InteractionIgnoreAnchoredInTileComponent + yml

* Main system

* Move it

* Directional arrow

* Add fade

* retry

* Split "Directional arrow"

* fix

* small thing

* Split "InteractionIgnoreAnchoredInTileComponent"

* correct description

* I hate the online editor

* retry

* ...

* Apply suggestions from code review

Co-authored-by: Jessica M <jessica@jessicamaybe.com>

* Additional comment

* cleanup

---------

Co-authored-by: Jessica M <jessica@jessicamaybe.com>
Co-authored-by: AJCM-git <ajcm_mail@disroot.org>

* 2

* Kinda useless

* Fade CVar

* Fix CVar runtime change

* Clear _originalAlphas on dispose

* Boring DI

* retry

* WallComponent

---------

Co-authored-by: Jessica M <jessica@jessicamaybe.com>
Co-authored-by: AJCM-git <ajcm_mail@disroot.org>
2026-07-30 19:40:53 +00:00

112 lines
3.2 KiB
C#

using Content.Shared.CCVar;
using Content.Shared.Wall;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Shared.Configuration;
using Robust.Shared.Map.Components;
namespace Content.Client.Wall.Systems;
/// <summary>
/// Manages the directional visibility overlay for wall-mounted entities.
/// </summary>
public sealed partial class WallMountVisibilitySystem : EntitySystem
{
[Dependency] private IConfigurationManager _cfg = default!;
[Dependency] private IOverlayManager _overlay = default!;
[Dependency] private SharedMapSystem _map = default!;
[Dependency] private SpriteSystem _sprite = default!;
private WallMountVisibilityOverlay _overlayInstance = default!;
/// <summary>
/// Whether directional visibility is currently enabled.
/// </summary>
public bool DirectionalVisibilityEnabled = true;
/// <summary>
/// Whether wall-mount visibility changes fade smoothly or snap instantly.
/// </summary>
public bool FadeEnabled = true;
public override void Initialize()
{
base.Initialize();
_overlayInstance = new WallMountVisibilityOverlay();
Subs.CVar(_cfg, CCVars.WallMountDirectionalVisibility, OnDirectionalVisibilityChanged, true);
Subs.CVar(_cfg, CCVars.WallMountFade, OnFadeChanged, true);
}
public override void Shutdown()
{
base.Shutdown();
_overlay.RemoveOverlay(_overlayInstance);
}
private void OnDirectionalVisibilityChanged(bool enabled)
{
DirectionalVisibilityEnabled = enabled;
if (enabled)
_overlay.AddOverlay(_overlayInstance);
else
{
_overlay.RemoveOverlay(_overlayInstance);
_overlayInstance.RestoreAll();
}
}
private void OnFadeChanged(bool enabled)
{
FadeEnabled = enabled;
}
/// <summary>
/// Makes the entity visible again on component shutdown.
/// </summary>
[SubscribeLocalEvent]
private void OnWallMountShutdown(Entity<WallMountComponent> ent, ref ComponentShutdown args)
{
if (TerminatingOrDeleted(ent))
return;
if (!TryComp<SpriteComponent>(ent, out var sprite))
return;
_sprite.SetVisible((ent, sprite), true);
}
/// <summary>
/// Makes the entity visible again if directional visibility is disabled for this mount.
/// </summary>
[SubscribeLocalEvent]
private void OnWallMountAfterHandleState(Entity<WallMountComponent> ent, ref AfterAutoHandleStateEvent args)
{
if (ent.Comp.DirectionalVisibility)
return;
if (!TryComp<SpriteComponent>(ent, out var sprite))
return;
_sprite.SetVisible((ent, sprite), true);
}
/// <summary>
/// Checks whether the tile contains any anchored blocking entity.
/// </summary>
public bool IsTileBlocked(Entity<MapGridComponent> grid, Vector2i tile)
{
var enumerator = _map.GetAnchoredEntitiesEnumerator(grid.Owner, grid, tile);
while (enumerator.MoveNext(out var anchored))
{
if (!HasComp<WallComponent>(anchored.Value))
continue;
return true;
}
return false;
}
}