use crate::EffectMergeRegistry; use bevy_app::{App, Plugin}; use bevy_ecs::prelude::{Component, EntityWorldMut}; use bevy_ecs::prelude::{EntityRef, ReflectComponent}; use bevy_reflect::Reflect; use bevy_reflect::prelude::ReflectDefault; use std::ops::{Add, AddAssign, Deref, DerefMut}; pub(crate) struct StackPlugin; impl Plugin for StackPlugin { fn build(&self, app: &mut App) { app.world_mut() .get_resource_or_init::() .register::(merge_effect_stacks); } } /// Tracks the number of times a [merge-mode](crate::EffectMode::Merge) effect has 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: Self) -> Self::Output { Self(self.0 + rhs.0) } } impl AddAssign for EffectStacks { fn add_assign(&mut self, rhs: Self) { self.0 += rhs.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 } } impl From for EffectStacks { fn from(value: u8) -> Self { EffectStacks(value) } } impl From for u8 { fn from(value: EffectStacks) -> Self { value.0 } } /// A [merge function](crate::EffectMergeFn) for the [`EffectStacks`] component. pub fn merge_effect_stacks(mut existing: EntityWorldMut, incoming: EntityRef) { let incoming = incoming.get::().unwrap(); *existing.get_mut::().unwrap() += incoming.0; }