Skip to content
Snippets Groups Projects
definitions.rs 5.85 KiB
Newer Older
Louis's avatar
Louis committed
use std::collections::HashMap;
Louis's avatar
Louis committed
use std::time::Duration;
Louis's avatar
Louis committed

Louis's avatar
Louis committed
use bevy::prelude::*;
Louis's avatar
Louis committed
use bevy::reflect::TypePath;
Louis's avatar
Louis committed

use crate::directionality::Directionality;

Louis's avatar
Louis committed
#[derive(Clone, PartialOrd, PartialEq, Debug, Default, Reflect)]
Louis's avatar
Louis committed
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct AnimationFrames {
	pub frames: Vec<usize>,
	pub frame_secs: f32,
}

impl AnimationFrames {
Louis's avatar
Louis committed
	pub fn duration(&self) -> Duration {
		Duration::from_secs_f32(self.frames.len() as f32 * self.frame_secs)
Louis's avatar
Louis committed
#[derive(Clone, Debug, TypePath, PartialEq, Default, Deref, DerefMut, Asset)]
Louis's avatar
Louis committed
#[cfg_attr(
	feature = "serde",
	derive(serde::Serialize, serde::Deserialize),
	serde(transparent)
)]
Louis's avatar
Louis committed
pub struct AnimationSet(pub HashMap<String, AnimationFrames>);

Louis's avatar
Louis committed
#[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Default)]
Louis's avatar
Louis committed
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
Louis's avatar
Louis committed
pub struct SyncToParent;
Louis's avatar
Louis committed

Louis's avatar
Louis committed
#[derive(Copy, Clone, Debug, Component, PartialEq, Eq, Default)]
Louis's avatar
Louis committed
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct AnimationPaused;

Louis's avatar
Louis committed
#[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")
)]
Louis's avatar
Louis committed
pub enum AnimationMode {
	#[default]
	Loop,
	Once,
Louis's avatar
Louis committed
	IntroLoop {
		intro: String,
		r#loop: String,
	},
Louis's avatar
Louis committed
}

#[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 From<String> for AnimationStatus {
	fn from(value: String) -> Self {
		AnimationStatus {
			active_name: value,
			active_step: 0,
			frame_time: 0.0,
		}
	}
}

Louis's avatar
Louis committed
impl AnimationStatus {
Louis's avatar
Louis committed
	pub fn set_animation(&mut self, name: impl ToString) {
Louis's avatar
Louis committed
		self.active_name = name.to_string();
	}
Louis's avatar
Louis committed
	pub fn start_animation(&mut self, name: impl ToString) {
Louis's avatar
Louis committed
		self.active_name = name.to_string();
		self.active_step = 0;
	}
Louis's avatar
Louis committed
	pub fn start_or_continue(&mut self, name: impl ToString) {
Louis's avatar
Louis committed
		let name = name.to_string();
		if self.active_name != name {
			self.active_name = name;
			self.active_step = 0;
		}
	}
}

#[derive(Clone, Debug, Bundle, Default)]
Louis's avatar
Louis committed
pub struct DirectionalAnimationBundle {
Louis's avatar
Louis committed
	pub animation_handle: Handle<AnimationSet>,
	pub mode: AnimationMode,
	pub status: AnimationStatus,
	pub direction: Directionality,
}

Louis's avatar
Louis committed
impl DirectionalAnimationBundle {
	pub fn new(initial_anim: impl ToString, handle: Handle<AnimationSet>) -> Self {
Louis's avatar
Louis committed
		Self {
			animation_handle: handle,
			status: AnimationStatus {
				active_name: initial_anim.to_string(),
Louis's avatar
Louis committed
				active_step: 0,
				frame_time: 0.0,
			},
			mode: AnimationMode::Loop,
			direction: Directionality::default(),
		}
	}
Louis's avatar
Louis committed
	pub fn with_direction(
Louis's avatar
Louis committed
		handle: Handle<AnimationSet>,
		direction: Directionality,
	) -> Self {
		Self {
			animation_handle: handle,
			status: AnimationStatus {
				active_name: initial_anim.to_string(),
Louis's avatar
Louis committed
				active_step: 0,
				frame_time: 0.0,
			},
			mode: AnimationMode::Loop,
			direction,
		}
	}
}

#[derive(Clone, Debug, Bundle, Default)]
Louis's avatar
Louis committed
pub struct SpriteAnimationBundle {
	pub animation_handle: Handle<AnimationSet>,
	pub mode: AnimationMode,
	pub status: AnimationStatus,
}

impl SpriteAnimationBundle {
	pub fn new(initial_anim: impl ToString, handle: Handle<AnimationSet>) -> Self {
Louis's avatar
Louis committed
		Self {
			animation_handle: handle,
			status: AnimationStatus {
				active_name: initial_anim.to_string(),
Louis's avatar
Louis committed
				active_step: 0,
				frame_time: 0.0,
			},
			mode: AnimationMode::Loop,
		}
	}
}

Louis's avatar
Louis committed
#[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)
	}
Louis's avatar
Louis committed
}

#[derive(Copy, Clone, Debug, Component, PartialEq, PartialOrd, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
Louis's avatar
Louis committed
pub struct SimpleAnimationStatus {
Louis's avatar
Louis committed
	pub active_step: usize,
	pub frame_time: f32,
}

#[derive(Clone, Debug, Bundle, PartialEq, PartialOrd, Default)]
pub struct SimpleAnimationBundle {
Louis's avatar
Louis committed
	pub anim: SimpleAnimation,
	pub status: SimpleAnimationStatus,
Louis's avatar
Louis committed
}

impl SimpleAnimationBundle {
	pub fn new(frames: Vec<usize>, frame_secs: f32) -> Self {
		SimpleAnimationBundle {
Louis's avatar
Louis committed
			anim: AnimationFrames { frames, frame_secs }.into(),
			status: SimpleAnimationStatus {
Louis's avatar
Louis committed
				active_step: 0,
				frame_time: 0.0,
			},
		}
	}
}

#[derive(Clone, Debug, Component, PartialEq, Eq, Default, Deref, DerefMut)]
Louis's avatar
Louis committed
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct OverrideData(pub u128);

#[derive(Clone, Debug, Component, PartialEq, Default, Deref, DerefMut)]
#[cfg_attr(
	feature = "serde",
	derive(serde::Serialize, serde::Deserialize),
	serde(transparent)
)]
pub struct AnimationOverride(pub AnimationStatus);

impl AnimationOverride {
Louis's avatar
Louis committed
	pub fn new(name: impl ToString) -> Self {
		AnimationOverride(name.to_string().into())
impl From<AnimationStatus> for AnimationOverride {
	fn from(other: AnimationStatus) -> Self {
		Self(other)
	}
}
impl From<String> for AnimationOverride {
	fn from(other: String) -> Self {
		AnimationStatus::from(other).into()
	}
}
#[derive(Bundle, Default)]
pub struct AnimationOverrideBundle {
	pub anim: AnimationOverride,
	pub data: OverrideData,
impl AnimationOverrideBundle {
	pub fn new(anim: impl Into<AnimationOverride>) -> Self {
Louis's avatar
Louis committed
		Self {
			anim: anim.into(),
			data: OverrideData(0),

#[derive(Clone, Debug, Bundle, Default)]
pub struct ChildAnimationBundle {
	marker: SyncToParent,
}