forge friendlier health and damage management

Removed knockback though
This commit is contained in:
2026-04-28 11:22:24 +02:00
parent dcfd937e53
commit ec44306d48
24 changed files with 776 additions and 490 deletions

View File

@@ -1,9 +1,13 @@
using System;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Gamesmiths.Forge.Abilities;
using Gamesmiths.Forge.Core;
using Gamesmiths.Forge.Effects;
using Gamesmiths.Forge.Events;
using Gamesmiths.Forge.Godot.Core;
using Gamesmiths.Forge.Godot.Nodes;
using Gamesmiths.Forge.Godot.Resources.Abilities;
using Gamesmiths.Forge.Statescript;
using Gamesmiths.Forge.Tags;
using Godot;
@@ -14,10 +18,9 @@ using Movementtests.systems;
using Movementtests.tools;
using Node = Godot.Node;
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_beetle.png")]
[GlobalClass, Icon("res://assets/ui/IconGodotNode/node_3D/icon_beetle.png"), Meta(typeof(IAutoOn), typeof(IAutoConnect))]
public partial class Enemy : CharacterBody3D,
IDamageable,
IDamageDealer,
IHealthable,
IKillable,
IMoveable,
@@ -27,14 +30,16 @@ public partial class Enemy : CharacterBody3D,
IStunnable,
IForgeEntity
{
// Signals and events
public event Action<IDamageable, DamageRecord> DamageTaken = null!;
public override void _Notification(int what) => this.Notify(what);
// Signals and events
public event Action<IDamageable, DamageRecord> DamageTaken = null!;
public event Action<IHealthable, HealthChangedRecord> HealthChanged = null!;
public event Action<IHealthable> HealthDepleted = null!;
// Public export components
[Export]
public Node3D Target { get; set; } = null!;
public Node3D? Target { get; set; }
[Export]
public float EnemyHeight { get; set; } = 1f;
@@ -48,16 +53,16 @@ public partial class Enemy : CharacterBody3D,
[ExportGroup("Damage")]
[Export]
public RDamage RDamage { get; set; } = null!;
public RDamage? RDamage { get; set; }
public IDamageable CDamageable { get; set; } = null!;
[Export]
public RKnockback RKnockback { get; set; } = null!;
public RKnockback? RKnockback { get; set; }
public IKnockbackable CKnockback { get; set; } = null!;
[ExportGroup("Movement")]
[Export]
public RMovement RMovement { get; set; } = null!;
public RMovement? RMovement { get; set; }
public IMoveable CMovement { get; set; } = null!;
// Public stuff
@@ -93,13 +98,15 @@ public partial class Enemy : CharacterBody3D,
get => _forgeEntity.Events;
set => _forgeEntity.Events = value;
}
[Export] public ForgeAbilityData? HitAbility;
public Variables SharedVariables { get; }
// Private stuff
private Area3D _damageBox = null!;
internal Node3D _target = null!;
private Healthbar _healthbar = null!;
private ResourceBar _resourceBar = null!;
private ForgeEntity _forgeEntity;
public override void _Ready()
@@ -107,6 +114,8 @@ public partial class Enemy : CharacterBody3D,
Initialize();
SetupSignals();
}
private AbilityHandle? _hitAbilityHandle;
public void Initialize()
{
@@ -119,14 +128,18 @@ public partial class Enemy : CharacterBody3D,
CHealth = (GetNode<Node>("CHealth") as IHealthable)!;
CKnockback = (GetNode<Node>("CKnockback") as IKnockbackable)!;
_healthbar = GetNode<CHealthbar>("CHealthBar").Healthbar;
_resourceBar = GetNode<CHealthbar>("CHealthBar").ResourceBar;
CMovement.RMovement = RMovement;
CHealth.RHealth = RHealth;
CHealth.CurrentHealth = RHealth.StartingHealth;
CKnockback.RKnockback = RKnockback;
_healthbar.Initialize(CHealth.CurrentHealth);
if (HitAbility != null)
_hitAbilityHandle = Abilities.GrantAbilityPermanently(HitAbility.GetAbilityData(), 1, LevelComparison.None, this);
Events.Subscribe(Tag.RequestTag(ForgeManagers.Instance.TagsManager, "events.combat.hit"),
data => {});
}
public void SetupSignals()
@@ -135,7 +148,7 @@ public partial class Enemy : CharacterBody3D,
CDamageable.DamageTaken += (source, record) => ReduceHealth(source, record);
CDamageable.DamageTaken += (_, record) => RegisterKnockback(new KnockbackRecord(record));
CHealth.HealthDepleted += Kill;
HealthChanged += (_, record) => _healthbar.SetHealth(record.CurrentHealth);
HealthChanged += (_, record) => _resourceBar.SetValue(record.CurrentHealth);
}
public override void _PhysicsProcess(double delta)
@@ -160,13 +173,19 @@ public partial class Enemy : CharacterBody3D,
public void ProcessGameplay(double delta)
{
if (IsStunned) return;
if (IsStunned || _hitAbilityHandle == null) return;
var bodies = _damageBox.GetOverlappingBodies();
foreach (var body in bodies)
{
if(body is IDamageable spawnable)
spawnable.TakeDamage(new DamageRecord(GlobalPosition, RDamage));
if (body is not IForgeEntity forgeEntity) continue;
var canActivate = _hitAbilityHandle.CanActivate(out var _);
if (!canActivate) return;
_hitAbilityHandle.Activate(out var _, forgeEntity);
// if(body is IDamageable spawnable)
// spawnable.TakeDamage(new DamageRecord(GlobalPosition, RDamage));
}
}