metro-rts/src/enemy_world_state.hpp

57 lines
1.9 KiB
C++

#ifndef ENEMY_WORLD_STATE_HPP
#define ENEMY_WORLD_STATE_HPP
#include "goap/goal.hpp"
#include "unit_world_state.hpp"
#include <godot_cpp/classes/area3d.hpp>
#include <godot_cpp/templates/vector.hpp>
#include <godot_cpp/variant/array.hpp>
namespace gd = godot;
class EntityHealth;
class EnemyWorldState : public UnitWorldState {
GDCLASS(EnemyWorldState, 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);
/*! Select the target with the highest priority and return it.
* Assigns the priority of found target to out_priority.
* \param out_priority Assigned to highest found priority, cannot be nullptr.
*/
Unit *select_target_from_known_with_priority(float *out_priority);
//! 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();
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);
void set_available_goals_inspector(gd::Array array);
gd::Array get_available_goals_inspector() const;
private:
gd::Callable aware_unit_death{callable_mp(this, &EnemyWorldState::on_aware_unit_death)};
gd::Vector<gd::Ref<goap::Goal>> available_goals{};
gd::Vector<Unit *> known_enemies{};
bool select_and_set_target_on_process{false};
gd::Ref<goap::Goal> last_goal{};
gd::Area3D *awareness_area{nullptr};
EntityHealth *health{nullptr};
};
#endif // !ENEMY_WORLD_STATE_HPP