use std::collections::HashMap; use std::ops::{Deref, DerefMut}; use std::time::Duration; use bevy::prelude::*; use bevy::reflect::TypeUuid; use crate::directionality::Directionality; #[derive(Clone, PartialOrd, PartialEq, Debug, Default, Reflect)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct AnimationFrames { pub frames: Vec<usize>, pub frame_secs: f32, } impl AnimationFrames { pub fn duration(&self) -> Duration { Duration::from_secs_f32(self.frames.len() as f32 * self.frame_secs) } } #[derive(Clone, Debug, TypeUuid, PartialEq, Default, Reflect, Deref, DerefMut)] #[cfg_attr( feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(transparent) )] #[uuid = "a2823f96-0f63-434e-9030-d8f762898a18"] pub struct AnimationSet(pub HashMap<String, AnimationFrames>); #[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct SyncToParent; #[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct AnimationPaused; #[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Default)] #[cfg_attr( feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(transparent) )] pub struct UserData(pub u128); #[derive(Clone, Debug, Component, PartialEq, Eq, Default)] #[cfg_attr( feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(untagged, rename_all = "snake_case") )] pub enum AnimationMode { #[default] Loop, Once, IntroLoop { intro: String, r#loop: 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 set_animation(&mut self, name: impl ToString) { self.active_name = name.to_string(); } pub fn start_animation(&mut self, name: impl ToString) { self.active_name = name.to_string(); self.active_step = 0; } pub fn start_or_continue(&mut self, name: impl ToString) { 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 DirectionalAnimationBundle { pub animation_handle: Handle<AnimationSet>, pub mode: AnimationMode, pub status: AnimationStatus, pub direction: Directionality, } impl DirectionalAnimationBundle { 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(), } } pub fn with_direction( 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, direction, } } } #[derive(Clone, Debug, Bundle, PartialEq, PartialOrd, Default)] pub struct SpriteAnimationBundle { pub animation_handle: Handle<AnimationSet>, pub mode: AnimationMode, pub status: AnimationStatus, } 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, } } } #[derive(Clone, Debug, Component, PartialEq, PartialOrd, Default, Deref, DerefMut)] #[cfg_attr( feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(transparent) )] pub struct SimpleAnimation(pub AnimationFrames); impl From<AnimationFrames> for SimpleAnimation { fn from(value: AnimationFrames) -> Self { SimpleAnimation(value) } } #[derive(Copy, Clone, Debug, Component, PartialEq, PartialOrd, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct SimpleAnimationStatus { pub active_step: usize, pub frame_time: f32, } #[derive(Clone, Debug, Bundle, PartialEq, PartialOrd, Default)] pub struct SimpleAnimationBundle { pub anim: SimpleAnimation, pub status: SimpleAnimationStatus, } impl SimpleAnimationBundle { pub fn new(frames: Vec<usize>, frame_secs: f32) -> Self { SimpleAnimationBundle { anim: AnimationFrames { frames, frame_secs }.into(), status: SimpleAnimationStatus { active_step: 0, frame_time: 0.0, }, } } } #[derive(Clone, Debug, Component, PartialEq, Eq, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct AnimationOverride { pub name: String, pub user_data: u128, } impl AnimationOverride { pub fn new(name: impl ToString) -> Self { AnimationOverride { name: name.to_string(), user_data: 0, } } pub fn with_user_data(name: impl ToString, user_data: u128) -> Self { AnimationOverride { name: name.to_string(), user_data, } } } #[derive(Clone, Debug, Component, PartialEq, Eq, Default, Deref, DerefMut)] pub struct OverrideStatus(pub AnimationStatus); impl From<AnimationStatus> for OverrideStatus { fn from(other: AnimationStatus) -> Self { Self(other) } } #[derive(Clone, Debug, Bundle, PartialEq, PartialOrd, Default)] pub struct ChildAnimationBundle { pub animation_handle: Handle<AnimationSet>, pub marker: SyncToParent, } impl ChildAnimationBundle { pub fn new(handle: Handle<AnimationSet>) -> Self { Self { animation_handle: handle, ..Default::default() } } }