using Content.Shared.GameTicking; using Content.Shared.Inventory; using Content.Shared.Inventory.Events; using Robust.Client.GameObjects; using Robust.Client.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!; 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(EntityUid uid, T component, ComponentStartup args) { RefreshOverlay(uid); } private void OnRemove(EntityUid uid, T component, ComponentRemove args) { RefreshOverlay(uid); } private void OnPlayerAttached(PlayerAttachedEvent args) { RefreshOverlay(args.Entity); } private void OnPlayerDetached(PlayerDetachedEvent args) { if (_player.LocalPlayer?.ControlledEntity == null) Deactivate(); } private void OnCompEquip(EntityUid uid, T component, GotEquippedEvent args) { RefreshOverlay(args.Equipee); } private void OnCompUnequip(EntityUid uid, T component, GotUnequippedEvent args) { RefreshOverlay(args.Equipee); } private void OnRoundRestart(RoundRestartCleanupEvent args) { Deactivate(); } protected virtual void OnRefreshEquipmentHud(EntityUid uid, T component, InventoryRelayedEvent> args) { args.Args.Active = true; } protected virtual void OnRefreshComponentHud(EntityUid uid, T component, RefreshEquipmentHudEvent args) { args.Active = true; } private void RefreshOverlay(EntityUid uid) { if (uid != _player.LocalPlayer?.ControlledEntity) return; var ev = new RefreshEquipmentHudEvent(TargetSlots); RaiseLocalEvent(uid, ev); if (ev.Active) Update(ev); else Deactivate(); } }