From cabaae949c3a0cc8d765c7600b10461d325b5d9f Mon Sep 17 00:00:00 2001 From: Sara Date: Thu, 8 Aug 2024 14:39:50 +0200 Subject: [PATCH] feat: added unconscious event --- src/enemy_world_state.cpp | 3 +- src/enemy_world_state.hpp | 2 +- src/entity_health.cpp | 66 ++++++++++++++++++++++++++++----------- src/entity_health.hpp | 12 +++++-- 4 files changed, 59 insertions(+), 24 deletions(-) diff --git a/src/enemy_world_state.cpp b/src/enemy_world_state.cpp index de875fc..c9f9219 100644 --- a/src/enemy_world_state.cpp +++ b/src/enemy_world_state.cpp @@ -17,7 +17,6 @@ void EnemyWorldState::_bind_methods() { void EnemyWorldState::_ready() { GDGAMEONLY(); this->awareness_area = this->get_node("%AwarenessArea"); this->awareness_area->connect("body_entered", callable_mp(this, &EnemyWorldState::on_awareness_entered)); - // this->awareness_area->connect("body_exited", callable_mp(this, &EnemyWorldState::on_awareness_exited)); this->health = this->get_node("%EntityHealth"); this->health->connect("damage", callable_mp(this, &EnemyWorldState::on_damaged)); this->parent_unit->connect("plan_interrupted", callable_mp(this, &EnemyWorldState::select_and_set_target)); @@ -68,7 +67,7 @@ void EnemyWorldState::add_aware_unit(Unit *unit) { return; if(this->known_enemies.has(unit)) return; - if(unit->get_entity_health()->get_is_dead()) + if(unit->get_entity_health()->is_dead()) return; if(!this->get_is_unit_enemy(unit)) return; diff --git a/src/enemy_world_state.hpp b/src/enemy_world_state.hpp index 9fc9edc..341c090 100644 --- a/src/enemy_world_state.hpp +++ b/src/enemy_world_state.hpp @@ -31,7 +31,7 @@ private: void add_aware_unit(Unit *unit); void remove_aware_unit(Unit *unit); void select_and_set_target(); - void on_aware_unit_death(Unit *_, Unit *dead_entity); + void on_aware_unit_death(Unit *, Unit *dead_entity); float calculate_priority(Unit *target); gd::Ref get_goal_for_target(Unit *unit); void try_set_target(Unit *target); diff --git a/src/entity_health.cpp b/src/entity_health.cpp index 1c93f4f..a38ff2a 100644 --- a/src/entity_health.cpp +++ b/src/entity_health.cpp @@ -21,6 +21,11 @@ void EntityHealth::_bind_methods() { gd::PropertyInfo(gd::Variant::OBJECT, "health_entity", gd::PROPERTY_HINT_NODE_TYPE, "EntityHealth"), gd::PropertyInfo(gd::Variant::INT, "change")); GDSIGNAL("death", gd::PropertyInfo(gd::Variant::OBJECT, "source", gd::PROPERTY_HINT_NODE_TYPE, "Unit")); + GDSIGNAL("unconscious", gd::PropertyInfo(gd::Variant::OBJECT, "source", gd::PROPERTY_HINT_NODE_TYPE, "Unit")); + GDSIGNAL("revived", + gd::PropertyInfo(gd::Variant::OBJECT, "health_entity", gd::PROPERTY_HINT_NODE_TYPE, "Unit"), + gd::PropertyInfo(gd::Variant::INT, "healed"), + gd::PropertyInfo(gd::Variant::OBJECT, "source", gd::PROPERTY_HINT_NODE_TYPE, "Unit")); } void EntityHealth::_enter_tree() { @@ -29,34 +34,57 @@ void EntityHealth::_enter_tree() { } void EntityHealth::damaged_by(int amount, Unit *source) { - // do not take damage when already dead - if(this->injury_current <= 0) - return; - amount = gd::Math::abs(amount); - this->wounds_current -= amount; - this->injury_current -= gd::Math::max(1, int(float(amount) * this->get_wounds_damage_factor())); - - this->emit_signal("damage", this, amount, source); - this->emit_signal("health_changed", this, -amount); - if(this->injury_current <= 0) - this->emit_signal("death", source); + if(!this->is_dead()) { + amount = gd::Math::abs(amount); + this->receive_wounds(amount, source); + this->receive_injury(amount, source); + this->emit_signal("damage", this, amount, source); + this->emit_signal("health_changed", this, -amount); + } } void EntityHealth::healed_by(int amount, Unit *source) { - // reviving takes a different action - if(this->injury_current <= 0) - return; - amount = gd::Math::abs(amount); - this->injury_current = gd::Math::min(this->injury_max, this->injury_current + amount); - this->emit_signal("heal", this, amount, source); - this->emit_signal("health_changed", this, amount); + if(this->can_be_healed()) { + amount = gd::Math::abs(amount); + this->injury_current = gd::Math::min(this->injury_max, this->injury_current + amount); + this->emit_signal("heal", this, amount, source); + this->emit_signal("health_changed", this, amount); + } +} + +void EntityHealth::receive_wounds(int incoming_amount, Unit *source) { + if(this->is_conscious()) { + this->wounds_current -= incoming_amount; + if(this->injury_current <= 0) + this->emit_signal("unconscious", source); + } +} + +void EntityHealth::receive_injury(int incoming_amount, Unit *source) { + if(!this->is_dead()) { + this->injury_current -= gd::Math::max(1, int(float(incoming_amount) * this->get_wounds_damage_factor())); + if(this->injury_current <= 0) + this->emit_signal("death", source); + } } float EntityHealth::get_wounds_damage_factor() const { return float(this->injury_current) / float(this->injury_max); } -bool EntityHealth::get_is_dead() const { +bool EntityHealth::is_conscious() const { + return !this->is_dead() && this->wounds_current > 0; +} + +bool EntityHealth::can_be_revived() const { + return this->wounds_current <= 0 && this->injury_current > 0; +} + +bool EntityHealth::can_be_healed() const { + return this->injury_current > 0 && this->wounds_current > 0 && this->wounds_current < this->wounds_max; +} + +bool EntityHealth::is_dead() const { return this->injury_current <= 0; } diff --git a/src/entity_health.hpp b/src/entity_health.hpp index 9cba59e..a75d918 100644 --- a/src/entity_health.hpp +++ b/src/entity_health.hpp @@ -14,9 +14,17 @@ public: virtual void _enter_tree() override; void damaged_by(int amount, Unit *source); void healed_by(int amount, Unit *source); - + void heal_and_revive(int heal_amount, Unit *source); +private: + void receive_wounds(int incoming_amount, Unit *source); + void receive_injury(int incoming_amount, Unit *source); float get_wounds_damage_factor() const; - bool get_is_dead() const; +public: + bool is_conscious() const; + bool can_be_revived() const; + bool can_be_healed() const; + bool can_be_damaged() const; + bool is_dead() const; void set_injury_max(int max_health); int get_injury_max() const; int get_injury_current() const;