From 04adb17b1b59b4ac6403c51d7895176b3868d5b8 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Mon, 21 Nov 2022 00:10:26 -0700 Subject: [PATCH] qbsp: fix -nodetail in q2 mode --- common/bspfile.cc | 14 ++++++++++++++ include/common/bspfile.hh | 1 + qbsp/brush.cc | 13 ++++++++----- tests/test_qbsp_q2.cc | 11 +++++++++++ 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/common/bspfile.cc b/common/bspfile.cc index b9fa51c0..4c8e02ef 100644 --- a/common/bspfile.cc +++ b/common/bspfile.cc @@ -401,6 +401,13 @@ public: return contentflags_from_bits(result); } + contentflags_t clear_detail(const contentflags_t &original) const override + { + auto bits = contentflags_to_bits(original); + bits.detail = false; + return contentflags_from_bits(bits); + } + bool contents_are_type_equal(const contentflags_t &self, const contentflags_t &other) const override { // fixme-brushbsp: document what this is supposed to do, remove if unneeded? @@ -996,6 +1003,13 @@ struct gamedef_q2_t : public gamedef_t return result; } + contentflags_t clear_detail(const contentflags_t &original) const override + { + contentflags_t result = original; + result.native &= ~Q2_CONTENTS_DETAIL; + return result; + } + bool contents_are_type_equal(const contentflags_t &self, const contentflags_t &other) const override { return self.illusionary_visblocker == other.illusionary_visblocker && diff --git a/include/common/bspfile.hh b/include/common/bspfile.hh index 12107bcb..5e458ef2 100644 --- a/include/common/bspfile.hh +++ b/include/common/bspfile.hh @@ -274,6 +274,7 @@ struct gamedef_t virtual contentflags_t create_detail_fence_contents(const contentflags_t &original) const = 0; virtual contentflags_t create_detail_wall_contents(const contentflags_t &original) const = 0; virtual contentflags_t create_detail_solid_contents(const contentflags_t &original) const = 0; + virtual contentflags_t clear_detail(const contentflags_t &original) const = 0; virtual bool contents_are_type_equal(const contentflags_t &self, const contentflags_t &other) const = 0; virtual bool contents_are_equal(const contentflags_t &self, const contentflags_t &other) const = 0; virtual bool contents_are_any_detail(const contentflags_t &contents) const = 0; diff --git a/qbsp/brush.cc b/qbsp/brush.cc index 75cc2fe5..5b4ebe02 100644 --- a/qbsp/brush.cc +++ b/qbsp/brush.cc @@ -676,28 +676,27 @@ static void Brush_LoadEntity(mapentity_t &dst, mapentity_t &src, hull_index_t hu { clock.max += src.mapbrushes.size(); - bool all_detail, all_detail_wall, all_detail_fence, all_detail_illusionary; + bool all_detail = false; + bool all_detail_wall = false; + bool all_detail_fence = false; + bool all_detail_illusionary = false; const std::string &classname = src.epairs.get("classname"); /* If the source entity is func_detail, set the content flag */ if (!qbsp_options.nodetail.value()) { - all_detail = false; if (!Q_strcasecmp(classname, "func_detail")) { all_detail = true; } - all_detail_wall = false; if (!Q_strcasecmp(classname, "func_detail_wall")) { all_detail_wall = true; } - all_detail_fence = false; if (!Q_strcasecmp(classname, "func_detail_fence")) { all_detail_fence = true; } - all_detail_illusionary = false; if (!Q_strcasecmp(classname, "func_detail_illusionary")) { all_detail_illusionary = true; } @@ -708,6 +707,10 @@ static void Brush_LoadEntity(mapentity_t &dst, mapentity_t &src, hull_index_t hu contentflags_t contents = mapbrush.contents; + if (qbsp_options.nodetail.value()) { + contents = qbsp_options.target_game->clear_detail(contents); + } + /* "origin" brushes always discarded beforehand */ Q_assert(!contents.is_origin(qbsp_options.target_game)); diff --git a/tests/test_qbsp_q2.cc b/tests/test_qbsp_q2.cc index 6ff1e397..f10afaa7 100644 --- a/tests/test_qbsp_q2.cc +++ b/tests/test_qbsp_q2.cc @@ -99,6 +99,17 @@ TEST_CASE("detail" * doctest::test_suite("testmaps_q2")) { CHECK(prt->portalleafs == 4); } +TEST_CASE("q2 detail with -nodetail" * doctest::test_suite("testmaps_q2")) { + const auto [bsp, bspx, prt] = LoadTestmapQ2("qbsp_q2_detail.map", {"-nodetail"}); + + const qvec3d inside_button{246, 436, 98}; + auto *inside_button_leaf = BSP_FindLeafAtPoint(&bsp, &bsp.dmodels[0], inside_button); + CHECK(Q2_CONTENTS_SOLID == inside_button_leaf->contents); + + CHECK(prt->portals.size() > 5); + CHECK(prt->portalleafs == 8); +} + TEST_CASE("q2 detail with -omitdetail" * doctest::test_suite("testmaps_q2")) { const auto [bsp, bspx, prt] = LoadTestmapQ2("qbsp_q2_detail.map", {"-omitdetail"});