177 lines
5.7 KiB
C#
177 lines
5.7 KiB
C#
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<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);
|
|
|
|
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<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)
|
|
{
|
|
if (_interactLabel != null)
|
|
{
|
|
var lookingAt = _world.GetComponent<IsLookingAtInteractableComponent>(_playerEntity);
|
|
if (lookingAt != null)
|
|
{
|
|
var targetEntity = lookingAt.Target;
|
|
var interactKey = "F";
|
|
|
|
var door = _world.GetComponent<DoorComponent>(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<ButtonComponent>(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)
|
|
{
|
|
}
|
|
} |