From d20da67bea5be29391351e5988062f3ca923ec70 Mon Sep 17 00:00:00 2001 From: Sara Date: Fri, 9 Aug 2024 15:47:14 +0200 Subject: [PATCH] feat: EnemyWorldState now queues re-planning --- src/enemy_world_state.cpp | 26 +++++++++++++++++++++++--- src/enemy_world_state.hpp | 6 +++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/enemy_world_state.cpp b/src/enemy_world_state.cpp index c9f9219..1514b2f 100644 --- a/src/enemy_world_state.cpp +++ b/src/enemy_world_state.cpp @@ -15,11 +15,18 @@ void EnemyWorldState::_bind_methods() { } void EnemyWorldState::_ready() { GDGAMEONLY(); + this->parent_unit->connect("plan_interrupted", callable_mp(this, &EnemyWorldState::queue_select_and_set_target)); this->awareness_area = this->get_node("%AwarenessArea"); this->awareness_area->connect("body_entered", callable_mp(this, &EnemyWorldState::on_awareness_entered)); 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)); +} + +void EnemyWorldState::_process(double) { + if(this->select_and_set_target_on_process) { + this->select_and_set_target_on_process = false; + this->select_and_set_target(); + } } void EnemyWorldState::on_awareness_entered(gd::Node3D *node) { @@ -36,7 +43,7 @@ void EnemyWorldState::on_awareness_exited(gd::Node3D *node) { void EnemyWorldState::on_damaged(EntityHealth *, int, Unit *source) { if(source != nullptr && !this->known_enemies.has(source)) this->add_aware_unit(source); - else + else if(!this->parent_unit->has_plan()) this->select_and_set_target(); } @@ -60,6 +67,10 @@ Unit *EnemyWorldState::select_target_from_known() { return this->select_target_from_known_with_priority(&dummy); } +void EnemyWorldState::queue_select_and_set_target() { + this->select_and_set_target_on_process = true; +} + void EnemyWorldState::add_aware_unit(Unit *unit) { if(unit == nullptr) return; @@ -103,13 +114,21 @@ float EnemyWorldState::calculate_priority(Unit *target) { gd::Ref EnemyWorldState::get_goal_for_target(Unit *unit) { gd::Node3D *store{this->target_node}; this->target_node = unit; + gd::Ref best_goal{}; for(gd::Ref const &goal : this->available_goals) { - if(goal->check_requirements_met(this)) { + if(!goal->check_requirements_met(this)) { + continue; + } else if(goal == this->last_goal) { + best_goal = goal; + } else { this->target_node = store; return goal; } } this->target_node = store; + if(best_goal.is_valid()) + return best_goal; + gd::UtilityFunctions::push_warning(this->get_path(), " failed to find goal for target ", unit->get_path()); return nullptr; } @@ -120,6 +139,7 @@ void EnemyWorldState::try_set_target(Unit *unit) { return; } gd::Ref goal{this->get_goal_for_target(unit)}; + this->last_goal = goal; if(goal.is_valid()) this->parent_unit->set_target_goal(unit, goal); } diff --git a/src/enemy_world_state.hpp b/src/enemy_world_state.hpp index 341c090..59c6719 100644 --- a/src/enemy_world_state.hpp +++ b/src/enemy_world_state.hpp @@ -16,7 +16,7 @@ class EnemyWorldState : public UnitWorldState { static void _bind_methods(); public: virtual void _ready() override; - + virtual void _process(double) override; void on_awareness_entered(gd::Node3D *node); void on_awareness_exited(gd::Node3D *node); void on_damaged(EntityHealth *, int, Unit *source); @@ -28,6 +28,7 @@ public: //! Shorthand for select_target_from_known_with_priority(nullptr) Unit *select_target_from_known(); private: + void queue_select_and_set_target(); void add_aware_unit(Unit *unit); void remove_aware_unit(Unit *unit); void select_and_set_target(); @@ -41,6 +42,9 @@ private: gd::Callable aware_unit_death{callable_mp(this, &EnemyWorldState::on_aware_unit_death)}; gd::Vector> available_goals{}; gd::Vector known_enemies{}; + bool select_and_set_target_on_process{false}; + + gd::Ref last_goal{}; gd::Area3D *awareness_area{nullptr}; EntityHealth *health{nullptr};