Add HUD presenter component and player HUD scene for health and ammo display
This commit is contained in:
121
Code/Presenters/HudPresenterComponent.cs
Normal file
121
Code/Presenters/HudPresenterComponent.cs
Normal 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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
1
Code/Presenters/HudPresenterComponent.cs.uid
Normal file
1
Code/Presenters/HudPresenterComponent.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://c6nouigv5wsu1
|
||||||
46
Objects/UI/player_hud.tscn
Normal file
46
Objects/UI/player_hud.tscn
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://b36xmciamjyc0"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://c6nouigv5wsu1" path="res://Code/Presenters/HudPresenterComponent.cs" id="1_yd76s"]
|
||||||
|
|
||||||
|
[node name="PlayerHUD" type="Control" node_paths=PackedStringArray("_healthLabel", "_ammoLabel", "_weaponLabel")]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_yd76s")
|
||||||
|
_healthLabel = NodePath("MarginContainer/HBoxContainer/HealthLabel")
|
||||||
|
_ammoLabel = NodePath("MarginContainer/HBoxContainer/AmmoLabel")
|
||||||
|
_weaponLabel = NodePath("MarginContainer/HBoxContainer/WeaponLabel")
|
||||||
|
metadata/_custom_type_script = "uid://c6nouigv5wsu1"
|
||||||
|
|
||||||
|
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
theme_override_constants/margin_left = 8
|
||||||
|
theme_override_constants/margin_top = 8
|
||||||
|
theme_override_constants/margin_right = 8
|
||||||
|
theme_override_constants/margin_bottom = 8
|
||||||
|
|
||||||
|
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="HealthLabel" type="Label" parent="MarginContainer/HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "health 100"
|
||||||
|
uppercase = true
|
||||||
|
|
||||||
|
[node name="AmmoLabel" type="Label" parent="MarginContainer/HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "ammo 100"
|
||||||
|
uppercase = true
|
||||||
|
|
||||||
|
[node name="WeaponLabel" type="Label" parent="MarginContainer/HBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "gun"
|
||||||
|
uppercase = true
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
[gd_scene load_steps=5 format=3 uid="uid://c576jiewfs5gj"]
|
[gd_scene load_steps=6 format=3 uid="uid://c576jiewfs5gj"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://hkiny1ftv4r7" path="res://Code/Presenters/CharacterBody3DPresenter.cs" id="2_3y5cq"]
|
[ext_resource type="Script" uid="uid://hkiny1ftv4r7" path="res://Code/Presenters/CharacterBody3DPresenter.cs" id="2_3y5cq"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://b36xmciamjyc0" path="res://Objects/UI/player_hud.tscn" id="3_0ad8t"]
|
||||||
[ext_resource type="Script" uid="uid://crx03e8buoni3" path="res://Code/Presenters/CameraPresenterComponent.cs" id="3_2i4gt"]
|
[ext_resource type="Script" uid="uid://crx03e8buoni3" path="res://Code/Presenters/CameraPresenterComponent.cs" id="3_2i4gt"]
|
||||||
|
|
||||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_y0qk3"]
|
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_y0qk3"]
|
||||||
@@ -26,3 +27,5 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5901337, 0)
|
|||||||
script = ExtResource("3_2i4gt")
|
script = ExtResource("3_2i4gt")
|
||||||
|
|
||||||
[node name="Camera3D" type="Camera3D" parent="CameraPivot"]
|
[node name="Camera3D" type="Camera3D" parent="CameraPivot"]
|
||||||
|
|
||||||
|
[node name="PlayerHUD" parent="." instance=ExtResource("3_0ad8t")]
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ project/assembly_name="cryptonym-thunder"
|
|||||||
folder_colors={
|
folder_colors={
|
||||||
"res://Code/": "blue",
|
"res://Code/": "blue",
|
||||||
"res://Objects/": "orange",
|
"res://Objects/": "orange",
|
||||||
|
"res://Objects/UI/": "green",
|
||||||
"res://Scenes/": "green"
|
"res://Scenes/": "green"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user