2019-04-16 21:06:33 +00:00
|
|
|
// Library
|
2019-05-09 17:58:16 +00:00
|
|
|
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage};
|
2019-04-16 21:06:33 +00:00
|
|
|
use vek::*;
|
|
|
|
|
|
|
|
// Crate
|
2019-05-01 16:55:29 +00:00
|
|
|
use crate::{
|
|
|
|
comp::{
|
|
|
|
phys::{Dir, Pos, Vel},
|
|
|
|
Animation, AnimationHistory, Control,
|
|
|
|
},
|
2019-05-09 17:58:16 +00:00
|
|
|
state::DeltaTime,
|
2019-05-01 16:55:29 +00:00
|
|
|
terrain::TerrainMap,
|
|
|
|
vol::{ReadVol, Vox},
|
2019-04-29 20:37:19 +00:00
|
|
|
};
|
2019-04-16 21:06:33 +00:00
|
|
|
|
|
|
|
// Basic ECS AI agent system
|
|
|
|
pub struct Sys;
|
|
|
|
|
|
|
|
impl<'a> System<'a> for Sys {
|
|
|
|
type SystemData = (
|
2019-05-01 16:55:29 +00:00
|
|
|
ReadExpect<'a, TerrainMap>,
|
2019-05-06 13:22:49 +00:00
|
|
|
Read<'a, DeltaTime>,
|
2019-04-17 08:59:38 +00:00
|
|
|
Entities<'a>,
|
2019-05-01 16:55:29 +00:00
|
|
|
ReadStorage<'a, Pos>,
|
2019-04-16 21:06:33 +00:00
|
|
|
WriteStorage<'a, Vel>,
|
|
|
|
WriteStorage<'a, Dir>,
|
2019-04-17 17:32:29 +00:00
|
|
|
WriteStorage<'a, AnimationHistory>,
|
2019-04-16 21:06:33 +00:00
|
|
|
ReadStorage<'a, Control>,
|
|
|
|
);
|
|
|
|
|
2019-05-09 17:58:16 +00:00
|
|
|
fn run(
|
|
|
|
&mut self,
|
|
|
|
(terrain, dt, entities, pos, mut vels, mut dirs, mut anims, controls): Self::SystemData,
|
|
|
|
) {
|
2019-05-01 16:55:29 +00:00
|
|
|
for (entity, pos, mut vel, mut dir, control) in
|
|
|
|
(&entities, &pos, &mut vels, &mut dirs, &controls).join()
|
2019-04-29 20:37:19 +00:00
|
|
|
{
|
2019-05-01 16:55:29 +00:00
|
|
|
let on_ground = terrain
|
|
|
|
.get((pos.0 - Vec3::unit_z() * 0.1).map(|e| e.floor() as i32))
|
|
|
|
.map(|vox| !vox.is_empty())
|
2019-05-09 17:58:16 +00:00
|
|
|
.unwrap_or(false)
|
|
|
|
&& vel.0.z <= 0.0;
|
2019-04-16 21:06:33 +00:00
|
|
|
|
2019-05-16 11:04:42 +00:00
|
|
|
let (gliding, friction) = if on_ground {
|
2019-05-01 16:55:29 +00:00
|
|
|
// TODO: Don't hard-code this
|
|
|
|
// Apply physics to the player: acceleration and non-linear decceleration
|
2019-05-13 23:25:49 +00:00
|
|
|
vel.0 += control.move_dir * 4.0;
|
2019-05-01 16:55:29 +00:00
|
|
|
|
|
|
|
if control.jumping {
|
|
|
|
vel.0.z += 16.0;
|
|
|
|
}
|
2019-05-13 23:25:49 +00:00
|
|
|
|
2019-05-16 11:04:42 +00:00
|
|
|
(false, 0.15)
|
2019-05-01 16:55:29 +00:00
|
|
|
} else {
|
|
|
|
// TODO: Don't hard-code this
|
|
|
|
// Apply physics to the player: acceleration and non-linear decceleration
|
2019-05-13 23:42:50 +00:00
|
|
|
vel.0 += control.move_dir * 0.2;
|
2019-05-13 20:59:42 +00:00
|
|
|
|
|
|
|
if control.gliding && vel.0.z < 0.0 {
|
2019-05-13 23:25:49 +00:00
|
|
|
// TODO: Don't hard-code this
|
|
|
|
let anti_grav = 9.81 * 3.95;
|
|
|
|
vel.0.z += anti_grav * dt.0 * Vec2::<f32>::from(vel.0 * 0.15).magnitude().min(1.0);
|
|
|
|
|
2019-05-16 11:04:42 +00:00
|
|
|
(true, 0.008)
|
2019-05-13 23:42:50 +00:00
|
|
|
} else {
|
2019-05-16 11:04:42 +00:00
|
|
|
(false, 0.015)
|
2019-05-13 23:42:50 +00:00
|
|
|
}
|
2019-05-13 23:25:49 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Friction
|
|
|
|
vel.0 -= vel.0.map(|e| (e.abs() * friction * (vel.0.magnitude() * 0.1 + 0.5)).min(e.abs()).copysign(e)) * Vec3::new(1.0, 1.0, 0.0);
|
|
|
|
|
|
|
|
if vel.0.magnitude_squared() != 0.0 {
|
|
|
|
dir.0 = vel.0.normalized() * Vec3::new(1.0, 1.0, 0.0);
|
2019-05-01 16:55:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let animation = if on_ground {
|
|
|
|
if control.move_dir.magnitude() > 0.01 {
|
|
|
|
Animation::Run
|
|
|
|
} else {
|
|
|
|
Animation::Idle
|
|
|
|
}
|
2019-05-16 11:04:42 +00:00
|
|
|
} else if gliding {
|
2019-05-16 04:40:35 +00:00
|
|
|
Animation::Gliding
|
2019-05-16 11:04:42 +00:00
|
|
|
} else {
|
|
|
|
Animation::Jump
|
2019-04-29 20:37:19 +00:00
|
|
|
};
|
2019-04-17 17:32:29 +00:00
|
|
|
|
2019-05-06 13:22:49 +00:00
|
|
|
let last_history = anims.get_mut(entity).cloned();
|
|
|
|
|
2019-05-09 17:58:16 +00:00
|
|
|
let time = if let Some((true, time)) =
|
|
|
|
last_history.map(|last| (last.current == animation, last.time))
|
2019-05-06 13:22:49 +00:00
|
|
|
{
|
2019-05-09 19:18:13 +00:00
|
|
|
time
|
2019-05-06 13:22:49 +00:00
|
|
|
} else {
|
|
|
|
0.0
|
|
|
|
};
|
2019-04-17 17:32:29 +00:00
|
|
|
|
2019-04-29 20:37:19 +00:00
|
|
|
anims.insert(
|
|
|
|
entity,
|
|
|
|
AnimationHistory {
|
2019-05-06 13:22:49 +00:00
|
|
|
last: last_history.map(|last| last.current),
|
2019-04-29 20:37:19 +00:00
|
|
|
current: animation,
|
2019-05-06 13:22:49 +00:00
|
|
|
time,
|
2019-04-29 20:37:19 +00:00
|
|
|
},
|
|
|
|
);
|
2019-04-16 21:06:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|