diff --git a/immediate_stats_macros/src/bevy_butler.rs b/immediate_stats_macros/src/bevy_butler.rs --- a/immediate_stats_macros/src/bevy_butler.rs +++ b/immediate_stats_macros/src/bevy_butler.rs @@ -14,32 +14,33 @@ continue; }; - match ident.to_string().as_str() { - "resource" => { - let _ = attr.parse_nested_meta(|meta| { - let Some(var_name) = meta.path.segments.first() else { - return Ok(()) - }; - - if var_name.ident.to_string() != "plugin" { - return Ok(()) - }; - - let input = &meta.input; - - input.parse::().expect("An equals sign."); - let input = input.parse::().expect("An identifier."); - - systems.push(quote! { - #[bevy_butler::system(generics = <#struct_name>, plugin = #input, schedule = bevy_app::PreUpdate)] - use crate::bevy::reset_resource_modifiers; - }); - - Ok(()) - }); - } + let use_system = match ident.to_string().as_str() { + "resource" => quote! { use crate::bevy::reset_resource_modifiers; }, + "stat_butler_component" => quote! { use crate::bevy::reset_component_modifiers; }, _ => continue, - } + }; + + attr.parse_nested_meta(|meta| { + let Some(var_name) = meta.path.segments.first() else { + return Ok(()) + }; + + if var_name.ident.to_string() != "plugin" { + return Ok(()) + }; + + let input = &meta.input; + + input.parse::().expect("An equals sign."); + let input = input.parse::().expect("An identifier."); + + systems.push(quote! { + #[bevy_butler::system(generics = <#struct_name>, plugin = #input, schedule = bevy_app::PreUpdate)] + #use_system + }); + + Ok(()) + }).unwrap(); } quote! { #(#systems)* } diff --git a/immediate_stats_macros/src/lib.rs b/immediate_stats_macros/src/lib.rs --- a/immediate_stats_macros/src/lib.rs +++ b/immediate_stats_macros/src/lib.rs @@ -8,7 +8,7 @@ use quote::{ToTokens, quote}; use syn::{Data, DataEnum, DataStruct, DeriveInput, Field, Ident, Index}; -#[proc_macro_derive(StatContainer, attributes(stat, stat_ignore))] +#[proc_macro_derive(StatContainer, attributes(stat, stat_ignore, stat_butler_component))] #[proc_macro_error] pub fn stat_container_derive(item: proc_macro::TokenStream) -> proc_macro::TokenStream { let tree: DeriveInput = syn::parse(item).expect("TokenStream must be valid."); diff --git a/immediate_stats/src/bevy/butler.rs b/immediate_stats/src/bevy/butler.rs --- a/immediate_stats/src/bevy/butler.rs +++ b/immediate_stats/src/bevy/butler.rs @@ -11,9 +11,33 @@ #[butler_plugin] struct MyPlugin; - #[derive(Reflect, Resource, StatContainer, Default, PartialEq, Debug)] + #[derive(Reflect, Resource, Component, StatContainer, Default, PartialEq, Debug)] + #[stat_butler_component(plugin = MyPlugin)] #[resource(plugin = MyPlugin)] struct Health(Stat); + + #[test] + fn reset_component_auto() { + let mut app = App::new(); + + app.add_plugins(MyPlugin); + + let entity = app + .world_mut() + .spawn(Health(Stat { + base: 100, + bonus: 50, + multiplier: 2.0, + })) + .id(); + + app.update(); + + assert_eq!( + app.world().get::(entity), + Some(Health(Stat::new(100))).as_ref() + ); + } #[test] fn reset_resource_auto() {