Overhaul the glider mechanics

Uses a variable called magnitude to be able to change directions and
keep your current speed.

Changd glide_wield.rs so that the user will not enter the glide
state until they are falling.

Animation while gliding is broken.
This commit is contained in:
Dioptase 2020-12-23 14:48:02 -06:00
parent be4d8a7138
commit 1d35bc4af8
2 changed files with 72 additions and 29 deletions

View File

@ -1,16 +1,21 @@
use super::utils::handle_climb;
use crate::{
comp::{CharacterState, EnergySource, StateUpdate},
comp::{CharacterState, StateUpdate},
states::behavior::{CharacterBehavior, JoinData},
util::Dir,
};
use serde::{Deserialize, Serialize};
use vek::Vec2;
use vek::Vec3;
// Gravity is 9.81 * 4, so this makes gravity equal to .15
const GLIDE_ANTIGRAV: f32 = crate::consts::GRAVITY * 0.90;
const GLIDE_ACCEL: f32 = 12.0;
const GLIDE_SPEED: f32 = 45.0;
const HORIZ_CHANGE: f32 = 0.8;
//This is used to lower AIR_FRIC applied in common/sys/source/phys.rs
//If you want to fully counteract AIR_FRIC = 0.0125, use 1.0126582278 (1/1-AIR_FRIC) here
const FRIC_REDUCE: f32 = 1.01;
//, Eq, Hash
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
pub struct Data;
@ -38,40 +43,77 @@ impl CharacterBehavior for Data {
// climb
handle_climb(&data, &mut update);
// 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.powi(2) {
GLIDE_ACCEL
// Determine orientation vector from movement direction vector
//let ori_dir = Vec2::from(update.vel.0);
//update.ori.0 = Dir::slerp_to_vec3(update.ori.0, ori_dir.into(), data.dt.0);
//A single variable that will control both vertical and horizontal speed while gliding
let magnitude: f32 = (update.vel.0.magnitude()
- if data.inputs.look_dir.z.abs() < 0.08 {
7.0 * data.dt.0
} else {
0.0
};
})
//Reduce the effects of AIR_FRIC
* FRIC_REDUCE.powf(data.dt.0 * 60.0);
// Determine orientation vector from movement direction vector
let horiz_vel = Vec2::from(update.vel.0);
update.ori.0 = Dir::slerp_to_vec3(update.ori.0, horiz_vel.into(), 2.0 * data.dt.0);
let ori_dir = Vec2::from(update.vel.0);
update.ori.0 = Dir::slerp_to_vec3(update.ori.0, ori_dir.into(), 0.5 * data.dt.0);
// Apply Glide antigrav lift
let horiz_speed_sq = horiz_vel.magnitude_squared();
if horiz_speed_sq < GLIDE_SPEED.powi(2) && update.vel.0.z < 0.0 {
let lift = (GLIDE_ANTIGRAV + update.vel.0.z.powi(2) * 0.15)
* (horiz_speed_sq * f32::powf(0.075, 2.0)).clamp(0.2, 1.0)
* data.dt.0;
let look_grav = crate::consts::GRAVITY * data.inputs.look_dir.z;
update.vel.0.z += lift;
/*
Vec3::slerp(update.vel.0,
Vec3::broadcast(magnitude) * look,
0.9);
*/
/*
if data.inputs.look_dir.z < 1.0 {
update.vel.0 += (Vec3::broadcast(magnitude)
* look
- update.vel.0)
* 0.9;
// Expend energy during strenuous maneuvers.
// Cost increases with lift exceeding that of calmly gliding.
let energy_cost = (10.0 * (lift - GLIDE_ANTIGRAV * data.dt.0)).max(0.0) as i32;
if update
.energy
.try_change_by(-energy_cost, EnergySource::Glide)
.is_err()
{
update.character = CharacterState::Idle {};
if data.inputs.look_dir.z > 0.0
&& magnitude < 5.0 {
update.vel.0.z *= -1.0 - 10.0 * data.dt.0;
}
}
*/
if data.inputs.look_dir.z < 0.707 {
update.vel.0.x += (magnitude
* data.inputs.look_dir.x
- update.vel.0.x)
* HORIZ_CHANGE;
update.vel.0.y += (magnitude
* data.inputs.look_dir.y
- update.vel.0.y)
* HORIZ_CHANGE;
if data.inputs.look_dir.z > 0.0
&& update.vel.0.z < 0.0
&& magnitude < 1.8
* look_grav {
update.vel.0.z += GLIDE_ANTIGRAV
* data.dt.0;
update.vel.0.x = update.vel.0.x.abs().min(look_grav) * update.vel.0.x.signum();
update.vel.0.y = update.vel.0.y.abs().min(look_grav) * update.vel.0.y.signum();
update.vel.0.z = update.vel.0.z.max(-look_grav);
} else {
update.vel.0.z += magnitude
* data.inputs.look_dir.z
- if data.inputs.look_dir.z.abs() < 0.08 {
GLIDE_ANTIGRAV * data.dt.0
} else {
0.0
}
- update.vel.0.z;
};
};
update
}

View File

@ -16,7 +16,8 @@ impl CharacterBehavior for Data {
handle_wield(data, &mut update);
// If not on the ground while wielding glider enter gliding state
if !data.physics.on_ground {
if !data.physics.on_ground
&& update.vel.0.z < 0.0 {
update.character = CharacterState::Glide;
}
if data