From 89a6a06a7b9290c1f370e5a2a8544cb9b1d4b296 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sun, 23 Aug 2020 14:24:58 +0100 Subject: [PATCH 01/18] Adjusted worldgen colours for new lighting model --- assets/world/style/colors.ron | 54 ++++++++++++++++--------------- assets/world/tree/mangroves/1.vox | 2 +- assets/world/tree/mangroves/2.vox | 2 +- assets/world/tree/mangroves/3.vox | 2 +- assets/world/tree/mangroves/4.vox | 2 +- assets/world/tree/mangroves/5.vox | 2 +- assets/world/tree/mangroves/6.vox | 2 +- assets/world/tree/mangroves/7.vox | 2 +- assets/world/tree/mangroves/8.vox | 2 +- world/src/block/mod.rs | 11 +++---- world/src/column/mod.rs | 4 ++- 11 files changed, 44 insertions(+), 41 deletions(-) diff --git a/assets/world/style/colors.ron b/assets/world/style/colors.ron index bc03c21078..7a04a4a666 100644 --- a/assets/world/style/colors.ron +++ b/assets/world/style/colors.ron @@ -17,13 +17,13 @@ Water: None, GreenSludge: None, // Leaves all actually get interpolated. - TemperateLeaves: (start: (0, 132, 94), end: (142, 181, 0)), - PineLeaves: (start: (0, 60, 50), end: (30, 100, 10)), + TemperateLeaves: (start: (0, 70, 45), end: (120, 185, 0)), + PineLeaves: (start: (0, 60, 50), end: (30, 80, 10)), PalmLeavesInner: (start: (61, 166, 43), end: (29, 130, 32)), PalmLeavesOuter: (start: (62, 171, 38), end: (45, 171, 65)), - Acacia: (start: (15, 126, 50), end: (30, 180, 10)), + Acacia: (start: (30, 80, 0), end: (90, 110, 20)), Liana: (start: (0, 125, 107), end: (0, 155, 129)), - Mangrove: (start: (32, 56, 22), end: (57, 69, 27)), + Mangrove: (start: (15, 60, 10), end: (20, 100, 47)), ) // Water blocks ignore color now so this isn't used, but just in case this color was worth @@ -31,34 +31,35 @@ // green_sludge: (30.0, 126.0, 23.0) ), column: ( - cold_grass: (0.0, 0.5, 0.25), - warm_grass: (0.4, 0.8, 0.0), + cold_grass: (-0.2, 0.3, 0.1), + warm_grass: (0.3, 0.25, -0.8), dark_grass: (0.15, 0.4, 0.1), wet_grass: (0.1, 0.8, 0.2), - cold_stone: (0.57, 0.67, 0.8), - hot_stone: (0.07, 0.07, 0.06), - warm_stone: (0.77, 0.77, 0.64), + cold_stone: (0.4, 0.67, 0.8), + hot_stone: (0.05, 0.05, 0.04), + warm_stone: (0.30, 0.2, 0.15), beach_sand: (0.8, 0.75, 0.5), desert_sand: (0.7, 0.4, 0.25), - snow: (0.8, 0.85, 1.0), + snow: (0.75, 0.8, 1.8), + snow_moss: (0.35, 0.55, 0.7), - stone_col: (195, 187, 201), + stone_col: (100, 100, 170), dirt_low: (0.075, 0.07, 0.3), dirt_high: (0.75, 0.55, 0.1), snow_high: (0.01, 0.3, 0.0), - warm_stone_high: (0.3, 0.12, 0.2), + warm_stone_high: (0.25, 0.22, 0.3), grass_high: (0.15, 0.2, 0.15), - tropical_high: (0.87, 0.62, 0.56), + tropical_high: (0.95, 0.55, 0.50), ), // NOTE: I think (but am not sure) that this is the color of stuff below the bottom-most // ground. I'm not sure how easy it is to see. deep_stone_color: (125, 120, 130), layer: ( bridge: (80, 80, 100), - stalagtite: (200, 200, 200), + stalagtite: (140, 110, 250), ), site: ( castle: (), @@ -74,24 +75,25 @@ pole: (90, 70, 50), flag: ( Evil: (80, 10, 130), - Good: (200, 80, 40), + Good: (150, 20, 0), ), stone: ( Evil: (65, 60, 55), - Good: (100, 100, 110), + Good: (70, 75, 80), ), ), house: ( - foundation: (100, 100, 100), + foundation: (70, 70, 70), floor: (100, 75, 50), roof: ( Roof1: (0x99, 0x5E, 0x54), Roof2: (0x43, 0x63, 0x64), Roof3: (0x76, 0x6D, 0x68), - Roof4: (0x7B, 0x41, 0x61), + Roof4: (0x65, 0x01, 0x41), Roof5: (0x52, 0x20, 0x20), - Roof6: (0x1A, 0x4A, 0x59), - Roof7: (0xCC, 0x76, 0x4E), + Roof6: (0x05, 0x3A, 0x40), + Roof7: (0xCC, 0x56, 0x3E), + Roof8: (0x05, 0x48, 0x40), // (0x1D, 0x4D, 0x45), // (0xB3, 0x7D, 0x60), // (0xAC, 0x5D, 0x26), @@ -122,18 +124,18 @@ Wall9: (0xAE, 0x8D, 0x9C), ), support: ( - Support1: (60, 45, 30), - Support2: (0x65, 0x55, 0x56), + Support1: (65, 30, 0), + Support2: (0x35, 0x25, 0x26), Support3: (0x53, 0x33, 0x13), - Support4: (0x58, 0x42, 0x33), + Support4: (0x65, 0x30, 0), ), ), ), ), - plot_town_path: (100, 95, 65), + plot_town_path: (90, 70, 45), - plot_field_dirt: (80, 55, 35), - plot_field_mound: (70, 80, 30), + plot_field_dirt: (70, 25, 15), + plot_field_mound: (40, 60, 10), wall_low: (130, 100, 0), wall_high :(90, 70, 50), diff --git a/assets/world/tree/mangroves/1.vox b/assets/world/tree/mangroves/1.vox index 01c27e08d2..35ceab2cda 100644 --- a/assets/world/tree/mangroves/1.vox +++ b/assets/world/tree/mangroves/1.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8b2216711df71746938e13dd5d764d2d440b9b41342e870db311c31edd863b55 +oid sha256:23658faec4e759287a5d5b48c4f79562cd51e0271922d740cf21bf6b3fd1da8b size 38312 diff --git a/assets/world/tree/mangroves/2.vox b/assets/world/tree/mangroves/2.vox index 3ee653ec0b..c9c4f2be2c 100644 --- a/assets/world/tree/mangroves/2.vox +++ b/assets/world/tree/mangroves/2.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3071e34a8192189c7f7c70bc4a75a06122c27a82e0bfc8d299c8843f8f42b6be +oid sha256:d697913274af3963801db91db118228969383112c2167e023bb7042f4babcea5 size 27900 diff --git a/assets/world/tree/mangroves/3.vox b/assets/world/tree/mangroves/3.vox index bf9fb014b2..622dc39174 100644 --- a/assets/world/tree/mangroves/3.vox +++ b/assets/world/tree/mangroves/3.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c35603fdbec8a0ed14cbf58133fefd999b457dda56bf8bb66ea519fa65a4bf04 +oid sha256:7626ee7467e8a37b516c4c9d81763e35230aa760975a3307ab9cc197efef1004 size 52528 diff --git a/assets/world/tree/mangroves/4.vox b/assets/world/tree/mangroves/4.vox index 4499836fcb..15a65048c4 100644 --- a/assets/world/tree/mangroves/4.vox +++ b/assets/world/tree/mangroves/4.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4dbca327b6129910e95f235c2c6d334b2ec0b77b192030ff0c5eb620fedaaff0 +oid sha256:dc5cf476e2a7ac97c0d52bd8d164db18c153d08adfd21327eb04c7a9f77459ca size 48860 diff --git a/assets/world/tree/mangroves/5.vox b/assets/world/tree/mangroves/5.vox index ee34c5a1ce..9deb4f07bf 100644 --- a/assets/world/tree/mangroves/5.vox +++ b/assets/world/tree/mangroves/5.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:28c0db8409627938b41986bf976d8ff5a84f86e036fb385fb52228b743ad5c73 +oid sha256:b5fcbb99af03f6c69ac8809616ce0948ae83dae6418ecfeeb1ea385325d8d888 size 44852 diff --git a/assets/world/tree/mangroves/6.vox b/assets/world/tree/mangroves/6.vox index 6a479a72f5..dcd4c248cc 100644 --- a/assets/world/tree/mangroves/6.vox +++ b/assets/world/tree/mangroves/6.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:05ae9ce6977e4b7ff6752023e53a6488e4ea8b2873f5aeb726dc83ffdbe85fbc +oid sha256:ec650fe354dde4546d6bb910edb709c71955cd2020a762e2ab5516bc6ceb22eb size 63060 diff --git a/assets/world/tree/mangroves/7.vox b/assets/world/tree/mangroves/7.vox index dbfb89aae5..1c039a13f1 100644 --- a/assets/world/tree/mangroves/7.vox +++ b/assets/world/tree/mangroves/7.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:963035ca5f4ab5b436620c1de7a0ef2e9ae8b57c54cd055db5c935f6147bd082 +oid sha256:2bf44e30f091d854deb2d164972294f278040d13d2ff12b7faef55832eb02159 size 49744 diff --git a/assets/world/tree/mangroves/8.vox b/assets/world/tree/mangroves/8.vox index af66eaadfb..2de12860d1 100644 --- a/assets/world/tree/mangroves/8.vox +++ b/assets/world/tree/mangroves/8.vox @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3aaa46ee933a356a7b4f9f2fdb93ce4ec6b8383be6bc202022d461291de19bb9 +oid sha256:7e12c756144c76edbb9250fbd85a7ff3f1e365ff490cfecbf141b9ef10bad86b size 68520 diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index 8e482d4c92..4433eba5d1 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -361,12 +361,11 @@ impl<'a> BlockGen<'a> { Some(Block::new( BlockKind::Rock, - stone_col - - Rgb::new( - field0.get(wpos) as u8 % 16, - field1.get(wpos) as u8 % 16, - field2.get(wpos) as u8 % 16, - ), + stone_col.map2(Rgb::new( + field0.get(wpos) as u8 % 16, + field1.get(wpos) as u8 % 16, + field2.get(wpos) as u8 % 16, + ), |stone, x| stone.saturating_sub(x)), )) } else { None diff --git a/world/src/column/mod.rs b/world/src/column/mod.rs index c8e07476e1..aa1bf46225 100644 --- a/world/src/column/mod.rs +++ b/world/src/column/mod.rs @@ -38,6 +38,7 @@ pub struct Colors { pub beach_sand: (f32, f32, f32), pub desert_sand: (f32, f32, f32), pub snow: (f32, f32, f32), + pub snow_moss: (f32, f32, f32), pub stone_col: (u8, u8, u8), @@ -802,6 +803,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> { beach_sand, desert_sand, snow, + snow_moss, stone_col, dirt_low, dirt_high, @@ -839,7 +841,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> { warm_grass, marble.sub(0.5).add(1.0.sub(humidity).mul(0.5)).powf(1.5), ); - let snow_moss = Rgb::lerp(snow, cold_grass, 0.4 + marble.powf(1.5) * 0.6); + let snow_moss = Rgb::lerp(snow_moss.into(), cold_grass, 0.4 + marble.powf(1.5) * 0.6); let moss = Rgb::lerp(dark_grass, cold_grass, marble.powf(1.5)); let rainforest = Rgb::lerp(wet_grass, warm_grass, marble.powf(1.5)); let sand = Rgb::lerp(beach_sand, desert_sand, marble); From 6e7620dbe11f9d1f5825834f75d5ae1211fb2e10 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sun, 23 Aug 2020 14:29:57 +0100 Subject: [PATCH 02/18] Prevented terrain scatter spawning in the air --- world/src/layer/mod.rs | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/world/src/layer/mod.rs b/world/src/layer/mod.rs index c6e689a22c..a86d1fe1dc 100644 --- a/world/src/layer/mod.rs +++ b/world/src/layer/mod.rs @@ -312,20 +312,30 @@ pub fn apply_scatter_to<'a>( }); if let Some(bk) = bk { - let mut z = col_sample.alt as i32 - 4; - for _ in 0..8 { - if vol - .get(Vec3::new(offs.x, offs.y, z)) - .map(|b| !b.is_solid()) - .unwrap_or(true) - { - let _ = vol.set( - Vec3::new(offs.x, offs.y, z), - Block::new(bk, Rgb::broadcast(0)), - ); - break; - } - z += 1; + let alt = col_sample.alt as i32; + + // Find the intersection between ground and air, if there is one near the + // surface + if let Some(solid_end) = (-4..8) + .find(|z| { + vol.get(Vec3::new(offs.x, offs.y, alt + z)) + .map(|b| b.is_solid()) + .unwrap_or(false) + }) + .and_then(|solid_start| { + (1..8) + .map(|z| solid_start + z) + .find(|z| { + vol.get(Vec3::new(offs.x, offs.y, alt + z)) + .map(|b| !b.is_solid()) + .unwrap_or(true) + }) + }) + { + let _ = vol.set( + Vec3::new(offs.x, offs.y, alt + solid_end), + Block::new(bk, Rgb::broadcast(0)), + ); } } } From c905819adc4a87b898e4bc80391a589c1a8c0c39 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sun, 23 Aug 2020 14:30:24 +0100 Subject: [PATCH 03/18] Made below-ground LoD dark --- assets/voxygen/shaders/lod-terrain-frag.glsl | 3 ++- assets/voxygen/shaders/lod-terrain-vert.glsl | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/assets/voxygen/shaders/lod-terrain-frag.glsl b/assets/voxygen/shaders/lod-terrain-frag.glsl index 8ae0f0ab2c..1625f902c4 100644 --- a/assets/voxygen/shaders/lod-terrain-frag.glsl +++ b/assets/voxygen/shaders/lod-terrain-frag.glsl @@ -25,6 +25,7 @@ in vec3 f_pos; in vec3 f_norm; +in float pull_down; // in vec2 v_pos_orig; // in vec4 f_shadow; // in vec4 f_square; @@ -106,7 +107,7 @@ void main() { // mat4 invfoo = foo * inverse(foo * all_mat); // vec3 old_coord = all_mat * vec4(f_pos.xyz, 1.0); // vec4 new_f_pos = invfoo * (old_coord);//vec4(f_pos, 1.0); - vec3 f_col = lod_col(f_pos.xy); + vec3 f_col = mix(lod_col(f_pos.xy), vec3(0), clamp(pull_down / 10, 0, 1)); // tgt_color = vec4(f_col, 1.0); // return; // vec3 f_col = srgb_to_linear(vec3(1.0)); diff --git a/assets/voxygen/shaders/lod-terrain-vert.glsl b/assets/voxygen/shaders/lod-terrain-vert.glsl index 6ef2dd7bdf..2e9d38da4d 100644 --- a/assets/voxygen/shaders/lod-terrain-vert.glsl +++ b/assets/voxygen/shaders/lod-terrain-vert.glsl @@ -29,6 +29,7 @@ uniform u_locals { out vec3 f_pos; out vec3 f_norm; +out float pull_down; // out vec2 v_pos_orig; // out vec4 f_square; // out vec4 f_shadow; @@ -48,7 +49,8 @@ void main() { // f_shadow = textureBicubic(t_horizon, pos_to_tex(f_pos.xy)); - f_pos.z -= 1.0 / pow(distance(focus_pos.xy, f_pos.xy) / (view_distance.x * 0.95), 20.0); + pull_down = 1.0 / pow(distance(focus_pos.xy, f_pos.xy) / (view_distance.x * 0.95), 20.0); + f_pos.z -= pull_down; // f_pos.z -= 100.0 * pow(1.0 + 0.01 / view_distance.x, -pow(distance(focus_pos.xy, f_pos.xy), 2.0)); // f_pos.z = mix(-f_pos.z, f_pos.z, view_distance.x <= distance(focus_pos.xy, f_pos.xy) + 32.0); From 6918020ed804201cecae1df2dd60decbac8b4988 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sun, 23 Aug 2020 15:05:58 +0100 Subject: [PATCH 04/18] Less bizarre rock and stalagtite colours --- assets/world/style/colors.ron | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/world/style/colors.ron b/assets/world/style/colors.ron index 7a04a4a666..d6f31edc7b 100644 --- a/assets/world/style/colors.ron +++ b/assets/world/style/colors.ron @@ -43,7 +43,7 @@ snow: (0.75, 0.8, 1.8), snow_moss: (0.35, 0.55, 0.7), - stone_col: (100, 100, 170), + stone_col: (70, 90, 150), dirt_low: (0.075, 0.07, 0.3), dirt_high: (0.75, 0.55, 0.1), @@ -59,7 +59,7 @@ deep_stone_color: (125, 120, 130), layer: ( bridge: (80, 80, 100), - stalagtite: (140, 110, 250), + stalagtite: (140, 150, 200), ), site: ( castle: (), From 86728c714f549b901032d9441a720c3773ce552d Mon Sep 17 00:00:00 2001 From: Monty Marz Date: Sun, 23 Aug 2020 17:05:04 +0200 Subject: [PATCH 05/18] better formatting and adjusted stone spawn rate --- world/src/layer/mod.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/world/src/layer/mod.rs b/world/src/layer/mod.rs index a86d1fe1dc..060d0cff6b 100644 --- a/world/src/layer/mod.rs +++ b/world/src/layer/mod.rs @@ -323,13 +323,11 @@ pub fn apply_scatter_to<'a>( .unwrap_or(false) }) .and_then(|solid_start| { - (1..8) - .map(|z| solid_start + z) - .find(|z| { - vol.get(Vec3::new(offs.x, offs.y, alt + z)) - .map(|b| !b.is_solid()) - .unwrap_or(true) - }) + (1..8).map(|z| solid_start + z).find(|z| { + vol.get(Vec3::new(offs.x, offs.y, alt + z)) + .map(|b| !b.is_solid()) + .unwrap_or(true) + }) }) { let _ = vol.set( From 7af1b45d5fc8bb6734de9fb9985d294e4016b07b Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sun, 23 Aug 2020 23:49:09 +0100 Subject: [PATCH 06/18] Better pet pathfinding --- common/src/path.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/path.rs b/common/src/path.rs index 78f0d76e51..de70785a48 100644 --- a/common/src/path.rs +++ b/common/src/path.rs @@ -458,7 +458,7 @@ where let is_walkable = |pos: &Vec3| walkable(vol, *pos); let get_walkable_z = |pos| { let mut z_incr = 0; - for _ in 0..32 { + for _ in 0..128 { let test_pos = pos + Vec3::unit_z() * z_incr; if is_walkable(&test_pos) { return Some(test_pos); From 91c8effc8068c1076a5c867b9534c774c6fef164 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sun, 23 Aug 2020 23:49:26 +0100 Subject: [PATCH 07/18] Less harsh terrain noise --- assets/voxygen/shaders/terrain-frag.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/voxygen/shaders/terrain-frag.glsl b/assets/voxygen/shaders/terrain-frag.glsl index efbc5d4125..dd4033ae29 100644 --- a/assets/voxygen/shaders/terrain-frag.glsl +++ b/assets/voxygen/shaders/terrain-frag.glsl @@ -345,7 +345,7 @@ void main() { const float A = 0.055; const float W_INV = 1 / (1 + A); const float W_2 = W_INV * W_INV;//pow(W_INV, 2.4); - const float NOISE_FACTOR = 0.02;//pow(0.02, 1.2); + const float NOISE_FACTOR = 0.015;//pow(0.02, 1.2); vec3 noise_delta = (sqrt(f_col) * W_INV + noise * NOISE_FACTOR); // noise_delta = noise_delta * noise_delta * W_2 - f_col; // lum = W ⋅ col From 90735f1ef73944a6614a750cda601d5afcc017ec Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Sun, 23 Aug 2020 23:49:34 +0100 Subject: [PATCH 08/18] Improved world colours --- assets/world/style/colors.ron | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/assets/world/style/colors.ron b/assets/world/style/colors.ron index d6f31edc7b..330bdbfc0b 100644 --- a/assets/world/style/colors.ron +++ b/assets/world/style/colors.ron @@ -17,13 +17,13 @@ Water: None, GreenSludge: None, // Leaves all actually get interpolated. - TemperateLeaves: (start: (0, 70, 45), end: (120, 185, 0)), + TemperateLeaves: (start: (0, 70, 45), end: (90, 140, 0)), PineLeaves: (start: (0, 60, 50), end: (30, 80, 10)), - PalmLeavesInner: (start: (61, 166, 43), end: (29, 130, 32)), - PalmLeavesOuter: (start: (62, 171, 38), end: (45, 171, 65)), - Acacia: (start: (30, 80, 0), end: (90, 110, 20)), + PalmLeavesInner: (start: (70, 140, 43), end: (55, 140, 32)), + PalmLeavesOuter: (start: (60, 130, 38), end: (30, 130, 65)), + Acacia: (start: (30, 100, 0), end: (90, 110, 20)), Liana: (start: (0, 125, 107), end: (0, 155, 129)), - Mangrove: (start: (15, 60, 10), end: (20, 100, 47)), + Mangrove: (start: (15, 80, 10), end: (20, 120, 47)), ) // Water blocks ignore color now so this isn't used, but just in case this color was worth @@ -31,7 +31,7 @@ // green_sludge: (30.0, 126.0, 23.0) ), column: ( - cold_grass: (-0.2, 0.3, 0.1), + cold_grass: (0.0, 0.3, 0.1), warm_grass: (0.3, 0.25, -0.8), dark_grass: (0.15, 0.4, 0.1), wet_grass: (0.1, 0.8, 0.2), @@ -39,14 +39,14 @@ hot_stone: (0.05, 0.05, 0.04), warm_stone: (0.30, 0.2, 0.15), beach_sand: (0.8, 0.75, 0.5), - desert_sand: (0.7, 0.4, 0.25), + desert_sand: (0.6, 0.4, 0.2), snow: (0.75, 0.8, 1.8), snow_moss: (0.35, 0.55, 0.7), - stone_col: (70, 90, 150), + stone_col: (90, 110, 150), dirt_low: (0.075, 0.07, 0.3), - dirt_high: (0.75, 0.55, 0.1), + dirt_high: (0.6, 0.3, 0.05), snow_high: (0.01, 0.3, 0.0), warm_stone_high: (0.25, 0.22, 0.3), From 6a4c5a05d021ad7bb355b6e2a4db4fd3623b7f38 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 24 Aug 2020 18:24:44 +0100 Subject: [PATCH 09/18] Fixed projectile collisions, hitboxes, better aiming --- common/src/comp/body.rs | 69 ++++++--- common/src/comp/phys.rs | 30 +++- common/src/states/dash_melee.rs | 2 +- common/src/states/triple_strike.rs | 2 +- common/src/sys/phys.rs | 234 +++++++++++++++++++---------- common/src/sys/projectile.rs | 150 +++++++++--------- server/src/state_ext.rs | 20 +-- voxygen/src/scene/mod.rs | 2 +- voxygen/src/session.rs | 2 +- world/src/block/mod.rs | 13 +- 10 files changed, 330 insertions(+), 194 deletions(-) diff --git a/common/src/comp/body.rs b/common/src/comp/body.rs index 7d29f69412..317c10d953 100644 --- a/common/src/comp/body.rs +++ b/common/src/comp/body.rs @@ -139,43 +139,62 @@ impl Body { pub fn radius(&self) -> f32 { // TODO: Improve these values (some might be reliant on more info in inner type) match self { - Body::Humanoid(_) => 0.2, - Body::QuadrupedSmall(_) => 0.3, + Body::Humanoid(_) => 0.6, + Body::QuadrupedSmall(_) => 0.6, Body::QuadrupedMedium(_) => 0.9, - Body::Critter(_) => 0.2, + Body::QuadrupedLow(_) => 1.0, + Body::Critter(_) => 0.5, Body::BirdMedium(_) => 0.5, Body::FishMedium(_) => 0.5, Body::Dragon(_) => 2.5, - Body::BirdSmall(_) => 0.2, - Body::FishSmall(_) => 0.2, - Body::BipedLarge(_) => 3.0, - Body::Golem(_) => 2.5, - Body::QuadrupedLow(_) => 1.0, - Body::Object(_) => 0.3, + Body::BirdSmall(_) => 0.4, + Body::FishSmall(_) => 0.4, + Body::BipedLarge(_) => 2.0, + Body::Golem(_) => 1.75, + Body::Object(_) => 0.4, } } pub fn height(&self) -> f32 { match self { Body::Humanoid(humanoid) => match humanoid.species { - humanoid::Species::Danari => 0.8, - humanoid::Species::Dwarf => 0.9, - humanoid::Species::Orc => 1.14, - humanoid::Species::Undead => 0.95, + humanoid::Species::Danari => 0.5, + humanoid::Species::Dwarf => 1.55, + humanoid::Species::Orc => 1.95, + _ => 1.8, + }, + Body::QuadrupedSmall(body) => match body.species { + quadruped_small::Species::Dodarock => 1.5, + quadruped_small::Species::Holladon => 1.5, + quadruped_small::Species::Truffler => 2.0, _ => 1.0, }, - Body::QuadrupedSmall(_) => 0.6, - Body::QuadrupedMedium(_) => 0.5, - Body::Critter(_) => 0.4, - Body::BirdMedium(_) => 1.2, - Body::FishMedium(_) => 1.0, - Body::Dragon(_) => 5.0, - Body::BirdSmall(_) => 0.4, - Body::FishSmall(_) => 0.4, - Body::BipedLarge(_) => 5.0, - Body::Golem(_) => 5.0, - Body::QuadrupedLow(_) => 0.5, - Body::Object(_) => 0.6, + Body::QuadrupedMedium(body) => match body.species { + quadruped_medium::Species::Tarasque => 2.5, + quadruped_medium::Species::Lion => 1.8, + quadruped_medium::Species::Saber => 1.8, + quadruped_medium::Species::Catoblepas => 2.8, + _ => 1.6, + }, + Body::QuadrupedLow(body) => match body.species { + quadruped_low::Species::Monitor => 1.5, + quadruped_low::Species::Tortoise => 2.0, + quadruped_low::Species::Rocksnapper => 2.0, + quadruped_low::Species::Maneater => 4.0, + _ => 1.3, + }, + Body::Critter(_) => 0.7, + Body::BirdMedium(body) => match body.species { + bird_medium::Species::Cockatrice => 1.8, + _ => 1.1, + }, + Body::FishMedium(_) => 1.1, + Body::Dragon(_) => 20.0, + Body::BirdSmall(_) => 1.1, + Body::FishSmall(_) => 0.9, + Body::BipedLarge(_) => 4.5, + Body::Golem(_) => 5.8, + Body::Object(_) => 1.0, } } diff --git a/common/src/comp/phys.rs b/common/src/comp/phys.rs index 4e38c59ef0..29dfbcc565 100644 --- a/common/src/comp/phys.rs +++ b/common/src/comp/phys.rs @@ -55,6 +55,22 @@ pub enum Collider { Point, } +impl Collider { + pub fn get_radius(&self) -> f32 { + match self { + Collider::Box { radius, .. } => *radius, + Collider::Point => 0.0, + } + } + + pub fn get_z_limits(&self) -> (f32, f32) { + match self { + Collider::Box { z_min, z_max, .. } => (*z_min, *z_max), + Collider::Point => (0.0, 0.0), + } + } +} + impl Component for Collider { type Storage = FlaggedStorage>; } @@ -74,16 +90,26 @@ impl Component for Sticky { } // PhysicsState -#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize)] +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] pub struct PhysicsState { pub on_ground: bool, pub on_ceiling: bool, pub on_wall: Option>, - pub touch_entity: Option, + pub touch_entities: Vec, pub in_fluid: Option, // Depth } impl PhysicsState { + pub fn clear(&mut self) { + // Avoid allocation overhead! + let mut touch_entities = std::mem::take(&mut self.touch_entities); + touch_entities.clear(); + *self = Self { + touch_entities, + ..Self::default() + } + } + pub fn on_surface(&self) -> Option> { self.on_ground .then_some(-Vec3::unit_z()) diff --git a/common/src/states/dash_melee.rs b/common/src/states/dash_melee.rs index c8130c1bb5..239d1fb2c1 100644 --- a/common/src/states/dash_melee.rs +++ b/common/src/states/dash_melee.rs @@ -33,7 +33,7 @@ impl CharacterBehavior for Data { } } - if self.buildup_duration != Duration::default() && data.physics.touch_entity.is_none() { + if self.buildup_duration != Duration::default() && data.physics.touch_entities.is_empty() { // Build up (this will move you forward) update.vel.0 = Vec3::new(0.0, 0.0, update.vel.0.z) + (update.vel.0 * Vec3::new(1.0, 1.0, 0.0) diff --git a/common/src/states/triple_strike.rs b/common/src/states/triple_strike.rs index fcb62f5846..bdf082b80f 100644 --- a/common/src/states/triple_strike.rs +++ b/common/src/states/triple_strike.rs @@ -113,7 +113,7 @@ impl CharacterBehavior for Data { // Handling movement if stage_time_active < Duration::from_millis(STAGE_DURATION / 3) { - let adjusted_accel = match (self.stage, data.physics.touch_entity.is_none()) { + let adjusted_accel = match (self.stage, data.physics.touch_entities.is_empty()) { (Stage::First, true) => INITIAL_ACCEL, (Stage::Second, true) => INITIAL_ACCEL * 0.75, (Stage::Third, true) => INITIAL_ACCEL * 0.75, diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index 99e914298c..cca5325346 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -11,8 +11,8 @@ use crate::{ }; use rayon::iter::ParallelIterator; use specs::{ - saveload::MarkerAllocator, Entities, Join, ParJoin, Read, ReadExpect, ReadStorage, System, - WriteStorage, + saveload::MarkerAllocator, storage, Entities, Join, ParJoin, Read, ReadExpect, ReadStorage, + System, WriteStorage, }; use std::ops::Range; use vek::*; @@ -95,7 +95,7 @@ impl<'a> System<'a> for Sys { ) { let mut event_emitter = event_bus.emitter(); - // Add physics state components + // Add/reset physics state components for entity in ( &entities, !&physics_states, @@ -108,7 +108,153 @@ impl<'a> System<'a> for Sys { .map(|(e, _, _, _, _, _)| e) .collect::>() { - let _ = physics_states.insert(entity, Default::default()); + match physics_states.entry(entity) { + Ok(storage::StorageEntry::Occupied(mut o)) => o.get_mut().clear(), + Ok(storage::StorageEntry::Vacant(v)) => { + v.insert(Default::default()); + }, + Err(_) => {}, + } + } + + // Apply pushback + // + // Note: We now do this first because we project velocity ahead. This is slighty + // imperfect and implies that we might get edge-cases where entities + // standing right next to the edge of a wall may get hit by projectiles + // fired into the wall very close to them. However, this sort of thing is + // already possible with poorly-defined hitboxes anyway so it's not too + // 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 + // 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 + // entities. + for (entity, pos, scale, mass, collider, _, _, physics, projectile) in ( + &entities, + &positions, + scales.maybe(), + masses.maybe(), + colliders.maybe(), + !&mountings, + stickies.maybe(), + &mut physics_states, + // TODO: if we need to avoid collisions for other things consider moving whether it + // should interact into the collider component or into a separate component + projectiles.maybe(), + ) + .join() + .filter(|(_, _, _, _, _, _, sticky, physics, _)| { + sticky.is_none() || (physics.on_wall.is_none() && !physics.on_ground) + }) + { + let scale = scale.map(|s| s.0).unwrap_or(1.0); + let radius = collider.map(|c| c.get_radius()).unwrap_or(0.5); + let z_limits = collider.map(|c| c.get_z_limits()).unwrap_or((-0.5, 0.5)); + let mass = mass.map(|m| m.0).unwrap_or(scale); + + // Group to ignore collisions with + let ignore_group = projectile + .and_then(|p| p.owner) + .and_then(|uid| uid_allocator.retrieve_entity_internal(uid.into())) + .and_then(|e| groups.get(e)); + + for ( + entity_other, + other, + pos_other, + scale_other, + mass_other, + collider_other, + _, + group, + ) in ( + &entities, + &uids, + &positions, + scales.maybe(), + masses.maybe(), + colliders.maybe(), + !&mountings, + groups.maybe(), + ) + .join() + { + if ignore_group.is_some() && ignore_group == group { + continue; + } + + let scale_other = scale_other.map(|s| s.0).unwrap_or(1.0); + let radius_other = collider_other.map(|c| c.get_radius()).unwrap_or(0.5); + let z_limits_other = collider_other + .map(|c| c.get_z_limits()) + .unwrap_or((-0.5, 0.5)); + let mass_other = mass_other.map(|m| m.0).unwrap_or(scale_other); + if mass_other == 0.0 { + continue; + } + + let collision_dist = scale * radius + scale_other * radius_other; + + let vel = velocities.get(entity).copied().unwrap_or_default().0; + let vel_other = velocities.get(entity_other).copied().unwrap_or_default().0; + + // Sanity check: don't try colliding entities that are too far from each other + // Note: I think this catches all cases. If you get entitiy collision problems, + // try removing this! + if (pos.0 - pos_other.0).magnitude() + > ((vel + vel_other) * dt.0).magnitude() + collision_dist + { + continue; + } + + let min_collision_dist = 0.3; + // Ideally we'd deal with collision speed to minimise work here, but for not + // taking the maximum velocity of the two is fine. + let increments = (vel + .magnitude_squared() + .max(vel_other.magnitude_squared()) + .sqrt() + * dt.0 + / min_collision_dist) + .ceil() as usize; + let step_delta = 1.0 / increments as f32; + let mut collided = false; + for i in 0..increments { + let factor = i as f32 * step_delta; + let pos = pos.0 + vel * dt.0 * factor; + let pos_other = pos_other.0 + vel_other * dt.0 * factor; + + let diff = pos.xy() - pos_other.xy(); + + if diff.magnitude_squared() <= collision_dist.powf(2.0) + && pos.z + z_limits.1 * scale + >= pos_other.z + z_limits_other.0 * scale_other + && pos.z + z_limits.0 * scale + <= pos_other.z + z_limits_other.1 * scale_other + { + if !collided { + physics.touch_entities.push(*other); + } + + if diff.magnitude_squared() > 0.0 { + let force = 40.0 * (collision_dist - diff.magnitude()) * mass_other + / (mass + mass_other); + + // Change velocity + velocities.get_mut(entity).map(|vel| { + vel.0 += Vec3::from(diff.normalized()) * force * dt.0 * step_delta + }); + } + + collided = true; + } + } + } } // Apply movement inputs @@ -116,7 +262,7 @@ impl<'a> System<'a> for Sys { &entities, scales.maybe(), stickies.maybe(), - &colliders, + colliders.maybe(), &mut positions, &mut velocities, &mut orientations, @@ -176,16 +322,17 @@ impl<'a> System<'a> for Sys { Vec3::zero() }; - match collider { + match collider.copied().unwrap_or(Collider::Point) { Collider::Box { radius, z_min, z_max, } => { // Scale collider - let radius = *radius; // * scale; - let z_min = *z_min; // * scale; - let z_max = *z_max; // * scale; + // TODO: Use scale when pathfinding is good enough to manage irregular entity sizes + let radius = radius; // * scale; + let z_min = z_min; // * scale; + let z_max = z_max.max(1.0); // * scale; // Probe distances let hdist = radius.ceil() as i32; @@ -514,74 +661,5 @@ impl<'a> System<'a> for Sys { land_on_grounds.into_iter().for_each(|(entity, vel)| { event_emitter.emit(ServerEvent::LandOnGround { entity, vel: vel.0 }); }); - - // Apply pushback - for (pos, scale, mass, vel, _, _, _, physics, projectile) in ( - &positions, - scales.maybe(), - masses.maybe(), - &mut velocities, - &colliders, - !&mountings, - stickies.maybe(), - &mut physics_states, - // TODO: if we need to avoid collisions for other things consider moving whether it - // should interact into the collider component or into a separate component - projectiles.maybe(), - ) - .join() - .filter(|(_, _, _, _, _, _, sticky, physics, _)| { - sticky.is_none() || (physics.on_wall.is_none() && !physics.on_ground) - }) - { - physics.touch_entity = None; - - let scale = scale.map(|s| s.0).unwrap_or(1.0); - let mass = mass.map(|m| m.0).unwrap_or(scale); - - // Group to ignore collisions with - let ignore_group = projectile - .and_then(|p| p.owner) - .and_then(|uid| uid_allocator.retrieve_entity_internal(uid.into())) - .and_then(|e| groups.get(e)); - - for (other, pos_other, scale_other, mass_other, _, _, group) in ( - &uids, - &positions, - scales.maybe(), - masses.maybe(), - &colliders, - !&mountings, - groups.maybe(), - ) - .join() - { - if ignore_group.is_some() && ignore_group == group { - continue; - } - - let scale_other = scale_other.map(|s| s.0).unwrap_or(1.0); - - let mass_other = mass_other.map(|m| m.0).unwrap_or(scale_other); - if mass_other == 0.0 { - continue; - } - - let diff = Vec2::::from(pos.0 - pos_other.0); - - let collision_dist = 0.55 * (scale + scale_other); - - if diff.magnitude_squared() > 0.0 - && diff.magnitude_squared() < collision_dist.powf(2.0) - && pos.0.z + 1.6 * scale > pos_other.0.z - && pos.0.z < pos_other.0.z + 1.6 * scale_other - { - let force = (collision_dist - diff.magnitude()) * 2.0 * mass_other - / (mass + mass_other); - vel.0 += Vec3::from(diff.normalized()) * force; - physics.touch_entity = Some(*other); - } - } - } } } diff --git a/common/src/sys/projectile.rs b/common/src/sys/projectile.rs index 439f038a95..75f769c17a 100644 --- a/common/src/sys/projectile.rs +++ b/common/src/sys/projectile.rs @@ -81,81 +81,91 @@ impl<'a> System<'a> for Sys { _ => {}, } } - } - // Hit entity - else if let Some(other) = physics.touch_entity { - for effect in projectile.hit_entity.drain(..) { - match effect { - projectile::Effect::Damage(healthchange) => { - let owner_uid = projectile.owner.unwrap(); - let mut damage = Damage { - healthchange: healthchange as f32, - source: DamageSource::Projectile, - }; + } else { + // Hit entity + for other in physics.touch_entities.iter().copied() { + if projectile.owner == Some(other) { + continue; + } - let other_entity = uid_allocator.retrieve_entity_internal(other.into()); - if let Some(loadout) = other_entity.and_then(|e| loadouts.get(e)) { - damage.modify_damage(false, loadout); - } + for effect in projectile.hit_entity.iter().cloned() { + match effect { + projectile::Effect::Damage(healthchange) => { + let owner_uid = projectile.owner.unwrap(); + let mut damage = Damage { + healthchange: healthchange as f32, + source: DamageSource::Projectile, + }; - if other != owner_uid { - server_emitter.emit(ServerEvent::Damage { - uid: other, - change: HealthChange { - amount: damage.healthchange as i32, - cause: HealthSource::Attack { by: owner_uid }, - }, - }); - } - }, - projectile::Effect::Knockback(knockback) => { - if let Some(entity) = - uid_allocator.retrieve_entity_internal(other.into()) - { - local_emitter.emit(LocalEvent::ApplyForce { - entity, - force: knockback - * *Dir::slerp(ori.0, Dir::new(Vec3::unit_z()), 0.5), - }); - } - }, - projectile::Effect::RewardEnergy(energy) => { - if let Some(energy_mut) = projectile - .owner - .and_then(|o| uid_allocator.retrieve_entity_internal(o.into())) - .and_then(|o| energies.get_mut(o)) - { - energy_mut.change_by(energy as i32, EnergySource::HitEnemy); - } - }, - 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, - }), - projectile::Effect::Possess => { - if other != projectile.owner.unwrap() { - if let Some(owner) = projectile.owner { - server_emitter.emit(ServerEvent::Possess(owner, other)); + let other_entity = + uid_allocator.retrieve_entity_internal(other.into()); + if let Some(loadout) = other_entity.and_then(|e| loadouts.get(e)) { + damage.modify_damage(false, loadout); } - } - }, - _ => {}, + + if other != owner_uid { + server_emitter.emit(ServerEvent::Damage { + uid: other, + change: HealthChange { + amount: damage.healthchange as i32, + cause: HealthSource::Attack { by: owner_uid }, + }, + }); + } + }, + projectile::Effect::Knockback(knockback) => { + if let Some(entity) = + uid_allocator.retrieve_entity_internal(other.into()) + { + local_emitter.emit(LocalEvent::ApplyForce { + entity, + force: knockback + * *Dir::slerp(ori.0, Dir::new(Vec3::unit_z()), 0.5), + }); + } + }, + projectile::Effect::RewardEnergy(energy) => { + if let Some(energy_mut) = projectile + .owner + .and_then(|o| uid_allocator.retrieve_entity_internal(o.into())) + .and_then(|o| energies.get_mut(o)) + { + energy_mut.change_by(energy as i32, EnergySource::HitEnemy); + } + }, + 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, + }) + }, + projectile::Effect::Possess => { + if other != projectile.owner.unwrap() { + if let Some(owner) = projectile.owner { + server_emitter.emit(ServerEvent::Possess(owner, other)); + } + } + }, + _ => {}, + } } } - } else if let Some(dir) = velocities - .get(entity) - .and_then(|vel| vel.0.try_normalized()) - { - ori.0 = dir.into(); + + if let Some(dir) = velocities + .get(entity) + .and_then(|vel| vel.0.try_normalized()) + { + ori.0 = dir.into(); + } } if projectile.time_left == Duration::default() { diff --git a/server/src/state_ext.rs b/server/src/state_ext.rs index ac5b8e098f..3b0a4afcbe 100644 --- a/server/src/state_ext.rs +++ b/server/src/state_ext.rs @@ -102,20 +102,15 @@ impl StateExt for State { .with(comp::Vel(Vec3::zero())) .with(comp::Ori::default()) .with(comp::Collider::Box { - radius: 0.4, + radius: body.radius(), z_min: 0.0, - z_max: 1.75, + z_max: body.height(), }) .with(comp::Controller::default()) .with(body) .with(stats) .with(comp::Alignment::Npc) .with(comp::Energy::new(500)) - .with(comp::Collider::Box { - radius: 0.4, - z_min: 0.0, - z_max: 1.75, - }) .with(comp::Gravity(1.0)) .with(comp::CharacterState::default()) .with(loadout) @@ -127,13 +122,13 @@ impl StateExt for State { .with(pos) .with(comp::Vel(Vec3::zero())) .with(comp::Ori::default()) - .with(comp::Body::Object(object)) .with(comp::Mass(5.0)) .with(comp::Collider::Box { - radius: 0.4, + radius: comp::Body::Object(object).radius(), z_min: 0.0, - z_max: 0.9, + z_max: comp::Body::Object(object).height(), }) + .with(comp::Body::Object(object)) .with(comp::Gravity(1.0)) } @@ -223,6 +218,11 @@ impl StateExt for State { }), )); + self.write_component(entity, comp::Collider::Box { + radius: body.radius(), + z_min: 0.0, + z_max: body.height(), + }); self.write_component(entity, body); self.write_component(entity, stats); self.write_component(entity, inventory); diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index 7e47fdeb72..8945e844cd 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -476,7 +476,7 @@ impl Scene { player_scale * 1.65 } }, - CameraMode::ThirdPerson if scene_data.is_aiming => player_scale * 2.1, + CameraMode::ThirdPerson if scene_data.is_aiming => player_scale * 2.2, CameraMode::ThirdPerson => player_scale * 1.65, CameraMode::Freefly => 0.0, }; diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index f83a6d3583..a66f73ede5 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -238,7 +238,7 @@ impl PlayState for SessionState { ( is_aiming, if is_aiming { - Vec3::unit_z() * 0.025 + Vec3::unit_z() * 0.05 } else { Vec3::zero() }, diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index 4433eba5d1..8490719cf7 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -361,11 +361,14 @@ impl<'a> BlockGen<'a> { Some(Block::new( BlockKind::Rock, - stone_col.map2(Rgb::new( - field0.get(wpos) as u8 % 16, - field1.get(wpos) as u8 % 16, - field2.get(wpos) as u8 % 16, - ), |stone, x| stone.saturating_sub(x)), + stone_col.map2( + Rgb::new( + field0.get(wpos) as u8 % 16, + field1.get(wpos) as u8 % 16, + field2.get(wpos) as u8 % 16, + ), + |stone, x| stone.saturating_sub(x), + ), )) } else { None From 80c71871b7635ab8cc9140df09795366f920969b Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 24 Aug 2020 18:27:50 +0100 Subject: [PATCH 10/18] Updated changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 817b10df57..89d4b586e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Colors for models and figures were adjusted to account for the saturation hack. - Fixed a bug where the closest item would be picked up instead of a selected item. - Fixed a bug where camera zoom in and zoom out distance didn't match. +- Overhauled world colours +- Improved projectile physics +- Improved overhead aiming ### Removed From 7e571c10cfab032b8b48b2ae9ddca5fcac495f4f Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 24 Aug 2020 18:29:59 +0100 Subject: [PATCH 11/18] Corrected hitbox mistake --- common/src/comp/body.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/comp/body.rs b/common/src/comp/body.rs index 317c10d953..7c35e58bfb 100644 --- a/common/src/comp/body.rs +++ b/common/src/comp/body.rs @@ -158,7 +158,7 @@ impl Body { pub fn height(&self) -> f32 { match self { Body::Humanoid(humanoid) => match humanoid.species { - humanoid::Species::Danari => 0.5, + humanoid::Species::Danari => 1.5, humanoid::Species::Dwarf => 1.55, humanoid::Species::Orc => 1.95, _ => 1.8, From 6cf223583a6b1c273012357c38a4fd51e277b2c4 Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 24 Aug 2020 20:37:47 +0100 Subject: [PATCH 12/18] Fixed failing audio tests --- .../audio/sfx/event_mapper/movement/tests.rs | 67 +++---------------- 1 file changed, 11 insertions(+), 56 deletions(-) diff --git a/voxygen/src/audio/sfx/event_mapper/movement/tests.rs b/voxygen/src/audio/sfx/event_mapper/movement/tests.rs index 6a004489d3..40ef0d5edb 100644 --- a/voxygen/src/audio/sfx/event_mapper/movement/tests.rs +++ b/voxygen/src/audio/sfx/event_mapper/movement/tests.rs @@ -82,10 +82,7 @@ fn maps_idle() { &CharacterState::Idle {}, &PhysicsState { on_ground: true, - on_ceiling: false, - on_wall: None, - touch_entity: None, - in_fluid: None, + ..Default::default() }, &PreviousEntityState { event: SfxEvent::Idle, @@ -104,10 +101,7 @@ fn maps_run_with_sufficient_velocity() { &CharacterState::Idle {}, &PhysicsState { on_ground: true, - on_ceiling: false, - on_wall: None, - touch_entity: None, - in_fluid: None, + ..Default::default() }, &PreviousEntityState { event: SfxEvent::Idle, @@ -126,10 +120,7 @@ fn does_not_map_run_with_insufficient_velocity() { &CharacterState::Idle {}, &PhysicsState { on_ground: true, - on_ceiling: false, - on_wall: None, - touch_entity: None, - in_fluid: None, + ..Default::default() }, &PreviousEntityState { event: SfxEvent::Idle, @@ -146,13 +137,7 @@ fn does_not_map_run_with_insufficient_velocity() { fn does_not_map_run_with_sufficient_velocity_but_not_on_ground() { let result = MovementEventMapper::map_movement_event( &CharacterState::Idle {}, - &PhysicsState { - on_ground: false, - on_ceiling: false, - on_wall: None, - touch_entity: None, - in_fluid: None, - }, + &Default::default(), &PreviousEntityState { event: SfxEvent::Idle, time: Instant::now(), @@ -173,10 +158,7 @@ fn maps_roll() { }), &PhysicsState { on_ground: true, - on_ceiling: false, - on_wall: None, - touch_entity: None, - in_fluid: None, + ..Default::default() }, &PreviousEntityState { event: SfxEvent::Run, @@ -195,10 +177,7 @@ fn maps_land_on_ground_to_run() { &CharacterState::Idle {}, &PhysicsState { on_ground: true, - on_ceiling: false, - on_wall: None, - touch_entity: None, - in_fluid: None, + ..Default::default() }, &PreviousEntityState { event: SfxEvent::Idle, @@ -215,13 +194,7 @@ fn maps_land_on_ground_to_run() { fn maps_glider_open() { let result = MovementEventMapper::map_movement_event( &CharacterState::Glide {}, - &PhysicsState { - on_ground: false, - on_ceiling: false, - on_wall: None, - touch_entity: None, - in_fluid: None, - }, + &Default::default(), &PreviousEntityState { event: SfxEvent::Jump, time: Instant::now(), @@ -237,13 +210,7 @@ fn maps_glider_open() { fn maps_glide() { let result = MovementEventMapper::map_movement_event( &CharacterState::Glide {}, - &PhysicsState { - on_ground: false, - on_ceiling: false, - on_wall: None, - touch_entity: None, - in_fluid: None, - }, + &Default::default(), &PreviousEntityState { event: SfxEvent::Glide, time: Instant::now(), @@ -259,13 +226,7 @@ fn maps_glide() { fn maps_glider_close_when_closing_mid_flight() { let result = MovementEventMapper::map_movement_event( &CharacterState::Idle {}, - &PhysicsState { - on_ground: false, - on_ceiling: false, - on_wall: None, - touch_entity: None, - in_fluid: None, - }, + &Default::default(), &PreviousEntityState { event: SfxEvent::Glide, time: Instant::now(), @@ -284,10 +245,7 @@ fn maps_glider_close_when_landing() { &CharacterState::Idle {}, &PhysicsState { on_ground: true, - on_ceiling: false, - on_wall: None, - touch_entity: None, - in_fluid: None, + ..Default::default() }, &PreviousEntityState { event: SfxEvent::Glide, @@ -305,10 +263,7 @@ fn maps_quadrupeds_running() { let result = MovementEventMapper::map_non_humanoid_movement_event( &PhysicsState { on_ground: true, - on_ceiling: false, - on_wall: None, - touch_entity: None, - in_fluid: None, + ..Default::default() }, Vec3::new(0.5, 0.8, 0.0), ); From 2b9d5ee4a2c0abe82d3f7554222a8c7e88577dbb Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 24 Aug 2020 20:52:18 +0100 Subject: [PATCH 13/18] Fixed bad hitbox radii and adjusted field colour --- assets/world/style/colors.ron | 4 ++-- common/src/comp/body.rs | 24 ++++++++++++------------ common/src/sys/phys.rs | 7 ++++--- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/assets/world/style/colors.ron b/assets/world/style/colors.ron index 330bdbfc0b..cf3aa46b2b 100644 --- a/assets/world/style/colors.ron +++ b/assets/world/style/colors.ron @@ -89,7 +89,7 @@ Roof1: (0x99, 0x5E, 0x54), Roof2: (0x43, 0x63, 0x64), Roof3: (0x76, 0x6D, 0x68), - Roof4: (0x65, 0x01, 0x41), + Roof4: (0x55, 0x25, 0x41), Roof5: (0x52, 0x20, 0x20), Roof6: (0x05, 0x3A, 0x40), Roof7: (0xCC, 0x56, 0x3E), @@ -134,7 +134,7 @@ ), plot_town_path: (90, 70, 45), - plot_field_dirt: (70, 25, 15), + plot_field_dirt: (35, 10, 5), plot_field_mound: (40, 60, 10), wall_low: (130, 100, 0), diff --git a/common/src/comp/body.rs b/common/src/comp/body.rs index 7c35e58bfb..6ba41afea7 100644 --- a/common/src/comp/body.rs +++ b/common/src/comp/body.rs @@ -139,18 +139,18 @@ impl Body { pub fn radius(&self) -> f32 { // TODO: Improve these values (some might be reliant on more info in inner type) match self { - Body::Humanoid(_) => 0.6, - Body::QuadrupedSmall(_) => 0.6, - Body::QuadrupedMedium(_) => 0.9, - Body::QuadrupedLow(_) => 1.0, - Body::Critter(_) => 0.5, - Body::BirdMedium(_) => 0.5, - Body::FishMedium(_) => 0.5, - Body::Dragon(_) => 2.5, - Body::BirdSmall(_) => 0.4, - Body::FishSmall(_) => 0.4, - Body::BipedLarge(_) => 2.0, - Body::Golem(_) => 1.75, + Body::Humanoid(_) => 0.35, + Body::QuadrupedSmall(_) => 0.4, + Body::QuadrupedMedium(_) => 0.45, + Body::QuadrupedLow(_) => 0.45, + Body::Critter(_) => 0.3, + Body::BirdMedium(_) => 0.35, + Body::FishMedium(_) => 0.35, + Body::Dragon(_) => 8.0, + Body::BirdSmall(_) => 0.3, + Body::FishSmall(_) => 0.3, + Body::BipedLarge(_) => 0.5, + Body::Golem(_) => 0.4, Body::Object(_) => 0.4, } } diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index cca5325346..532a88d48a 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -329,10 +329,11 @@ impl<'a> System<'a> for Sys { z_max, } => { // Scale collider - // TODO: Use scale when pathfinding is good enough to manage irregular entity sizes - let radius = radius; // * scale; + // TODO: Use scale & actual proportions when pathfinding is good enough to manage irregular entity + // sizes + let radius = radius.min(0.45); // * scale; let z_min = z_min; // * scale; - let z_max = z_max.max(1.0); // * scale; + let z_max = z_max.clamped(1.0, 1.95); // * scale; // Probe distances let hdist = radius.ceil() as i32; From e4de32ac25f21ba82dbd87e0cb7e1c7b972f385c Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 24 Aug 2020 21:46:08 +0100 Subject: [PATCH 14/18] Fixed quadruped hitboxes --- assets/world/style/colors.ron | 2 +- common/src/comp/body.rs | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/assets/world/style/colors.ron b/assets/world/style/colors.ron index cf3aa46b2b..909387eda2 100644 --- a/assets/world/style/colors.ron +++ b/assets/world/style/colors.ron @@ -134,7 +134,7 @@ ), plot_town_path: (90, 70, 45), - plot_field_dirt: (35, 10, 5), + plot_field_dirt: (55, 20, 5), plot_field_mound: (40, 60, 10), wall_low: (130, 100, 0), diff --git a/common/src/comp/body.rs b/common/src/comp/body.rs index 6ba41afea7..ef0496043f 100644 --- a/common/src/comp/body.rs +++ b/common/src/comp/body.rs @@ -141,15 +141,29 @@ impl Body { match self { Body::Humanoid(_) => 0.35, Body::QuadrupedSmall(_) => 0.4, - Body::QuadrupedMedium(_) => 0.45, - Body::QuadrupedLow(_) => 0.45, + Body::QuadrupedMedium(body) => match body.species { + quadruped_medium::Species::Grolgar => 1.9, + quadruped_medium::Species::Tarasque => 2.2, + quadruped_medium::Species::Lion => 1.9, + quadruped_medium::Species::Saber => 1.8, + quadruped_medium::Species::Catoblepas => 1.7, + _ => 1.5, + }, + Body::QuadrupedLow(body) => match body.species { + quadruped_low::Species::Asp => 1.8, + quadruped_low::Species::Monitor => 1.75, + quadruped_low::Species::Crocodile => 2.1, + quadruped_low::Species::Salamander => 1.9, + quadruped_low::Species::Pangolin => 1.3, + _ => 1.6, + }, Body::Critter(_) => 0.3, Body::BirdMedium(_) => 0.35, Body::FishMedium(_) => 0.35, Body::Dragon(_) => 8.0, Body::BirdSmall(_) => 0.3, Body::FishSmall(_) => 0.3, - Body::BipedLarge(_) => 0.5, + Body::BipedLarge(_) => 0.75, Body::Golem(_) => 0.4, Body::Object(_) => 0.4, } From 9b812b0d8bd99db144bc71993f8739b6de86669b Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Mon, 24 Aug 2020 21:53:17 +0100 Subject: [PATCH 15/18] Allowed small animals to block-hop again --- common/src/sys/phys.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index 532a88d48a..b16bb29991 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -333,7 +333,7 @@ impl<'a> System<'a> for Sys { // sizes let radius = radius.min(0.45); // * scale; let z_min = z_min; // * scale; - let z_max = z_max.clamped(1.0, 1.95); // * scale; + let z_max = z_max.clamped(1.2, 1.95); // * scale; // Probe distances let hdist = radius.ceil() as i32; From 12ea028a3d5c032a614c75bf98b5eb5b456095ca Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 25 Aug 2020 00:04:04 +0100 Subject: [PATCH 16/18] Improved single-tick projectile wall/entity collision bug --- assets/world/style/colors.ron | 2 +- common/src/sys/phys.rs | 4 - common/src/sys/projectile.rs | 165 +++++++++++++++++----------------- 3 files changed, 82 insertions(+), 89 deletions(-) diff --git a/assets/world/style/colors.ron b/assets/world/style/colors.ron index 909387eda2..6f234e82d0 100644 --- a/assets/world/style/colors.ron +++ b/assets/world/style/colors.ron @@ -32,7 +32,7 @@ ), column: ( 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), wet_grass: (0.1, 0.8, 0.2), cold_stone: (0.4, 0.67, 0.8), diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index b16bb29991..4be1d1eee0 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -126,10 +126,6 @@ impl<'a> System<'a> for Sys { // already possible with poorly-defined hitboxes anyway so it's not too // 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 // 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 diff --git a/common/src/sys/projectile.rs b/common/src/sys/projectile.rs index 75f769c17a..44dbf39a73 100644 --- a/common/src/sys/projectile.rs +++ b/common/src/sys/projectile.rs @@ -61,6 +61,81 @@ impl<'a> System<'a> for Sys { ) .join() { + // Hit entity + for other in physics.touch_entities.iter().copied() { + if projectile.owner == Some(other) { + continue; + } + + for effect in projectile.hit_entity.iter().cloned() { + match effect { + projectile::Effect::Damage(healthchange) => { + let owner_uid = projectile.owner.unwrap(); + let mut damage = Damage { + healthchange: healthchange as f32, + source: DamageSource::Projectile, + }; + + let other_entity = uid_allocator.retrieve_entity_internal(other.into()); + if let Some(loadout) = other_entity.and_then(|e| loadouts.get(e)) { + damage.modify_damage(false, loadout); + } + + if other != owner_uid { + server_emitter.emit(ServerEvent::Damage { + uid: other, + change: HealthChange { + amount: damage.healthchange as i32, + cause: HealthSource::Attack { by: owner_uid }, + }, + }); + } + }, + projectile::Effect::Knockback(knockback) => { + if let Some(entity) = + uid_allocator.retrieve_entity_internal(other.into()) + { + local_emitter.emit(LocalEvent::ApplyForce { + entity, + force: knockback + * *Dir::slerp(ori.0, Dir::new(Vec3::unit_z()), 0.5), + }); + } + }, + projectile::Effect::RewardEnergy(energy) => { + if let Some(energy_mut) = projectile + .owner + .and_then(|o| uid_allocator.retrieve_entity_internal(o.into())) + .and_then(|o| energies.get_mut(o)) + { + energy_mut.change_by(energy as i32, EnergySource::HitEnemy); + } + }, + 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, + }), + projectile::Effect::Possess => { + if other != projectile.owner.unwrap() { + if let Some(owner) = projectile.owner { + server_emitter.emit(ServerEvent::Possess(owner, other)); + } + } + }, + _ => {}, + } + } + } + // Hit something solid if physics.on_wall.is_some() || physics.on_ground || physics.on_ceiling { for effect in projectile.hit_solid.drain(..) { @@ -81,91 +156,13 @@ impl<'a> System<'a> for Sys { _ => {}, } } - } else { - // Hit entity - for other in physics.touch_entities.iter().copied() { - if projectile.owner == Some(other) { - continue; - } + } - for effect in projectile.hit_entity.iter().cloned() { - match effect { - projectile::Effect::Damage(healthchange) => { - let owner_uid = projectile.owner.unwrap(); - let mut damage = Damage { - healthchange: healthchange as f32, - source: DamageSource::Projectile, - }; - - let other_entity = - uid_allocator.retrieve_entity_internal(other.into()); - if let Some(loadout) = other_entity.and_then(|e| loadouts.get(e)) { - damage.modify_damage(false, loadout); - } - - if other != owner_uid { - server_emitter.emit(ServerEvent::Damage { - uid: other, - change: HealthChange { - amount: damage.healthchange as i32, - cause: HealthSource::Attack { by: owner_uid }, - }, - }); - } - }, - projectile::Effect::Knockback(knockback) => { - if let Some(entity) = - uid_allocator.retrieve_entity_internal(other.into()) - { - local_emitter.emit(LocalEvent::ApplyForce { - entity, - force: knockback - * *Dir::slerp(ori.0, Dir::new(Vec3::unit_z()), 0.5), - }); - } - }, - projectile::Effect::RewardEnergy(energy) => { - if let Some(energy_mut) = projectile - .owner - .and_then(|o| uid_allocator.retrieve_entity_internal(o.into())) - .and_then(|o| energies.get_mut(o)) - { - energy_mut.change_by(energy as i32, EnergySource::HitEnemy); - } - }, - 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, - }) - }, - projectile::Effect::Possess => { - if other != projectile.owner.unwrap() { - if let Some(owner) = projectile.owner { - server_emitter.emit(ServerEvent::Possess(owner, other)); - } - } - }, - _ => {}, - } - } - } - - if let Some(dir) = velocities - .get(entity) - .and_then(|vel| vel.0.try_normalized()) - { - ori.0 = dir.into(); - } + if let Some(dir) = velocities + .get(entity) + .and_then(|vel| vel.0.try_normalized()) + { + ori.0 = dir.into(); } if projectile.time_left == Duration::default() { From 37b45ba5f4a83d3cea573aa1cffd48f9b9477b4c Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 25 Aug 2020 11:01:17 +0100 Subject: [PATCH 17/18] Addressed review issues --- common/src/comp/phys.rs | 2 +- common/src/path.rs | 4 ++-- common/src/sys/phys.rs | 49 +++++++++++++++++------------------------ 3 files changed, 23 insertions(+), 32 deletions(-) diff --git a/common/src/comp/phys.rs b/common/src/comp/phys.rs index 29dfbcc565..88e4a64032 100644 --- a/common/src/comp/phys.rs +++ b/common/src/comp/phys.rs @@ -100,7 +100,7 @@ pub struct PhysicsState { } impl PhysicsState { - pub fn clear(&mut self) { + pub fn reset(&mut self) { // Avoid allocation overhead! let mut touch_entities = std::mem::take(&mut self.touch_entities); touch_entities.clear(); diff --git a/common/src/path.rs b/common/src/path.rs index de70785a48..cf02e684ae 100644 --- a/common/src/path.rs +++ b/common/src/path.rs @@ -418,7 +418,7 @@ impl Chaser { }); if !walking_towards_edge { - Some(((tgt - pos) * Vec3::new(1.0, 1.0, 0.0), 0.75)) + Some(((tgt - pos) * Vec3::new(1.0, 1.0, 0.0), 1.0)) } else { None } @@ -458,7 +458,7 @@ where let is_walkable = |pos: &Vec3| walkable(vol, *pos); let get_walkable_z = |pos| { let mut z_incr = 0; - for _ in 0..128 { + for _ in 0..32 { let test_pos = pos + Vec3::unit_z() * z_incr; if is_walkable(&test_pos) { return Some(test_pos); diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index 4be1d1eee0..9491296d7c 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -11,8 +11,8 @@ use crate::{ }; use rayon::iter::ParallelIterator; use specs::{ - saveload::MarkerAllocator, storage, Entities, Join, ParJoin, Read, ReadExpect, ReadStorage, - System, WriteStorage, + saveload::MarkerAllocator, Entities, Join, ParJoin, Read, ReadExpect, ReadStorage, System, + WriteStorage, }; use std::ops::Range; use vek::*; @@ -96,25 +96,18 @@ impl<'a> System<'a> for Sys { let mut event_emitter = event_bus.emitter(); // Add/reset physics state components - for entity in ( + for (entity, _, _, _, _) in ( &entities, - !&physics_states, &colliders, &positions, &velocities, &orientations, ) .join() - .map(|(e, _, _, _, _, _)| e) - .collect::>() { - match physics_states.entry(entity) { - Ok(storage::StorageEntry::Occupied(mut o)) => o.get_mut().clear(), - Ok(storage::StorageEntry::Vacant(v)) => { - v.insert(Default::default()); - }, - Err(_) => {}, - } + let _ = physics_states + .entry(entity) + .map(|e| e.or_insert_with(Default::default)); } // Apply pushback @@ -159,6 +152,8 @@ impl<'a> System<'a> for Sys { .and_then(|uid| uid_allocator.retrieve_entity_internal(uid.into())) .and_then(|e| groups.get(e)); + let mut vel_delta = Vec3::zero(); + for ( entity_other, other, @@ -200,23 +195,17 @@ impl<'a> System<'a> for Sys { let vel_other = velocities.get(entity_other).copied().unwrap_or_default().0; // Sanity check: don't try colliding entities that are too far from each other - // Note: I think this catches all cases. If you get entitiy collision problems, + // Note: I think this catches all cases. If you get entity collision problems, // try removing this! if (pos.0 - pos_other.0).magnitude() - > ((vel + vel_other) * dt.0).magnitude() + collision_dist + > ((vel - vel_other) * dt.0).magnitude() + collision_dist { continue; } let min_collision_dist = 0.3; - // Ideally we'd deal with collision speed to minimise work here, but for not - // taking the maximum velocity of the two is fine. - let increments = (vel - .magnitude_squared() - .max(vel_other.magnitude_squared()) - .sqrt() - * dt.0 - / min_collision_dist) + let increments = ((vel - vel_other).magnitude() * dt.0 / min_collision_dist) + .max(1.0) .ceil() as usize; let step_delta = 1.0 / increments as f32; let mut collided = false; @@ -241,16 +230,18 @@ impl<'a> System<'a> for Sys { let force = 40.0 * (collision_dist - diff.magnitude()) * mass_other / (mass + mass_other); - // Change velocity - velocities.get_mut(entity).map(|vel| { - vel.0 += Vec3::from(diff.normalized()) * force * dt.0 * step_delta - }); + vel_delta += Vec3::from(diff.normalized()) * force * step_delta; } collided = true; } } } + + // Change velocity + velocities + .get_mut(entity) + .map(|vel| vel.0 += vel_delta * dt.0); } // Apply movement inputs @@ -258,7 +249,7 @@ impl<'a> System<'a> for Sys { &entities, scales.maybe(), stickies.maybe(), - colliders.maybe(), + &colliders, &mut positions, &mut velocities, &mut orientations, @@ -318,7 +309,7 @@ impl<'a> System<'a> for Sys { Vec3::zero() }; - match collider.copied().unwrap_or(Collider::Point) { + match *collider { Collider::Box { radius, z_min, From 24780e4f582729f0a3420aa148905b6a9ce7bdfe Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Tue, 25 Aug 2020 12:54:30 +0100 Subject: [PATCH 18/18] Handled 3d/2d sanity check bug --- common/src/sys/phys.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index 9491296d7c..6a62345e7c 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -197,8 +197,8 @@ impl<'a> System<'a> for Sys { // Sanity check: don't try colliding entities that are too far from each other // Note: I think this catches all cases. If you get entity collision problems, // try removing this! - if (pos.0 - pos_other.0).magnitude() - > ((vel - vel_other) * dt.0).magnitude() + collision_dist + if (pos.0 - pos_other.0).xy().magnitude() + > ((vel - vel_other) * dt.0).xy().magnitude() + collision_dist { continue; }