diff --git a/common/src/comp/energy.rs b/common/src/comp/energy.rs index 8cf2d9224e..6a0c1853f8 100644 --- a/common/src/comp/energy.rs +++ b/common/src/comp/energy.rs @@ -12,6 +12,8 @@ pub struct Energy { #[derive(Clone, Copy, Debug, Serialize, Deserialize)] pub enum EnergySource { CastSpell, + Roll, + Climb, LevelUp, Regen, Revive, diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs index 1f46394548..bcc3f4701a 100644 --- a/common/src/sys/controller.rs +++ b/common/src/sys/controller.rs @@ -17,6 +17,7 @@ use std::time::Duration; use vek::*; const CHARGE_COST: i32 = 200; +const ROLL_COST: i32 = 30; /// # Controller System /// #### Responsible for validating controller inputs and setting new Character @@ -568,6 +569,7 @@ impl<'a> System<'a> for Sys { } // Try to climb + if let (true, Some(_wall_dir)) = ( (inputs.climb.is_pressed() | inputs.climb_down.is_pressed()) && can_climb(body), @@ -603,7 +605,7 @@ impl<'a> System<'a> for Sys { { character.action = Charge { time_left: Duration::from_millis(250), - } + }; } continue; } @@ -613,10 +615,16 @@ impl<'a> System<'a> for Sys { && inputs.roll.is_pressed() && body.is_humanoid() { - character.action = Roll { - time_left: ROLL_DURATION, - was_wielding: character.action.is_wield(), - }; + if energy + .get_mut_unchecked() + .try_change_by(-ROLL_COST, EnergySource::Roll) + .is_ok() + { + character.action = Roll { + time_left: ROLL_DURATION, + was_wielding: character.action.is_wield(), + }; + } continue; } } diff --git a/common/src/sys/movement.rs b/common/src/sys/movement.rs index ac35e6ac8a..439ff9ceea 100644 --- a/common/src/sys/movement.rs +++ b/common/src/sys/movement.rs @@ -1,8 +1,8 @@ use super::phys::GRAVITY; use crate::{ comp::{ - ActionState, CharacterState, Controller, Mounting, MovementState::*, Ori, PhysicsState, - Pos, Stats, Vel, + ActionState, CharacterState, Controller, Energy, EnergySource, Mounting, MovementState::*, + Ori, PhysicsState, Pos, Stats, Vel, }, event::{EventBus, ServerEvent}, state::DeltaTime, @@ -31,6 +31,7 @@ const BLOCK_SPEED: f32 = 75.0; // Gravity is 9.81 * 4, so this makes gravity equal to .15 const GLIDE_ANTIGRAV: f32 = GRAVITY * 0.96; const CLIMB_SPEED: f32 = 5.0; +const CLIMB_COST: i32 = 5; pub const MOVEMENT_THRESHOLD_VEL: f32 = 3.0; @@ -54,6 +55,7 @@ impl<'a> System<'a> for Sys { WriteStorage<'a, Pos>, WriteStorage<'a, Vel>, WriteStorage<'a, Ori>, + WriteStorage<'a, Energy>, ReadStorage<'a, Uid>, ReadStorage<'a, Stats>, ReadStorage<'a, Controller>, @@ -72,6 +74,7 @@ impl<'a> System<'a> for Sys { mut positions, mut velocities, mut orientations, + mut energies, uids, stats, controllers, @@ -86,6 +89,7 @@ impl<'a> System<'a> for Sys { mut _pos, mut vel, mut ori, + mut energy, _uid, stats, controller, @@ -97,6 +101,7 @@ impl<'a> System<'a> for Sys { &mut positions, &mut velocities, &mut orientations, + &mut energies.restrict_mut(), &uids, &stats, &controllers, @@ -228,9 +233,21 @@ impl<'a> System<'a> for Sys { physics.on_wall, ) { if inputs.climb_down.is_pressed() && !inputs.climb.is_pressed() { - vel.0 -= dt.0 * vel.0.map(|e| e.abs().powf(1.5) * e.signum() * 6.0); + if energy + .get_mut_unchecked() + .try_change_by(-CLIMB_COST, EnergySource::Climb) + .is_ok() + { + vel.0 -= dt.0 * vel.0.map(|e| e.abs().powf(1.5) * e.signum() * 6.0); + } } else if inputs.climb.is_pressed() && !inputs.climb_down.is_pressed() { - vel.0.z = (vel.0.z + dt.0 * GRAVITY * 1.25).min(CLIMB_SPEED).max(0.0); + if energy + .get_mut_unchecked() + .try_change_by(-CLIMB_COST, EnergySource::Climb) + .is_ok() + { + vel.0.z = (vel.0.z + dt.0 * GRAVITY * 1.25).min(CLIMB_SPEED).max(0.0); + } } else { vel.0.z = (vel.0.z - dt.0 * GRAVITY * 0.01).min(CLIMB_SPEED); }