use crate::app_state::overworld::character::components::{StateIdle, StateRunning, StateWalking};
use crate::core::animation::components::{
SpriteAnimationClip, SpriteAnimationCurrentFrame, SpriteAnimationTimer,
};
use crate::core::basic_components::Facing;
use crate::core::character_asset::{AnimationConfigAsset, CharacterAnimator};
use crate::core::sprite::params::SpriteParams;
use bevy::log::error;
use bevy::prelude::*;
pub(crate) fn character_animation_system(
mut sprite_params: SpriteParams,
anim_configs: Res<Assets<AnimationConfigAsset>>,
mut query: Query<(
&Facing,
&CharacterAnimator,
&mut Sprite,
&mut SpriteAnimationClip,
&mut SpriteAnimationCurrentFrame,
&mut SpriteAnimationTimer,
Option<&StateIdle>,
Option<&StateWalking>,
Option<&StateRunning>,
)>,
) {
for (facing, animator, mut sprite, mut clip, mut frame, mut timer, _idle, walking, running) in
query.iter_mut()
{
let Some(config) = anim_configs.get(&animator.config) else {
continue;
};
let state_name = if running.is_some() {
"Run"
} else if walking.is_some() {
"Walk"
} else {
"Idle"
};
let Some(state_mapping) = config.states.get(state_name) else {
continue;
};
let clip_name = state_mapping.get_clip_name(&facing.value);
if clip.clip_name() != clip_name {
let new_clip = match SpriteAnimationClip::new(
&mut sprite_params.create_sprite_context(),
&config.sprite_source,
clip_name,
) {
Ok(clip) => clip,
Err(e) => {
error!(
"Failed to change animation to {}: {}. Using fallback.",
clip_name, e
);
SpriteAnimationClip::fallback(
&mut sprite_params.create_sprite_context(),
&config.sprite_source,
clip_name,
)
}
};
frame.value = 0;
timer.reset();
*clip = new_clip;
*sprite = clip.get_current_sprite().clone();
}
}
}