metro-rts/src/unit_world_state.cpp

53 lines
2 KiB
C++

#include "unit_world_state.hpp"
#include "unit.hpp"
#include "utils/godot_macros.hpp"
#include <godot_cpp/classes/physics_ray_query_parameters3d.hpp>
#include <godot_cpp/classes/world3d.hpp>
#include <godot_cpp/classes/physics_direct_space_state3d.hpp>
#include <godot_cpp/variant/callable_method_pointer.hpp>
#include <godot_cpp/variant/utility_functions.hpp>
void UnitWorldState::_bind_methods() {
#define CLASSNAME UnitWorldState
GDSIGNAL("attention_changed");
GDFUNCTION(get_can_see_target);
GDFUNCTION(get_target_dead);
GDFUNCTION(get_is_at_target);
GDFUNCTION(get_target_node);
}
void UnitWorldState::_enter_tree() { GDGAMEONLY();
this->parent_unit = gd::Object::cast_to<Unit>(this->get_parent());
this->agent = this->get_node<gd::NavigationAgent3D>("../NavigationAgent3D");
if(this->parent_unit == nullptr)
gd::UtilityFunctions::push_warning("UnitWorldState needs to be a child node of a Unit");
}
bool UnitWorldState::get_can_see_target() const {
gd::Transform3D const eyes = this->parent_unit->get_eye_transform();
gd::Transform3D const target = this->target_node->get_global_transform();
gd::Ref<gd::PhysicsRayQueryParameters3D> const query{gd::PhysicsRayQueryParameters3D::create(eyes.origin, target.origin, 0x1 | 0x4, {this->target_node})};
return this->parent_unit->get_world_3d()->get_direct_space_state()->intersect_ray(query).is_empty();
}
bool UnitWorldState::get_is_at_target() const {
if(this->target_node == nullptr) return true;
gd::Vector3 const target = this->target_node->get_global_position();
gd::Vector3 const current = this->parent_unit->get_global_position();
float const min_dist = this->agent->get_target_desired_distance();
return (target - current).length_squared() < min_dist * min_dist;
}
bool UnitWorldState::get_target_dead() const {
return false;
}
void UnitWorldState::set_target_node(gd::Node3D *node) {
this->target_node = node;
this->emit_signal("attention_changed");
}
gd::Node3D *UnitWorldState::get_target_node() const {
return this->target_node;
}