Skip to content
Snippets Groups Projects
definitions.rs 5.85 KiB
use std::collections::HashMap;
use std::time::Duration;

use bevy::prelude::*;
use bevy::reflect::TypePath;

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, TypePath, PartialEq, Default, Deref, DerefMut, Asset)]
#[cfg_attr(
	feature = "serde",
	derive(serde::Serialize, serde::Deserialize),
	serde(transparent)
)]
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 From<String> for AnimationStatus {
	fn from(value: String) -> Self {
		AnimationStatus {
			active_name: value,
			active_step: 0,
			frame_time: 0.0,
		}
	}
}

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, 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: impl ToString, handle: Handle<AnimationSet>) -> Self {
		Self {
			animation_handle: handle,
			status: AnimationStatus {
				active_name: initial_anim.to_string(),
				active_step: 0,
				frame_time: 0.0,
			},
			mode: AnimationMode::Loop,
			direction: Directionality::default(),
		}
	}
	pub fn with_direction(
		initial_anim: impl ToString,
		handle: Handle<AnimationSet>,
		direction: Directionality,
	) -> Self {
		Self {
			animation_handle: handle,
			status: AnimationStatus {
				active_name: initial_anim.to_string(),
				active_step: 0,
				frame_time: 0.0,
			},
			mode: AnimationMode::Loop,
			direction,
		}
	}
}

#[derive(Clone, Debug, Bundle, Default)]
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 {
		Self {
			animation_handle: handle,
			status: AnimationStatus {
				active_name: initial_anim.to_string(),
				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, Deref, DerefMut)]
#[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 {
	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 {
		Self {
			anim: anim.into(),
			data: OverrideData(0),
		}
	}
}

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