feat: added unconscious event

This commit is contained in:
Sara 2024-08-08 14:39:50 +02:00
parent d94b24f617
commit cabaae949c
4 changed files with 59 additions and 24 deletions

View file

@ -17,7 +17,6 @@ void EnemyWorldState::_bind_methods() {
void EnemyWorldState::_ready() { GDGAMEONLY();
this->awareness_area = this->get_node<gd::Area3D>("%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>("%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;

View file

@ -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<goap::Goal> get_goal_for_target(Unit *unit);
void try_set_target(Unit *target);

View file

@ -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;
}

View file

@ -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;