knockback component
This commit is contained in:
@@ -3,37 +3,53 @@ using Godot;
|
||||
using Movementtests.interfaces;
|
||||
|
||||
[GlobalClass]
|
||||
public partial class Enemy : CharacterBody3D, IDamageable, IDamageMaker, IHealthable, IKillable, IMoveable, ISpawnable
|
||||
public partial class Enemy : CharacterBody3D,
|
||||
IDamageable,
|
||||
IDamageDealer,
|
||||
IHealthable,
|
||||
IKillable,
|
||||
IMoveable,
|
||||
ISpawnable,
|
||||
IKnockbackable
|
||||
{
|
||||
public event Action<IDamageable, float> DamageTaken;
|
||||
// Signals and events
|
||||
public event Action<IDamageable, DamageRecord> DamageTaken;
|
||||
public event Action<IHealthable, float> HealthChanged;
|
||||
public event Action<IHealthable> HealthDepleted;
|
||||
|
||||
// Public export components
|
||||
[Export]
|
||||
public Node3D Target { get; set; }
|
||||
|
||||
[ExportGroup("Health")]
|
||||
[Export]
|
||||
public Node CHealth { get; set; }
|
||||
[Export]
|
||||
public RHealth RHealth { get; set; }
|
||||
|
||||
public float CurrentHealth { get; set; }
|
||||
|
||||
[Export]
|
||||
public RDeathEffect[] DeathEffects { get; set; }
|
||||
|
||||
[ExportGroup("Damage")]
|
||||
[Export]
|
||||
public Node CDamage { get; set; }
|
||||
|
||||
[Export]
|
||||
public RDamage RDamage { get; set; }
|
||||
[Export]
|
||||
public Node CKnockback { get; set; }
|
||||
[Export]
|
||||
public RKnockback RKnockback { get; set; }
|
||||
|
||||
[ExportGroup("Movement")]
|
||||
[Export]
|
||||
public Node CMovement { get; set; }
|
||||
[Export]
|
||||
public RMovement RMovement { get; set; }
|
||||
|
||||
|
||||
[Export]
|
||||
public RDeathEffect[] DeathEffects { get; set; }
|
||||
|
||||
// Public stuff
|
||||
public float CurrentHealth { get; set; }
|
||||
|
||||
// Private stuff
|
||||
private Area3D _damageBox;
|
||||
|
||||
public override void _Ready()
|
||||
@@ -52,12 +68,17 @@ public partial class Enemy : CharacterBody3D, IDamageable, IDamageMaker, IHealth
|
||||
healthable.RHealth = RHealth;
|
||||
healthable.CurrentHealth = RHealth.StartingHealth;
|
||||
}
|
||||
if (CKnockback is IKnockbackable knockbackable && RKnockback != null) knockbackable.RKnockback = RKnockback;
|
||||
}
|
||||
|
||||
public void SetupSignals()
|
||||
{
|
||||
_damageBox.BodyEntered += OnDamageBoxTriggered;
|
||||
if (CDamage is IDamageable damageable) damageable.DamageTaken += ReduceHealth;
|
||||
if (CDamage is IDamageable damageable)
|
||||
{
|
||||
damageable.DamageTaken += ReduceHealth;
|
||||
damageable.DamageTaken += RegisterKnockback;
|
||||
}
|
||||
if (CHealth is IHealthable healthable) healthable.HealthDepleted += Kill;
|
||||
}
|
||||
|
||||
@@ -74,6 +95,7 @@ public partial class Enemy : CharacterBody3D, IDamageable, IDamageMaker, IHealth
|
||||
delta: delta
|
||||
);
|
||||
Velocity = ComputeVelocity(inputs);
|
||||
Velocity += ComputeKnockback();
|
||||
MoveAndSlide();
|
||||
}
|
||||
|
||||
@@ -85,25 +107,28 @@ public partial class Enemy : CharacterBody3D, IDamageable, IDamageMaker, IHealth
|
||||
|
||||
public void OnDamageBoxTriggered(Node3D body)
|
||||
{
|
||||
GD.Print("Take this!");
|
||||
if (body is not IDamageable damageable) return;
|
||||
damageable.TakeDamage(RDamage);
|
||||
|
||||
var damageRecord = new DamageRecord(this, RDamage);
|
||||
damageable.TakeDamage(damageRecord);
|
||||
}
|
||||
|
||||
public float TakeDamage(RDamage damage)
|
||||
public DamageRecord TakeDamage(DamageRecord damageRecord)
|
||||
{
|
||||
GD.Print("Ouch!");
|
||||
if (CDamage is not IDamageable damageable) return 0;
|
||||
if (CDamage is not IDamageable damageable)
|
||||
return damageRecord with { Damage = new RDamage(0, damageRecord.Damage.DamageType) };
|
||||
|
||||
var finalDamage = damageable.TakeDamage(damage);
|
||||
DamageTaken?.Invoke(this, damage.DamageDealt);
|
||||
var finalDamage = damageable.TakeDamage(damageRecord);
|
||||
DamageTaken?.Invoke(this, finalDamage);
|
||||
|
||||
GD.Print($"Received damage: {finalDamage.Damage.DamageDealt}");
|
||||
return finalDamage;
|
||||
}
|
||||
|
||||
public void ReduceHealth(IDamageable source, float amount)
|
||||
public void ReduceHealth(IDamageable source, DamageRecord damageRecord)
|
||||
{
|
||||
if (CHealth is not IHealthable healthable) return;
|
||||
healthable.ReduceHealth(source, amount);
|
||||
healthable.ReduceHealth(source, damageRecord);
|
||||
}
|
||||
|
||||
public void Kill(IHealthable source)
|
||||
@@ -114,4 +139,16 @@ public partial class Enemy : CharacterBody3D, IDamageable, IDamageMaker, IHealth
|
||||
}
|
||||
QueueFree();
|
||||
}
|
||||
|
||||
public void RegisterKnockback(IDamageable source, DamageRecord damageRecord)
|
||||
{
|
||||
if (CKnockback is not IKnockbackable knockbackable) return;
|
||||
knockbackable.RegisterKnockback(source, damageRecord);
|
||||
}
|
||||
|
||||
public Vector3 ComputeKnockback()
|
||||
{
|
||||
if (CKnockback is not IKnockbackable knockbackable) return Vector3.Zero;
|
||||
return knockbackable.ComputeKnockback();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user