Skip to content
Snippets Groups Projects
definitions.rs 6.76 KiB
Newer Older
Louis's avatar
Louis committed
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, PartialOrd, Default)]
Louis's avatar
Louis committed
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct AnimationOverride {
	pub name: String,
	pub frame_step: usize,
	pub frame_time: f32,
Louis's avatar
Louis committed
	pub user_data: u128,
}

impl AnimationOverride {
	pub fn new(name: String) -> Self {
		Self {
			name,
			frame_time: 0.0,
			frame_step: 0,
			user_data: 0,
		}
	}

	pub fn new_with_user_data(name: String, user_data: u128) -> Self {
		Self {
			name,
			user_data,
			frame_step: 0,
			frame_time: 0.0,
		}
	}
}

pub struct OverrideStatus(pub AnimationStatus);
impl From<AnimationStatus> for OverrideStatus {
	fn from(other: AnimationStatus) -> Self {
		Self(other)
	}
}
impl Deref for OverrideStatus {
	type Target = AnimationStatus;

	fn deref(&self) -> &Self::Target {
		&self.0
	}
}
impl DerefMut for OverrideStatus {
	fn deref_mut(&mut self) -> &mut Self::Target {
		&mut self.0
	}
}

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