Update common/src/sys/controller.rs, common/src/sys/movement.rs files

Deleted energy.rs, movement.rs files
This commit is contained in:
Ben Simpson 2020-02-13 07:59:54 +00:00
parent 1aa98dbb62
commit a49482503d
4 changed files with 9 additions and 336 deletions

View File

@ -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;
}

View File

@ -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 {

View File

@ -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<Self, IDVStorage<Self>>;
}

View File

@ -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<ServerEvent>>,
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::<f32>::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::<f32>::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::<f32>::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);
}
}
}
}