diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index 71262d5b0a..8d6a072ab6 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -146,8 +146,10 @@ impl<'a> System<'a> for Sys { for _ in 0..increments as usize { pos.0 += pos_delta / increments; + const MAX_ATTEMPTS: usize = 16; + // While the player is colliding with the terrain... - while collision_with(pos.0, near_iter.clone()) && attempts < 16 { + while collision_with(pos.0, near_iter.clone()) && attempts < MAX_ATTEMPTS { // Calculate the player's AABB let player_aabb = Aabb { min: pos.0 + Vec3::new(-player_rad, -player_rad, 0.0), @@ -180,9 +182,11 @@ impl<'a> System<'a> for Sys { }) // Find the maximum of the minimum collision axes (this bit is weird, trust me that it works) .max_by_key(|(_, block_aabb)| { - ((player_aabb.collision_vector_with_aabb(*block_aabb) / vel.0) + ((player_aabb + .collision_vector_with_aabb(*block_aabb) .map(|e| e.abs()) - .reduce_partial_min() + .product() + + block_aabb.min.z) * 1_000_000.0) as i32 }) .expect("Collision detected, but no colliding blocks found!"); @@ -240,6 +244,11 @@ impl<'a> System<'a> for Sys { attempts += 1; } + + if attempts == MAX_ATTEMPTS { + pos.0 = old_pos; + break; + } } if on_ground { diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index fd5cffde92..8ad014a25b 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -127,8 +127,18 @@ impl Scene { // Alter camera position to match player. let tilt = self.camera.get_orientation().y; let dist = self.camera.get_distance(); + let up = if client + .state() + .read_storage::() + .get(client.entity()) + .is_some() + { + 1.5 + } else { + 1.2 + }; self.camera.set_focus_pos( - player_pos + Vec3::unit_z() * (1.2 + dist * 0.15 - tilt.min(0.0) * dist * 0.75), + player_pos + Vec3::unit_z() * (up + dist * 0.15 - tilt.min(0.0) * dist * 0.75), ); // Tick camera for interpolation.