mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'sam/explosion-fix' into 'master'
Explosions now take into account hitbox of entity. See merge request veloren/veloren!1905
This commit is contained in:
commit
ad49318a63
@ -3,7 +3,7 @@ BasicRanged(
|
|||||||
buildup_duration: 0.5,
|
buildup_duration: 0.5,
|
||||||
recover_duration: 0.35,
|
recover_duration: 0.35,
|
||||||
projectile: Fireball(
|
projectile: Fireball(
|
||||||
damage: 100.0,
|
damage: 80.0,
|
||||||
radius: 5.0,
|
radius: 5.0,
|
||||||
energy_regen: 50,
|
energy_regen: 50,
|
||||||
),
|
),
|
||||||
|
@ -3,7 +3,7 @@ BasicRanged(
|
|||||||
buildup_duration: 0.5,
|
buildup_duration: 0.5,
|
||||||
recover_duration: 0.35,
|
recover_duration: 0.35,
|
||||||
projectile: Fireball(
|
projectile: Fireball(
|
||||||
damage: 100.0,
|
damage: 80.0,
|
||||||
radius: 5.0,
|
radius: 5.0,
|
||||||
energy_regen: 50,
|
energy_regen: 50,
|
||||||
),
|
),
|
||||||
|
@ -3,7 +3,7 @@ BasicRanged(
|
|||||||
buildup_duration: 0.8,
|
buildup_duration: 0.8,
|
||||||
recover_duration: 0.35,
|
recover_duration: 0.35,
|
||||||
projectile: Fireball(
|
projectile: Fireball(
|
||||||
damage: 100.0,
|
damage: 80.0,
|
||||||
radius: 5.0,
|
radius: 5.0,
|
||||||
energy_regen: 0,
|
energy_regen: 0,
|
||||||
),
|
),
|
||||||
|
@ -3,7 +3,7 @@ BasicRanged(
|
|||||||
buildup_duration: 0.5,
|
buildup_duration: 0.5,
|
||||||
recover_duration: 0.35,
|
recover_duration: 0.35,
|
||||||
projectile: Frostball(
|
projectile: Frostball(
|
||||||
damage: 100.0,
|
damage: 80.0,
|
||||||
radius: 5.0,
|
radius: 5.0,
|
||||||
),
|
),
|
||||||
projectile_body: Object(BoltFire), // TODO: Get ice projectile model
|
projectile_body: Object(BoltFire), // TODO: Get ice projectile model
|
||||||
|
@ -34,7 +34,7 @@ use hashbrown::HashSet;
|
|||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use specs::{join::Join, saveload::MarkerAllocator, Entity as EcsEntity, WorldExt};
|
use specs::{join::Join, saveload::MarkerAllocator, Entity as EcsEntity, WorldExt};
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
use vek::Vec3;
|
use vek::{Vec2, Vec3};
|
||||||
|
|
||||||
pub fn handle_poise(
|
pub fn handle_poise(
|
||||||
server: &Server,
|
server: &Server,
|
||||||
@ -599,6 +599,26 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
|
|||||||
});
|
});
|
||||||
let groups = ecs.read_storage::<comp::Group>();
|
let groups = ecs.read_storage::<comp::Group>();
|
||||||
|
|
||||||
|
// Used to get strength of explosion effects as they falloff over distance
|
||||||
|
fn cylinder_sphere_strength(
|
||||||
|
sphere_pos: Vec3<f32>,
|
||||||
|
radius: f32,
|
||||||
|
cyl_pos: Vec3<f32>,
|
||||||
|
cyl_body: Body,
|
||||||
|
) -> f32 {
|
||||||
|
// 2d check
|
||||||
|
let horiz_dist =
|
||||||
|
Vec2::<f32>::from(sphere_pos - cyl_pos).distance(Vec2::default()) - cyl_body.radius();
|
||||||
|
// z check
|
||||||
|
let half_body_height = cyl_body.height() / 2.0;
|
||||||
|
let vert_distance =
|
||||||
|
(sphere_pos.z - (cyl_pos.z + half_body_height)).abs() - half_body_height;
|
||||||
|
|
||||||
|
// Compare both checks, take whichever gives weaker effect, sets minimum of 0 so
|
||||||
|
// that explosions reach a max strength on edge of entity
|
||||||
|
((horiz_dist.max(vert_distance).max(0.0) / radius).min(1.0) - 1.0).powi(2)
|
||||||
|
}
|
||||||
|
|
||||||
for effect in explosion.effects {
|
for effect in explosion.effects {
|
||||||
match effect {
|
match effect {
|
||||||
RadiusEffect::TerrainDestruction(power) => {
|
RadiusEffect::TerrainDestruction(power) => {
|
||||||
@ -677,19 +697,25 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
|
|||||||
RadiusEffect::Attack(attack) => {
|
RadiusEffect::Attack(attack) => {
|
||||||
let energies = &ecs.read_storage::<comp::Energy>();
|
let energies = &ecs.read_storage::<comp::Energy>();
|
||||||
let combos = &ecs.read_storage::<comp::Combo>();
|
let combos = &ecs.read_storage::<comp::Combo>();
|
||||||
for (entity_b, pos_b, _health_b, inventory_b_maybe, stats_b_maybe) in (
|
for (entity_b, pos_b, _health_b, inventory_b_maybe, stats_b_maybe, body_b_maybe) in
|
||||||
|
(
|
||||||
&ecs.entities(),
|
&ecs.entities(),
|
||||||
&ecs.read_storage::<comp::Pos>(),
|
&ecs.read_storage::<comp::Pos>(),
|
||||||
&ecs.read_storage::<comp::Health>(),
|
&ecs.read_storage::<comp::Health>(),
|
||||||
ecs.read_storage::<comp::Inventory>().maybe(),
|
ecs.read_storage::<comp::Inventory>().maybe(),
|
||||||
ecs.read_storage::<comp::Stats>().maybe(),
|
ecs.read_storage::<comp::Stats>().maybe(),
|
||||||
|
ecs.read_storage::<comp::Body>().maybe(),
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
.filter(|(_, _, h, _, _)| !h.is_dead)
|
.filter(|(_, _, h, _, _, _)| !h.is_dead)
|
||||||
{
|
{
|
||||||
// Check if it is a hit
|
// Check if it is a hit
|
||||||
|
let strength = if let Some(body) = body_b_maybe {
|
||||||
|
cylinder_sphere_strength(pos, explosion.radius, pos_b.0, *body)
|
||||||
|
} else {
|
||||||
let distance_squared = pos.distance_squared(pos_b.0);
|
let distance_squared = pos.distance_squared(pos_b.0);
|
||||||
let strength = 1.0 - distance_squared / explosion.radius.powi(2);
|
1.0 - distance_squared / explosion.radius.powi(2)
|
||||||
|
};
|
||||||
if strength > 0.0 {
|
if strength > 0.0 {
|
||||||
// See if entities are in the same group
|
// See if entities are in the same group
|
||||||
let same_group = owner_entity
|
let same_group = owner_entity
|
||||||
@ -740,10 +766,19 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
RadiusEffect::Entity(mut effect) => {
|
RadiusEffect::Entity(mut effect) => {
|
||||||
for (entity_b, pos_b) in (&ecs.entities(), &ecs.read_storage::<comp::Pos>()).join()
|
for (entity_b, pos_b, body_b_maybe) in (
|
||||||
|
&ecs.entities(),
|
||||||
|
&ecs.read_storage::<comp::Pos>(),
|
||||||
|
ecs.read_storage::<comp::Body>().maybe(),
|
||||||
|
)
|
||||||
|
.join()
|
||||||
{
|
{
|
||||||
|
let strength = if let Some(body) = body_b_maybe {
|
||||||
|
cylinder_sphere_strength(pos, explosion.radius, pos_b.0, *body)
|
||||||
|
} else {
|
||||||
let distance_squared = pos.distance_squared(pos_b.0);
|
let distance_squared = pos.distance_squared(pos_b.0);
|
||||||
let strength = 1.0 - distance_squared / explosion.radius.powi(2);
|
1.0 - distance_squared / explosion.radius.powi(2)
|
||||||
|
};
|
||||||
|
|
||||||
if strength > 0.0 {
|
if strength > 0.0 {
|
||||||
let is_alive = ecs
|
let is_alive = ecs
|
||||||
|
@ -56,7 +56,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
effects: vec![
|
effects: vec![
|
||||||
RadiusEffect::Entity(Effect::Damage(Damage {
|
RadiusEffect::Entity(Effect::Damage(Damage {
|
||||||
source: DamageSource::Explosion,
|
source: DamageSource::Explosion,
|
||||||
value: 500.0,
|
value: 400.0,
|
||||||
})),
|
})),
|
||||||
RadiusEffect::Entity(Effect::PoiseChange(PoiseChange {
|
RadiusEffect::Entity(Effect::PoiseChange(PoiseChange {
|
||||||
source: PoiseSource::Explosion,
|
source: PoiseSource::Explosion,
|
||||||
|
Loading…
Reference in New Issue
Block a user