From 29d77b0979dee2d817119be9e98be39a02c295e5 Mon Sep 17 00:00:00 2001
From: Louis Capitanchik <contact@louiscap.co>
Date: Mon, 14 Nov 2022 03:52:09 +0000
Subject: [PATCH] Update bevy version, support AnimationOverride correctly

---
 CHANGELOG.md       | 14 +++++++
 Cargo.toml         | 14 +++----
 README.md          |  9 ++++-
 src/definitions.rs | 43 +++++++++++++++++++++-
 src/lib.rs         | 12 ++++--
 src/query.rs       | 91 ++++++++++++++++++++++++++++------------------
 src/systems.rs     |  5 ++-
 7 files changed, 138 insertions(+), 50 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index fad2cd9..1d0f824 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,20 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## [0.2.0]
+
+### Added
+- Constructor functions for `AnimationOverride`
+
+### Changed
+- `bevy` version `0.9`
+- `bevy_ecs_tilemap` version `0.9`
+- `AnimationOverride` now contains its own state
+
+### Fixed
+
+- `AnimationOverride` will play animation without needing to be driven by `apply_direction_animation`
+
 ## [0.1.1]
 
 ### Fixed
diff --git a/Cargo.toml b/Cargo.toml
index fb2ba21..8f78a35 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "micro_banimate"
-version = "0.1.1"
+version = "0.2.0"
 edition = "2021"
 license = "Apache-2.0"
 description = "Easily manage complex Bevy 2D sprite animations"
@@ -17,9 +17,9 @@ ecs_tilemap = ["dep:bevy_ecs_tilemap"]
 serde = ["dep:serde"]
 
 [dependencies]
-anyhow = "1.0.65"
-serde = { version = "1.0.145", optional = true }
-serde_json = { version = "1.0.85", optional = true }
-toml = { version = "0.5.9", optional = true }
-bevy = { version = "0.8.1", default-features = false, features = ["bevy_asset", "render"] }
-bevy_ecs_tilemap = { version = "0.7.0", optional = true }
+anyhow = "^1.0.65"
+serde = { version = "^1.0.145", optional = true }
+serde_json = { version = "^1.0.85", optional = true }
+toml = { version = "^0.5.9", optional = true }
+bevy = { version = "^0.9.0", default-features = false, features = ["bevy_asset", "render"] }
+bevy_ecs_tilemap = { version = "^0.9.0", optional = true }
diff --git a/README.md b/README.md
index 9029e6d..cb68524 100644
--- a/README.md
+++ b/README.md
@@ -116,4 +116,11 @@ frame_time = 250
 [shoot_right]
 frames = [34, 34, 34, 35, 36]
 frame_time = 100
-```
\ No newline at end of file
+```
+
+## Compatibility
+
+| banimate version | bevy version | tilemap version |
+|------------------|--------------|-----------------|
+| 0.2.x            | 0.9          | 0.9             |
+| 0.1.x            | 0.8          | 0.8             |
diff --git a/src/definitions.rs b/src/definitions.rs
index 3558442..54bba6a 100644
--- a/src/definitions.rs
+++ b/src/definitions.rs
@@ -194,13 +194,54 @@ impl SimpleAnimationBundle {
 	}
 }
 
-#[derive(Clone, Debug, Component, PartialEq, Eq, PartialOrd, Ord, Default)]
+#[derive(Clone, Debug, Component, PartialEq, PartialOrd, Default)]
 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
 pub struct AnimationOverride {
 	pub name: String,
+	pub frame_step: usize,
+	pub frame_time: f32,
 	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
+	}
+}
+
 #[derive(Clone, Debug, Bundle, PartialEq, PartialOrd, Default)]
 pub struct ChildAnimationBundle {
 	pub animation_handle: Handle<AnimationSet>,
diff --git a/src/lib.rs b/src/lib.rs
index a2cdc25..198ee30 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -11,10 +11,16 @@ mod plugin {
 
 	pub struct BanimatePluginGroup;
 	impl PluginGroup for BanimatePluginGroup {
-		fn build(&mut self, group: &mut PluginGroupBuilder) {
-			group.add(super::systems::AnimationSystemsPlugin);
+		fn build(self) -> PluginGroupBuilder {
+			let mut group =
+				PluginGroupBuilder::start::<Self>().add(super::systems::AnimationSystemsPlugin);
+
 			#[cfg(any(feature = "json_loader", feature = "toml_loader"))]
-			group.add(loader::AnimationLoadersPlugin);
+			{
+				group = group.add(loader::AnimationLoadersPlugin);
+			}
+
+			group
 		}
 	}
 }
diff --git a/src/query.rs b/src/query.rs
index 5bf2985..b18d1ae 100644
--- a/src/query.rs
+++ b/src/query.rs
@@ -50,7 +50,7 @@ pub struct AnimationQuery<'w, 's> {
 		),
 	>,
 	direction: Query<'w, 's, &'static mut Directionality>,
-	action_animation: Query<'w, 's, &'static AnimationOverride>,
+	action_animation: Query<'w, 's, &'static mut AnimationOverride>,
 	tile_sprite: Query<'w, 's, &'static mut TextureAtlasSprite>,
 	paused: Query<'w, 's, Entity, With<AnimationPaused>>,
 	events: EventWriter<'w, 's, AnimationCompleted>,
@@ -259,55 +259,74 @@ impl<'w, 's> AnimationQuery<'w, 's> {
 			if self.paused.get(entity).is_ok() {
 				continue;
 			}
-
 			let sheet = match self.animations.get(handle) {
 				Some(sheet) => sheet,
 				None => continue,
 			};
 
-			let mut current = match sheet.get(&status.active_name) {
-				Some(set) => set,
-				None => continue,
-			};
-
-			status.frame_time += dt;
-			while status.frame_time >= current.frame_secs {
-				status.frame_time -= current.frame_secs;
-				status.active_step += 1;
-			}
-
-			if status.active_step >= current.frames.len() {
-				match mode.clone() {
-					AnimationMode::Loop => {
-						status.active_step = 0;
-					}
-					AnimationMode::Once => {
-						status.active_step = current.frames.len() - 1;
-					}
-					AnimationMode::OnceThenPlay(next) => {
-						*mode = AnimationMode::Loop;
-						status.active_name = next.clone();
-						status.frame_time = 0.0;
-						status.active_step = 0;
-
-						current = match sheet.get(&status.active_name) {
-							Some(set) => set,
-							None => continue,
-						};
+			if let Ok(mut status) = self.action_animation.get_mut(entity) {
+				let current = match sheet.get(&status.name) {
+					Some(set) => set,
+					None => {
+						self.commands.entity(entity).remove::<AnimationOverride>();
+						continue;
 					}
+				};
+
+				status.frame_time += dt;
+				while status.frame_time >= current.frame_secs {
+					status.frame_time -= current.frame_secs;
+					status.frame_step += 1;
 				}
 
-				if let Ok(action_anim) = self.action_animation.get(entity) {
+				if status.frame_step >= current.frames.len() {
 					self.commands.entity(entity).remove::<AnimationOverride>();
 					self.events.send(AnimationCompleted {
 						entity,
-						user_data: action_anim.user_data,
+						user_data: status.user_data,
 					});
 				}
-			}
 
-			if let Ok(mut sprite) = self.tile_sprite.get_mut(entity) {
-				sprite.index = current.frames[status.active_step];
+				if let Ok(mut sprite) = self.tile_sprite.get_mut(entity) {
+					sprite.index = current.frames[status.frame_step];
+				}
+			} else {
+				let mut current = match sheet.get(&status.active_name) {
+					Some(set) => set,
+					None => continue,
+				};
+
+				status.frame_time += dt;
+				while status.frame_time >= current.frame_secs {
+					status.frame_time -= current.frame_secs;
+					status.active_step += 1;
+				}
+
+				if status.active_step >= current.frames.len() {
+					match mode.clone() {
+						AnimationMode::Loop => {
+							status.active_step = 0;
+						}
+						AnimationMode::Once => {
+							status.active_step = current.frames.len() - 1;
+						}
+						AnimationMode::OnceThenPlay(next) => {
+							*mode = AnimationMode::Loop;
+							status.active_name = next.clone();
+							status.frame_time = 0.0;
+							status.active_step = 0;
+
+							current = match sheet.get(&status.active_name) {
+								Some(set) => set,
+								None => continue,
+							};
+						}
+					}
+				}
+
+				if let Ok(mut sprite) = self.tile_sprite.get_mut(entity) {
+					sprite.index = current.frames[status.active_step];
+				}
 			}
 		}
 
diff --git a/src/systems.rs b/src/systems.rs
index 6a04c2f..1101632 100644
--- a/src/systems.rs
+++ b/src/systems.rs
@@ -58,7 +58,7 @@ pub fn tick_simple_tilemap_animation(
 		(
 			&SimpleLoopedAnimation,
 			&mut SimpleLoopedAnimationStatus,
-			&mut bevy_ecs_tilemap::tiles::TileTexture,
+			&mut bevy_ecs_tilemap::tiles::TileTextureIndex,
 		),
 		With<HasSimpleAnimations>,
 	>,
@@ -74,7 +74,8 @@ pub fn tick_simple_tilemap_animation(
 			}
 		}
 
-		*tile = bevy_ecs_tilemap::tiles::TileTexture(animation.frames[state.active_step] as u32);
+		*tile =
+			bevy_ecs_tilemap::tiles::TileTextureIndex(animation.frames[state.active_step] as u32);
 	}
 }
 
-- 
GitLab