mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Account for surface normal when calculating collision damage
This commit is contained in:
parent
b086b43a88
commit
9127d6cbf2
@ -188,6 +188,7 @@ pub enum ServerEvent {
|
||||
LandOnGround {
|
||||
entity: EcsEntity,
|
||||
vel: Vec3<f32>,
|
||||
surface_normal: Vec3<f32>,
|
||||
},
|
||||
EnableLantern(EcsEntity),
|
||||
DisableLantern(EcsEntity),
|
||||
|
@ -889,7 +889,9 @@ impl<'a> PhysicsData<'a> {
|
||||
was_on_ground,
|
||||
block_snap,
|
||||
climbing,
|
||||
|entity, vel| land_on_ground = Some((entity, vel)),
|
||||
|entity, vel, surface_normal| {
|
||||
land_on_ground = Some((entity, vel, surface_normal))
|
||||
},
|
||||
read,
|
||||
&ori,
|
||||
);
|
||||
@ -921,7 +923,9 @@ impl<'a> PhysicsData<'a> {
|
||||
was_on_ground,
|
||||
block_snap,
|
||||
climbing,
|
||||
|entity, vel| land_on_ground = Some((entity, vel)),
|
||||
|entity, vel, surface_normal| {
|
||||
land_on_ground = Some((entity, vel, surface_normal))
|
||||
},
|
||||
read,
|
||||
&ori,
|
||||
);
|
||||
@ -1200,10 +1204,12 @@ impl<'a> PhysicsData<'a> {
|
||||
was_on_ground,
|
||||
block_snap,
|
||||
climbing,
|
||||
|entity, vel| {
|
||||
|entity, vel, surface_normal| {
|
||||
land_on_ground = Some((
|
||||
entity,
|
||||
Vel(ori_other.to_quat() * vel.0),
|
||||
Vel(previous_cache_other.ori * vel.0
|
||||
+ vel_other),
|
||||
surface_normal,
|
||||
));
|
||||
},
|
||||
read,
|
||||
@ -1337,9 +1343,15 @@ impl<'a> PhysicsData<'a> {
|
||||
drop(guard);
|
||||
|
||||
let mut event_emitter = read.event_bus.emitter();
|
||||
land_on_grounds.into_iter().for_each(|(entity, vel)| {
|
||||
event_emitter.emit(ServerEvent::LandOnGround { entity, vel: vel.0 });
|
||||
});
|
||||
land_on_grounds
|
||||
.into_iter()
|
||||
.for_each(|(entity, vel, surface_normal)| {
|
||||
event_emitter.emit(ServerEvent::LandOnGround {
|
||||
entity,
|
||||
vel: vel.0,
|
||||
surface_normal,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn update_cached_spatial_grid(&mut self) {
|
||||
@ -1418,7 +1430,7 @@ fn box_voxel_collision<T: BaseVol<Vox = Block> + ReadVol>(
|
||||
was_on_ground: bool,
|
||||
block_snap: bool,
|
||||
climbing: bool,
|
||||
mut land_on_ground: impl FnMut(Entity, Vel),
|
||||
mut land_on_ground: impl FnMut(Entity, Vel, Vec3<f32>),
|
||||
read: &PhysicsRead,
|
||||
ori: &Ori,
|
||||
) {
|
||||
@ -1594,7 +1606,7 @@ fn box_voxel_collision<T: BaseVol<Vox = Block> + ReadVol>(
|
||||
}
|
||||
|
||||
if resolve_dir.magnitude_squared() > 0.0 {
|
||||
land_on_ground(entity, *vel);
|
||||
land_on_ground(entity, *vel, resolve_dir.normalized());
|
||||
}
|
||||
|
||||
// When the resolution direction is non-vertical, we must be colliding
|
||||
|
@ -595,14 +595,21 @@ pub fn handle_delete(server: &mut Server, entity: EcsEntity) {
|
||||
.map_err(|e| error!(?e, ?entity, "Failed to delete destroyed entity"));
|
||||
}
|
||||
|
||||
pub fn handle_land_on_ground(server: &Server, entity: EcsEntity, vel: Vec3<f32>) {
|
||||
pub fn handle_land_on_ground(
|
||||
server: &Server,
|
||||
entity: EcsEntity,
|
||||
vel: Vec3<f32>,
|
||||
surface_normal: Vec3<f32>,
|
||||
) {
|
||||
let ecs = server.state.ecs();
|
||||
|
||||
let relative_vel = vel.dot(-surface_normal);
|
||||
|
||||
// The second part of this if statement disables all fall damage when in the
|
||||
// water. This was added as a *temporary* fix a bug that causes you to take
|
||||
// fall damage while swimming downwards. FIXME: Fix the actual bug and
|
||||
// remove the following relevant part of the if statement.
|
||||
if vel.magnitude() >= 30.0
|
||||
if relative_vel >= 30.0
|
||||
&& ecs
|
||||
.read_storage::<PhysicsState>()
|
||||
.get(entity)
|
||||
@ -610,10 +617,10 @@ pub fn handle_land_on_ground(server: &Server, entity: EcsEntity, vel: Vec3<f32>)
|
||||
{
|
||||
let char_states = ecs.read_storage::<CharacterState>();
|
||||
|
||||
let reduced_vel_z = if let Some(CharacterState::DiveMelee(c)) = char_states.get(entity) {
|
||||
(vel.magnitude() + c.static_data.vertical_speed).min(0.0)
|
||||
let reduced_vel = if let Some(CharacterState::DiveMelee(c)) = char_states.get(entity) {
|
||||
(relative_vel + c.static_data.vertical_speed).min(0.0)
|
||||
} else {
|
||||
vel.magnitude()
|
||||
relative_vel
|
||||
};
|
||||
|
||||
let mass = ecs
|
||||
@ -621,7 +628,7 @@ pub fn handle_land_on_ground(server: &Server, entity: EcsEntity, vel: Vec3<f32>)
|
||||
.get(entity)
|
||||
.copied()
|
||||
.unwrap_or_default();
|
||||
let impact_energy = mass.0 * reduced_vel_z.powi(2) / 2.0;
|
||||
let impact_energy = mass.0 * reduced_vel.powi(2) / 2.0;
|
||||
let falldmg = impact_energy / 1000.0;
|
||||
|
||||
let inventories = ecs.read_storage::<Inventory>();
|
||||
@ -655,7 +662,7 @@ pub fn handle_land_on_ground(server: &Server, entity: EcsEntity, vel: Vec3<f32>)
|
||||
server_eventbus.emit_now(ServerEvent::HealthChange { entity, change });
|
||||
|
||||
// Emit poise change
|
||||
let poise_damage = -(mass.0 * reduced_vel_z.powi(2) / 1500.0);
|
||||
let poise_damage = -(mass.0 * reduced_vel.powi(2) / 1500.0);
|
||||
let poise_change = Poise::apply_poise_reduction(
|
||||
poise_damage,
|
||||
inventories.get(entity),
|
||||
|
@ -120,9 +120,11 @@ impl Server {
|
||||
ServerEvent::InventoryManip(entity, manip) => handle_inventory(self, entity, manip),
|
||||
ServerEvent::GroupManip(entity, manip) => handle_group(self, entity, manip),
|
||||
ServerEvent::Respawn(entity) => handle_respawn(self, entity),
|
||||
ServerEvent::LandOnGround { entity, vel } => {
|
||||
handle_land_on_ground(self, entity, vel)
|
||||
},
|
||||
ServerEvent::LandOnGround {
|
||||
entity,
|
||||
vel,
|
||||
surface_normal,
|
||||
} => handle_land_on_ground(self, entity, vel, surface_normal),
|
||||
ServerEvent::EnableLantern(entity) => handle_lantern(self, entity, true),
|
||||
ServerEvent::DisableLantern(entity) => handle_lantern(self, entity, false),
|
||||
ServerEvent::NpcInteract(interactor, target, subject) => {
|
||||
|
Loading…
Reference in New Issue
Block a user