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; /// /// Manages the directional visibility overlay for wall-mounted entities. /// 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!; [Dependency] private EntityQuery _spriteQuery; [Dependency] private EntityQuery _wallQuery; private WallMountVisibilityOverlay _overlayInstance = default!; /// /// Whether directional visibility is currently enabled. /// public bool DirectionalVisibilityEnabled = true; /// /// Whether wall-mount visibility changes fade smoothly or snap instantly. /// 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; } /// /// Makes the entity visible again on component shutdown. /// [SubscribeLocalEvent] private void OnWallMountShutdown(Entity ent, ref ComponentShutdown args) { if (TerminatingOrDeleted(ent)) return; if (!_spriteQuery.TryComp(ent, out var sprite)) return; _sprite.SetVisible((ent, sprite), true); } /// /// Makes the entity visible again if directional visibility is disabled for this mount. /// [SubscribeLocalEvent] private void OnWallMountAfterHandleState(Entity ent, ref AfterAutoHandleStateEvent args) { if (ent.Comp.DirectionalVisibility) return; if (!_spriteQuery.TryComp(ent, out var sprite)) return; _sprite.SetVisible((ent, sprite), true); } /// /// Checks whether the tile contains any anchored blocking entity. /// public bool IsTileBlocked(Entity grid, Vector2i tile) { var enumerator = _map.GetAnchoredEntities(grid.Owner, grid, tile); while (enumerator.MoveNext(out var anchored)) { if (!_wallQuery.HasComp(anchored.Value)) continue; return true; } return false; } }