bevy_alchemy 0.4.0

An experimental, status effects-as-entities system for Bevy.
Documentation
use crate::EffectMergeRegistry;
use bevy_app::{App, Plugin};
use bevy_ecs::prelude::ReflectComponent;
use bevy_ecs::prelude::{Component, Entity, EntityWorldMut};
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::<EffectMergeRegistry>()
            .register::<EffectStacks>(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<u8> for EffectStacks {
    type Output = Self;

    fn add(self, rhs: u8) -> Self::Output {
        Self(self.0 + rhs)
    }
}

impl AddAssign<u8> for EffectStacks {
    fn add_assign(&mut self, rhs: u8) {
        self.0 += rhs
    }
}

impl From<u8> for EffectStacks {
    fn from(value: u8) -> Self {
        EffectStacks(value)
    }
}

impl From<EffectStacks> for u8 {
    fn from(value: EffectStacks) -> Self {
        value.0
    }
}

/// A [merge function](crate::EffectMergeFn) for the [`EffectStacks`] component.
pub fn merge_effect_stacks(mut new: EntityWorldMut, outgoing: Entity) {
    let outgoing = *new.world().get::<EffectStacks>(outgoing).unwrap();
    *new.get_mut::<EffectStacks>().unwrap() += outgoing.0;
}