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 {
|
LandOnGround {
|
||||||
entity: EcsEntity,
|
entity: EcsEntity,
|
||||||
vel: Vec3<f32>,
|
vel: Vec3<f32>,
|
||||||
|
surface_normal: Vec3<f32>,
|
||||||
},
|
},
|
||||||
EnableLantern(EcsEntity),
|
EnableLantern(EcsEntity),
|
||||||
DisableLantern(EcsEntity),
|
DisableLantern(EcsEntity),
|
||||||
|
@ -889,7 +889,9 @@ impl<'a> PhysicsData<'a> {
|
|||||||
was_on_ground,
|
was_on_ground,
|
||||||
block_snap,
|
block_snap,
|
||||||
climbing,
|
climbing,
|
||||||
|entity, vel| land_on_ground = Some((entity, vel)),
|
|entity, vel, surface_normal| {
|
||||||
|
land_on_ground = Some((entity, vel, surface_normal))
|
||||||
|
},
|
||||||
read,
|
read,
|
||||||
&ori,
|
&ori,
|
||||||
);
|
);
|
||||||
@ -921,7 +923,9 @@ impl<'a> PhysicsData<'a> {
|
|||||||
was_on_ground,
|
was_on_ground,
|
||||||
block_snap,
|
block_snap,
|
||||||
climbing,
|
climbing,
|
||||||
|entity, vel| land_on_ground = Some((entity, vel)),
|
|entity, vel, surface_normal| {
|
||||||
|
land_on_ground = Some((entity, vel, surface_normal))
|
||||||
|
},
|
||||||
read,
|
read,
|
||||||
&ori,
|
&ori,
|
||||||
);
|
);
|
||||||
@ -1200,10 +1204,12 @@ impl<'a> PhysicsData<'a> {
|
|||||||
was_on_ground,
|
was_on_ground,
|
||||||
block_snap,
|
block_snap,
|
||||||
climbing,
|
climbing,
|
||||||
|entity, vel| {
|
|entity, vel, surface_normal| {
|
||||||
land_on_ground = Some((
|
land_on_ground = Some((
|
||||||
entity,
|
entity,
|
||||||
Vel(ori_other.to_quat() * vel.0),
|
Vel(previous_cache_other.ori * vel.0
|
||||||
|
+ vel_other),
|
||||||
|
surface_normal,
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
read,
|
read,
|
||||||
@ -1337,9 +1343,15 @@ impl<'a> PhysicsData<'a> {
|
|||||||
drop(guard);
|
drop(guard);
|
||||||
|
|
||||||
let mut event_emitter = read.event_bus.emitter();
|
let mut event_emitter = read.event_bus.emitter();
|
||||||
land_on_grounds.into_iter().for_each(|(entity, vel)| {
|
land_on_grounds
|
||||||
event_emitter.emit(ServerEvent::LandOnGround { entity, vel: vel.0 });
|
.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) {
|
fn update_cached_spatial_grid(&mut self) {
|
||||||
@ -1418,7 +1430,7 @@ fn box_voxel_collision<T: BaseVol<Vox = Block> + ReadVol>(
|
|||||||
was_on_ground: bool,
|
was_on_ground: bool,
|
||||||
block_snap: bool,
|
block_snap: bool,
|
||||||
climbing: bool,
|
climbing: bool,
|
||||||
mut land_on_ground: impl FnMut(Entity, Vel),
|
mut land_on_ground: impl FnMut(Entity, Vel, Vec3<f32>),
|
||||||
read: &PhysicsRead,
|
read: &PhysicsRead,
|
||||||
ori: &Ori,
|
ori: &Ori,
|
||||||
) {
|
) {
|
||||||
@ -1594,7 +1606,7 @@ fn box_voxel_collision<T: BaseVol<Vox = Block> + ReadVol>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if resolve_dir.magnitude_squared() > 0.0 {
|
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
|
// 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"));
|
.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 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
|
// 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
|
// 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
|
// fall damage while swimming downwards. FIXME: Fix the actual bug and
|
||||||
// remove the following relevant part of the if statement.
|
// remove the following relevant part of the if statement.
|
||||||
if vel.magnitude() >= 30.0
|
if relative_vel >= 30.0
|
||||||
&& ecs
|
&& ecs
|
||||||
.read_storage::<PhysicsState>()
|
.read_storage::<PhysicsState>()
|
||||||
.get(entity)
|
.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 char_states = ecs.read_storage::<CharacterState>();
|
||||||
|
|
||||||
let reduced_vel_z = if let Some(CharacterState::DiveMelee(c)) = char_states.get(entity) {
|
let reduced_vel = if let Some(CharacterState::DiveMelee(c)) = char_states.get(entity) {
|
||||||
(vel.magnitude() + c.static_data.vertical_speed).min(0.0)
|
(relative_vel + c.static_data.vertical_speed).min(0.0)
|
||||||
} else {
|
} else {
|
||||||
vel.magnitude()
|
relative_vel
|
||||||
};
|
};
|
||||||
|
|
||||||
let mass = ecs
|
let mass = ecs
|
||||||
@ -621,7 +628,7 @@ pub fn handle_land_on_ground(server: &Server, entity: EcsEntity, vel: Vec3<f32>)
|
|||||||
.get(entity)
|
.get(entity)
|
||||||
.copied()
|
.copied()
|
||||||
.unwrap_or_default();
|
.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 falldmg = impact_energy / 1000.0;
|
||||||
|
|
||||||
let inventories = ecs.read_storage::<Inventory>();
|
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 });
|
server_eventbus.emit_now(ServerEvent::HealthChange { entity, change });
|
||||||
|
|
||||||
// Emit poise 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(
|
let poise_change = Poise::apply_poise_reduction(
|
||||||
poise_damage,
|
poise_damage,
|
||||||
inventories.get(entity),
|
inventories.get(entity),
|
||||||
|
@ -120,9 +120,11 @@ impl Server {
|
|||||||
ServerEvent::InventoryManip(entity, manip) => handle_inventory(self, entity, manip),
|
ServerEvent::InventoryManip(entity, manip) => handle_inventory(self, entity, manip),
|
||||||
ServerEvent::GroupManip(entity, manip) => handle_group(self, entity, manip),
|
ServerEvent::GroupManip(entity, manip) => handle_group(self, entity, manip),
|
||||||
ServerEvent::Respawn(entity) => handle_respawn(self, entity),
|
ServerEvent::Respawn(entity) => handle_respawn(self, entity),
|
||||||
ServerEvent::LandOnGround { entity, vel } => {
|
ServerEvent::LandOnGround {
|
||||||
handle_land_on_ground(self, entity, vel)
|
entity,
|
||||||
},
|
vel,
|
||||||
|
surface_normal,
|
||||||
|
} => handle_land_on_ground(self, entity, vel, surface_normal),
|
||||||
ServerEvent::EnableLantern(entity) => handle_lantern(self, entity, true),
|
ServerEvent::EnableLantern(entity) => handle_lantern(self, entity, true),
|
||||||
ServerEvent::DisableLantern(entity) => handle_lantern(self, entity, false),
|
ServerEvent::DisableLantern(entity) => handle_lantern(self, entity, false),
|
||||||
ServerEvent::NpcInteract(interactor, target, subject) => {
|
ServerEvent::NpcInteract(interactor, target, subject) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user