#include "player_anim_tree.hpp" #include "utils/godot_macros.hpp" #include void PlayerAnimTree::_bind_methods() { #define CLASSNAME PlayerAnimTree GDPROPERTY(target_turn_speed, gd::Variant::FLOAT); GDPROPERTY(is_walking, gd::Variant::FLOAT); GDPROPERTY(walk_speed, gd::Variant::FLOAT); GDPROPERTY(lock_running, gd::Variant::BOOL); GDFUNCTION(get_is_running); GDPROPERTY(aim_weapon, gd::Variant::BOOL); GDFUNCTION(get_fire_weapon); GDFUNCTION(get_stab); } void PlayerAnimTree::_ready() { this->parent_3d = gd::Object::cast_to(this->get_parent()); this->fsm = this->get("parameters/Actions/playback"); } void PlayerAnimTree::_process(double delta) { if(gd::Engine::get_singleton()->is_editor_hint()) return; // update timers this->fire_weapon -= delta; this->stab -= delta; this->running_time -= delta; // increase death counter if(this->is_dead && this->death_blend < 1.f) { this->death_blend = gd::Math::min(this->death_blend + float(delta * this->DEATH_BLEND_SPEED), 1.f); this->set("parameters/DeathBlend/blend_amount", this->death_blend); } // turn speed smoothing if(this->match_tags(Tags::Turn)) { this->turn_speed = gd::Math::move_toward(this->turn_speed, this->target_turn_speed, float(delta * 20.)); this->commit_turn_speed(); } // rotational root motion this->parent_3d->set_quaternion(this->get_root_motion_rotation_accumulator()); this->parent_3d->rotate_y(M_PIf); this->update_tags(this->fsm->get_current_node()); } void PlayerAnimTree::set_target_turn_speed(float value) { this->target_turn_speed = gd::Math::clamp(value, -1.f, 1.f); } float PlayerAnimTree::get_target_turn_speed() const { return this->target_turn_speed; } void PlayerAnimTree::set_is_walking(bool value) { this->is_walking = value; } bool PlayerAnimTree::get_is_walking() const { return this->is_walking; } void PlayerAnimTree::set_walk_speed(float value) { this->walk_speed = value; this->commit_walk_speed(); } float PlayerAnimTree::get_walk_speed() const { return this->walk_speed; } void PlayerAnimTree::set_lock_running(bool value) { this->lock_running = value; } bool PlayerAnimTree::get_lock_running() const { return this->lock_running; } void PlayerAnimTree::set_is_running() { this->running_time = this->RUN_PARAM_DECAY; } bool PlayerAnimTree::get_is_running() const { return this->lock_running || this->running_time > 0.0; } void PlayerAnimTree::set_aim_weapon(bool value) { this->aim_weapon = value; } bool PlayerAnimTree::get_aim_weapon() const { return this->aim_weapon; } void PlayerAnimTree::set_fire_weapon() { this->fire_weapon = this->BUTTON_PARAM_DECAY; } bool PlayerAnimTree::get_fire_weapon() { bool const is_set{this->fire_weapon > 0.0}; this->fire_weapon = 0.0; return is_set; } void PlayerAnimTree::set_stab() { this->stab = this->BUTTON_PARAM_DECAY; } bool PlayerAnimTree::get_stab() { bool const is_set{this->stab > 0.0}; this->stab = 0.0; return is_set; } void PlayerAnimTree::death_animation() { this->set("parameters/DeathSeek/request", 0.f); this->is_dead = true; } bool PlayerAnimTree::match_tags(Tags tags) const { return (this->current_tags & tags) != Tags::None; } gd::StringName const &PlayerAnimTree::get_current_state() const { return this->last_known_anim; } void PlayerAnimTree::update_tags(gd::StringName const &anim) { if(anim != this->last_known_anim && this->fsm->get_travel_path().size() <= 1) { this->last_known_anim = anim; this->current_tags = Tags::None; if(anim.contains("[turn]")) this->current_tags = Tags(this->current_tags | Tags::Turn); else this->turn_speed = 0.f; if(anim.contains("[aim]")) this->current_tags = Tags(this->current_tags | Tags::Aim); } } void PlayerAnimTree::commit_turn_speed() { this->set("parameters/Actions/Stationary [turn]/Turn/blend_position", gd::Math::abs(this->turn_speed)*this->turn_speed); } void PlayerAnimTree::commit_walk_speed() { this->set("parameters/Actions/Walk [turn]/Speed/blend_amount", this->walk_speed); this->set("parameters/Actions/Run/Speed/blend_amount", this->walk_speed); }