veloren/common/src/states/glide.rs

67 lines
2.1 KiB
Rust
Raw Normal View History

2020-02-24 18:17:16 +00:00
use crate::{
2020-03-07 18:15:02 +00:00
comp::{CharacterState, StateUpdate},
2020-03-07 19:02:54 +00:00
sys::character_behavior::JoinData,
2020-02-24 18:17:16 +00:00
};
2020-02-03 10:54:50 +00:00
use std::collections::VecDeque;
2019-12-26 14:43:59 +00:00
use vek::{Vec2, Vec3};
2020-01-07 15:49:08 +00:00
// Gravity is 9.81 * 4, so this makes gravity equal to .15
const GLIDE_ANTIGRAV: f32 = crate::sys::phys::GRAVITY * 0.96;
const GLIDE_ACCEL: f32 = 15.0;
const GLIDE_SPEED: f32 = 45.0;
2020-03-07 18:15:02 +00:00
pub fn behavior(data: &JoinData) -> StateUpdate {
let mut update = StateUpdate {
pos: *data.pos,
vel: *data.vel,
ori: *data.ori,
energy: *data.energy,
character: *data.character,
local_events: VecDeque::new(),
server_events: VecDeque::new(),
};
2019-12-26 14:43:59 +00:00
2020-03-07 18:15:02 +00:00
// If glide button isn't held or player is on ground, end glide
if !data.inputs.glide.is_pressed() || data.physics.on_ground {
update.character = CharacterState::Idle {};
}
2019-12-26 18:01:19 +00:00
2020-03-07 18:15:02 +00:00
// If there is a wall in front of character go to climb
if let Some(_) = data.physics.on_wall {
update.character = CharacterState::Climb {};
}
2019-12-26 14:43:59 +00:00
2020-03-07 18:15:02 +00:00
// Move player according to movement direction vector
update.vel.0 += Vec2::broadcast(data.dt.0)
* data.inputs.move_dir
* if data.vel.0.magnitude_squared() < GLIDE_SPEED.powf(2.0) {
GLIDE_ACCEL
} else {
0.0
};
2019-12-26 14:43:59 +00:00
2020-03-07 18:15:02 +00:00
// Determine orientation vector from movement direction vector
let ori_dir = Vec2::from(update.vel.0);
if ori_dir.magnitude_squared() > 0.0001
&& (update.ori.0.normalized() - Vec3::from(ori_dir).normalized()).magnitude_squared()
> 0.001
{
update.ori.0 = vek::ops::Slerp::slerp(update.ori.0, ori_dir.into(), 2.0 * data.dt.0);
}
2019-12-26 14:43:59 +00:00
2020-03-07 18:15:02 +00:00
// Apply Glide antigrav lift
if Vec2::<f32>::from(update.vel.0).magnitude_squared() < GLIDE_SPEED.powf(2.0)
&& update.vel.0.z < 0.0
{
let lift = GLIDE_ANTIGRAV + update.vel.0.z.abs().powf(2.0) * 0.15;
update.vel.0.z += data.dt.0
* lift
* (Vec2::<f32>::from(update.vel.0).magnitude() * 0.075)
.min(1.0)
.max(0.2);
2019-12-26 14:43:59 +00:00
}
2020-03-07 18:15:02 +00:00
// Otherwise keep gliding
update
2019-12-26 14:43:59 +00:00
}