84 lines
3 KiB
C++
84 lines
3 KiB
C++
#include "party_member_states.h"
|
|
#include "authority/nav_marker.h"
|
|
#include "authority/player_character.h"
|
|
#include "core/config/engine.h"
|
|
#include "core/error/error_macros.h"
|
|
#include "core/templates/vector.h"
|
|
|
|
void PartyMemberFollow::_bind_methods() {}
|
|
|
|
void PartyMemberFollow::process_position_target() {
|
|
Vector3 const marker_position{ this->claimed_marker->get_global_position() };
|
|
Vector3 const nav_target{ this->nav->get_target_position() };
|
|
Vector3 const global_position{ get_character()->get_global_position() };
|
|
if (global_position.distance_squared_to(marker_position) < 0.5) {
|
|
return;
|
|
}
|
|
if (nav_target.distance_squared_to(marker_position) > 0.25) {
|
|
this->nav->set_target_position(marker_position);
|
|
}
|
|
if (this->nav->is_navigation_finished()) {
|
|
return;
|
|
}
|
|
Vector3 velocity{ global_position.direction_to(this->nav->get_next_path_position()) };
|
|
velocity.y = 0;
|
|
if (this->nav->get_avoidance_enabled()) {
|
|
this->nav->set_velocity(velocity * get_character()->get_data()->get_speed());
|
|
} else {
|
|
push_movement_direction(velocity * get_character()->get_data()->get_speed());
|
|
}
|
|
}
|
|
|
|
void PartyMemberFollow::push_movement_direction(Vector3 velocity) {
|
|
get_character()->set_movement(Vector2{ velocity.x, velocity.z });
|
|
}
|
|
|
|
void PartyMemberFollow::_notification(int what) {
|
|
if (Engine::get_singleton()->is_editor_hint()) {
|
|
return;
|
|
}
|
|
switch (what) {
|
|
default:
|
|
return;
|
|
case NOTIFICATION_READY:
|
|
this->nav = cast_to<NavigationAgent3D>(get_parent()->get_node(NodePath("%NavigationAgent3D")));
|
|
ERR_FAIL_COND_EDMSG(this->nav == nullptr, "PartyMemberFollow cannot initialise without a navigation agent");
|
|
return;
|
|
case NOTIFICATION_PROCESS:
|
|
process_position_target();
|
|
return;
|
|
}
|
|
}
|
|
|
|
PackedStringArray PartyMemberFollow::get_configuration_warnings() const {
|
|
PackedStringArray warnings{ super_type::get_configuration_warnings() };
|
|
if (!get_parent()->has_node(NodePath("%NavigationAgent3D")) || !cast_to<NavigationAgent3D>(get_parent()->get_node(NodePath("%NavigationAgent3D")))) {
|
|
warnings.push_back("PartyMemberFollow expects a scene sibling of type NavigationAgent3D named with unique name '%NavigationAgent3D'");
|
|
}
|
|
return warnings;
|
|
}
|
|
|
|
void PartyMemberFollow::state_entered() {
|
|
Vector<NavMarker *> const &markers{ PlayerCharacter::get_singleton()->get_party_follow_markers() };
|
|
for (NavMarker *marker : markers) {
|
|
if (marker->get_claimed() == nullptr) {
|
|
marker->set_claimed(get_character());
|
|
this->claimed_marker = marker;
|
|
if (this->nav->get_avoidance_enabled()) {
|
|
this->nav->connect("velocity_computed", callable_mp(this, &self_type::push_movement_direction));
|
|
}
|
|
set_process(true);
|
|
return;
|
|
}
|
|
}
|
|
ERR_FAIL_EDMSG("PartyMemberFollow could not find an unclaimed player follow marker");
|
|
set_state_active(false);
|
|
}
|
|
|
|
void PartyMemberFollow::state_exited() {
|
|
if (this->claimed_marker) {
|
|
this->claimed_marker->set_claimed(nullptr);
|
|
this->nav->disconnect("velocity_computed", callable_mp(this, &self_type::push_movement_direction));
|
|
set_process(false);
|
|
}
|
|
}
|