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