2020-06-16 21:32:39 +00:00
|
|
|
use super::utils::handle_climb;
|
2020-02-24 18:17:16 +00:00
|
|
|
use crate::{
|
2020-03-07 18:15:02 +00:00
|
|
|
comp::{CharacterState, StateUpdate},
|
2020-03-14 21:17:27 +00:00
|
|
|
sys::character_behavior::{CharacterBehavior, JoinData},
|
2020-03-28 01:31:22 +00:00
|
|
|
util::Dir,
|
2020-02-24 18:17:16 +00:00
|
|
|
};
|
2020-07-06 14:23:08 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
2020-03-21 03:23:46 +00:00
|
|
|
use vek::Vec2;
|
2019-12-26 14:43:59 +00:00
|
|
|
|
2020-01-07 15:49:08 +00:00
|
|
|
// Gravity is 9.81 * 4, so this makes gravity equal to .15
|
2020-03-26 16:19:12 +00:00
|
|
|
const GLIDE_ANTIGRAV: f32 = crate::sys::phys::GRAVITY * 0.90;
|
|
|
|
const GLIDE_ACCEL: f32 = 12.0;
|
2020-01-07 15:49:08 +00:00
|
|
|
const GLIDE_SPEED: f32 = 45.0;
|
|
|
|
|
2020-03-14 21:17:27 +00:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
|
|
|
|
pub struct Data;
|
2019-12-26 14:43:59 +00:00
|
|
|
|
2020-03-14 21:17:27 +00:00
|
|
|
impl CharacterBehavior for Data {
|
|
|
|
fn behavior(&self, data: &JoinData) -> StateUpdate {
|
2020-03-21 21:16:26 +00:00
|
|
|
let mut update = StateUpdate::from(data);
|
2019-12-26 18:01:19 +00:00
|
|
|
|
2020-06-16 21:32:39 +00:00
|
|
|
// If player is on ground, end glide
|
|
|
|
if data.physics.on_ground {
|
|
|
|
update.character = CharacterState::GlideWield;
|
2020-03-26 19:02:01 +00:00
|
|
|
return update;
|
2020-03-14 21:17:27 +00:00
|
|
|
}
|
2020-08-11 11:13:18 +00:00
|
|
|
if data.physics.in_fluid.map(|depth| depth > 0.5).unwrap_or(false) {
|
2020-08-08 21:05:48 +00:00
|
|
|
update.character = CharacterState::Idle;
|
|
|
|
}
|
2020-06-16 21:32:39 +00:00
|
|
|
// If there is a wall in front of character and they are trying to climb go to
|
|
|
|
// climb
|
|
|
|
handle_climb(&data, &mut update);
|
2019-12-26 14:43:59 +00:00
|
|
|
|
2020-03-14 21:17:27 +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-14 21:17:27 +00:00
|
|
|
// Determine orientation vector from movement direction vector
|
|
|
|
let ori_dir = Vec2::from(update.vel.0);
|
2020-03-28 01:31:22 +00:00
|
|
|
update.ori.0 = Dir::slerp_to_vec3(update.ori.0, ori_dir.into(), 2.0 * data.dt.0);
|
2020-03-07 18:15:02 +00:00
|
|
|
|
2020-03-14 21:17:27 +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);
|
|
|
|
}
|
|
|
|
|
|
|
|
update
|
|
|
|
}
|
2020-06-16 21:32:39 +00:00
|
|
|
|
|
|
|
fn unwield(&self, data: &JoinData) -> StateUpdate {
|
|
|
|
let mut update = StateUpdate::from(data);
|
|
|
|
update.character = CharacterState::Idle;
|
|
|
|
update
|
|
|
|
}
|
2019-12-26 14:43:59 +00:00
|
|
|
}
|