#![cfg(feature = "bevy")]
#[cfg(feature = "bevy_auto_plugin")]
mod auto_plugin;
use crate::StatContainer;
use crate::modifier::Modifier;
use crate::stat::Stat;
use bevy_app::{App, Plugin, PreUpdate, Update};
use bevy_ecs::component::Mutable;
use bevy_ecs::prelude::{Component, Query, ResMut, Resource, Without};
use bevy_ecs::prelude::{IntoScheduleConfigs, ReflectComponent, SystemSet};
use bevy_reflect::Reflect;
use bevy_reflect::prelude::ReflectDefault;
use std::marker::PhantomData;
#[cfg(feature = "bevy_auto_plugin")]
pub use auto_plugin::*;
pub struct ImmediateStatsPlugin;
impl Plugin for ImmediateStatsPlugin {
fn build(&self, app: &mut App) {
app.register_type::<PauseStatReset>()
.register_type::<Stat>()
.register_type::<Modifier>()
.configure_sets(Update, StatSystems::Modify.before(StatSystems::Read))
.configure_sets(PreUpdate, StatSystems::Reset);
}
}
#[derive(SystemSet, Debug, Clone, Eq, PartialEq, Hash)]
pub enum StatSystems {
Reset,
Modify,
Read,
}
#[derive(Component, Reflect, Eq, PartialEq, Debug, Default, Clone)]
#[component(storage = "SparseSet")]
#[reflect(Component, PartialEq, Debug, Default, Clone)]
pub struct PauseStatReset;
pub struct ResetComponentPlugin<T: Component<Mutability = Mutable> + StatContainer> {
_phantom: PhantomData<T>,
}
impl<T: Component<Mutability = Mutable> + StatContainer> Plugin for ResetComponentPlugin<T> {
fn build(&self, app: &mut App) {
app.add_systems(
PreUpdate,
reset_component_modifiers::<T>.in_set(StatSystems::Reset),
);
}
}
pub fn reset_component_modifiers<T: Component<Mutability = Mutable> + StatContainer>(
mut query: Query<&mut T, Without<PauseStatReset>>,
) {
for mut stat in &mut query {
stat.reset_modifiers();
}
}
impl<T: Component<Mutability = Mutable> + StatContainer> ResetComponentPlugin<T> {
#[allow(missing_docs)]
pub fn new() -> Self {
Self::default()
}
}
impl<T: Component<Mutability = Mutable> + StatContainer> Default for ResetComponentPlugin<T> {
fn default() -> Self {
Self {
_phantom: PhantomData::default(),
}
}
}
pub struct ResetResourcePlugin<T: Resource + StatContainer> {
_phantom: PhantomData<T>,
}
impl<T: Resource + StatContainer> Plugin for ResetResourcePlugin<T> {
fn build(&self, app: &mut App) {
app.add_systems(
PreUpdate,
reset_resource_modifiers::<T>.in_set(StatSystems::Reset),
);
}
}
pub fn reset_resource_modifiers<T: Resource + StatContainer>(res: Option<ResMut<T>>) {
if let Some(mut res) = res {
res.reset_modifiers();
}
}
impl<T: Resource + StatContainer> ResetResourcePlugin<T> {
#[allow(missing_docs)]
pub fn new() -> Self {
Self::default()
}
}
impl<T: Resource + StatContainer> Default for ResetResourcePlugin<T> {
fn default() -> Self {
Self {
_phantom: PhantomData::default(),
}
}
}