diff --git a/common/bspfile.cc b/common/bspfile.cc index fcb3beb2..bb1363e8 100644 --- a/common/bspfile.cc +++ b/common/bspfile.cc @@ -148,7 +148,7 @@ struct gamedef_q1_like_t : public gamedef_t } else if (contents.extended & CFLAGS_DETAIL_FENCE) { return 4; } else if (contents.extended & CFLAGS_DETAIL_ILLUSIONARY) { - return 3; + return 2; } else if (contents.extended & CFLAGS_ILLUSIONARY_VISBLOCKER) { return 2; } else { @@ -157,9 +157,9 @@ struct gamedef_q1_like_t : public gamedef_t case CONTENTS_SKY: return 6; - case CONTENTS_WATER: return 2; - case CONTENTS_SLIME: return 2; - case CONTENTS_LAVA: return 2; + case CONTENTS_WATER: return 3; + case CONTENTS_SLIME: return 3; + case CONTENTS_LAVA: return 3; case CONTENTS_EMPTY: return 1; case 0: return 0; diff --git a/common/bsputils.cc b/common/bsputils.cc index 5832fc01..2da2fad4 100644 --- a/common/bsputils.cc +++ b/common/bsputils.cc @@ -417,6 +417,28 @@ const bsp2_dnode_t* BSP_FindNodeAtPoint( return BSP_FindNodeAtPoint_r(bsp, model->headnode[0], point, wanted_normal); } +static const mleaf_t *BSP_FindLeafAtPoint_r( + const mbsp_t *bsp, const int nodenum, const qvec3d &point) +{ + if (nodenum < 0) { + return BSP_GetLeafFromNodeNum(bsp, nodenum); + } + + const bsp2_dnode_t *node = &bsp->dnodes[nodenum]; + const vec_t dist = bsp->dplanes[node->planenum].distance_to_fast(point); + + if (dist >= 0) { + return BSP_FindLeafAtPoint_r(bsp, node->children[0], point); + } else { + return BSP_FindLeafAtPoint_r(bsp, node->children[1], point); + } +} + +const mleaf_t* BSP_FindLeafAtPoint(const mbsp_t* bsp, const dmodelh2_t* model, const qvec3d& point) +{ + return BSP_FindLeafAtPoint_r(bsp, model->headnode[0], point); +} + // glm stuff std::vector GLM_FacePoints(const mbsp_t *bsp, const mface_t *face) { diff --git a/include/common/bsputils.hh b/include/common/bsputils.hh index 46c8eae6..f78f6f16 100644 --- a/include/common/bsputils.hh +++ b/include/common/bsputils.hh @@ -66,6 +66,8 @@ const mface_t *BSP_FindFaceAtPoint( const bsp2_dnode_t *BSP_FindNodeAtPoint( const mbsp_t *bsp, const dmodelh2_t *model, const qvec3d &point, const qvec3d &wanted_normal); +const mleaf_t *BSP_FindLeafAtPoint(const mbsp_t *bsp, const dmodelh2_t *model, const qvec3d &point); + const qvec3f &Face_PointAtIndex(const mbsp_t *bsp, const mface_t *f); const qvec3f &Vertex_GetPos(const mbsp_t *bsp, int num); qvec3d Face_Normal(const mbsp_t *bsp, const mface_t *f); diff --git a/qbsp/test_qbsp.cc b/qbsp/test_qbsp.cc index 070ca5d3..8b0fb958 100644 --- a/qbsp/test_qbsp.cc +++ b/qbsp/test_qbsp.cc @@ -374,6 +374,18 @@ TEST(testmaps_q1, simple_worldspawn_detail) ASSERT_EQ(bsp.dfaces.size(), 14); } +TEST(testmaps_q1, water_detail_illusionary) +{ + const mbsp_t bsp = LoadTestmap("qbsp_water_detail_illusionary.map"); + + ASSERT_FALSE(map.leakfile); + + const qvec3d inside_water_and_fence{-20, -52, 124}; + const auto *leaf = BSP_FindLeafAtPoint(&bsp, &bsp.dmodels[0], inside_water_and_fence); + ASSERT_EQ(leaf->contents, CONTENTS_WATER); +} + + TEST(testmaps_q1, noclipfaces) { const mbsp_t bsp = LoadTestmap("qbsp_noclipfaces.map"); diff --git a/testmaps/qbsp_water_detail_illusionary.map b/testmaps/qbsp_water_detail_illusionary.map new file mode 100644 index 00000000..a2ef7385 --- /dev/null +++ b/testmaps/qbsp_water_detail_illusionary.map @@ -0,0 +1,91 @@ +// 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 +{ +( -112 -112 96 ) ( -112 -111 96 ) ( -112 -112 97 ) orangestuff8 [ 0 1 0 -16 ] [ 0 0 -1 0 ] 0 2 2 +( -80 -96 80 ) ( -81 -96 80 ) ( -80 -96 81 ) orangestuff8 [ -1 0 0 16 ] [ 0 0 -1 0 ] 180 2 2 +( -80 -432 80 ) ( -80 -431 80 ) ( -81 -432 80 ) orangestuff8 [ 1 0 0 -16 ] [ 0 -1 0 16 ] 180 2 2 +( -160 -112 96 ) ( -161 -112 96 ) ( -160 -111 96 ) orangestuff8 [ -1 0 0 16 ] [ 0 -1 0 16 ] 180 2 2 +( -160 0 96 ) ( -160 0 97 ) ( -161 0 96 ) orangestuff8 [ 1 0 0 -16 ] [ 0 0 -1 0 ] 180 2 2 +( 64 -432 80 ) ( 64 -432 81 ) ( 64 -431 80 ) orangestuff8 [ 0 -1 0 16 ] [ 0 0 -1 0 ] 0 2 2 +} +// brush 1 +{ +( -112 -96 96 ) ( -112 -95 96 ) ( -112 -96 97 ) orangestuff8 [ 0 1 0 -16 ] [ 0 0 -1 0 ] 0 2 2 +( -80 0 80 ) ( -81 0 80 ) ( -80 0 81 ) orangestuff8 [ -1 0 0 16 ] [ 0 0 -1 0 ] 180 2 2 +( -80 -416 80 ) ( -80 -415 80 ) ( -81 -416 80 ) orangestuff8 [ 1 0 0 -16 ] [ 0 -1 0 16 ] 180 2 2 +( -160 -96 224 ) ( -161 -96 224 ) ( -160 -95 224 ) orangestuff8 [ -1 0 0 16 ] [ 0 -1 0 16 ] 180 2 2 +( -160 16 96 ) ( -160 16 97 ) ( -161 16 96 ) orangestuff8 [ 1 0 0 -16 ] [ 0 0 -1 0 ] 180 2 2 +( 64 -416 80 ) ( 64 -416 81 ) ( 64 -415 80 ) orangestuff8 [ 0 -1 0 16 ] [ 0 0 -1 0 ] 0 2 2 +} +// brush 2 +{ +( -112 -208 96 ) ( -112 -207 96 ) ( -112 -208 97 ) orangestuff8 [ 0 1 0 -16 ] [ 0 0 -1 0 ] 0 2 2 +( -80 -112 80 ) ( -81 -112 80 ) ( -80 -112 81 ) orangestuff8 [ -1 0 0 16 ] [ 0 0 -1 0 ] 180 2 2 +( -80 -528 80 ) ( -80 -527 80 ) ( -81 -528 80 ) orangestuff8 [ 1 0 0 -16 ] [ 0 -1 0 16 ] 180 2 2 +( -160 -208 224 ) ( -161 -208 224 ) ( -160 -207 224 ) orangestuff8 [ -1 0 0 16 ] [ 0 -1 0 16 ] 180 2 2 +( -160 -96 96 ) ( -160 -96 97 ) ( -161 -96 96 ) orangestuff8 [ 1 0 0 -16 ] [ 0 0 -1 0 ] 180 2 2 +( 64 -528 80 ) ( 64 -528 81 ) ( 64 -527 80 ) orangestuff8 [ 0 -1 0 16 ] [ 0 0 -1 0 ] 0 2 2 +} +// brush 3 +{ +( -128 -112 96 ) ( -128 -111 96 ) ( -128 -112 97 ) orangestuff8 [ 0 1 0 -16 ] [ 0 0 -1 0 ] 0 2 2 +( -256 -96 80 ) ( -257 -96 80 ) ( -256 -96 81 ) orangestuff8 [ -1 0 0 16 ] [ 0 0 -1 0 ] 180 2 2 +( -256 -432 80 ) ( -256 -431 80 ) ( -257 -432 80 ) orangestuff8 [ 1 0 0 -16 ] [ 0 -1 0 16 ] 180 2 2 +( -336 -112 224 ) ( -337 -112 224 ) ( -336 -111 224 ) orangestuff8 [ -1 0 0 16 ] [ 0 -1 0 16 ] 180 2 2 +( -336 0 96 ) ( -336 0 97 ) ( -337 0 96 ) orangestuff8 [ 1 0 0 -16 ] [ 0 0 -1 0 ] 180 2 2 +( -112 -432 80 ) ( -112 -432 81 ) ( -112 -431 80 ) orangestuff8 [ 0 -1 0 16 ] [ 0 0 -1 0 ] 0 2 2 +} +// brush 4 +{ +( 64 -112 96 ) ( 64 -111 96 ) ( 64 -112 97 ) orangestuff8 [ 0 1 0 -16 ] [ 0 0 -1 0 ] 0 2 2 +( -64 -96 80 ) ( -65 -96 80 ) ( -64 -96 81 ) orangestuff8 [ -1 0 0 16 ] [ 0 0 -1 0 ] 180 2 2 +( -64 -432 80 ) ( -64 -431 80 ) ( -65 -432 80 ) orangestuff8 [ 1 0 0 -16 ] [ 0 -1 0 16 ] 180 2 2 +( -144 -112 224 ) ( -145 -112 224 ) ( -144 -111 224 ) orangestuff8 [ -1 0 0 16 ] [ 0 -1 0 16 ] 180 2 2 +( -144 0 96 ) ( -144 0 97 ) ( -145 0 96 ) orangestuff8 [ 1 0 0 -16 ] [ 0 0 -1 0 ] 180 2 2 +( 80 -432 80 ) ( 80 -432 81 ) ( 80 -431 80 ) orangestuff8 [ 0 -1 0 16 ] [ 0 0 -1 0 ] 0 2 2 +} +// brush 5 +{ +( -112 -112 240 ) ( -112 -111 240 ) ( -112 -112 241 ) orangestuff8 [ 0 1 0 -16 ] [ 0 0 -1 0 ] 0 2 2 +( -80 -96 224 ) ( -81 -96 224 ) ( -80 -96 225 ) orangestuff8 [ -1 0 0 16 ] [ 0 0 -1 0 ] 180 2 2 +( -80 -432 224 ) ( -80 -431 224 ) ( -81 -432 224 ) orangestuff8 [ 1 0 0 -16 ] [ 0 -1 0 16 ] 180 2 2 +( -160 -112 240 ) ( -161 -112 240 ) ( -160 -111 240 ) orangestuff8 [ -1 0 0 16 ] [ 0 -1 0 16 ] 180 2 2 +( -160 0 240 ) ( -160 0 241 ) ( -161 0 240 ) orangestuff8 [ 1 0 0 -16 ] [ 0 0 -1 0 ] 180 2 2 +( 64 -432 224 ) ( 64 -432 225 ) ( 64 -431 224 ) orangestuff8 [ 0 -1 0 16 ] [ 0 0 -1 0 ] 0 2 2 +} +// brush 6 +{ +( -112 -112 108 ) ( -112 -111 108 ) ( -112 -112 109 ) *swater5 [ 0 1 0 -16 ] [ 0 0 -1 0 ] 0 2 2 +( -80 -96 92 ) ( -81 -96 92 ) ( -80 -96 93 ) *swater5 [ -1 0 0 16 ] [ 0 0 -1 0 ] 180 2 2 +( -80 -432 92 ) ( -80 -431 92 ) ( -81 -432 92 ) *swater5 [ 1 0 0 -16 ] [ 0 -1 0 16 ] 180 2 2 +( -160 -112 148 ) ( -161 -112 148 ) ( -160 -111 148 ) *swater5 [ -1 0 0 16 ] [ 0 -1 0 16 ] 180 2 2 +( -160 0 108 ) ( -160 0 109 ) ( -161 0 108 ) *swater5 [ 1 0 0 -16 ] [ 0 0 -1 0 ] 180 2 2 +( 64 -432 92 ) ( 64 -432 93 ) ( 64 -431 92 ) *swater5 [ 0 -1 0 16 ] [ 0 0 -1 0 ] 0 2 2 +} +} +// entity 1 +{ +"classname" "info_player_start" +"origin" "-88 -64 120" +} +// entity 2 +{ +"classname" "func_detail_illusionary" +// brush 0 +{ +( -40 -76 96 ) ( -40 -75 96 ) ( -40 -76 97 ) {trigger [ 0 -1 0 -16 ] [ 0 0 -1 0 ] 0 1 1 +( -8 -72 96 ) ( -8 -72 97 ) ( -7 -72 96 ) {trigger [ 1 0 0 16 ] [ 0 0 -1 0 ] 0 1 1 +( -8 -76 96 ) ( -7 -76 96 ) ( -8 -75 96 ) {trigger [ -1 0 0 -16 ] [ 0 -1 0 -16 ] 0 1 1 +( 56 -28 224 ) ( 56 -27 224 ) ( 57 -28 224 ) {trigger [ 1 0 0 16 ] [ 0 -1 0 -16 ] 0 1 1 +( 56 -36 112 ) ( 57 -36 112 ) ( 56 -36 113 ) {trigger [ -1 0 0 -16 ] [ 0 0 -1 0 ] 0 1 1 +( 24 -28 112 ) ( 24 -28 113 ) ( 24 -27 112 ) {trigger [ 0 1 0 16 ] [ 0 0 -1 0 ] 0 1 1 +} +}