#ifndef PLAYER_CHARACTER_HPP #define PLAYER_CHARACTER_HPP #include "character_data.hpp" #include "health.hpp" #include "projectile_pool.hpp" #include "state.hpp" #include #include namespace godot { class NavigationAgent3D; class TunnelsPlayer; class AnimationPlayer; namespace goap { class Planner; }; class CharacterActor : public CharacterBody3D, public IHealthEntity { GDCLASS(CharacterActor, CharacterBody3D); static void _bind_methods(); public: virtual void _enter_tree() override; virtual void _process(double delta_time) override; virtual void _physics_process(double delta_time) override; // manually set target_velocity void move(Vector3 world_vector); // manually aim at a target position // calls aim_direction with the flattened direction to 'at' void aim(Vector3 at); // manually set the forward vector of target_rotation void aim_direction(Vector3 direction); // set a movement target to navigate towards void move_to(Vector3 to, float target_distance = 0.5f); // fire weapon at a target position // calls aim(at) and set_firing(true) void shoot_at(Vector3 at); // getter-setters void set_firing(bool firing); void set_manual_mode(bool value); void set_rotation_speed_curve(Ref curve); Ref get_rotation_speed_curve() const; virtual Health *get_health() override; virtual Health const *get_health() const override; void set_character_data(Ref data); void set_weapon_muzzle(Node3D *node); void set_velocity_target(Vector3 value); Vector3 get_velocity_target() const; bool get_is_near_player() const; CharacterActor *get_player_character() const; void set_state(goap::State state); protected: void process_behaviour(double delta_time); void process_navigation(double delta_time); void process_rotation(double delta_time); void try_fire_weapon(); private: // desired velocity, accelerated towards each frame Vector3 velocity_target{0.f,0.f,0.f}; // target rotation, slerped towards each frame Basis target_rotation{}; // ignore any ai planning or navigation bool mode_manual{false}; // fire weapon at whatever we're aiming at bool firing{false}; // the next timestamp at which a weapon can be fired float fire_timer{0.f}; // the origin point for projectiles Node3D *weapon_muzzle{nullptr}; // something that the AI wants to target Node *target{nullptr}; // the current state of the actor goap::State current_state{goap::State::new_invalid()}; AnimationPlayer *anim_player{nullptr}; Health *health{nullptr}; ProjectilePool *primary_weapon_pool{nullptr}; NavigationAgent3D *nav_agent{nullptr}; goap::Planner *planner{nullptr}; Ref rotation_speed_curve{}; // character data assigned when spawned Ref data; float fire_interval{0.f}; // derived from 1 / the current weapon's rps static float const ACCELERATION; static float const WALK_SPEED; static float const SPRINT_SPEED; static float const ROTATION_SPEED; }; } #endif // !PLAYER_CHARACTER_HPP