Improved single-tick projectile wall/entity collision bug

This commit is contained in:
Joshua Barretto 2020-08-25 00:04:04 +01:00
parent 9b812b0d8b
commit 12ea028a3d
3 changed files with 82 additions and 89 deletions

View File

@ -32,7 +32,7 @@
), ),
column: ( column: (
cold_grass: (0.0, 0.3, 0.1), cold_grass: (0.0, 0.3, 0.1),
warm_grass: (0.3, 0.25, -0.8), warm_grass: (0.5, 0.55, 0.0),
dark_grass: (0.15, 0.4, 0.1), dark_grass: (0.15, 0.4, 0.1),
wet_grass: (0.1, 0.8, 0.2), wet_grass: (0.1, 0.8, 0.2),
cold_stone: (0.4, 0.67, 0.8), cold_stone: (0.4, 0.67, 0.8),

View File

@ -126,10 +126,6 @@ impl<'a> System<'a> for Sys {
// already possible with poorly-defined hitboxes anyway so it's not too // already possible with poorly-defined hitboxes anyway so it's not too
// much of a concern. // much of a concern.
// //
// Actually, the aforementioned case can't happen, but only because wall
// collision is checked prior to entity collision in the projectile
// code.
//
// If this situation becomes a problem, this code should be integrated with the // If this situation becomes a problem, this code should be integrated with the
// terrain collision code below, although that's not trivial to do since // terrain collision code below, although that's not trivial to do since
// it means the step needs to take into account the speeds of both // it means the step needs to take into account the speeds of both

View File

@ -61,27 +61,6 @@ impl<'a> System<'a> for Sys {
) )
.join() .join()
{ {
// Hit something solid
if physics.on_wall.is_some() || physics.on_ground || physics.on_ceiling {
for effect in projectile.hit_solid.drain(..) {
match effect {
projectile::Effect::Explode { power } => {
server_emitter.emit(ServerEvent::Explosion {
pos: pos.0,
power,
owner: projectile.owner,
friendly_damage: false,
reagent: None,
})
},
projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy {
entity,
cause: HealthSource::World,
}),
_ => {},
}
}
} else {
// Hit entity // Hit entity
for other in physics.touch_entities.iter().copied() { for other in physics.touch_entities.iter().copied() {
if projectile.owner == Some(other) { if projectile.owner == Some(other) {
@ -97,8 +76,7 @@ impl<'a> System<'a> for Sys {
source: DamageSource::Projectile, source: DamageSource::Projectile,
}; };
let other_entity = let other_entity = uid_allocator.retrieve_entity_internal(other.into());
uid_allocator.retrieve_entity_internal(other.into());
if let Some(loadout) = other_entity.and_then(|e| loadouts.get(e)) { if let Some(loadout) = other_entity.and_then(|e| loadouts.get(e)) {
damage.modify_damage(false, loadout); damage.modify_damage(false, loadout);
} }
@ -142,12 +120,10 @@ impl<'a> System<'a> for Sys {
reagent: None, reagent: None,
}) })
}, },
projectile::Effect::Vanish => { projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy {
server_emitter.emit(ServerEvent::Destroy {
entity, entity,
cause: HealthSource::World, cause: HealthSource::World,
}) }),
},
projectile::Effect::Possess => { projectile::Effect::Possess => {
if other != projectile.owner.unwrap() { if other != projectile.owner.unwrap() {
if let Some(owner) = projectile.owner { if let Some(owner) = projectile.owner {
@ -160,13 +136,34 @@ impl<'a> System<'a> for Sys {
} }
} }
// Hit something solid
if physics.on_wall.is_some() || physics.on_ground || physics.on_ceiling {
for effect in projectile.hit_solid.drain(..) {
match effect {
projectile::Effect::Explode { power } => {
server_emitter.emit(ServerEvent::Explosion {
pos: pos.0,
power,
owner: projectile.owner,
friendly_damage: false,
reagent: None,
})
},
projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy {
entity,
cause: HealthSource::World,
}),
_ => {},
}
}
}
if let Some(dir) = velocities if let Some(dir) = velocities
.get(entity) .get(entity)
.and_then(|vel| vel.0.try_normalized()) .and_then(|vel| vel.0.try_normalized())
{ {
ori.0 = dir.into(); ori.0 = dir.into();
} }
}
if projectile.time_left == Duration::default() { if projectile.time_left == Duration::default() {
server_emitter.emit(ServerEvent::Destroy { server_emitter.emit(ServerEvent::Destroy {