diff --git a/common/bspfile.cc b/common/bspfile.cc index 9957615f..906f8a7a 100644 --- a/common/bspfile.cc +++ b/common/bspfile.cc @@ -621,6 +621,9 @@ public: if (contents_are_solid(a) || contents_are_solid(b)) { return create_solid_contents(); } + if (contents_are_sky(a) || contents_are_sky(b)) { + return contentflags_t{CONTENTS_SKY}; + } return contentflags_from_bits(bits_a | bits_b); } diff --git a/testmaps/q1_sealing_contents.map b/testmaps/q1_sealing_contents.map new file mode 100644 index 00000000..90494859 --- /dev/null +++ b/testmaps/q1_sealing_contents.map @@ -0,0 +1,162 @@ +// Game: Quake +// Format: Valve +// entity 0 +{ +"mapversion" "220" +"classname" "worldspawn" +"wad" "deprecated/free_wad.wad;deprecated/fence.wad;deprecated/origin.wad;deprecated/hintskip.wad" +"_wateralpha" "0.5" +"_tb_def" "builtin:Quake.fgd" +// brush 0 +{ +( -144 -192 48 ) ( -144 32 48 ) ( -144 -192 208 ) orangestuff8 [ 0 1 0 16 ] [ 0 0 -1 48 ] 0 1 1 +( -144 -640 208 ) ( -128 -640 208 ) ( -144 -640 48 ) orangestuff8 [ -1 0 0 -16 ] [ 0 0 -1 48 ] 180 1 1 +( -144 -192 48 ) ( -128 -192 48 ) ( -144 32 48 ) orangestuff8 [ 1 0 0 16 ] [ 0 -1 0 -16 ] 180 1 1 +( -144 32 336 ) ( -128 32 336 ) ( -144 -192 336 ) orangestuff8 [ -1 0 0 -16 ] [ 0 -1 0 -16 ] 180 1 1 +( -144 32 48 ) ( -128 32 48 ) ( -144 32 208 ) orangestuff8 [ 1 0 0 16 ] [ 0 0 -1 48 ] 180 1 1 +( -128 -192 48 ) ( -128 -192 208 ) ( -128 32 48 ) orangestuff8 [ 0 1 0 16 ] [ 0 0 -1 48 ] 0 1 1 +} +// brush 1 +{ +( -128 32 208 ) ( -128 16 208 ) ( -128 32 48 ) orangestuff8 [ 0 1 0 16 ] [ 0 0 -1 48 ] 0 1 1 +( 96 16 208 ) ( 96 16 48 ) ( -128 16 208 ) orangestuff8 [ 1 0 0 16 ] [ 0 0 -1 48 ] 180 1 1 +( -128 32 48 ) ( -128 16 48 ) ( 96 32 48 ) orangestuff8 [ 1 0 0 16 ] [ 0 -1 0 -16 ] 180 1 1 +( 96 32 336 ) ( 96 16 336 ) ( -128 32 336 ) orangestuff8 [ -1 0 0 -16 ] [ 0 -1 0 -16 ] 180 1 1 +( 96 32 208 ) ( -128 32 208 ) ( 96 32 48 ) orangestuff8 [ 1 0 0 16 ] [ 0 0 -1 48 ] 180 1 1 +( 464 32 48 ) ( 464 16 48 ) ( 464 32 208 ) orangestuff8 [ 0 -1 0 -16 ] [ 0 0 -1 48 ] 0 1 1 +} +// brush 2 +{ +( -128 -656 48 ) ( -128 -640 48 ) ( -128 -656 208 ) orangestuff8 [ 0 1 0 -32 ] [ 0 0 -1 48 ] 0 1 1 +( 464 -656 48 ) ( 240 -656 48 ) ( 464 -656 208 ) orangestuff8 [ -1 0 0 32 ] [ 0 0 -1 48 ] 180 1 1 +( 464 -656 48 ) ( 464 -640 48 ) ( 240 -656 48 ) orangestuff8 [ 1 0 0 -32 ] [ 0 -1 0 32 ] 180 1 1 +( 240 -656 336 ) ( 240 -640 336 ) ( 464 -656 336 ) orangestuff8 [ -1 0 0 32 ] [ 0 -1 0 32 ] 180 1 1 +( 240 -640 48 ) ( 464 -640 48 ) ( 240 -640 208 ) orangestuff8 [ -1 0 0 32 ] [ 0 0 -1 48 ] 180 1 1 +( 464 -656 208 ) ( 464 -640 208 ) ( 464 -656 48 ) orangestuff8 [ 0 -1 0 32 ] [ 0 0 -1 48 ] 0 1 1 +} +// brush 3 +{ +( -128 -176 352 ) ( -128 -176 336 ) ( -128 16 352 ) sky3 [ 0 1 0 16 ] [ 0 0 -1 64 ] 0 1 1 +( 96 -640 352 ) ( 96 -640 336 ) ( -128 -640 352 ) sky3 [ -1 0 0 -16 ] [ 0 0 -1 64 ] 180 1 1 +( 96 16 336 ) ( -128 16 336 ) ( 96 -176 336 ) sky3 [ -1 0 0 -16 ] [ 0 -1 0 -16 ] 180 1 1 +( 96 16 352 ) ( 96 -176 352 ) ( -128 16 352 ) sky3 [ -1 0 0 -16 ] [ 0 -1 0 -16 ] 180 1 1 +( -128 16 352 ) ( -128 16 336 ) ( 96 16 352 ) sky3 [ 1 0 0 16 ] [ 0 0 -1 64 ] 180 1 1 +( 464 16 352 ) ( 464 16 336 ) ( 464 -176 352 ) sky3 [ 0 -1 0 -16 ] [ 0 0 -1 64 ] 0 1 1 +} +// brush 4 +{ +( -128 16 48 ) ( -128 16 64 ) ( -128 -176 48 ) orangestuff8 [ 0 1 0 16 ] [ 0 0 -1 48 ] 0 1 1 +( -128 -640 48 ) ( -128 -640 64 ) ( 96 -640 48 ) orangestuff8 [ -1 0 0 -16 ] [ 0 0 -1 48 ] 180 1 1 +( -128 16 48 ) ( -128 -176 48 ) ( 96 16 48 ) orangestuff8 [ 1 0 0 16 ] [ 0 -1 0 -16 ] 180 1 1 +( -128 -176 64 ) ( -128 16 64 ) ( 96 -176 64 ) orangestuff8 [ 1 0 0 16 ] [ 0 -1 0 -16 ] 180 1 1 +( 96 16 48 ) ( 96 16 64 ) ( -128 16 48 ) orangestuff8 [ 1 0 0 16 ] [ 0 0 -1 48 ] 180 1 1 +( 464 -176 48 ) ( 464 -176 64 ) ( 464 16 48 ) orangestuff8 [ 0 -1 0 -16 ] [ 0 0 -1 48 ] 0 1 1 +} +// brush 5 +{ +( 464 -432 208 ) ( 464 -656 208 ) ( 464 -432 48 ) orangestuff8 [ 0 -1 0 32 ] [ 0 0 -1 48 ] 0 1 1 +( 480 -656 48 ) ( 464 -656 48 ) ( 480 -656 208 ) orangestuff8 [ -1 0 0 32 ] [ 0 0 -1 48 ] 180 1 1 +( 480 -432 48 ) ( 464 -432 48 ) ( 480 -656 48 ) orangestuff8 [ 1 0 0 -32 ] [ 0 -1 0 32 ] 180 1 1 +( 480 -656 336 ) ( 464 -656 336 ) ( 480 -432 336 ) orangestuff8 [ -1 0 0 32 ] [ 0 -1 0 32 ] 180 1 1 +( 480 16 208 ) ( 464 16 208 ) ( 480 16 48 ) orangestuff8 [ 1 0 0 -32 ] [ 0 0 -1 48 ] 180 1 1 +( 480 -656 208 ) ( 480 -432 208 ) ( 480 -656 48 ) orangestuff8 [ 0 -1 0 32 ] [ 0 0 -1 48 ] 0 1 1 +} +} +// entity 1 +{ +"classname" "info_player_start" +"origin" "-56 -96 120" +} +// entity 2 +{ +"classname" "func_detail" +// brush 0 +{ +( 272 -576 336 ) ( 272 -575 336 ) ( 272 -576 337 ) bolt1 [ 0 -1 0 0 ] [ 0 0 -1 16 ] 0 1 1 +( 272 -576 336 ) ( 272 -576 337 ) ( 273 -576 336 ) bolt1 [ 1 0 0 0 ] [ 0 0 -1 16 ] 0 1 1 +( 272 -576 320 ) ( 273 -576 320 ) ( 272 -575 320 ) bolt1 [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( 320 -528 352 ) ( 320 -527 352 ) ( 321 -528 352 ) bolt1 [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( 320 -528 352 ) ( 321 -528 352 ) ( 320 -528 353 ) bolt1 [ -1 0 0 0 ] [ 0 0 -1 16 ] 0 1 1 +( 320 -528 352 ) ( 320 -528 353 ) ( 320 -527 352 ) bolt1 [ 0 1 0 0 ] [ 0 0 -1 16 ] 0 1 1 +} +// brush 1 +{ +( 272 -576 64 ) ( 272 -575 64 ) ( 272 -576 65 ) bolt1 [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( 272 -576 64 ) ( 272 -576 65 ) ( 273 -576 64 ) bolt1 [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( 272 -576 48 ) ( 273 -576 48 ) ( 272 -575 48 ) bolt1 [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( 320 -528 80 ) ( 320 -527 80 ) ( 321 -528 80 ) bolt1 [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( 320 -528 80 ) ( 321 -528 80 ) ( 320 -528 81 ) bolt1 [ -1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( 320 -528 80 ) ( 320 -528 81 ) ( 320 -527 80 ) bolt1 [ 0 1 0 0 ] [ 0 0 -1 0 ] 0 1 1 +} +} +// entity 3 +{ +"classname" "func_detail_illusionary" +// brush 0 +{ +( 144 -576 336 ) ( 144 -575 336 ) ( 144 -576 337 ) bolt1 [ 0 -1 0 0 ] [ 0 0 -1 16 ] 0 1 1 +( 144 -576 336 ) ( 144 -576 337 ) ( 145 -576 336 ) bolt1 [ 1 0 0 0 ] [ 0 0 -1 16 ] 0 1 1 +( 144 -576 320 ) ( 145 -576 320 ) ( 144 -575 320 ) bolt1 [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( 192 -528 352 ) ( 192 -527 352 ) ( 193 -528 352 ) bolt1 [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( 192 -528 352 ) ( 193 -528 352 ) ( 192 -528 353 ) bolt1 [ -1 0 0 0 ] [ 0 0 -1 16 ] 0 1 1 +( 192 -528 352 ) ( 192 -528 353 ) ( 192 -527 352 ) bolt1 [ 0 1 0 0 ] [ 0 0 -1 16 ] 0 1 1 +} +// brush 1 +{ +( 144 -576 64 ) ( 144 -575 64 ) ( 144 -576 65 ) bolt1 [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( 144 -576 64 ) ( 144 -576 65 ) ( 145 -576 64 ) bolt1 [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( 144 -576 48 ) ( 145 -576 48 ) ( 144 -575 48 ) bolt1 [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( 192 -528 80 ) ( 192 -527 80 ) ( 193 -528 80 ) bolt1 [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( 192 -528 80 ) ( 193 -528 80 ) ( 192 -528 81 ) bolt1 [ -1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( 192 -528 80 ) ( 192 -528 81 ) ( 192 -527 80 ) bolt1 [ 0 1 0 0 ] [ 0 0 -1 0 ] 0 1 1 +} +} +// entity 4 +{ +"classname" "func_detail_wall" +// brush 0 +{ +( 208 -576 336 ) ( 208 -575 336 ) ( 208 -576 337 ) bolt1 [ 0 -1 0 0 ] [ 0 0 -1 16 ] 0 1 1 +( 208 -576 336 ) ( 208 -576 337 ) ( 209 -576 336 ) bolt1 [ 1 0 0 0 ] [ 0 0 -1 16 ] 0 1 1 +( 208 -576 320 ) ( 209 -576 320 ) ( 208 -575 320 ) bolt1 [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( 256 -528 352 ) ( 256 -527 352 ) ( 257 -528 352 ) bolt1 [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( 256 -528 352 ) ( 257 -528 352 ) ( 256 -528 353 ) bolt1 [ -1 0 0 0 ] [ 0 0 -1 16 ] 0 1 1 +( 256 -528 352 ) ( 256 -528 353 ) ( 256 -527 352 ) bolt1 [ 0 1 0 0 ] [ 0 0 -1 16 ] 0 1 1 +} +// brush 1 +{ +( 208 -576 64 ) ( 208 -575 64 ) ( 208 -576 65 ) bolt1 [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( 208 -576 64 ) ( 208 -576 65 ) ( 209 -576 64 ) bolt1 [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( 208 -576 48 ) ( 209 -576 48 ) ( 208 -575 48 ) bolt1 [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( 256 -528 80 ) ( 256 -527 80 ) ( 257 -528 80 ) bolt1 [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( 256 -528 80 ) ( 257 -528 80 ) ( 256 -528 81 ) bolt1 [ -1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( 256 -528 80 ) ( 256 -528 81 ) ( 256 -527 80 ) bolt1 [ 0 1 0 0 ] [ 0 0 -1 0 ] 0 1 1 +} +} +// entity 5 +{ +"classname" "func_group" +// brush 0 +{ +( 336 -576 336 ) ( 336 -575 336 ) ( 336 -576 337 ) *swater4 [ 0 -1 0 0 ] [ 0 0 -1 16 ] 0 1 1 +( 336 -576 336 ) ( 336 -576 337 ) ( 337 -576 336 ) *swater4 [ 1 0 0 0 ] [ 0 0 -1 16 ] 0 1 1 +( 336 -576 320 ) ( 337 -576 320 ) ( 336 -575 320 ) *swater4 [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( 384 -528 352 ) ( 384 -527 352 ) ( 385 -528 352 ) *swater4 [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( 384 -528 352 ) ( 385 -528 352 ) ( 384 -528 353 ) *swater4 [ -1 0 0 0 ] [ 0 0 -1 16 ] 0 1 1 +( 384 -528 352 ) ( 384 -528 353 ) ( 384 -527 352 ) *swater4 [ 0 1 0 0 ] [ 0 0 -1 16 ] 0 1 1 +} +// brush 1 +{ +( 336 -576 64 ) ( 336 -575 64 ) ( 336 -576 65 ) *swater4 [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( 336 -576 64 ) ( 336 -576 65 ) ( 337 -576 64 ) *swater4 [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( 336 -576 48 ) ( 337 -576 48 ) ( 336 -575 48 ) *swater4 [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( 384 -528 80 ) ( 384 -527 80 ) ( 385 -528 80 ) *swater4 [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( 384 -528 80 ) ( 385 -528 80 ) ( 384 -528 81 ) *swater4 [ -1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( 384 -528 80 ) ( 384 -528 81 ) ( 384 -527 80 ) *swater4 [ 0 1 0 0 ] [ 0 0 -1 0 ] 0 1 1 +} +} +// entity 6 +{ +"classname" "ambient_drip" +"origin" "168 -296 200" +} diff --git a/tests/test_common.cc b/tests/test_common.cc index c9462fca..f402fddb 100644 --- a/tests/test_common.cc +++ b/tests/test_common.cc @@ -57,10 +57,20 @@ TEST_SUITE("common") { auto combined = game_q1->combine_contents(detail_solid, contentflags_t{CONTENTS_WATER}); + CHECK(combined.is_any_solid(game_q1)); CHECK(combined.is_detail_solid(game_q1)); CHECK(!combined.is_liquid(game_q1)); CHECK(!combined.is_solid(game_q1)); } + + SUBCASE("detail_solid plus sky") + { + auto combined = game_q1->combine_contents(detail_solid, contentflags_t{CONTENTS_SKY}); + + CHECK(!combined.is_detail_solid(game_q1)); + CHECK(combined.is_sky(game_q1)); + CHECK(!combined.is_solid(game_q1)); + } } TEST_CASE("shared content flag tests") diff --git a/tests/test_qbsp.cc b/tests/test_qbsp.cc index d4cf0de0..41d68098 100644 --- a/tests/test_qbsp.cc +++ b/tests/test_qbsp.cc @@ -861,6 +861,13 @@ TEST_CASE("q1_detail_non_sealing" * doctest::test_suite("testmaps_q1")) CHECK(!prt.has_value()); } +TEST_CASE("q1_sealing_contents" * doctest::test_suite("testmaps_q1")) +{ + const auto [bsp, bspx, prt] = LoadTestmapQ1("q1_sealing_contents.map"); + + CHECK(prt.has_value()); +} + TEST_CASE("detail_doesnt_remove_world_nodes" * doctest::test_suite("testmaps_q1")) { const auto [bsp, bspx, prt] = LoadTestmapQ1("qbsp_detail_doesnt_remove_world_nodes.map");