From a970a611928a5c7e421431c6df59eda22ebfd705 Mon Sep 17 00:00:00 2001 From: Joseph Gerardot Date: Wed, 20 Nov 2019 13:31:36 -0500 Subject: [PATCH] Add energy comsumption on rolling and charging, and accelerating regeneration when idle. --- common/src/comp/energy.rs | 3 +++ common/src/comp/mod.rs | 2 +- common/src/comp/stats.rs | 5 +---- common/src/sys/stats.rs | 44 +++++++++++++++++++++++++++++++++++---- 4 files changed, 45 insertions(+), 9 deletions(-) diff --git a/common/src/comp/energy.rs b/common/src/comp/energy.rs index 88164813e0..23d4d9535d 100644 --- a/common/src/comp/energy.rs +++ b/common/src/comp/energy.rs @@ -5,6 +5,7 @@ use specs_idvs::IDVStorage; pub struct Energy { current: u32, maximum: u32, + pub regen_rate: i32, pub last_change: Option<(i32, f64, EnergySource)>, } @@ -12,6 +13,7 @@ pub struct Energy { pub enum EnergySource { CastSpell, LevelUp, + Regen, Unknown, } @@ -20,6 +22,7 @@ impl Energy { Energy { current: amount, maximum: amount, + regen_rate: 0, last_change: None, } } diff --git a/common/src/comp/mod.rs b/common/src/comp/mod.rs index 5f2a631c89..21f6114608 100644 --- a/common/src/comp/mod.rs +++ b/common/src/comp/mod.rs @@ -26,7 +26,7 @@ pub use controller::{ ControlEvent, Controller, ControllerInputs, Input, InputState, InventoryManip, MountState, Mounting, }; -pub use energy::Energy; +pub use energy::{Energy, EnergySource}; pub use inputs::CanBuild; pub use inventory::{item, Inventory, InventoryUpdate, Item, ItemKind}; pub use last::Last; diff --git a/common/src/comp/stats.rs b/common/src/comp/stats.rs index 532f6cb8be..117f064f04 100644 --- a/common/src/comp/stats.rs +++ b/common/src/comp/stats.rs @@ -164,10 +164,7 @@ impl Stats { current: 0, maximum: 50, }, - equipment: Equipment { - main: main, - alt: None, - }, + equipment: Equipment { main, alt: None }, is_dead: false, }; diff --git a/common/src/sys/stats.rs b/common/src/sys/stats.rs index f4ac03e576..6e668a98fc 100644 --- a/common/src/sys/stats.rs +++ b/common/src/sys/stats.rs @@ -1,9 +1,13 @@ use crate::{ - comp::{HealthSource, Stats}, + comp::{ActionState, CharacterState, Energy, EnergySource, HealthSource, Stats}, event::{EventBus, ServerEvent}, state::DeltaTime, }; -use specs::{Entities, Join, Read, System, WriteStorage}; +use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage}; + +const ENERGY_REGEN_ACCEL: i32 = 1; +const BLOCK_COST: i32 = 50; +const ROLL_CHARGE_COST: i32 = 200; /// This system kills players /// and handles players levelling up @@ -13,10 +17,15 @@ impl<'a> System<'a> for Sys { Entities<'a>, Read<'a, DeltaTime>, Read<'a, EventBus>, + ReadStorage<'a, CharacterState>, WriteStorage<'a, Stats>, + WriteStorage<'a, Energy>, ); - fn run(&mut self, (entities, dt, server_event_bus, mut stats): Self::SystemData) { + fn run( + &mut self, + (entities, dt, server_event_bus, character_states, mut stats,mut energies): Self::SystemData, + ) { let mut server_event_emitter = server_event_bus.emitter(); // Increment last change timer @@ -27,7 +36,14 @@ impl<'a> System<'a> for Sys { stats.set_event_emission(true); // Mutates all stats every tick causing the server to resend this component for every entity every tick - for (entity, mut stats) in (&entities, &mut stats.restrict_mut()).join() { + for (entity, character_state, mut stats, energy) in ( + &entities, + &character_states, + &mut stats.restrict_mut(), + &mut energies, + ) + .join() + { let (set_dead, level_up) = { let stat = stats.get_unchecked(); ( @@ -58,6 +74,26 @@ impl<'a> System<'a> for Sys { stat.health .set_to(stat.health.maximum(), HealthSource::LevelUp) } + + // Recharge energy if not wielding, and accelerate. + match character_state.action { + ActionState::Wield { .. } | ActionState::Attack { .. } => energy.regen_rate = 0, + ActionState::Block { .. } => { + energy.change_by(framerate_dt(-BLOCK_COST, dt.0), EnergySource::CastSpell) + } + ActionState::Roll { .. } | ActionState::Charge { .. } => energy.change_by( + framerate_dt(-ROLL_CHARGE_COST, dt.0), + EnergySource::CastSpell, + ), + ActionState::Idle => { + energy.regen_rate += ENERGY_REGEN_ACCEL; + energy.change_by(energy.regen_rate, EnergySource::Regen); + } + } } } } +/// Convience method to scale an integer by dt +fn framerate_dt(a: i32, dt: f32) -> i32 { + (a as f32 * (dt)) as i32 +}