From a3d55f905e0514397cfbdee2508ae47decc367b0 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Sun, 26 Mar 2023 17:13:34 -0600 Subject: [PATCH] qbsp: fix structural solid not eating other content types --- common/bspfile.cc | 5 +- .../q2_detail_overlapping_solid_sealing.map | 76 +++++++++++++++++++ tests/test_qbsp_q2.cc | 14 ++++ 3 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 testmaps/q2_detail_overlapping_solid_sealing.map diff --git a/common/bspfile.cc b/common/bspfile.cc index fb4590a4..bf5fe8d3 100644 --- a/common/bspfile.cc +++ b/common/bspfile.cc @@ -1287,11 +1287,10 @@ struct gamedef_q2_t : public gamedef_t contentflags_t combine_contents(const contentflags_t &a, const contentflags_t &b) const override { -#if 0 - if ((a.native & Q2_CONTENTS_SOLID) || (b.native & Q2_CONTENTS_SOLID)) { + // structural solid (but not detail solid) eats any other contents + if (contents_are_solid(a) || contents_are_solid(b)) { return {Q2_CONTENTS_SOLID}; } -#endif contentflags_t result; result.native = a.native | b.native; diff --git a/testmaps/q2_detail_overlapping_solid_sealing.map b/testmaps/q2_detail_overlapping_solid_sealing.map new file mode 100644 index 00000000..96eee421 --- /dev/null +++ b/testmaps/q2_detail_overlapping_solid_sealing.map @@ -0,0 +1,76 @@ +// Game: Quake 2 +// Format: Quake2 +// entity 0 +{ +"classname" "worldspawn" +"_tb_textures" "textures/e1u1" +"message" "Detail brush seals the world" +// brush 0 +{ +( -64 256 192 ) ( -64 32 192 ) ( -64 256 16 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -48 32 16 ) ( -64 32 16 ) ( -48 32 192 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -48 256 16 ) ( -64 256 16 ) ( -48 32 16 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -48 32 192 ) ( -64 32 192 ) ( -48 256 192 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -48 256 192 ) ( -64 256 192 ) ( -48 256 16 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -48 32 192 ) ( -48 256 192 ) ( -48 32 16 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +} +// brush 1 +{ +( -304 32 16 ) ( -304 256 16 ) ( -304 32 192 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -304 32 192 ) ( -288 32 192 ) ( -304 32 16 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -304 32 16 ) ( -288 32 16 ) ( -304 256 16 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -304 256 192 ) ( -288 256 192 ) ( -304 32 192 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -304 256 16 ) ( -288 256 16 ) ( -304 256 192 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -288 32 16 ) ( -288 32 192 ) ( -288 256 16 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +} +// brush 2 +{ +( -288 256 192 ) ( -288 240 192 ) ( -288 256 16 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -64 240 192 ) ( -64 240 16 ) ( -288 240 192 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -288 256 16 ) ( -288 240 16 ) ( -64 256 16 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -64 256 192 ) ( -64 240 192 ) ( -288 256 192 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -64 256 192 ) ( -288 256 192 ) ( -64 256 16 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -64 256 16 ) ( -64 240 16 ) ( -64 256 192 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +} +// brush 3 +{ +( -288 32 16 ) ( -288 48 16 ) ( -288 32 192 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -64 32 16 ) ( -288 32 16 ) ( -64 32 192 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -64 32 16 ) ( -64 48 16 ) ( -288 32 16 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -288 32 192 ) ( -288 48 192 ) ( -64 32 192 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -288 48 16 ) ( -64 48 16 ) ( -288 48 192 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -64 32 192 ) ( -64 48 192 ) ( -64 32 16 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +} +// brush 4 +{ +( -288 48 192 ) ( -288 48 176 ) ( -288 240 192 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -64 48 192 ) ( -64 48 176 ) ( -288 48 192 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -64 240 176 ) ( -288 240 176 ) ( -64 48 176 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -64 240 192 ) ( -64 48 192 ) ( -288 240 192 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -288 240 192 ) ( -288 240 176 ) ( -64 240 192 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -64 240 192 ) ( -64 240 176 ) ( -64 48 192 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +} +// brush 5 +{ +( -288 240 16 ) ( -288 240 32 ) ( -288 48 16 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -288 48 16 ) ( -288 48 32 ) ( -64 48 16 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -288 240 16 ) ( -288 48 16 ) ( -64 240 16 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -288 48 32 ) ( -288 240 32 ) ( -64 48 32 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -64 240 16 ) ( -64 240 32 ) ( -288 240 16 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +( -64 48 16 ) ( -64 48 32 ) ( -64 240 16 ) e1u1/color1_6 0 0 0 1 1 0 0 0 +} +// brush 6 +{ +( -80 32 32 ) ( -80 33 32 ) ( -80 32 33 ) e1u1/color1_6 0 0 0 1 1 134217728 0 0 +( -80 48 32 ) ( -80 48 33 ) ( -79 48 32 ) e1u1/color1_6 0 0 0 1 1 134217728 0 0 +( -80 32 32 ) ( -79 32 32 ) ( -80 33 32 ) e1u1/color1_6 0 0 0 1 1 134217728 0 0 +( -48 240 176 ) ( -48 241 176 ) ( -47 240 176 ) e1u1/color1_6 0 0 0 1 1 134217728 0 0 +( -48 240 48 ) ( -47 240 48 ) ( -48 240 49 ) e1u1/color1_6 0 0 0 1 1 134217728 0 0 +( -32 240 48 ) ( -32 240 49 ) ( -32 241 48 ) e1u1/color1_6 0 0 0 1 1 134217728 0 0 +} +} +// entity 1 +{ +"classname" "info_player_start" +"origin" "-240 80 56" +} diff --git a/tests/test_qbsp_q2.cc b/tests/test_qbsp_q2.cc index 9d13a101..d082ea95 100644 --- a/tests/test_qbsp_q2.cc +++ b/tests/test_qbsp_q2.cc @@ -514,6 +514,20 @@ TEST_CASE("q2_detail_non_sealing" * doctest::test_suite("testmaps_q2")) CHECK(Q2_CONTENTS_EMPTY == BSP_FindLeafAtPoint(&bsp, &bsp.dmodels[0], in_void)->contents); } +TEST_CASE("q2_detail_overlapping_solid_sealing" * doctest::test_suite("testmaps_q2")) +{ + const auto [bsp, bspx, prt] = LoadTestmapQ2("q2_detail_overlapping_solid_sealing.map"); + + CHECK(GAME_QUAKE_II == bsp.loadversion->game->id); + + const qvec3d in_start_room{-240, 80, 56}; + const qvec3d in_void{-336, 80, 56}; + + // check leaf contents + CHECK(Q2_CONTENTS_EMPTY == BSP_FindLeafAtPoint(&bsp, &bsp.dmodels[0], in_start_room)->contents); + CHECK(Q2_CONTENTS_SOLID == BSP_FindLeafAtPoint(&bsp, &bsp.dmodels[0], in_void)->contents); +} + /** * Two areaportals with a small gap in between creating another area. *