use std::collections::HashMap; use std::ops::{Deref, DerefMut}; use bevy::asset::Handle; use bevy::prelude::{Bundle, Component}; use bevy::reflect::TypeUuid; use crate::directionality::Directionality; #[derive(Clone, PartialOrd, PartialEq, Debug, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct AnimationFrames { pub frames: Vec<usize>, pub frame_secs: f32, } impl AnimationFrames { pub fn len_secs(&self) -> f32 { self.frames.len() as f32 * self.frame_secs } } #[derive(Clone, Debug, TypeUuid, PartialEq, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[uuid = "a2823f96-0f63-434e-9030-d8f762898a18"] pub struct AnimationSet(pub HashMap<String, AnimationFrames>); impl Deref for AnimationSet { type Target = HashMap<String, AnimationFrames>; fn deref(&self) -> &Self::Target { &self.0 } } impl DerefMut for AnimationSet { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } } #[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Ord, PartialOrd, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct SyncAnimationsToParent; #[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Ord, PartialOrd, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct HasAnimations; #[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Ord, PartialOrd, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct HasSimpleAnimations; #[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Ord, PartialOrd, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct HasDirectionalityAnimation; #[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Ord, PartialOrd, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct AnimationPaused; #[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Ord, PartialOrd, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct AnimationUserData(pub u128); #[derive(Clone, Debug, Component, PartialEq, Eq, Ord, PartialOrd, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum AnimationMode { #[default] Loop, Once, OnceThenPlay(String), } #[derive(Clone, Debug, Component, PartialEq, PartialOrd, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct AnimationStatus { pub active_name: String, pub active_step: usize, pub frame_time: f32, } impl AnimationStatus { pub fn assert_animation<T: ToString>(&mut self, name: T) { self.active_name = name.to_string(); } pub fn start_animation<T: ToString>(&mut self, name: T) { self.active_name = name.to_string(); self.active_step = 0; } pub fn start_or_continue<T: ToString>(&mut self, name: T) { let name = name.to_string(); if self.active_name != name { self.active_name = name; self.active_step = 0; } } } #[derive(Clone, Debug, Bundle, PartialEq, PartialOrd, Default)] pub struct DirectionalSpriteAnimationBundle { pub animation_handle: Handle<AnimationSet>, pub mode: AnimationMode, pub status: AnimationStatus, pub direction: Directionality, pub marker: HasDirectionalityAnimation, } impl DirectionalSpriteAnimationBundle { pub fn new(initial_anim: String, handle: Handle<AnimationSet>) -> Self { Self { animation_handle: handle, status: AnimationStatus { active_name: initial_anim, active_step: 0, frame_time: 0.0, }, mode: AnimationMode::Loop, direction: Directionality::default(), marker: HasDirectionalityAnimation, } } pub fn with_initial_facing( initial_anim: String, handle: Handle<AnimationSet>, direction: Directionality, ) -> Self { Self { animation_handle: handle, status: AnimationStatus { active_name: initial_anim, active_step: 0, frame_time: 0.0, }, mode: AnimationMode::Loop, marker: HasDirectionalityAnimation, direction, } } } #[derive(Clone, Debug, Bundle, PartialEq, PartialOrd, Default)] pub struct SpriteAnimationBundle { pub animation_handle: Handle<AnimationSet>, pub mode: AnimationMode, pub status: AnimationStatus, pub marker: HasAnimations, } impl SpriteAnimationBundle { pub fn new(initial_anim: String, handle: Handle<AnimationSet>) -> Self { Self { animation_handle: handle, status: AnimationStatus { active_name: initial_anim, active_step: 0, frame_time: 0.0, }, mode: AnimationMode::Loop, marker: HasAnimations, } } } #[derive(Clone, Debug, Component, PartialEq, PartialOrd, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct SimpleLoopedAnimation { pub frames: Vec<usize>, pub frame_secs: f32, } #[derive(Copy, Clone, Debug, Component, PartialEq, PartialOrd, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct SimpleLoopedAnimationStatus { pub active_step: usize, pub frame_time: f32, } #[derive(Clone, Debug, Bundle, PartialEq, PartialOrd, Default)] pub struct SimpleAnimationBundle { pub anim: SimpleLoopedAnimation, pub status: SimpleLoopedAnimationStatus, pub marker: HasSimpleAnimations, } impl SimpleAnimationBundle { pub fn new(frames: Vec<usize>, frame_secs: f32) -> Self { SimpleAnimationBundle { anim: SimpleLoopedAnimation { frames, frame_secs }, status: SimpleLoopedAnimationStatus { active_step: 0, frame_time: 0.0, }, marker: HasSimpleAnimations, } } } #[derive(Clone, Debug, Component, PartialEq, Eq, PartialOrd, Ord, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct AnimationOverride { pub name: String, pub user_data: u128, } #[derive(Clone, Debug, Bundle, PartialEq, PartialOrd, Default)] pub struct ChildAnimationBundle { pub animation_handle: Handle<AnimationSet>, pub status: AnimationStatus, pub marker: SyncAnimationsToParent, } impl ChildAnimationBundle { pub fn new(handle: Handle<AnimationSet>) -> Self { Self { animation_handle: handle, ..Default::default() } } }