diff --git a/src/component.rs b/src/component.rs new file mode 100644 index 0000000..059730b --- /dev/null +++ b/src/component.rs @@ -0,0 +1,5 @@ +mod stack; +mod timer; + +pub use stack::*; +pub use timer::*; diff --git a/src/component/stack.rs b/src/component/stack.rs new file mode 100644 index 0000000..3464c00 --- /dev/null +++ b/src/component/stack.rs @@ -0,0 +1,62 @@ +use crate::EffectMergeRegistry; +use bevy_app::{App, Plugin}; +use bevy_ecs::prelude::ReflectComponent; +use bevy_ecs::prelude::{Component, Entity, EntityWorldMut}; +use bevy_reflect::prelude::ReflectDefault; +use bevy_reflect::Reflect; +use std::ops::{Add, AddAssign, Deref, DerefMut}; + +pub(crate) struct StackPlugin; + +impl Plugin for StackPlugin { + fn build(&self, app: &mut App) { + app.world_mut() + .resource_mut::() + .register::(merge_effect_stacks); + } +} + +/// Tracks the number stacks of a [merge effect](crate::EffectMode::Merge) that have been applied to an entity. +#[derive(Component, Reflect, Eq, PartialEq, Ord, PartialOrd, Debug, Copy, Clone)] +#[reflect(Component, Default, PartialEq, Debug, Clone)] +pub struct EffectStacks(pub u8); + +impl Default for EffectStacks { + fn default() -> Self { + Self(1) + } +} + +impl Deref for EffectStacks { + type Target = u8; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for EffectStacks { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl Add for EffectStacks { + type Output = Self; + + fn add(self, rhs: u8) -> Self::Output { + Self(self.0 + rhs) + } +} + +impl AddAssign for EffectStacks { + fn add_assign(&mut self, rhs: u8) { + self.0 += rhs + } +} + +/// Merge logic for [`EffectStacks`]. +fn merge_effect_stacks(mut new: EntityWorldMut, outgoing: Entity) { + let outgoing = *new.world().get::(outgoing).unwrap(); + *new.get_mut::().unwrap() += outgoing.0; +} diff --git a/src/timer.rs b/src/component/timer.rs similarity index 99% rename from src/timer.rs rename to src/component/timer.rs index dea46d5..f037da7 100644 --- a/src/timer.rs +++ b/src/component/timer.rs @@ -1,5 +1,5 @@ -use crate::ReflectComponent; use crate::registry::EffectMergeRegistry; +use crate::ReflectComponent; use bevy_app::{App, Plugin, PreUpdate}; use bevy_ecs::component::Mutable; use bevy_ecs::prelude::{Commands, Component, Entity, Query, Res}; @@ -9,7 +9,7 @@ use bevy_reflect::Reflect; use bevy_time::{Time, Timer, TimerMode}; use std::time::Duration; -pub(super) struct TimerPlugin; +pub(crate) struct TimerPlugin; impl Plugin for TimerPlugin { fn build(&self, app: &mut App) { diff --git a/src/lib.rs b/src/lib.rs index 7ac1c06..aa13687 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,20 +2,20 @@ mod bundle; mod command; +mod component; mod registry; mod relation; -mod timer; use bevy_app::{App, Plugin}; use bevy_ecs::prelude::*; -use bevy_reflect::Reflect; use bevy_reflect::prelude::ReflectDefault; +use bevy_reflect::Reflect; pub use bundle::*; pub use command::*; +pub use component::*; pub use registry::*; pub use relation::*; -pub use timer::*; /// Setup required types and systems for `bevy_alchemy`. pub struct AlchemyPlugin; @@ -29,7 +29,8 @@ impl Plugin for AlchemyPlugin { .register_type::() .register_type::() .init_resource::() - .add_plugins(TimerPlugin); + .add_plugins(TimerPlugin) + .add_plugins(StackPlugin); } }