using Content.Shared.GameTicking; using Content.Shared.Inventory; using Content.Shared.Inventory.Events; using Robust.Client.Player; using Robust.Shared.Player; namespace Content.Client.Overlays; /// /// This is a base system to make it easier to enable or disabling UI elements based on whether or not the player has /// some component, either on their controlled entity on some worn piece of equipment. /// public abstract class EquipmentHudSystem : EntitySystem where T : IComponent { [Dependency] private readonly IPlayerManager _player = default!; [ViewVariables] protected bool IsActive; protected virtual SlotFlags TargetSlots => ~SlotFlags.POCKET; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnStartup); SubscribeLocalEvent(OnRemove); SubscribeLocalEvent(OnPlayerAttached); SubscribeLocalEvent(OnPlayerDetached); SubscribeLocalEvent(OnCompEquip); SubscribeLocalEvent(OnCompUnequip); SubscribeLocalEvent>(OnRefreshComponentHud); SubscribeLocalEvent>>(OnRefreshEquipmentHud); SubscribeLocalEvent(OnRoundRestart); } private void Update(RefreshEquipmentHudEvent ev) { IsActive = true; UpdateInternal(ev); } public void Deactivate() { if (!IsActive) return; IsActive = false; DeactivateInternal(); } protected virtual void UpdateInternal(RefreshEquipmentHudEvent args) { } protected virtual void DeactivateInternal() { } private void OnStartup(Entity ent, ref ComponentStartup args) { RefreshOverlay(); } private void OnRemove(Entity ent, ref ComponentRemove args) { RefreshOverlay(); } private void OnPlayerAttached(LocalPlayerAttachedEvent args) { RefreshOverlay(); } private void OnPlayerDetached(LocalPlayerDetachedEvent args) { if (_player.LocalSession?.AttachedEntity is null) Deactivate(); } private void OnCompEquip(Entity ent, ref GotEquippedEvent args) { RefreshOverlay(); } private void OnCompUnequip(Entity ent, ref GotUnequippedEvent args) { RefreshOverlay(); } private void OnRoundRestart(RoundRestartCleanupEvent args) { Deactivate(); } protected virtual void OnRefreshEquipmentHud(Entity ent, ref InventoryRelayedEvent> args) { OnRefreshComponentHud(ent, ref args.Args); } protected virtual void OnRefreshComponentHud(Entity ent, ref RefreshEquipmentHudEvent args) { args.Active = true; args.Components.Add(ent.Comp); } protected void RefreshOverlay() { if (_player.LocalSession?.AttachedEntity is not { } entity) return; var ev = new RefreshEquipmentHudEvent(TargetSlots); RaiseLocalEvent(entity, ref ev); if (ev.Active) Update(ev); else Deactivate(); } }