Zombie death and damage indicators

This commit is contained in:
Rendo 2025-07-12 00:15:17 +05:00
commit b524f97e7f
14 changed files with 324 additions and 117 deletions

View file

@ -10,7 +10,7 @@ public partial class Entity : Node2D
#region Health points
[Export] public float MaxHP;
public float HP;
[Signal] public delegate void OnHPChangedEventHandler(int deltaHP, Node origin);
[Signal] public delegate void OnHPChangedEventHandler(float deltaHP, Node origin);
[Signal] public delegate void OnDamagedEventHandler();
public virtual void TakeDamage(float amount, Node origin)

View file

@ -0,0 +1,32 @@
using Godot;
namespace Newlon.Components;
public partial class EntityHPObserver : Node
{
[Export] private float _threshold = 0.5f;
[Export] private bool _setGreater = false;
[Export] private Entity _observedEntity;
[Signal] public delegate void ThresholdReachedEventHandler();
public override void _Ready()
{
_observedEntity.OnHPChanged += OnHPChanged;
}
private void OnHPChanged(float delta, Node origin)
{
if (_setGreater == false && _observedEntity.HP / _observedEntity.MaxHP < _threshold)
{
EmitSignal(SignalName.ThresholdReached);
_observedEntity.OnHPChanged -= OnHPChanged;
QueueFree();
}
else if (_setGreater && _observedEntity.HP / _observedEntity.MaxHP > _threshold)
{
EmitSignal(SignalName.ThresholdReached);
_observedEntity.OnHPChanged -= OnHPChanged;
QueueFree();
}
}
}

View file

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

View file

@ -0,0 +1,24 @@
using Godot;
using Newlon.Components.Zombies;
public partial class ZombieKillHandler : Node
{
[Export] private AnimationTree _tree;
[Export] private CollisionShape2D _collider;
private void OnKilled(RuntimeZombieData who)
{
var tween = CreateTween();
tween.TweenInterval(4.0);
tween.TweenCallback(Callable.From(() =>
{
((AnimationNodeStateMachinePlayback)_tree.Get("parameters/Tree/playback")).Travel("Death");
_collider.Disabled = true;
}));
tween.TweenInterval(3.0);
tween.TweenProperty(who, "modulate",new Color(1, 1, 1, 0),1.0);
tween.TweenCallback(Callable.From(() =>
{
who.Kill();
}));
}
}

View file

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

View file

@ -2,6 +2,9 @@ using Godot;
using Newlon.Components.Level;
using Newlon.Components.Zombies;
namespace Newlon.Components;
[GlobalClass]
public partial class FallParticle : RigidBody2D
{
[Export] private RuntimeZombieData data;
@ -19,10 +22,11 @@ public partial class FallParticle : RigidBody2D
}
Callable.From(() =>
{
Reparent(PoolContainer.Instance.Zombies);
Reparent(PoolContainer.Instance.Particles);
float rng_angle = Mathf.DegToRad((float)GD.RandRange(minAngle, maxAngle));
float rng_torque = Mathf.DegToRad((float)GD.RandRange(minTorque, maxTorque));
ApplyImpulse(new Vector2(Mathf.Sin(rng_angle) * Impulse, Mathf.Cos(rng_angle) * Impulse));
if (Impulse != 0)
ApplyImpulse(new Vector2(Mathf.Sin(rng_angle) * Impulse, Mathf.Cos(rng_angle) * Impulse));
ApplyTorqueImpulse(rng_torque);
}).CallDeferred();
var tween = CreateTween();

View file

@ -10,6 +10,7 @@ public partial class RuntimeZombieData : Entity
private AudioStream garlicSound;
[Export]
private AudioStream freezeSound;
[Signal] public delegate void HasBeenKilledEventHandler(RuntimeZombieData who);
public bool AbleToEat = true;
public override void Heal(float amount, Node origin)
@ -44,9 +45,13 @@ public partial class RuntimeZombieData : Entity
}
}
#region Death sequence
private bool _killed = false;
public override void KillByDamage()
{
if (_killed) return;
_killed = true;
AbleToEat = false;
EmitSignal(SignalName.HasBeenKilled,this);
}
#endregion