using System.Linq; using GameCore.Attributes; using GameCore.Combat; using GameCore.Combat.Effects; using GameCore.ECS; using GameCore.ECS.Interfaces; using GameCore.Events; using GameCore.Interaction; using GameCore.Inventory; using GameCore.Player; using Godot; namespace CryptonymThunder.Code.Presenters; [GlobalClass] public partial class HudPresenterComponent : Control, IPresenterComponent { private World _world; private Entity _playerEntity; private AttributeComponent _playerAttributes; private EquipmentComponent _playerEquipment; private InventoryComponent _playerInventory; [Export] private Label _healthLabel; [Export] private Label _ammoLabel; [Export] private Label _weaponLabel; [Export] private Label _interactLabel; private string _currentAmmoId; public void Initialize(Entity coreEntity, World world) { _world = world; _playerEntity = coreEntity; _playerAttributes = world.GetComponent(_playerEntity); _playerEquipment = world.GetComponent(_playerEntity); _playerInventory = world.GetComponent(_playerEntity); if (_playerAttributes != null) { _playerAttributes.OnAttributeChanged += OnAttributeChanged; OnAttributeChanged(Attribute.Health, _playerAttributes.GetValue(Attribute.Health)); } _world.Subscribe(OnEntityDamaged); _world.Subscribe(OnEntityHealed); _world.Subscribe(OnInventoryChanged); _world.Subscribe(OnWeaponEquipped); if (_interactLabel != null) { _interactLabel.Visible = false; } } private void OnWeaponEquipped(WeaponEquippedEvent e) { if (!e.Owner.Equals(_playerEntity)) return; _weaponLabel.Text = e.NewWeaponItemId; _currentAmmoId = null; var playerWeapon = _world.GetComponent(_playerEntity); var ammoCost = playerWeapon?.FireCosts .OfType() .FirstOrDefault(); if (ammoCost != null) { _currentAmmoId = ammoCost.AmmoId; } _world.Logger.Info($"Current ammo ID set to {_currentAmmoId}"); if (_currentAmmoId != null) { var ammoCount = _playerInventory.GetItemCount(_currentAmmoId); _ammoLabel.Text = $"Ammo: {ammoCount}"; } else { _ammoLabel.Text = "Ammo: --"; } } private void OnInventoryChanged(InventoryItemChangedEvent e) { if (!e.Owner.Equals(_playerEntity)) return; _world.Logger.Info($"Inventory changed: {e.ItemId} new quantity: {e.NewQuantity}"); if (e.ItemId == _currentAmmoId) { _ammoLabel.Text = $"Ammo: {e.NewQuantity}"; } } private void OnEntityHealed(EntityHealedEvent e) { if (!e.Target.Equals(_playerEntity)) return; _world.Logger.Info($"Player healed {e.AmountHealed}, new health: {e.NewHealth}"); } private void OnEntityDamaged(EntityDamagedEvent e) { if (!e.Target.Equals(_playerEntity)) return; _world.Logger.Info($"Player took {e.DamageTaken} damage, new health: {e.NewHealth}"); } private void OnAttributeChanged(Attribute attr, float newValue) { if (attr == Attribute.Health) { _healthLabel.Text = $"Health: {Mathf.CeilToInt(newValue)}"; } } public void SyncToPresentation(float delta) { if (_interactLabel != null) { var lookingAt = _world.GetComponent(_playerEntity); if (lookingAt != null) { var targetEntity = lookingAt.Target; var interactKey = "F"; var door = _world.GetComponent(targetEntity); if (door != null) { _interactLabel.Text = door.CurrentState switch { DoorComponent.DoorState.Locked => $"[{interactKey}] Interact (Locked)", DoorComponent.DoorState.Closed => $"[{interactKey}] Open Door", DoorComponent.DoorState.Open => $"[{interactKey}] Close Door", _ => "" }; _interactLabel.Visible = !string.IsNullOrEmpty(_interactLabel.Text); } else { var button = _world.GetComponent(targetEntity); if (button != null) { if (button.IsOneTimeUse && button.HasBeenUsed) { _interactLabel.Text = "(Used)"; } else if (button.IsToggle) { _interactLabel.Text = button.IsPressed ? $"[{interactKey}] Deactivate" : $"[{interactKey}] Activate"; } else { _interactLabel.Text = $"[{interactKey}] Press Button"; } _interactLabel.Visible = true; } else { _interactLabel.Visible = false; } } } else { _interactLabel.Visible = false; } } } public void SyncToCore(float delta) { } }