using Content.Shared.CCVar; using Content.Shared.Ghost; using Content.Shared.StatusIcon; using Content.Shared.StatusIcon.Components; using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Client.Player; using Robust.Shared.Configuration; namespace Content.Client.StatusIcon; /// /// This handles rendering gathering and rendering icons on entities. /// public sealed class StatusIconSystem : SharedStatusIconSystem { [Dependency] private readonly IConfigurationManager _configuration = default!; [Dependency] private readonly IOverlayManager _overlay = default!; [Dependency] private readonly IPlayerManager _playerMan = default!; private EntityQuery _ghostQuery; private EntityQuery _spriteQuery; private bool _globalEnabled; private bool _localEnabled; /// public override void Initialize() { _ghostQuery = GetEntityQuery(); _spriteQuery = GetEntityQuery(); Subs.CVar(_configuration, CCVars.LocalStatusIconsEnabled, OnLocalStatusIconChanged, true); Subs.CVar(_configuration, CCVars.GlobalStatusIconsEnabled, OnGlobalStatusIconChanged, true); } private void OnLocalStatusIconChanged(bool obj) { _localEnabled = obj; UpdateOverlayVisible(); } private void OnGlobalStatusIconChanged(bool obj) { _globalEnabled = obj; UpdateOverlayVisible(); } private void UpdateOverlayVisible() { if (_overlay.RemoveOverlay()) return; if (_globalEnabled && _localEnabled) _overlay.AddOverlay(new StatusIconOverlay()); } public List GetStatusIcons(EntityUid uid, MetaDataComponent? meta = null) { var list = new List(); if (!Resolve(uid, ref meta)) return list; if (meta.EntityLifeStage >= EntityLifeStage.Terminating) return list; var inContainer = (meta.Flags & MetaDataFlags.InContainer) != 0; var ev = new GetStatusIconsEvent(list, inContainer); RaiseLocalEvent(uid, ref ev); return ev.StatusIcons; } /// /// For overlay to check if an entity can be seen. /// public bool IsVisible(EntityUid uid) { // ghosties can always see them var viewer = _playerMan.LocalSession?.AttachedEntity; if (_ghostQuery.HasComponent(viewer)) return true; if (_spriteQuery.TryGetComponent(uid, out var sprite) && !sprite.Visible) return false; var ev = new StatusIconVisibleEvent(true); RaiseLocalEvent(uid, ref ev); return ev.Visible; } } /// /// Raised on an entity to check if it should draw hud icons. /// Used to check invisibility etc inside the screen bounds. /// [ByRefEvent] public record struct StatusIconVisibleEvent(bool Visible);