mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-01 10:25:35 +00:00
103 lines
No EOL
3 KiB
C#
103 lines
No EOL
3 KiB
C#
using System.Linq;
|
|
using Cirno.Scripts.Enums;
|
|
using Cirno.Scripts.Resources;
|
|
using Godot;
|
|
using Godot.Collections;
|
|
|
|
namespace Cirno.Scripts.Components.Actors;
|
|
|
|
public partial class GenericDamageReceiver : Area2D, IHittable
|
|
{
|
|
[Export] public ActorResourceProvider HealthProvider { get; private set; }
|
|
|
|
[Export] public bool Invulnerable { get; private set; } = false;
|
|
|
|
[Export] public BulletOwner BulletGroup { get; set; } = BulletOwner.None;
|
|
|
|
[Export] public PackedScene Debris { get; set; }
|
|
|
|
[Export] public Array<DamageResistance> DamageResistances { get; set; } = [];
|
|
|
|
[Export] public bool DeleteParentOnDeath { get; private set; } = true;
|
|
|
|
[Signal]
|
|
public delegate void ShieldHitEventHandler();
|
|
|
|
[Signal] public delegate void BulletHitEventHandler(Bullet bullet, Vector2 position, Vector2 direction);
|
|
|
|
//[Signal] public delegate void DeathEventHandler();
|
|
|
|
private Node2D _parent;
|
|
|
|
public bool Enabled { get; private set; } = true;
|
|
|
|
public override void _Ready()
|
|
{
|
|
_parent = GetParent<Node2D>();
|
|
HealthProvider.FillResource();
|
|
HealthProvider.ResourceDepleted += OnDeath;
|
|
}
|
|
|
|
public void ChangeState(bool enabled)
|
|
{
|
|
Enabled = enabled;
|
|
}
|
|
|
|
private void _on_damage_hitbox_area_entered(Area2D area)
|
|
{
|
|
if (!Enabled) return;
|
|
if (area is not Bullet bullet) return;
|
|
if (Invulnerable)
|
|
{
|
|
EmitSignalShieldHit();
|
|
return;
|
|
};
|
|
|
|
if (BulletGroup is BulletOwner.None)
|
|
{
|
|
this.Hit(bullet.Damage, bullet.DamageType);
|
|
|
|
EmitSignalBulletHit(bullet, area.GlobalPosition, (this.GlobalPosition - area.GlobalPosition).Normalized());
|
|
|
|
bullet.RequestCollisionDestruction();
|
|
return;
|
|
}
|
|
|
|
if (bullet.BulletInfo.Owner == BulletGroup) return;
|
|
|
|
this.Hit(bullet.Damage, bullet.DamageType);
|
|
|
|
EmitSignalBulletHit(bullet, area.GlobalPosition, (this.GlobalPosition - area.GlobalPosition).Normalized());
|
|
|
|
bullet.RequestCollisionDestruction();
|
|
}
|
|
|
|
public void Hit(float damage, DamageType damageType = DamageType.Neutral)
|
|
{
|
|
if (!Enabled) return;
|
|
if (Invulnerable) return;
|
|
|
|
// Change value based on difficulty
|
|
float difficultyReducedDmg = damage * GlobalState.Instance.SessionSettings.DifficultyDamageMultiplier;
|
|
|
|
var dmg = DamageResistances.Aggregate(difficultyReducedDmg, (current, resistance) => current * resistance.CalculateDamage(current, damageType));
|
|
|
|
HealthProvider.CurrentResource -= dmg;
|
|
}
|
|
|
|
private void OnDeath()
|
|
{
|
|
if (Debris is not null)
|
|
{
|
|
_parent.CreateSibling<Node2D>(Debris);
|
|
}
|
|
|
|
// Not needed because the health provider is accessible
|
|
//EmitSignal(SignalName.Death);
|
|
|
|
if (DeleteParentOnDeath)
|
|
{
|
|
_parent.QueueFree();
|
|
}
|
|
}
|
|
} |