An experimental, status effects-as-entities system for Bevy.
1use crate::EffectMergeRegistry;
2use bevy_app::{App, Plugin};
3use bevy_ecs::prelude::{Component, EntityWorldMut};
4use bevy_ecs::prelude::{EntityRef, ReflectComponent};
5use bevy_reflect::Reflect;
6use bevy_reflect::prelude::ReflectDefault;
7use std::ops::{Add, AddAssign, Deref, DerefMut};
8
9pub(crate) struct StackPlugin;
10
11impl Plugin for StackPlugin {
12 fn build(&self, app: &mut App) {
13 app.world_mut()
14 .get_resource_or_init::<EffectMergeRegistry>()
15 .register::<EffectStacks>(merge_effect_stacks);
16 }
17}
18
19/// Tracks the number of times a [merge-mode](crate::EffectMode::Merge) effect has been applied to an entity.
20#[derive(Component, Reflect, Eq, PartialEq, Ord, PartialOrd, Debug, Copy, Clone)]
21#[reflect(Component, Default, PartialEq, Debug, Clone)]
22pub struct EffectStacks(pub u8);
23
24impl Default for EffectStacks {
25 fn default() -> Self {
26 Self(1)
27 }
28}
29
30impl Deref for EffectStacks {
31 type Target = u8;
32
33 fn deref(&self) -> &Self::Target {
34 &self.0
35 }
36}
37
38impl DerefMut for EffectStacks {
39 fn deref_mut(&mut self) -> &mut Self::Target {
40 &mut self.0
41 }
42}
43
44impl Add for EffectStacks {
45 type Output = Self;
46
47 fn add(self, rhs: Self) -> Self::Output {
48 Self(self.0 + rhs.0)
49 }
50}
51
52impl AddAssign for EffectStacks {
53 fn add_assign(&mut self, rhs: Self) {
54 self.0 += rhs.0
55 }
56}
57
58impl Add<u8> for EffectStacks {
59 type Output = Self;
60
61 fn add(self, rhs: u8) -> Self::Output {
62 Self(self.0 + rhs)
63 }
64}
65
66impl AddAssign<u8> for EffectStacks {
67 fn add_assign(&mut self, rhs: u8) {
68 self.0 += rhs
69 }
70}
71
72impl From<u8> for EffectStacks {
73 fn from(value: u8) -> Self {
74 EffectStacks(value)
75 }
76}
77
78impl From<EffectStacks> for u8 {
79 fn from(value: EffectStacks) -> Self {
80 value.0
81 }
82}
83
84/// A [merge function](crate::EffectMergeFn) for the [`EffectStacks`] component.
85pub fn merge_effect_stacks(mut existing: EntityWorldMut, incoming: EntityRef) {
86 let incoming = incoming.get::<EffectStacks>().unwrap();
87 *existing.get_mut::<EffectStacks>().unwrap() += incoming.0;
88}