181 lines
5.4 KiB
Rust
181 lines
5.4 KiB
Rust
use crate::{
|
|
GameState, character::CharacterAnimations, head::ActiveHead, heads_database::HeadsDatabase,
|
|
};
|
|
use bevy::{animation::RepeatAnimation, ecs::query::QueryData, prelude::*};
|
|
use std::time::Duration;
|
|
|
|
pub fn plugin(app: &mut App) {
|
|
app.register_type::<AnimationFlags>();
|
|
|
|
app.add_systems(
|
|
Update,
|
|
update_animation.run_if(in_state(GameState::Playing)),
|
|
);
|
|
}
|
|
|
|
#[derive(Component, Default, Reflect)]
|
|
#[reflect(Component)]
|
|
pub struct AnimationFlags {
|
|
pub any_direction: bool,
|
|
pub jumping: bool,
|
|
pub just_jumped: bool,
|
|
pub shooting: bool,
|
|
pub restart_shooting: bool,
|
|
pub hit: bool,
|
|
}
|
|
|
|
#[derive(QueryData)]
|
|
#[query_data(mutable)]
|
|
pub struct AnimationController {
|
|
pub transitions: &'static mut AnimationTransitions,
|
|
pub player: &'static mut AnimationPlayer,
|
|
}
|
|
|
|
impl AnimationController {
|
|
pub fn play_inner(
|
|
player: &mut AnimationPlayer,
|
|
transitions: &mut AnimationTransitions,
|
|
animation: AnimationNodeIndex,
|
|
transition: Duration,
|
|
repeat: RepeatAnimation,
|
|
) {
|
|
transitions
|
|
.play(player, animation, transition)
|
|
.set_repeat(repeat);
|
|
}
|
|
}
|
|
|
|
impl AnimationControllerItem<'_> {
|
|
pub fn play(
|
|
&mut self,
|
|
animation: AnimationNodeIndex,
|
|
transition: Duration,
|
|
repeat: RepeatAnimation,
|
|
) {
|
|
AnimationController::play_inner(
|
|
&mut self.player,
|
|
&mut self.transitions,
|
|
animation,
|
|
transition,
|
|
repeat,
|
|
);
|
|
}
|
|
|
|
pub fn is_playing(&self, index: AnimationNodeIndex) -> bool {
|
|
self.player.is_playing_animation(index)
|
|
}
|
|
}
|
|
|
|
const DEFAULT_TRANSITION_DURATION: Duration = Duration::ZERO;
|
|
|
|
fn update_animation(
|
|
mut animated: Query<(
|
|
AnimationController,
|
|
&CharacterAnimations,
|
|
&mut AnimationFlags,
|
|
)>,
|
|
character: Query<&ActiveHead>,
|
|
headdb: Res<HeadsDatabase>,
|
|
) {
|
|
for (mut controller, anims, mut flags) in animated.iter_mut() {
|
|
let head = character.get(anims.of_character).unwrap();
|
|
let head = headdb.head_stats(head.0);
|
|
|
|
let is_playing_shoot = anims.shoot.is_some()
|
|
&& controller.is_playing(anims.shoot.unwrap())
|
|
&& !controller
|
|
.player
|
|
.animation(anims.shoot.unwrap())
|
|
.unwrap()
|
|
.is_finished();
|
|
let is_playing_run_shoot = anims.run_shoot.is_some()
|
|
&& controller.is_playing(anims.run_shoot.unwrap())
|
|
&& !controller
|
|
.player
|
|
.animation(anims.run_shoot.unwrap())
|
|
.unwrap()
|
|
.is_finished();
|
|
let wait_for_shoot = !head.interrupt_shoot && (is_playing_shoot || is_playing_run_shoot);
|
|
if wait_for_shoot {
|
|
return;
|
|
} else if flags.shooting && flags.any_direction && anims.run_shoot.is_some() {
|
|
if !controller.is_playing(anims.run_shoot.unwrap()) {
|
|
controller.play(
|
|
anims.run_shoot.unwrap(),
|
|
DEFAULT_TRANSITION_DURATION,
|
|
RepeatAnimation::Never,
|
|
);
|
|
}
|
|
if controller
|
|
.player
|
|
.animation(anims.run_shoot.unwrap())
|
|
.unwrap()
|
|
.is_finished()
|
|
|| flags.restart_shooting
|
|
{
|
|
controller
|
|
.player
|
|
.animation_mut(anims.run_shoot.unwrap())
|
|
.unwrap()
|
|
.replay();
|
|
|
|
flags.restart_shooting = false;
|
|
}
|
|
} else if flags.shooting && anims.shoot.is_some() {
|
|
if !controller.is_playing(anims.shoot.unwrap()) {
|
|
controller.play(
|
|
anims.shoot.unwrap(),
|
|
DEFAULT_TRANSITION_DURATION,
|
|
RepeatAnimation::Never,
|
|
);
|
|
}
|
|
if controller
|
|
.player
|
|
.animation(anims.shoot.unwrap())
|
|
.unwrap()
|
|
.is_finished()
|
|
|| flags.restart_shooting
|
|
{
|
|
controller
|
|
.player
|
|
.animation_mut(anims.shoot.unwrap())
|
|
.unwrap()
|
|
.replay();
|
|
|
|
flags.restart_shooting = false;
|
|
}
|
|
} else if flags.hit {
|
|
if !controller.is_playing(anims.hit) {
|
|
controller.play(
|
|
anims.hit,
|
|
DEFAULT_TRANSITION_DURATION,
|
|
RepeatAnimation::Never,
|
|
);
|
|
}
|
|
} else if flags.jumping {
|
|
if !controller.is_playing(anims.jump) || flags.just_jumped {
|
|
controller.play(
|
|
anims.jump,
|
|
DEFAULT_TRANSITION_DURATION,
|
|
RepeatAnimation::Never,
|
|
);
|
|
flags.just_jumped = false;
|
|
}
|
|
} else if flags.any_direction {
|
|
if !controller.player.is_playing_animation(anims.run) {
|
|
controller.play(
|
|
anims.run,
|
|
DEFAULT_TRANSITION_DURATION,
|
|
RepeatAnimation::Forever,
|
|
);
|
|
}
|
|
} else if !controller.is_playing(anims.idle) {
|
|
controller.play(
|
|
anims.idle,
|
|
DEFAULT_TRANSITION_DURATION,
|
|
RepeatAnimation::Forever,
|
|
);
|
|
}
|
|
}
|
|
}
|