From 1aa98dbb62ac2a26207f64581a7668324aadffe6 Mon Sep 17 00:00:00 2001 From: Ben Simpson Date: Thu, 13 Feb 2020 07:30:32 +0000 Subject: [PATCH 1/5] Update common/src/comp/energy.rs, energy.rs, common/src/sys/controller.rs, common/src/sys/movement.rs, movement.rs files --- common/src/comp/energy.rs | 2 + common/src/sys/controller.rs | 35 +++-- common/src/sys/movement.rs | 15 ++- energy.rs | 77 +++++++++++ movement.rs | 253 +++++++++++++++++++++++++++++++++++ 5 files changed, 368 insertions(+), 14 deletions(-) create mode 100644 energy.rs create mode 100644 movement.rs 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..fe7d17b970 100644 --- a/common/src/sys/controller.rs +++ b/common/src/sys/controller.rs @@ -17,6 +17,8 @@ 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,14 +570,16 @@ impl<'a> System<'a> for Sys { } // Try to climb - if let (true, Some(_wall_dir)) = ( + + if let (true, Some(_wall_dir)) = ( (inputs.climb.is_pressed() | inputs.climb_down.is_pressed()) && can_climb(body), - physics.on_wall, - ) { - character.movement = Climb; - continue; - } + physics.on_wall,) + { + + character.movement = Climb; + continue; + } // Try to swim if !physics.on_ground { @@ -603,7 +607,8 @@ impl<'a> System<'a> for Sys { { character.action = Charge { time_left: Duration::from_millis(250), - } + }; + } continue; } @@ -613,10 +618,18 @@ 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..5724eee013 100644 --- a/common/src/sys/movement.rs +++ b/common/src/sys/movement.rs @@ -2,7 +2,7 @@ use super::phys::GRAVITY; use crate::{ comp::{ ActionState, CharacterState, Controller, Mounting, MovementState::*, Ori, PhysicsState, - Pos, Stats, Vel, + Pos, Stats, Vel, Energy, EnergySource }, 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,13 @@ 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); } diff --git a/energy.rs b/energy.rs new file mode 100644 index 0000000000..6a0c1853f8 --- /dev/null +++ b/energy.rs @@ -0,0 +1,77 @@ +use specs::{Component, FlaggedStorage}; +use specs_idvs::IDVStorage; + +#[derive(Clone, Copy, Debug, Serialize, Deserialize)] +pub struct Energy { + current: u32, + maximum: u32, + pub regen_rate: f32, + pub last_change: Option<(i32, f64, EnergySource)>, +} + +#[derive(Clone, Copy, Debug, Serialize, Deserialize)] +pub enum EnergySource { + CastSpell, + Roll, + Climb, + LevelUp, + Regen, + Revive, + Unknown, +} + +#[derive(Debug)] +pub enum StatChangeError { + Underflow, + Overflow, +} + +impl Energy { + pub fn new(amount: u32) -> Energy { + Energy { + current: amount, + maximum: amount, + regen_rate: 0.0, + last_change: None, + } + } + + pub fn current(&self) -> u32 { self.current } + + pub fn maximum(&self) -> u32 { self.maximum } + + pub fn set_to(&mut self, amount: u32, cause: EnergySource) { + let amount = amount.min(self.maximum); + self.last_change = Some((amount as i32 - self.current as i32, 0.0, cause)); + self.current = amount; + } + + pub fn change_by(&mut self, amount: i32, cause: EnergySource) { + self.current = ((self.current as i32 + amount).max(0) as u32).min(self.maximum); + self.last_change = Some((amount, 0.0, cause)); + } + + pub fn try_change_by( + &mut self, + amount: i32, + cause: EnergySource, + ) -> Result<(), StatChangeError> { + if self.current as i32 + amount < 0 { + Err(StatChangeError::Underflow) + } else if self.current as i32 + amount > self.maximum as i32 { + Err(StatChangeError::Overflow) + } else { + self.change_by(amount, cause); + Ok(()) + } + } + + pub fn set_maximum(&mut self, amount: u32) { + self.maximum = amount; + self.current = self.current.min(self.maximum); + } +} + +impl Component for Energy { + type Storage = FlaggedStorage>; +} diff --git a/movement.rs b/movement.rs new file mode 100644 index 0000000000..5724eee013 --- /dev/null +++ b/movement.rs @@ -0,0 +1,253 @@ +use super::phys::GRAVITY; +use crate::{ + comp::{ + ActionState, CharacterState, Controller, Mounting, MovementState::*, Ori, PhysicsState, + Pos, Stats, Vel, Energy, EnergySource + }, + event::{EventBus, ServerEvent}, + state::DeltaTime, + sync::Uid, + terrain::TerrainGrid, +}; +use specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage}; +use std::time::Duration; +use vek::*; + +pub const ROLL_DURATION: Duration = Duration::from_millis(600); + +const BASE_HUMANOID_ACCEL: f32 = 100.0; +const BASE_HUMANOID_SPEED: f32 = 120.0; +const BASE_HUMANOID_AIR_ACCEL: f32 = 15.0; +const BASE_HUMANOID_AIR_SPEED: f32 = 100.0; +const BASE_HUMANOID_WATER_ACCEL: f32 = 70.0; +const BASE_HUMANOID_WATER_SPEED: f32 = 120.0; +const BASE_HUMANOID_CLIMB_ACCEL: f32 = 10.0; +const ROLL_SPEED: f32 = 17.0; +const CHARGE_SPEED: f32 = 20.0; +const GLIDE_ACCEL: f32 = 15.0; +const GLIDE_SPEED: f32 = 45.0; +const BLOCK_ACCEL: f32 = 30.0; +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; + +/// # Movement System +/// #### Applies forces, calculates new positions and velocities,7 +/// #### based on Controller(Inputs) and CharacterState. +/// ---- +/// +/// **Writes:** +/// Pos, Vel, Ori +/// +/// **Reads:** +/// Uid, Stats, Controller, PhysicsState, CharacterState, Mounting +pub struct Sys; +impl<'a> System<'a> for Sys { + type SystemData = ( + Entities<'a>, + ReadExpect<'a, TerrainGrid>, + Read<'a, EventBus>, + Read<'a, DeltaTime>, + WriteStorage<'a, Pos>, + WriteStorage<'a, Vel>, + WriteStorage<'a, Ori>, + WriteStorage<'a, Energy>, + ReadStorage<'a, Uid>, + ReadStorage<'a, Stats>, + ReadStorage<'a, Controller>, + ReadStorage<'a, PhysicsState>, + ReadStorage<'a, CharacterState>, + ReadStorage<'a, Mounting>, + ); + + fn run( + &mut self, + ( + entities, + _terrain, + _server_bus, + dt, + mut positions, + mut velocities, + mut orientations, + mut energies, + uids, + stats, + controllers, + physics_states, + character_states, + mountings, + ): Self::SystemData, + ) { + // Apply movement inputs + for ( + _entity, + mut _pos, + mut vel, + mut ori, + mut energy, + _uid, + stats, + controller, + physics, + character, + mount, + ) in ( + &entities, + &mut positions, + &mut velocities, + &mut orientations, + &mut energies.restrict_mut(), + &uids, + &stats, + &controllers, + &physics_states, + &character_states, + mountings.maybe(), + ) + .join() + { + if stats.is_dead { + continue; + } + + if mount.is_some() { + continue; + } + + let inputs = &controller.inputs; + + if character.action.is_roll() { + vel.0 = Vec3::new(0.0, 0.0, vel.0.z) + + (vel.0 * Vec3::new(1.0, 1.0, 0.0) + + 1.5 * inputs.move_dir.try_normalized().unwrap_or_default()) + .try_normalized() + .unwrap_or_default() + * ROLL_SPEED; + } else if character.action.is_charge() { + vel.0 = Vec3::new(0.0, 0.0, vel.0.z) + + (vel.0 * Vec3::new(1.0, 1.0, 0.0) + + 1.5 * inputs.move_dir.try_normalized().unwrap_or_default()) + .try_normalized() + .unwrap_or_default() + * CHARGE_SPEED; + } else if character.action.is_block() { + vel.0 += Vec2::broadcast(dt.0) + * inputs.move_dir + * match physics.on_ground { + true if vel.0.magnitude_squared() < BLOCK_SPEED.powf(2.0) => BLOCK_ACCEL, + _ => 0.0, + } + } else { + // Move player according to move_dir + vel.0 += Vec2::broadcast(dt.0) + * inputs.move_dir + * match (physics.on_ground, &character.movement) { + (true, Run) + if vel.0.magnitude_squared() + < (BASE_HUMANOID_SPEED + stats.fitness as f32 * 50.0).powf(2.0) => + { + BASE_HUMANOID_ACCEL + }, + (false, Climb) + if vel.0.magnitude_squared() < BASE_HUMANOID_SPEED.powf(2.0) => + { + BASE_HUMANOID_CLIMB_ACCEL + }, + (false, Glide) if vel.0.magnitude_squared() < GLIDE_SPEED.powf(2.0) => { + GLIDE_ACCEL + }, + (false, Fall) | (false, Jump) + if vel.0.magnitude_squared() + < (BASE_HUMANOID_AIR_SPEED + stats.fitness as f32 * 10.0) + .powf(2.0) => + { + BASE_HUMANOID_AIR_ACCEL + }, + (false, Swim) + if vel.0.magnitude_squared() + < (BASE_HUMANOID_WATER_SPEED + stats.fitness as f32 * 30.0) + .powf(2.0) => + { + BASE_HUMANOID_WATER_ACCEL + stats.fitness as f32 * 10.0 + }, + _ => 0.0, + }; + } + + // Set direction based on move direction when on the ground + let ori_dir = if + //character.action.is_wield() || + character.action.is_attack() || character.action.is_block() { + Vec2::from(inputs.look_dir).normalized() + } else if let (Climb, Some(wall_dir)) = (character.movement, physics.on_wall) { + if Vec2::::from(wall_dir).magnitude_squared() > 0.001 { + Vec2::from(wall_dir).normalized() + } else { + Vec2::from(inputs.move_dir) + } + } else if let Glide = character.movement { + // Note: non-gliding forces will also affect velocity and thus orientation + // producing potentially unexpected changes in direction + Vec2::from(vel.0) + } else { + if let ActionState::Roll { .. } = character.action { + // So can can't spin/slip around while rolling + Vec2::from(vel.0) + } else { + Vec2::from(inputs.move_dir) + } + }; + + if ori_dir.magnitude_squared() > 0.0001 + && (ori.0.normalized() - Vec3::from(ori_dir).normalized()).magnitude_squared() + > 0.001 + { + ori.0 = vek::ops::Slerp::slerp( + ori.0, + ori_dir.into(), + if physics.on_ground { 9.0 } else { 2.0 } * dt.0, + ); + } + + // Glide + if character.movement == Glide + && Vec2::::from(vel.0).magnitude_squared() < GLIDE_SPEED.powf(2.0) + && vel.0.z < 0.0 + { + let lift = GLIDE_ANTIGRAV + vel.0.z.abs().powf(2.0) * 0.15; + vel.0.z += dt.0 + * lift + * (Vec2::::from(vel.0).magnitude() * 0.075) + .min(1.0) + .max(0.2); + } + + // Climb + if let (true, Some(_wall_dir)) = ( + character.movement == Climb && vel.0.z <= CLIMB_SPEED, + physics.on_wall, + ) { + if inputs.climb_down.is_pressed() && !inputs.climb.is_pressed() { + 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() { + 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); + } + } + + if character.movement == Swim && inputs.jump.is_pressed() { + vel.0.z = (vel.0.z + dt.0 * GRAVITY * 1.25).min(BASE_HUMANOID_WATER_SPEED); + } + } + } +} From a49482503d2fd169b9922af3a5cac6ff8c77784a Mon Sep 17 00:00:00 2001 From: Ben Simpson Date: Thu, 13 Feb 2020 07:59:54 +0000 Subject: [PATCH 2/5] Update common/src/sys/controller.rs, common/src/sys/movement.rs files Deleted energy.rs, movement.rs files --- common/src/sys/controller.rs | 5 +- common/src/sys/movement.rs | 10 +- energy.rs | 77 ----------- movement.rs | 253 ----------------------------------- 4 files changed, 9 insertions(+), 336 deletions(-) delete mode 100644 energy.rs delete mode 100644 movement.rs diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs index fe7d17b970..1e9c9de561 100644 --- a/common/src/sys/controller.rs +++ b/common/src/sys/controller.rs @@ -576,8 +576,7 @@ impl<'a> System<'a> for Sys { && can_climb(body), physics.on_wall,) { - - character.movement = Climb; + character.movement = Climb; continue; } @@ -627,8 +626,6 @@ impl<'a> System<'a> for Sys { 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 5724eee013..5a7108ae34 100644 --- a/common/src/sys/movement.rs +++ b/common/src/sys/movement.rs @@ -233,11 +233,17 @@ impl<'a> System<'a> for Sys { physics.on_wall, ) { if inputs.climb_down.is_pressed() && !inputs.climb.is_pressed() { - if energy.get_mut_unchecked().try_change_by(-CLIMB_COST, EnergySource::Climb).is_ok(){ + 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() { - if energy.get_mut_unchecked().try_change_by(-CLIMB_COST, EnergySource::Climb).is_ok(){ + 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 { diff --git a/energy.rs b/energy.rs deleted file mode 100644 index 6a0c1853f8..0000000000 --- a/energy.rs +++ /dev/null @@ -1,77 +0,0 @@ -use specs::{Component, FlaggedStorage}; -use specs_idvs::IDVStorage; - -#[derive(Clone, Copy, Debug, Serialize, Deserialize)] -pub struct Energy { - current: u32, - maximum: u32, - pub regen_rate: f32, - pub last_change: Option<(i32, f64, EnergySource)>, -} - -#[derive(Clone, Copy, Debug, Serialize, Deserialize)] -pub enum EnergySource { - CastSpell, - Roll, - Climb, - LevelUp, - Regen, - Revive, - Unknown, -} - -#[derive(Debug)] -pub enum StatChangeError { - Underflow, - Overflow, -} - -impl Energy { - pub fn new(amount: u32) -> Energy { - Energy { - current: amount, - maximum: amount, - regen_rate: 0.0, - last_change: None, - } - } - - pub fn current(&self) -> u32 { self.current } - - pub fn maximum(&self) -> u32 { self.maximum } - - pub fn set_to(&mut self, amount: u32, cause: EnergySource) { - let amount = amount.min(self.maximum); - self.last_change = Some((amount as i32 - self.current as i32, 0.0, cause)); - self.current = amount; - } - - pub fn change_by(&mut self, amount: i32, cause: EnergySource) { - self.current = ((self.current as i32 + amount).max(0) as u32).min(self.maximum); - self.last_change = Some((amount, 0.0, cause)); - } - - pub fn try_change_by( - &mut self, - amount: i32, - cause: EnergySource, - ) -> Result<(), StatChangeError> { - if self.current as i32 + amount < 0 { - Err(StatChangeError::Underflow) - } else if self.current as i32 + amount > self.maximum as i32 { - Err(StatChangeError::Overflow) - } else { - self.change_by(amount, cause); - Ok(()) - } - } - - pub fn set_maximum(&mut self, amount: u32) { - self.maximum = amount; - self.current = self.current.min(self.maximum); - } -} - -impl Component for Energy { - type Storage = FlaggedStorage>; -} diff --git a/movement.rs b/movement.rs deleted file mode 100644 index 5724eee013..0000000000 --- a/movement.rs +++ /dev/null @@ -1,253 +0,0 @@ -use super::phys::GRAVITY; -use crate::{ - comp::{ - ActionState, CharacterState, Controller, Mounting, MovementState::*, Ori, PhysicsState, - Pos, Stats, Vel, Energy, EnergySource - }, - event::{EventBus, ServerEvent}, - state::DeltaTime, - sync::Uid, - terrain::TerrainGrid, -}; -use specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage}; -use std::time::Duration; -use vek::*; - -pub const ROLL_DURATION: Duration = Duration::from_millis(600); - -const BASE_HUMANOID_ACCEL: f32 = 100.0; -const BASE_HUMANOID_SPEED: f32 = 120.0; -const BASE_HUMANOID_AIR_ACCEL: f32 = 15.0; -const BASE_HUMANOID_AIR_SPEED: f32 = 100.0; -const BASE_HUMANOID_WATER_ACCEL: f32 = 70.0; -const BASE_HUMANOID_WATER_SPEED: f32 = 120.0; -const BASE_HUMANOID_CLIMB_ACCEL: f32 = 10.0; -const ROLL_SPEED: f32 = 17.0; -const CHARGE_SPEED: f32 = 20.0; -const GLIDE_ACCEL: f32 = 15.0; -const GLIDE_SPEED: f32 = 45.0; -const BLOCK_ACCEL: f32 = 30.0; -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; - -/// # Movement System -/// #### Applies forces, calculates new positions and velocities,7 -/// #### based on Controller(Inputs) and CharacterState. -/// ---- -/// -/// **Writes:** -/// Pos, Vel, Ori -/// -/// **Reads:** -/// Uid, Stats, Controller, PhysicsState, CharacterState, Mounting -pub struct Sys; -impl<'a> System<'a> for Sys { - type SystemData = ( - Entities<'a>, - ReadExpect<'a, TerrainGrid>, - Read<'a, EventBus>, - Read<'a, DeltaTime>, - WriteStorage<'a, Pos>, - WriteStorage<'a, Vel>, - WriteStorage<'a, Ori>, - WriteStorage<'a, Energy>, - ReadStorage<'a, Uid>, - ReadStorage<'a, Stats>, - ReadStorage<'a, Controller>, - ReadStorage<'a, PhysicsState>, - ReadStorage<'a, CharacterState>, - ReadStorage<'a, Mounting>, - ); - - fn run( - &mut self, - ( - entities, - _terrain, - _server_bus, - dt, - mut positions, - mut velocities, - mut orientations, - mut energies, - uids, - stats, - controllers, - physics_states, - character_states, - mountings, - ): Self::SystemData, - ) { - // Apply movement inputs - for ( - _entity, - mut _pos, - mut vel, - mut ori, - mut energy, - _uid, - stats, - controller, - physics, - character, - mount, - ) in ( - &entities, - &mut positions, - &mut velocities, - &mut orientations, - &mut energies.restrict_mut(), - &uids, - &stats, - &controllers, - &physics_states, - &character_states, - mountings.maybe(), - ) - .join() - { - if stats.is_dead { - continue; - } - - if mount.is_some() { - continue; - } - - let inputs = &controller.inputs; - - if character.action.is_roll() { - vel.0 = Vec3::new(0.0, 0.0, vel.0.z) - + (vel.0 * Vec3::new(1.0, 1.0, 0.0) - + 1.5 * inputs.move_dir.try_normalized().unwrap_or_default()) - .try_normalized() - .unwrap_or_default() - * ROLL_SPEED; - } else if character.action.is_charge() { - vel.0 = Vec3::new(0.0, 0.0, vel.0.z) - + (vel.0 * Vec3::new(1.0, 1.0, 0.0) - + 1.5 * inputs.move_dir.try_normalized().unwrap_or_default()) - .try_normalized() - .unwrap_or_default() - * CHARGE_SPEED; - } else if character.action.is_block() { - vel.0 += Vec2::broadcast(dt.0) - * inputs.move_dir - * match physics.on_ground { - true if vel.0.magnitude_squared() < BLOCK_SPEED.powf(2.0) => BLOCK_ACCEL, - _ => 0.0, - } - } else { - // Move player according to move_dir - vel.0 += Vec2::broadcast(dt.0) - * inputs.move_dir - * match (physics.on_ground, &character.movement) { - (true, Run) - if vel.0.magnitude_squared() - < (BASE_HUMANOID_SPEED + stats.fitness as f32 * 50.0).powf(2.0) => - { - BASE_HUMANOID_ACCEL - }, - (false, Climb) - if vel.0.magnitude_squared() < BASE_HUMANOID_SPEED.powf(2.0) => - { - BASE_HUMANOID_CLIMB_ACCEL - }, - (false, Glide) if vel.0.magnitude_squared() < GLIDE_SPEED.powf(2.0) => { - GLIDE_ACCEL - }, - (false, Fall) | (false, Jump) - if vel.0.magnitude_squared() - < (BASE_HUMANOID_AIR_SPEED + stats.fitness as f32 * 10.0) - .powf(2.0) => - { - BASE_HUMANOID_AIR_ACCEL - }, - (false, Swim) - if vel.0.magnitude_squared() - < (BASE_HUMANOID_WATER_SPEED + stats.fitness as f32 * 30.0) - .powf(2.0) => - { - BASE_HUMANOID_WATER_ACCEL + stats.fitness as f32 * 10.0 - }, - _ => 0.0, - }; - } - - // Set direction based on move direction when on the ground - let ori_dir = if - //character.action.is_wield() || - character.action.is_attack() || character.action.is_block() { - Vec2::from(inputs.look_dir).normalized() - } else if let (Climb, Some(wall_dir)) = (character.movement, physics.on_wall) { - if Vec2::::from(wall_dir).magnitude_squared() > 0.001 { - Vec2::from(wall_dir).normalized() - } else { - Vec2::from(inputs.move_dir) - } - } else if let Glide = character.movement { - // Note: non-gliding forces will also affect velocity and thus orientation - // producing potentially unexpected changes in direction - Vec2::from(vel.0) - } else { - if let ActionState::Roll { .. } = character.action { - // So can can't spin/slip around while rolling - Vec2::from(vel.0) - } else { - Vec2::from(inputs.move_dir) - } - }; - - if ori_dir.magnitude_squared() > 0.0001 - && (ori.0.normalized() - Vec3::from(ori_dir).normalized()).magnitude_squared() - > 0.001 - { - ori.0 = vek::ops::Slerp::slerp( - ori.0, - ori_dir.into(), - if physics.on_ground { 9.0 } else { 2.0 } * dt.0, - ); - } - - // Glide - if character.movement == Glide - && Vec2::::from(vel.0).magnitude_squared() < GLIDE_SPEED.powf(2.0) - && vel.0.z < 0.0 - { - let lift = GLIDE_ANTIGRAV + vel.0.z.abs().powf(2.0) * 0.15; - vel.0.z += dt.0 - * lift - * (Vec2::::from(vel.0).magnitude() * 0.075) - .min(1.0) - .max(0.2); - } - - // Climb - if let (true, Some(_wall_dir)) = ( - character.movement == Climb && vel.0.z <= CLIMB_SPEED, - physics.on_wall, - ) { - if inputs.climb_down.is_pressed() && !inputs.climb.is_pressed() { - 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() { - 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); - } - } - - if character.movement == Swim && inputs.jump.is_pressed() { - vel.0.z = (vel.0.z + dt.0 * GRAVITY * 1.25).min(BASE_HUMANOID_WATER_SPEED); - } - } - } -} From 0cd8150e98492ff6634cf7961a36668a54c31509 Mon Sep 17 00:00:00 2001 From: Ben Simpson Date: Thu, 13 Feb 2020 08:13:36 +0000 Subject: [PATCH 3/5] Update common/src/sys/movement.rs --- common/src/sys/movement.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/common/src/sys/movement.rs b/common/src/sys/movement.rs index 5a7108ae34..32bda35226 100644 --- a/common/src/sys/movement.rs +++ b/common/src/sys/movement.rs @@ -232,18 +232,18 @@ impl<'a> System<'a> for Sys { character.movement == Climb && vel.0.z <= CLIMB_SPEED, physics.on_wall, ) { - if inputs.climb_down.is_pressed() && !inputs.climb.is_pressed() { - if energy + if inputs.climb_down.is_pressed() && !inputs.climb.is_pressed() && energy .get_mut_unchecked() .try_change_by(-CLIMB_COST, EnergySource::Climb) - .is_ok(){ + .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() { - if energy + } else if inputs.climb.is_pressed() && !inputs.climb_down.is_pressed() && energy .get_mut_unchecked() .try_change_by(-CLIMB_COST, EnergySource::Climb) - .is_ok(){ + .is_ok() + { vel.0.z = (vel.0.z + dt.0 * GRAVITY * 1.25).min(CLIMB_SPEED).max(0.0); } } else { From bfd2f345b1eb73a081c0204b1a0ea3b2fe4b20cf Mon Sep 17 00:00:00 2001 From: Ben Simpson Date: Thu, 13 Feb 2020 08:19:36 +0000 Subject: [PATCH 4/5] Update common/src/sys/movement.rs --- common/src/sys/movement.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/sys/movement.rs b/common/src/sys/movement.rs index 32bda35226..a5f2e756fb 100644 --- a/common/src/sys/movement.rs +++ b/common/src/sys/movement.rs @@ -245,7 +245,7 @@ impl<'a> System<'a> for Sys { .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); } From 3343f8e5c022a847e9df1aec44ae913c069781bd Mon Sep 17 00:00:00 2001 From: Ben Simpson Date: Thu, 13 Feb 2020 08:36:29 +0000 Subject: [PATCH 5/5] Update common/src/sys/controller.rs, common/src/sys/movement.rs, common/src/comp/energy.rs files --- common/src/sys/controller.rs | 24 +++++++++++------------- common/src/sys/movement.rs | 26 ++++++++++++++------------ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/common/src/sys/controller.rs b/common/src/sys/controller.rs index 1e9c9de561..bcc3f4701a 100644 --- a/common/src/sys/controller.rs +++ b/common/src/sys/controller.rs @@ -19,7 +19,6 @@ use vek::*; const CHARGE_COST: i32 = 200; const ROLL_COST: i32 = 30; - /// # Controller System /// #### Responsible for validating controller inputs and setting new Character /// States ---- @@ -570,15 +569,15 @@ impl<'a> System<'a> for Sys { } // Try to climb - - if let (true, Some(_wall_dir)) = ( + + if let (true, Some(_wall_dir)) = ( (inputs.climb.is_pressed() | inputs.climb_down.is_pressed()) && can_climb(body), - physics.on_wall,) - { - character.movement = Climb; - continue; - } + physics.on_wall, + ) { + character.movement = Climb; + continue; + } // Try to swim if !physics.on_ground { @@ -607,7 +606,6 @@ impl<'a> System<'a> for Sys { character.action = Charge { time_left: Duration::from_millis(250), }; - } continue; } @@ -622,10 +620,10 @@ impl<'a> System<'a> for Sys { .try_change_by(-ROLL_COST, EnergySource::Roll) .is_ok() { - character.action = Roll { - time_left: ROLL_DURATION, - was_wielding: character.action.is_wield(), - }; + 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 a5f2e756fb..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, Energy, EnergySource + ActionState, CharacterState, Controller, Energy, EnergySource, Mounting, MovementState::*, + Ori, PhysicsState, Pos, Stats, Vel, }, event::{EventBus, ServerEvent}, state::DeltaTime, @@ -232,20 +232,22 @@ impl<'a> System<'a> for Sys { character.movement == Climb && vel.0.z <= CLIMB_SPEED, physics.on_wall, ) { - if inputs.climb_down.is_pressed() && !inputs.climb.is_pressed() && 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() && energy + if inputs.climb_down.is_pressed() && !inputs.climb.is_pressed() { + 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() { + 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); }