diff --git a/src/player_states.cpp b/src/player_states.cpp index 1ec935f..4050e30 100644 --- a/src/player_states.cpp +++ b/src/player_states.cpp @@ -11,8 +11,8 @@ void PlayerState::_bind_methods() { void PlayerState::init(Node *target, StateMachine *machine) { this->state_machine = machine; - this->target = Object::cast_to(target); - if(!this->target) + this->parent = Object::cast_to(target); + if(!this->parent) UtilityFunctions::push_error("Attempt to apply player state to non-PlayerCharacter node of type '", target->get_class(), "'"); Ref game_mode = GameRoot::get_singleton()->get_game_mode(); this->player = game_mode->get_player_instance(); @@ -24,6 +24,17 @@ StringName PlayerState::get_next() const { return this->get_class(); } +float PlayerState::get_distance_from_player(bool sqr) const { + Vector3 const target_position = this->get_manual_character()->get_global_position(); + return sqr + ? target_position.distance_squared_to(this->parent->get_global_position()) + : target_position.distance_to(this->parent->get_global_position()); +} + +PlayerCharacter *PlayerState::get_manual_character() const { + return this->player->get_character(); +} + #undef CLASSNAME // PlayerState void FollowingPlayer::_bind_methods() { @@ -31,13 +42,40 @@ void FollowingPlayer::_bind_methods() { } void FollowingPlayer::_process(double delta_time) { - UtilityFunctions::print(this->get_path(), " _process"); - Vector3 const target_position = this->player->get_character()->get_global_position(); - if(target_position.distance_squared_to(this->target->get_global_position()) < 5.f * 5.f) - this->target->move(this->player->get_character()->get_velocity().normalized()); - else - this->target->move_to(target_position, 5.f); + this->parent->move(this->get_manual_character()->get_velocity_target().normalized()); +} + +StringName FollowingPlayer::get_next() const { + if(this->get_distance_from_player(true) > std::pow(4.f, 2.f)) + return "Regroup"; + return this->get_class(); } #undef CLASSNAME // FollowingPlayer + +void Regroup::_bind_methods() { +#define CLASSNAME Regroup +} + +void Regroup::_process(double delta_time) { + Basis const player_basis = this->get_manual_character()->get_global_transform().basis; + Vector3 const parent_position = this->parent->get_global_position(); + Vector3 const player_position = this->get_manual_character()->get_global_position(); + Vector3 const left = player_basis.get_column(2); + Vector3 const offset = left.dot(parent_position - player_position) * left; + this->target = player_position - player_basis.get_column(2) + offset; + this->parent->move_to(this->target, 1.f); +} + +void Regroup::_exit_tree() { + this->parent->move_to(this->parent->get_global_position(), 0.5f); +} + +StringName Regroup::get_next() const { + if(this->target.distance_squared_to(this->parent->get_global_position()) < std::pow(1.f, 2.f)) + return "FollowingPlayer"; + return this->get_class(); +} + +#undef CLASSNAME // Regroup } diff --git a/src/player_states.hpp b/src/player_states.hpp index aac2aaa..c9c48a2 100644 --- a/src/player_states.hpp +++ b/src/player_states.hpp @@ -16,7 +16,10 @@ public: virtual void init(Node *target, StateMachine *machine) override; virtual StringName get_next() const override; protected: - PlayerCharacter *target{nullptr}; + float get_distance_from_player(bool sqr = false) const; + PlayerCharacter *get_manual_character() const; +protected: + PlayerCharacter *parent{nullptr}; StateMachine *state_machine{nullptr}; TunnelsPlayer *player{nullptr}; }; @@ -26,6 +29,18 @@ class FollowingPlayer : public PlayerState { static void _bind_methods(); public: virtual void _process(double delta_time) override; + virtual StringName get_next() const override; +}; + +class Regroup : public PlayerState { + GDCLASS(Regroup, PlayerState); + static void _bind_methods(); +public: + virtual void _process(double delta_time) override; + virtual void _exit_tree() override; + virtual StringName get_next() const override; +private: + Vector3 target{0.f, 0.f, 0.f}; }; } diff --git a/src/register_types.cpp b/src/register_types.cpp index 92d2518..4bb4a43 100644 --- a/src/register_types.cpp +++ b/src/register_types.cpp @@ -58,6 +58,7 @@ void initialize_gdextension_types(ModuleInitializationLevel p_level) ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); + ClassDB::register_class(); } extern "C"