Add HUD presenter component and player HUD scene for health and ammo display

This commit is contained in:
2025-10-29 02:59:02 +01:00
parent 853378c9c6
commit 9c0cd3f549
5 changed files with 173 additions and 1 deletions

View File

@@ -0,0 +1,121 @@
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.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;
private string _currentAmmoId;
public void Initialize(Entity coreEntity, World world)
{
_world = world;
_playerEntity = coreEntity;
_playerAttributes = world.GetComponent<AttributeComponent>(_playerEntity);
_playerEquipment = world.GetComponent<EquipmentComponent>(_playerEntity);
_playerInventory = world.GetComponent<InventoryComponent>(_playerEntity);
if (_playerAttributes != null)
{
_playerAttributes.OnAttributeChanged += OnAttributeChanged;
OnAttributeChanged(Attribute.Health, _playerAttributes.GetValue(Attribute.Health));
}
_world.Subscribe<EntityDamagedEvent>(OnEntityDamaged);
_world.Subscribe<EntityHealedEvent>(OnEntityHealed);
_world.Subscribe<InventoryItemChangedEvent>(OnInventoryChanged);
_world.Subscribe<WeaponEquippedEvent>(OnWeaponEquipped);
}
private void OnWeaponEquipped(WeaponEquippedEvent e)
{
if (!e.Owner.Equals(_playerEntity)) return;
_weaponLabel.Text = e.NewWeaponItemId;
_currentAmmoId = null;
var playerWeapon = _world.GetComponent<WeaponComponent>(_playerEntity);
var ammoCost = playerWeapon?.FireCosts
.OfType<ConsumeAmmoCost>()
.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)
{
}
public void SyncToCore(float delta)
{
}
}

View File

@@ -0,0 +1 @@
uid://c6nouigv5wsu1