Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add reflection to all types #57

Merged
merged 1 commit into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions src/charges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
//! Actions may only be used if at least one charge is available.
//! Unlike pools, charges are not shared across abilities.

use bevy::ecs::prelude::{Component, Resource};
use bevy::{
ecs::prelude::{Component, Resource},
reflect::Reflect,
};
use std::marker::PhantomData;

use crate::{Abilitylike, CannotUseAbility};
Expand Down Expand Up @@ -80,10 +83,11 @@ use std::collections::HashMap;
/// Action::Spell.trigger(&mut abilities_bundle.charges, &mut abilities_bundle.cooldowns, Some(&mut mana_bundle.pool), Some(&mut mana_bundle.ability_costs));
/// }
/// ```
#[derive(Resource, Component, Clone, PartialEq, Eq, Debug)]
#[derive(Resource, Component, Clone, PartialEq, Eq, Debug, Reflect)]
pub struct ChargeState<A: Abilitylike> {
/// The underlying [`Charges`].
charges_map: HashMap<A, Charges>,
#[reflect(ignore)]
_phantom: PhantomData<A>,
}

Expand All @@ -100,7 +104,7 @@ impl<A: Abilitylike> Default for ChargeState<A> {
///
/// Charges refresh when [`Charges::refresh`] is called manually,
/// or when the corresponding cooldown expires (if the [`InputManagerPlugin`](crate::plugin::InputManagerPlugin) is added).
#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, PartialEq, Eq, Debug, Reflect)]
pub struct Charges {
current: u8,
max: u8,
Expand All @@ -111,7 +115,7 @@ pub struct Charges {
}

/// What happens when [`Charges`] are replenished?
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Reflect)]
pub enum ReplenishStrategy {
/// A single charge will be recovered.
///
Expand All @@ -124,7 +128,7 @@ pub enum ReplenishStrategy {
}

/// How do these charges replenish when cooldowns are refreshed?
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Reflect)]
pub enum CooldownStrategy {
/// Cooldowns refresh will have no effect on the charges.
Ignore,
Expand Down
10 changes: 7 additions & 3 deletions src/cooldown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ use crate::{
Abilitylike, CannotUseAbility,
};

use bevy::ecs::prelude::{Component, Resource};
use bevy::utils::Duration;
use bevy::{
ecs::prelude::{Component, Resource},
reflect::Reflect,
};
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, marker::PhantomData};

Expand Down Expand Up @@ -49,7 +52,7 @@ use std::{collections::HashMap, marker::PhantomData};
/// // We just jumped, so the cooldown isn't ready yet
/// assert_eq!(cooldowns.ready(Action::Jump), Err(CannotUseAbility::OnCooldown));
/// ```
#[derive(Resource, Component, Debug, Clone, PartialEq, Eq)]
#[derive(Resource, Component, Debug, Clone, PartialEq, Eq, Reflect)]
pub struct CooldownState<A: Abilitylike> {
/// The [`Cooldown`] of each action
///
Expand All @@ -61,6 +64,7 @@ pub struct CooldownState<A: Abilitylike> {
/// Whenever any cooldown for an action of type `A` is triggered,
/// this global cooldown is triggered.
pub global_cooldown: Option<Cooldown>,
#[reflect(ignore)]
_phantom: PhantomData<A>,
}

Expand Down Expand Up @@ -251,7 +255,7 @@ impl<A: Abilitylike> CooldownState<A> {
/// cooldown.refresh();
/// assert!(cooldown.ready().is_ok());
/// ```
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize, Reflect)]
pub struct Cooldown {
max_time: Duration,
/// The amount of time that has elapsed since all [`Charges`](crate::charges::Charges) were fully replenished.
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#![doc = include_str!("../README.md")]

use crate::cooldown::CooldownState;
use bevy::ecs::prelude::*;
use bevy::{ecs::prelude::*, reflect::Reflect};
use charges::{ChargeState, Charges};
use cooldown::Cooldown;
use leafwing_input_manager::Actionlike;
Expand Down Expand Up @@ -219,7 +219,7 @@ pub fn trigger_ability<P: Pool>(
/// If you would like to track resource costs for your abilities, combine this with a [`PoolBundle`](crate::pool::PoolBundle).
///
/// Use with [`AbilityPlugin`](crate::plugin::AbilityPlugin), providing the same enum type to both.
#[derive(Bundle, Clone, Debug, PartialEq, Eq)]
#[derive(Bundle, Clone, Debug, PartialEq, Eq, Reflect)]
pub struct AbilitiesBundle<A: Abilitylike> {
/// A [`CooldownState`] component
pub cooldowns: CooldownState<A>,
Expand Down
5 changes: 4 additions & 1 deletion src/plugin.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Contains main plugin exported by this crate.

use crate::Abilitylike;
use crate::{AbilitiesBundle, Abilitylike};
use bevy::ecs::prelude::*;
use core::marker::PhantomData;

Expand Down Expand Up @@ -65,6 +65,9 @@ impl<A: Abilitylike> Plugin for AbilityPlugin<A> {
.before(InputManagerSystem::Update),
);

// Type registration
app.register_type::<AbilitiesBundle<A>>();

// Resources
app.init_resource::<ToggleActions<A>>();
}
Expand Down
13 changes: 9 additions & 4 deletions src/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
//! Pools have a maximum value and a minimum value (almost always zero), can regenerate over time, and can be spent to pay for abilities.
//!
//! The [`regenerate_resource_pool`](crate::systems::regenerate_resource_pool) system will regenerate resource pools of a given type if manually added.
//!
//! Remember to manually register these types for reflection with [`App::register_type`](bevy::app::App::register_type) if you wish to serialize or inspect them.

use bevy::ecs::prelude::*;
use bevy::utils::Duration;
use bevy::{ecs::prelude::*, reflect::Reflect};
use core::ops::{Add, AddAssign, Div, Mul, Sub, SubAssign};
use std::{collections::HashMap, marker::PhantomData};
use thiserror::Error;
Expand Down Expand Up @@ -146,7 +148,7 @@ pub trait RegeneratingPool: Pool {
pub struct MaxPoolLessThanMin;

/// Stores the cost (in terms of the [`Pool::Quantity`] of ability) associated with each ability of type `A`.
#[derive(Component, Debug)]
#[derive(Component, Resource, Debug, Reflect)]
pub struct AbilityCosts<A: Abilitylike, P: Pool> {
/// The underlying cost of each ability.
cost_map: HashMap<A, P::Quantity>,
Expand Down Expand Up @@ -270,12 +272,15 @@ impl<A: Abilitylike, P: Pool> AbilityCosts<A, P> {
/// as you want the other functionality of pools (current, max, regen, depletion)
/// but often cannot spend it on abilities.
///
/// # Important Note
/// # Usage
///
/// Note that resource pools are not controlled by [`AbilityPlugin`](crate::plugin::AbilityPlugin).
/// If you want regeneration to occur automatically, add [`regenerate_resource_pool`](crate::systems::regenerate_resource_pool)
/// to your schedule.
#[derive(Bundle)]
///
/// These types are not automatically registered by [`AbilityPlugin`](crate::plugin::AbilityPlugin).
/// You must register them manually with [`App::register_type`](bevy::app::App::register_type) if you wish to serialize or inspect them.
#[derive(Bundle, Reflect)]
pub struct PoolBundle<A: Abilitylike, P: Pool + Component> {
/// The resource pool used to pay for abilities
pub pool: P,
Expand Down
12 changes: 8 additions & 4 deletions src/premade_pools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use derive_more::{Add, AddAssign, Sub, SubAssign};

/// A premade resource pool for life (aka health, hit points or HP).
pub mod life {
use bevy::reflect::Reflect;

use crate::pool::RegeneratingPool;

use super::*;
Expand All @@ -19,7 +21,7 @@ pub mod life {
/// If they lose it all, they die or pass out.
///
/// This is intended to be stored as a component on each entity.
#[derive(Debug, Clone, PartialEq, Component, Resource)]
#[derive(Debug, Clone, PartialEq, Component, Resource, Reflect)]
pub struct LifePool {
/// The current life.
current: Life,
Expand Down Expand Up @@ -52,7 +54,7 @@ pub mod life {
///
/// This can be used for damage computations, life regeneration, healing and so on.
#[derive(
Debug, Clone, Copy, PartialEq, PartialOrd, Default, Add, Sub, AddAssign, SubAssign,
Debug, Clone, Copy, PartialEq, PartialOrd, Default, Add, Sub, AddAssign, SubAssign, Reflect,
)]
pub struct Life(pub f32);

Expand Down Expand Up @@ -172,6 +174,8 @@ pub mod life {

/// A premade resource pool for mana (aka MP).
pub mod mana {
use bevy::reflect::Reflect;

use crate::pool::RegeneratingPool;

use super::*;
Expand All @@ -180,7 +184,7 @@ pub mod mana {
/// Units must spend mana to cast spells according to their [`AbilityCosts<A, Mana>`](crate::pool::AbilityCosts) component.
///
/// This is intended to be stored as a component on each entity.
#[derive(Debug, Clone, PartialEq, Component, Resource)]
#[derive(Debug, Clone, PartialEq, Component, Resource, Reflect)]
pub struct ManaPool {
/// The current mana.
current: Mana,
Expand Down Expand Up @@ -212,7 +216,7 @@ pub mod mana {
///
/// This can be used for ability costs, mana regeneration and so on.
#[derive(
Debug, Clone, Copy, PartialEq, PartialOrd, Default, Add, Sub, AddAssign, SubAssign,
Debug, Clone, Copy, PartialEq, PartialOrd, Default, Add, Sub, AddAssign, SubAssign, Reflect,
)]
pub struct Mana(pub f32);

Expand Down
Loading