Fixed jumping inconsistencies, no block-snapping for ships

This commit is contained in:
Joshua Barretto 2021-03-13 20:51:32 +00:00 committed by Avi Weinstock
parent 8247c136bc
commit e232a2e473
5 changed files with 25 additions and 46 deletions

View File

@ -20,17 +20,12 @@ pub type SiteId = u64;
pub enum LocalEvent {
/// Applies upward force to entity's `Vel`
Jump(EcsEntity),
Jump(EcsEntity, f32),
/// Applies the `impulse` to `entity`'s `Vel`
ApplyImpulse {
entity: EcsEntity,
impulse: Vec3<f32>,
},
/// Applies leaping force to `entity`'s `Vel` away from `wall_dir` direction
WallLeap {
entity: EcsEntity,
wall_dir: Vec3<f32>,
},
/// Applies `vel` velocity to `entity`
Boost { entity: EcsEntity, vel: Vec3<f32> },
}

View File

@ -36,7 +36,7 @@ impl CharacterBehavior for Data {
// They've climbed atop something, give them a boost
update
.local_events
.push_front(LocalEvent::Jump(data.entity));
.push_front(LocalEvent::Jump(data.entity, BASE_JUMP_IMPULSE * 0.5));
}
update.character = CharacterState::Idle {};
return update;

View File

@ -21,6 +21,7 @@ const BASE_HUMANOID_AIR_ACCEL: f32 = 2.0;
const BASE_FLIGHT_ACCEL: f32 = 2.0;
const BASE_HUMANOID_WATER_ACCEL: f32 = 150.0;
const BASE_HUMANOID_WATER_SPEED: f32 = 180.0;
pub const BASE_JUMP_IMPULSE: f32 = 16.0;
// const BASE_HUMANOID_CLIMB_ACCEL: f32 = 10.0;
// const ROLL_SPEED: f32 = 17.0;
// const CHARGE_SPEED: f32 = 20.0;
@ -181,10 +182,10 @@ impl Body {
}
}
pub fn can_jump(&self) -> bool {
pub fn jump_impulse(&self) -> Option<f32> {
match self {
Body::Object(_) | Body::Ship(_) => false,
_ => true,
Body::Object(_) | Body::Ship(_) => None,
_ => Some(BASE_JUMP_IMPULSE),
}
}
@ -442,11 +443,12 @@ pub fn handle_jump(data: &JoinData, update: &mut StateUpdate) {
.in_liquid
.map(|depth| depth > 1.0)
.unwrap_or(false)
&& data.body.can_jump()
&& data.body.jump_impulse().is_some()
{
update
.local_events
.push_front(LocalEvent::Jump(data.entity));
update.local_events.push_front(LocalEvent::Jump(
data.entity,
data.body.jump_impulse().unwrap(),
));
}
}

View File

@ -1,8 +1,8 @@
use common::{
comp::{
body::ship::figuredata::VOXEL_COLLIDER_MANIFEST, BeamSegment, CharacterState, Collider,
Gravity, Mass, Mounting, Ori, PhysicsState, Pos, PreviousPhysCache, Projectile, Scale,
Shockwave, Sticky, Vel,
body::ship::figuredata::VOXEL_COLLIDER_MANIFEST, BeamSegment, Body, CharacterState,
Collider, Gravity, Mass, Mounting, Ori, PhysicsState, Pos, PreviousPhysCache, Projectile,
Scale, Shockwave, Sticky, Vel,
},
consts::{FRIC_GROUND, GRAVITY},
event::{EventBus, ServerEvent},
@ -85,6 +85,7 @@ pub struct PhysicsRead<'a> {
beams: ReadStorage<'a, BeamSegment>,
shockwaves: ReadStorage<'a, Shockwave>,
char_states: ReadStorage<'a, CharacterState>,
bodies: ReadStorage<'a, Body>,
}
#[derive(SystemData)]
@ -438,6 +439,7 @@ impl<'a> PhysicsData<'a> {
positions,
velocities,
orientations,
read.bodies.maybe(),
&mut write.physics_states,
previous_phys_cache,
!&read.mountings,
@ -454,6 +456,7 @@ impl<'a> PhysicsData<'a> {
pos,
vel,
_ori,
body,
mut physics_state,
_previous_cache,
_,
@ -502,6 +505,7 @@ impl<'a> PhysicsData<'a> {
let mut tgt_pos = pos.0 + pos_delta;
let was_on_ground = physics_state.on_ground;
let block_snap = body.map_or(false, |body| body.jump_impulse().is_some());
match &collider {
Collider::Voxel { .. } => {
@ -526,6 +530,7 @@ impl<'a> PhysicsData<'a> {
Vec3::zero(),
&read.dt,
was_on_ground,
block_snap,
|entity, vel| land_on_grounds.push((entity, vel)),
);
tgt_pos = cpos.0;
@ -553,6 +558,7 @@ impl<'a> PhysicsData<'a> {
Vec3::zero(),
&read.dt,
was_on_ground,
block_snap,
|entity, vel| land_on_grounds.push((entity, vel)),
);
tgt_pos = cpos.0;
@ -693,6 +699,7 @@ impl<'a> PhysicsData<'a> {
ori_to.mul_direction(vel_other.0),
&read.dt,
was_on_ground,
block_snap,
|entity, vel| {
land_on_grounds
.push((entity, Vel(ori_from.mul_direction(vel.0))))
@ -818,6 +825,7 @@ fn cylinder_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
ground_vel: Vec3<f32>,
dt: &DeltaTime,
was_on_ground: bool,
block_snap: bool,
mut land_on_ground: impl FnMut(Entity, Vel),
) {
let (radius, z_min, z_max) = cylinder;
@ -1062,15 +1070,7 @@ fn cylinder_voxel_collision<'a, T: BaseVol<Vox = Block> + ReadVol>(
z_range.clone(),
) && vel.0.z < 0.25
&& vel.0.z > -1.5
// && was_on_ground
// && !collision_with(
// pos.0 - Vec3::unit_z() * 0.0,
// &terrain,
// |block| block.solid_height() >= (pos.0.z - 0.1).rem_euclid(1.0),
// near_iter.clone(),
// radius,
// z_range.clone(),
// )
&& block_snap
{
let snap_height = terrain
.get(Vec3::new(pos.0.x, pos.0.y, pos.0.z - 0.1).map(|e| e.floor() as i32))

View File

@ -36,7 +36,6 @@ const DAY_CYCLE_FACTOR: f64 = 24.0 * 2.0;
/// this value, the game's physics will begin to produce time lag. Ideally, we'd
/// avoid such a situation.
const MAX_DELTA_TIME: f32 = 1.0;
const HUMANOID_JUMP_ACCEL: f32 = 16.0;
#[derive(Default)]
pub struct BlockChange {
@ -454,13 +453,11 @@ impl State {
let events = self.ecs.read_resource::<EventBus<LocalEvent>>().recv_all();
for event in events {
let mut velocities = self.ecs.write_storage::<comp::Vel>();
let mut controllers = self.ecs.write_storage::<comp::Controller>();
let physics = self.ecs.read_storage::<comp::PhysicsState>();
match event {
LocalEvent::Jump(entity) => {
LocalEvent::Jump(entity, impulse) => {
if let Some(vel) = velocities.get_mut(entity) {
vel.0.z = HUMANOID_JUMP_ACCEL
+ physics.get(entity).map_or(0.0, |ps| ps.ground_vel.z);
vel.0.z = impulse + physics.get(entity).map_or(0.0, |ps| ps.ground_vel.z);
}
},
LocalEvent::ApplyImpulse { entity, impulse } => {
@ -468,21 +465,6 @@ impl State {
vel.0 = impulse;
}
},
LocalEvent::WallLeap { entity, wall_dir } => {
if let (Some(vel), Some(_controller)) =
(velocities.get_mut(entity), controllers.get_mut(entity))
{
let hspeed = Vec2::<f32>::from(vel.0).magnitude();
if hspeed > 0.001 && hspeed < 0.5 {
vel.0 += vel.0.normalized()
* Vec3::new(1.0, 1.0, 0.0)
* HUMANOID_JUMP_ACCEL
* 1.5
- wall_dir * 0.03;
vel.0.z = HUMANOID_JUMP_ACCEL * 0.5;
}
}
},
LocalEvent::Boost {
entity,
vel: extra_vel,