diff --git a/interfaces/IDamageable.cs b/interfaces/IDamageable.cs index 8c17492c..5c54b43d 100644 --- a/interfaces/IDamageable.cs +++ b/interfaces/IDamageable.cs @@ -4,5 +4,6 @@ namespace Movementtests.interfaces; public interface IDamageable { + event Action DamageTaken; float TakeDamage(RDamage damage); } \ No newline at end of file diff --git a/interfaces/IHealthable.cs b/interfaces/IHealthable.cs index a86d72f5..93915252 100644 --- a/interfaces/IHealthable.cs +++ b/interfaces/IHealthable.cs @@ -1,6 +1,11 @@ +using System; + namespace Movementtests.interfaces; public interface IHealthable { - void ReduceHealth(float amount); + event Action HealthChanged; + event Action HealthDepleted; + + void ReduceHealth(IDamageable source, float amount); } \ No newline at end of file diff --git a/interfaces/IKillable.cs b/interfaces/IKillable.cs index ce532e6e..7e357034 100644 --- a/interfaces/IKillable.cs +++ b/interfaces/IKillable.cs @@ -2,5 +2,5 @@ namespace Movementtests.interfaces; public interface IKillable { - void Kill(); + void Kill(IHealthable source); } \ No newline at end of file diff --git a/maps/GYMs/enemies.tscn b/maps/GYMs/enemies.tscn index 95444e11..850b8f46 100644 --- a/maps/GYMs/enemies.tscn +++ b/maps/GYMs/enemies.tscn @@ -1,14 +1,15 @@ -[gd_scene load_steps=10 format=3 uid="uid://q7uc1h2jpbd2"] +[gd_scene load_steps=12 format=3 uid="uid://q7uc1h2jpbd2"] [ext_resource type="PackedScene" uid="uid://bei4nhkf8lwdo" path="res://player_controller/PlayerController.tscn" id="1_62kkh"] [ext_resource type="Material" uid="uid://31aulub2nqov" path="res://assets/greybox/m_greybox.tres" id="2_3uydm"] [ext_resource type="Script" uid="uid://jitubgv6judn" path="res://resource_definitions/RDamage.cs" id="2_sysok"] [ext_resource type="PackedScene" uid="uid://dxt0e2ugmttqq" path="res://scenes/enemies/first_enemy/first_enemy.tscn" id="3_3uydm"] +[ext_resource type="Script" uid="uid://b4cwruitopcee" path="res://resource_definitions/RDeathEffect.cs" id="5_7m3bq"] [ext_resource type="PackedScene" uid="uid://cmlud1hwkd6sv" path="res://scenes/enemies/flying_enemy/flying_enemy.tscn" id="5_8fd2t"] [sub_resource type="Resource" id="Resource_gp7s3"] script = ExtResource("2_sysok") -DamageDealt = 3.0 +DamageDealt = 10.0 metadata/_custom_type_script = "uid://jitubgv6judn" [sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_0xm2m"] @@ -33,6 +34,10 @@ ssil_radius = 8.4 sdfgi_use_occlusion = true glow_enabled = true +[sub_resource type="Resource" id="Resource_sysok"] +script = ExtResource("5_7m3bq") +metadata/_custom_type_script = "uid://b4cwruitopcee" + [node name="Main" type="Node3D"] [node name="Player" parent="." instance=ExtResource("1_62kkh")] @@ -103,6 +108,7 @@ material = ExtResource("2_3uydm") [node name="Enemy" parent="." node_paths=PackedStringArray("Target") instance=ExtResource("3_3uydm")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -16.83681) Target = NodePath("../Player") +DeathEffects = Array[Object]([SubResource("Resource_sysok")]) [node name="Enemy2" parent="." node_paths=PackedStringArray("Target") instance=ExtResource("3_3uydm")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 0, -16.83681) diff --git a/player_controller/Scripts/PlayerController.cs b/player_controller/Scripts/PlayerController.cs index afcadaa9..da7a1bd0 100644 --- a/player_controller/Scripts/PlayerController.cs +++ b/player_controller/Scripts/PlayerController.cs @@ -32,6 +32,8 @@ public partial class PlayerController : CharacterBody3D, IDamageable, IKnockback /////////////////////////// // Signals and events // /////////////////////////// + + public event Action DamageTaken; /////////////////////////// // Public stuff // @@ -1735,7 +1737,9 @@ public partial class PlayerController : CharacterBody3D, IDamageable, IKnockback public float TakeDamage(RDamage damage) { - return CDamage.TakeDamage(damage); + var finalDamage = CDamage.TakeDamage(damage); + DamageTaken?.Invoke(this, finalDamage); + return finalDamage; } /////////////////////////// diff --git a/resource_definitions/RDamageModifier.cs b/resource_definitions/RDamageModifier.cs index 8755fca2..29920497 100644 --- a/resource_definitions/RDamageModifier.cs +++ b/resource_definitions/RDamageModifier.cs @@ -6,6 +6,8 @@ using Movementtests.systems.damage; [GlobalClass] public partial class RDamageModifier : Resource, IDamageable { + public event Action DamageTaken; + [Export] public EDamageTypes DamageType = EDamageTypes.Normal; [Export] @@ -26,6 +28,7 @@ public partial class RDamageModifier : Resource, IDamageable { if (damage.DamageType != DamageType) return 0; var finalDamage = damage.DamageDealt * Modifier; + DamageTaken?.Invoke(this, finalDamage); return finalDamage; } } diff --git a/resource_definitions/RDeathEffect.cs b/resource_definitions/RDeathEffect.cs index bf5ad607..e0626553 100644 --- a/resource_definitions/RDeathEffect.cs +++ b/resource_definitions/RDeathEffect.cs @@ -5,8 +5,8 @@ using Movementtests.interfaces; [GlobalClass] public partial class RDeathEffect : Resource, IKillable { - public void Kill() + public void Kill(IHealthable source) { - GD.Print("Death Effect triggered"); + GD.Print($"Death Effect triggered on {source}"); } } diff --git a/scenes/damage/CDamageable.cs b/scenes/damage/CDamageable.cs index eaeca291..53158071 100644 --- a/scenes/damage/CDamageable.cs +++ b/scenes/damage/CDamageable.cs @@ -5,18 +5,18 @@ using Movementtests.interfaces; [GlobalClass] public partial class CDamageable : Node, IDamageable { - [Signal] - public delegate void DamageTakenEventHandler(float damageTaken); + public event Action DamageTaken; [Export] public RDamageModifier[] DamageModifiers { get; set; } + public float TakeDamage(RDamage damage) { var finalDamage = 0f; foreach (var damageable in DamageModifiers.ToIDamageables()) finalDamage += damageable.TakeDamage(damage); - EmitSignalDamageTaken(finalDamage); + DamageTaken?.Invoke(this, finalDamage); return finalDamage; } } diff --git a/scenes/enemies/Enemy.cs b/scenes/enemies/Enemy.cs index d9112db8..74d3576b 100644 --- a/scenes/enemies/Enemy.cs +++ b/scenes/enemies/Enemy.cs @@ -1,9 +1,15 @@ +using System; using Godot; using Movementtests.interfaces; [GlobalClass] public partial class Enemy : CharacterBody3D, IDamageable, IDamageMaker, IHealthable, IKillable { + public event Action DamageTaken; + + public event Action HealthChanged; + public event Action HealthDepleted; + [Export] public Node3D Target { get; set; } @@ -11,10 +17,10 @@ public partial class Enemy : CharacterBody3D, IDamageable, IDamageMaker, IHealth public RDamage GetDamageDealt { get; set; } [Export] - public CHealth CHealth { get; set; } + public Node CHealth { get; set; } [Export] - public CDamageable CDamage { get; set; } + public Node CDamage { get; set; } [Export] public Node CMovement { get; set; } @@ -29,8 +35,8 @@ public partial class Enemy : CharacterBody3D, IDamageable, IDamageMaker, IHealth _damageBox = GetNode("DamageBox"); _damageBox.BodyEntered += OnDamageBoxTriggered; - CDamage.DamageTaken += ReduceHealth; - CHealth.Dead += Kill; + if (CDamage is IDamageable damageable) damageable.DamageTaken += ReduceHealth; + if (CHealth is IHealthable healthable) healthable.HealthDepleted += Kill; } public override void _PhysicsProcess(double delta) @@ -54,25 +60,31 @@ public partial class Enemy : CharacterBody3D, IDamageable, IDamageMaker, IHealth public void OnDamageBoxTriggered(Node3D body) { GD.Print("Take this!"); - if(body is IDamageable damageable) damageable.TakeDamage(GetDamageDealt); + if (body is not IDamageable damageable) return; + damageable.TakeDamage(GetDamageDealt); } public float TakeDamage(RDamage damage) { GD.Print("Ouch!"); - return CDamage.TakeDamage(damage); + if (CDamage is not IDamageable damageable) return 0; + + var finalDamage = damageable.TakeDamage(damage); + DamageTaken?.Invoke(this, damage.DamageDealt); + return finalDamage; } - public void ReduceHealth(float amount) + public void ReduceHealth(IDamageable source, float amount) { - CHealth.ReduceHealth(amount); + if (CHealth is not IHealthable healthable) return; + healthable.ReduceHealth(source, amount); } - public void Kill() + public void Kill(IHealthable source) { foreach (var killable in DeathEffects.ToIKillables()) { - killable.Kill(); + killable.Kill(source); } QueueFree(); } diff --git a/scenes/enemies/first_enemy/first_enemy.tscn b/scenes/enemies/first_enemy/first_enemy.tscn index 708be9e5..4c08a751 100644 --- a/scenes/enemies/first_enemy/first_enemy.tscn +++ b/scenes/enemies/first_enemy/first_enemy.tscn @@ -17,9 +17,9 @@ metadata/_custom_type_script = "uid://baiapod3csndf" script = ExtResource("2_r3cnf") metadata/_custom_type_script = "uid://b6y3ugfydvch0" -[sub_resource type="Resource" id="Resource_s01ng"] +[sub_resource type="Resource" id="Resource_6d4gl"] script = ExtResource("8_6d4gl") -Speed = 3.0 +Speed = 5.0 metadata/_custom_type_script = "uid://dtpxijlnb2c5" [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_62kkh"] @@ -59,7 +59,7 @@ DamageModifiers = Array[Object]([SubResource("Resource_qj0ob")]) metadata/_custom_type_script = "uid://b0u23nkpaimyc" [node name="CGroundedMovement" parent="." node_paths=PackedStringArray("WallInFrontRayCast") instance=ExtResource("7_qyswd")] -RMovement = SubResource("Resource_s01ng") +RMovement = SubResource("Resource_6d4gl") WallInFrontRayCast = NodePath("../WallInFrontRayCast") [node name="CollisionShape3D" type="CollisionShape3D" parent="."] diff --git a/scenes/enemies/flying_enemy/flying_enemy.tscn b/scenes/enemies/flying_enemy/flying_enemy.tscn index 51ddcd74..4b4952e7 100644 --- a/scenes/enemies/flying_enemy/flying_enemy.tscn +++ b/scenes/enemies/flying_enemy/flying_enemy.tscn @@ -23,9 +23,9 @@ script = ExtResource("2_1bsgx") DamageType = 1 metadata/_custom_type_script = "uid://b6y3ugfydvch0" -[sub_resource type="Resource" id="Resource_ma2bq"] +[sub_resource type="Resource" id="Resource_on7rt"] script = ExtResource("8_on7rt") -Speed = 2.0 +Speed = 3.0 TargetHeight = 10.0 metadata/_custom_type_script = "uid://dtpxijlnb2c5" @@ -67,7 +67,7 @@ DamageModifiers = Array[Object]([SubResource("Resource_jnv07"), SubResource("Res metadata/_custom_type_script = "uid://b0u23nkpaimyc" [node name="CFlyingMovement" parent="." instance=ExtResource("7_vaeds")] -RMovement = SubResource("Resource_ma2bq") +RMovement = SubResource("Resource_on7rt") TerrainCollision = 256 [node name="CollisionShape3D" type="CollisionShape3D" parent="."] diff --git a/scenes/health/CHealth.cs b/scenes/health/CHealth.cs index ea78fb3a..4d56fdb3 100644 --- a/scenes/health/CHealth.cs +++ b/scenes/health/CHealth.cs @@ -5,10 +5,8 @@ using Movementtests.interfaces; [GlobalClass] public partial class CHealth : Node, IHealthable { - [Signal] - public delegate void HealthChangedEventHandler(float health); - [Signal] - public delegate void DeadEventHandler(); + public event Action HealthChanged; + public event Action HealthDepleted; [Export] public RHealth HealthResource; @@ -20,15 +18,15 @@ public partial class CHealth : Node, IHealthable CurrentHealth = HealthResource.StartingHealth; } - public void ReduceHealth(float amount) + public void ReduceHealth(IDamageable source, float amount) { CurrentHealth -= amount; - EmitSignalHealthChanged(CurrentHealth); + HealthChanged?.Invoke(this, CurrentHealth); if (CurrentHealth <= 0) { CurrentHealth = 0; - EmitSignalDead(); + HealthDepleted?.Invoke(this); } } } diff --git a/scenes/movement/CFlyingMovement.cs b/scenes/movement/CFlyingMovement.cs index 6afd1e70..d9000104 100644 --- a/scenes/movement/CFlyingMovement.cs +++ b/scenes/movement/CFlyingMovement.cs @@ -19,7 +19,7 @@ public partial class CFlyingMovement : Node3D, IMoveable _randomDirection = new Vector3(GD.RandRange(-1, 1), 1, GD.RandRange(-1, 1)).Normalized(); } - public new Vector3 ComputeVelocity(MovementInputs inputs) + public Vector3 ComputeVelocity(MovementInputs inputs) { var velocity = inputs.Velocity; var spaceState = GetWorld3D().DirectSpaceState; diff --git a/scenes/movement/CGroundedMovement.cs b/scenes/movement/CGroundedMovement.cs index 63153f89..8554fa13 100644 --- a/scenes/movement/CGroundedMovement.cs +++ b/scenes/movement/CGroundedMovement.cs @@ -11,7 +11,7 @@ public partial class CGroundedMovement : Node3D, IMoveable public RayCast3D WallInFrontRayCast { get; set; } - public new Vector3 ComputeVelocity(MovementInputs inputs) + public Vector3 ComputeVelocity(MovementInputs inputs) { var velocity = inputs.Velocity; var target = inputs.TargetLocation;