#include "unit_world_state.hpp" #include "unit.hpp" #include "utils/godot_macros.hpp" #include #include #include #include #include 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(this->get_parent()); this->agent = this->get_node("../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 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; }