163 lines
3.9 KiB
C++
163 lines
3.9 KiB
C++
#include "revolver.h"
|
|
#include "scene/animation/animation_player.h"
|
|
#include "wave_survival/macros.h"
|
|
#include "wave_survival/player_body.h"
|
|
#include "wave_survival/player_camera.h"
|
|
#include "wave_survival/player_input.h"
|
|
|
|
void Revolver::_bind_methods() {
|
|
ClassDB::bind_method(D_METHOD("start_recoil"), &self_type::start_recoil);
|
|
BIND_PROPERTY(Variant::FLOAT, single_action_spread);
|
|
BIND_PROPERTY(Variant::FLOAT, double_action_spread);
|
|
}
|
|
|
|
void Revolver::queue_idle_anim() {
|
|
if (get_anim()->get_current_animation() == "run") {
|
|
stop_running();
|
|
}
|
|
// set a delay between the end of an action and (re)starting the run animation
|
|
this->run_animation_timer = this->run_animation_delay;
|
|
if (this->alt_active == true) {
|
|
get_anim()->queue("idle_single");
|
|
} else {
|
|
get_anim()->queue("idle_double");
|
|
}
|
|
}
|
|
|
|
void Revolver::start_running() {
|
|
if (this->run_animation_timer <= 0.0) {
|
|
get_anim()->queue("run");
|
|
}
|
|
}
|
|
|
|
void Revolver::stop_running() {
|
|
String const current{ get_anim()->get_current_animation() };
|
|
|
|
if (current == "run") {
|
|
get_anim()->stop();
|
|
}
|
|
if (current.begins_with("run")) {
|
|
if (this->alt_active) {
|
|
get_anim()->queue("run_to_single");
|
|
} else {
|
|
get_anim()->queue("run_to_double");
|
|
}
|
|
}
|
|
}
|
|
|
|
void Revolver::play_equip_anim() {
|
|
get_anim()->play("equip", 0.0);
|
|
queue_idle_anim();
|
|
get_anim()->advance(0.0);
|
|
}
|
|
|
|
void Revolver::shoot() {
|
|
if (animation_is_idle()) {
|
|
stop_running();
|
|
if (this->alt_active) {
|
|
this->alt_active = false;
|
|
this->muzzle->set_spread(this->single_action_spread);
|
|
get_anim()->queue("fire_single");
|
|
} else {
|
|
this->muzzle->set_spread(this->double_action_spread);
|
|
get_anim()->queue("fire_double");
|
|
}
|
|
queue_idle_anim();
|
|
}
|
|
}
|
|
|
|
void Revolver::cock_hammer() {
|
|
if (!this->alt_active && animation_is_idle()) {
|
|
stop_running();
|
|
this->alt_active = true;
|
|
get_anim()->queue("to_single");
|
|
queue_idle_anim();
|
|
}
|
|
}
|
|
|
|
void Revolver::on_primary_fire(bool pressed) {
|
|
if (pressed) {
|
|
shoot();
|
|
}
|
|
}
|
|
|
|
void Revolver::on_alt_mode(bool pressed) {
|
|
if (!this->alt_active && pressed) {
|
|
cock_hammer();
|
|
}
|
|
}
|
|
|
|
void Revolver::ready() {
|
|
this->muzzle = cast_to<HitscanMuzzle>(get_node(NodePath("%HitscanMuzzle")));
|
|
get_input()->connect(PlayerInput::sig_primary_fire, callable_mp(this, &self_type::on_primary_fire));
|
|
get_input()->connect(PlayerInput::sig_alt_mode, callable_mp(this, &self_type::on_alt_mode));
|
|
play_equip_anim();
|
|
}
|
|
|
|
void Revolver::process(double delta) {
|
|
//String const current{ get_anim()->get_current_animation() };
|
|
//double animation_time{ get_anim()->get_current_animation_position() };
|
|
if (this->recoil_timer > 0.0) {
|
|
this->recoil_timer -= delta;
|
|
double t{ 1.0 - CLAMP(this->recoil_timer / this->recoil_time, 0.0, 1.0) };
|
|
get_camera()->recoil(Math::lerp((double)this->recoil_force, 0.0, t) * delta);
|
|
}
|
|
if (this->run_animation_timer > 0.0) {
|
|
this->run_animation_timer -= delta;
|
|
}
|
|
if (!is_animating() && get_body()->get_is_running()) {
|
|
start_running();
|
|
} else if (!get_body()->get_is_running() && get_anim()->get_current_animation() == "run") {
|
|
queue_idle_anim();
|
|
}
|
|
}
|
|
|
|
bool Revolver::animation_is_idle() const {
|
|
return !is_animating() || get_anim()->get_current_animation() == "run";
|
|
}
|
|
|
|
void Revolver::_notification(int what) {
|
|
if (Engine::get_singleton()->is_editor_hint()) {
|
|
return;
|
|
}
|
|
switch (what) {
|
|
default:
|
|
return;
|
|
case NOTIFICATION_READY:
|
|
set_process(true);
|
|
ready();
|
|
return;
|
|
case NOTIFICATION_PROCESS:
|
|
process(get_process_delta_time());
|
|
return;
|
|
}
|
|
}
|
|
|
|
void Revolver::notify_selected() {
|
|
play_equip_anim();
|
|
}
|
|
|
|
bool Revolver::allows_running() const {
|
|
return true;
|
|
}
|
|
|
|
void Revolver::start_recoil() {
|
|
this->recoil_timer = this->recoil_time;
|
|
}
|
|
|
|
void Revolver::set_single_action_spread(float value) {
|
|
this->single_action_spread = value;
|
|
}
|
|
|
|
float Revolver::get_single_action_spread() const {
|
|
return this->single_action_spread;
|
|
}
|
|
|
|
void Revolver::set_double_action_spread(float value) {
|
|
this->double_action_spread = value;
|
|
}
|
|
|
|
float Revolver::get_double_action_spread() const {
|
|
return this->double_action_spread;
|
|
}
|