Skip to content

Commit

Permalink
qbsp: more func_illusionary_visblocker fixes..
Browse files Browse the repository at this point in the history
fix illusionary_visblocker covered by func_detail_illusionary
  • Loading branch information
ericwa committed Nov 24, 2024
1 parent a095376 commit dfa164f
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 3 deletions.
18 changes: 15 additions & 3 deletions common/bspfile.cc
Original file line number Diff line number Diff line change
Expand Up @@ -466,14 +466,15 @@ struct gamedef_q1_like_t : public gamedef_t
if (contents_are_detail_fence(contents) || contents_are_detail_wall(contents)) {
return create_solid_contents();
}

if (contents.flags & EWT_VISCONTENTS_MIST) {
// clear mist. detail_illusionary on its own becomes CONTENTS_EMPTY,
// detail_illusionary in water becomes CONTENTS_WATER, etc.
return contentflags_t::make(contents.flags & ~EWT_VISCONTENTS_MIST);
contents = contentflags_t::make(contents.flags & ~EWT_VISCONTENTS_MIST);
}
if (contents.flags & EWT_VISCONTENTS_ILLUSIONARY_VISBLOCKER) {
// this exports as empty
return contentflags_t::make(contents.flags & ~EWT_VISCONTENTS_ILLUSIONARY_VISBLOCKER);
contents = contentflags_t::make(contents.flags & ~EWT_VISCONTENTS_ILLUSIONARY_VISBLOCKER);
}

return contents;
Expand All @@ -484,14 +485,20 @@ struct gamedef_q1_like_t : public gamedef_t
auto bits_a = a.flags;
auto bits_b = b.flags;

auto result = contentflags_t::make(bits_a | bits_b);

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::make(EWT_VISCONTENTS_SKY);
}
if ((a.flags & EWT_VISCONTENTS_ILLUSIONARY_VISBLOCKER) || (b.flags & EWT_VISCONTENTS_ILLUSIONARY_VISBLOCKER)) {
// strip out detail flag, otherwise it breaks the visblocker feature
result = contentflags_t::make(result.flags & ~EWT_CFLAG_DETAIL);
}

return contentflags_t::make(bits_a | bits_b);
return result;
}

contentflags_t portal_visible_contents(contentflags_t a, contentflags_t b) const override
Expand Down Expand Up @@ -1297,6 +1304,11 @@ struct gamedef_q2_t : public gamedef_t
bits_a &= ~EWT_CFLAG_DETAIL;
bits_b &= ~EWT_CFLAG_DETAIL;
}
if ((bits_a & EWT_VISCONTENTS_ILLUSIONARY_VISBLOCKER) || (bits_b & EWT_VISCONTENTS_ILLUSIONARY_VISBLOCKER)) {
// strip out detail flag, otherwise it breaks the visblocker feature
bits_a &= ~EWT_CFLAG_DETAIL;
bits_b &= ~EWT_CFLAG_DETAIL;
}

return contentflags_t::make(bits_a | bits_b);
}
Expand Down
32 changes: 32 additions & 0 deletions testmaps/q1_func_illusionary_visblocker_interactions.map
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,35 @@
"classname" "ambient_flouro_buzz"
"origin" "280 -48 104"
}
// entity 15
{
"classname" "func_detail_illusionary"
"_mirrorinside" "1"
// brush 0
{
( 8 328 -32 ) ( 8 329 -32 ) ( 8 328 -31 ) bolt14 8 -48 0 1 1
( -56 208 -32 ) ( -56 208 -31 ) ( -55 208 -32 ) bolt14 -8 -48 0 1 1
( -56 328 16 ) ( -55 328 16 ) ( -56 329 16 ) bolt14 -8 -8 0 1 1
( 184 376 128 ) ( 184 377 128 ) ( 185 376 128 ) bolt14 -8 -8 0 1 1
( 184 288 -16 ) ( 185 288 -16 ) ( 184 288 -15 ) bolt14 -8 -48 0 1 1
( 104 376 -16 ) ( 104 376 -15 ) ( 104 377 -16 ) bolt14 8 -48 0 1 1
}
}
// entity 16
{
"classname" "func_illusionary_visblocker"
// brush 0
{
( 16 344 -32 ) ( 16 345 -32 ) ( 16 344 -31 ) *zwater1 56 -48 0 1 1
( -48 216 -32 ) ( -48 216 -31 ) ( -47 216 -32 ) *zwater1 -16 -48 0 1 1
( -48 344 16 ) ( -47 344 16 ) ( -48 345 16 ) *zwater1 -16 -56 0 1 1
( 192 392 120 ) ( 192 393 120 ) ( 193 392 120 ) *zwater1 -16 -56 0 1 1
( 192 280 -16 ) ( 193 280 -16 ) ( 192 280 -15 ) *zwater1 -16 -48 0 1 1
( 96 392 -16 ) ( 96 392 -15 ) ( 96 393 -16 ) *zwater1 56 -48 0 1 1
}
}
// entity 17
{
"classname" "info_null"
"origin" "48 248 56"
}
16 changes: 16 additions & 0 deletions tests/test_vis.cc
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,22 @@ TEST(vis, q1FuncIllusionaryVisblocker)
}
}

TEST(vis, q1FuncIllusionaryVisblockerInteractions)
{
SCOPED_TRACE("make sure illusionary_visblocker covered by detail_illusionary doesn't break the visblocker");
auto [bsp, bspx, lit] = QbspVisLight_Q1("q1_func_illusionary_visblocker_interactions.map", {}, runvis_t::yes);

const auto vis = DecompressAllVis(&bsp);

const auto player_start = qvec3d(80, -272, 40);
const auto in_visblocker_covered_by_illusionary = qvec3d(48, 248, 56);

auto *player_start_leaf = BSP_FindLeafAtPoint(&bsp, &bsp.dmodels[0], player_start);
auto *in_visblocker_covered_by_illusionary_leaf = BSP_FindLeafAtPoint(&bsp, &bsp.dmodels[0], in_visblocker_covered_by_illusionary);

EXPECT_FALSE(q1_leaf_sees(bsp, vis, in_visblocker_covered_by_illusionary_leaf, player_start_leaf));
}

TEST(vis, ClipStackWinding)
{
pstack_t stack{};
Expand Down

0 comments on commit dfa164f

Please sign in to comment.