#include "enemy_rifleman.h" #include "core/os/memory.h" #include "scene/animation/animation_player.h" #include "wave_survival/macros.h" #include "wave_survival/npc_unit.h" #include "wave_survival/player_body.h" #include "wave_survival/player_detector.h" #include "wave_survival/state_machine.h" void EnemyRifleman::_bind_methods() { BIND_PROPERTY(Variant::INT, damage_amount); ClassDB::bind_method(D_METHOD("shoot"), &self_type::shoot); } void EnemyRifleman::ready() { get_fsm()->add_state(memnew(RiflemanPatrolState)); get_fsm()->add_state(memnew(RiflemanChaseState)); get_fsm()->add_state(memnew(RiflemanFireState)); } void EnemyRifleman::_notification(int what) { if (Engine::get_singleton()->is_editor_hint()) { return; } switch (what) { default: return; case NOTIFICATION_READY: ready(); return; } } void EnemyRifleman::shoot() { if (get_detector()->line_of_sight_exists()) { PlayerBody::get_singleton()->get_health()->damage(this->damage_amount); } } void EnemyRifleman::set_damage_amount(int amount) { this->damage_amount = amount; } int EnemyRifleman::get_damage_amount() const { return this->damage_amount; } EnemyRifleman *RiflemanState::get_target() const { return cast_to(get_body()); } String RiflemanPatrolState::get_next_state() const { if (get_body()->get_unit()->is_aware_of_player()) { return RiflemanChaseState::get_class_static(); } return get_class(); } void RiflemanChaseState::enter_state() { super_type::enter_state(); if (get_body()->get_detector()->line_of_sight_exists()) { this->fire_timer = 0.3; } else { this->fire_timer = 0.0; } } void RiflemanChaseState::process(double delta) { super_type::process(delta); if (get_body()->get_detector()->line_of_sight_exists()) { this->fire_timer += delta; } else { this->fire_timer = 0.0; } } String RiflemanChaseState::get_next_state() const { if (this->fire_timer >= 0.3) { return RiflemanFireState::get_class_static(); } else { return get_class(); } } void RiflemanFireState::enter_state() { get_anim()->play("fire"); get_target()->set_movement_direction(Vector2()); } void RiflemanFireState::process(double delta) { Vector3 const body_pos{ get_target()->get_global_position() }; Vector3 player_pos{ PlayerBody::get_singleton()->get_global_position() }; player_pos.y = body_pos.y; get_target()->look_at(body_pos + player_pos - body_pos); } String RiflemanFireState::get_next_state() const { if (get_anim()->get_current_animation().is_empty()) { return RiflemanChaseState::get_class_static(); } return get_class(); }