feat: EnemyWorldState now queues re-planning
This commit is contained in:
		
							parent
							
								
									e71a27876d
								
							
						
					
					
						commit
						d20da67bea
					
				|  | @ -15,11 +15,18 @@ void EnemyWorldState::_bind_methods() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void EnemyWorldState::_ready() { GDGAMEONLY(); | 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<gd::Area3D>("%AwarenessArea"); |     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_entered", callable_mp(this, &EnemyWorldState::on_awareness_entered)); | ||||||
|     this->health = this->get_node<EntityHealth>("%EntityHealth"); |     this->health = this->get_node<EntityHealth>("%EntityHealth"); | ||||||
|     this->health->connect("damage", callable_mp(this, &EnemyWorldState::on_damaged)); |     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) { | 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) { | void EnemyWorldState::on_damaged(EntityHealth *, int, Unit *source) { | ||||||
|     if(source != nullptr && !this->known_enemies.has(source)) |     if(source != nullptr && !this->known_enemies.has(source)) | ||||||
|         this->add_aware_unit(source); |         this->add_aware_unit(source); | ||||||
|     else |     else if(!this->parent_unit->has_plan()) | ||||||
|         this->select_and_set_target(); |         this->select_and_set_target(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -60,6 +67,10 @@ Unit *EnemyWorldState::select_target_from_known() { | ||||||
|     return this->select_target_from_known_with_priority(&dummy); |     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) { | void EnemyWorldState::add_aware_unit(Unit *unit) { | ||||||
|     if(unit == nullptr) |     if(unit == nullptr) | ||||||
|         return; |         return; | ||||||
|  | @ -103,13 +114,21 @@ float EnemyWorldState::calculate_priority(Unit *target) { | ||||||
| gd::Ref<goap::Goal> EnemyWorldState::get_goal_for_target(Unit *unit) { | gd::Ref<goap::Goal> EnemyWorldState::get_goal_for_target(Unit *unit) { | ||||||
|     gd::Node3D *store{this->target_node}; |     gd::Node3D *store{this->target_node}; | ||||||
|     this->target_node = unit; |     this->target_node = unit; | ||||||
|  |     gd::Ref<goap::Goal> best_goal{}; | ||||||
|     for(gd::Ref<goap::Goal> const &goal : this->available_goals) { |     for(gd::Ref<goap::Goal> 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; |             this->target_node = store; | ||||||
|             return goal; |             return goal; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     this->target_node = store; |     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; |     return nullptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -120,6 +139,7 @@ void EnemyWorldState::try_set_target(Unit *unit) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     gd::Ref<goap::Goal> goal{this->get_goal_for_target(unit)}; |     gd::Ref<goap::Goal> goal{this->get_goal_for_target(unit)}; | ||||||
|  |     this->last_goal = goal; | ||||||
|     if(goal.is_valid()) |     if(goal.is_valid()) | ||||||
|         this->parent_unit->set_target_goal(unit, goal); |         this->parent_unit->set_target_goal(unit, goal); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -16,7 +16,7 @@ class EnemyWorldState : public UnitWorldState { | ||||||
|     static void _bind_methods(); |     static void _bind_methods(); | ||||||
| public: | public: | ||||||
|     virtual void _ready() override; |     virtual void _ready() override; | ||||||
| 
 |     virtual void _process(double) override; | ||||||
|     void on_awareness_entered(gd::Node3D *node); |     void on_awareness_entered(gd::Node3D *node); | ||||||
|     void on_awareness_exited(gd::Node3D *node); |     void on_awareness_exited(gd::Node3D *node); | ||||||
|     void on_damaged(EntityHealth *, int, Unit *source); |     void on_damaged(EntityHealth *, int, Unit *source); | ||||||
|  | @ -28,6 +28,7 @@ public: | ||||||
|     //! Shorthand for select_target_from_known_with_priority(nullptr)
 |     //! Shorthand for select_target_from_known_with_priority(nullptr)
 | ||||||
|     Unit *select_target_from_known(); |     Unit *select_target_from_known(); | ||||||
| private: | private: | ||||||
|  |     void queue_select_and_set_target(); | ||||||
|     void add_aware_unit(Unit *unit); |     void add_aware_unit(Unit *unit); | ||||||
|     void remove_aware_unit(Unit *unit); |     void remove_aware_unit(Unit *unit); | ||||||
|     void select_and_set_target(); |     void select_and_set_target(); | ||||||
|  | @ -41,6 +42,9 @@ private: | ||||||
|     gd::Callable aware_unit_death{callable_mp(this, &EnemyWorldState::on_aware_unit_death)}; |     gd::Callable aware_unit_death{callable_mp(this, &EnemyWorldState::on_aware_unit_death)}; | ||||||
|     gd::Vector<gd::Ref<goap::Goal>> available_goals{}; |     gd::Vector<gd::Ref<goap::Goal>> available_goals{}; | ||||||
|     gd::Vector<Unit *> known_enemies{}; |     gd::Vector<Unit *> known_enemies{}; | ||||||
|  |     bool select_and_set_target_on_process{false}; | ||||||
|  | 
 | ||||||
|  |     gd::Ref<goap::Goal> last_goal{}; | ||||||
| 
 | 
 | ||||||
|     gd::Area3D *awareness_area{nullptr}; |     gd::Area3D *awareness_area{nullptr}; | ||||||
|     EntityHealth *health{nullptr}; |     EntityHealth *health{nullptr}; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Sara
						Sara