diff --git a/common/bspinfo.cc b/common/bspinfo.cc index 991aa2e8..c78c2197 100644 --- a/common/bspinfo.cc +++ b/common/bspinfo.cc @@ -49,7 +49,7 @@ static std::string hex_string(const uint8_t *bytes, const size_t count) /** * returns a JSON array of models */ -static json serialize_bspxbrushlist(const std::vector &lump) +json serialize_bspxbrushlist(const std::vector &lump) { json j = json::array(); diff --git a/include/common/bspinfo.hh b/include/common/bspinfo.hh index 1fc1267c..a06e0e74 100644 --- a/include/common/bspinfo.hh +++ b/include/common/bspinfo.hh @@ -24,6 +24,8 @@ #include "common/imglib.hh" #include "common/qvec.hh" +#include + #include #include @@ -44,3 +46,5 @@ struct full_atlas_t full_atlas_t build_lightmap_atlas(const mbsp_t &bsp, const bspxentries_t &bspx, const std::vector &litdata, bool use_bspx, bool use_decoupled); void serialize_bsp(const bspdata_t &bspdata, const mbsp_t &bsp, const fs::path &name); + +nlohmann::json serialize_bspxbrushlist(const std::vector &lump); diff --git a/qbsp/brush.cc b/qbsp/brush.cc index 6acfd724..1a5a87d5 100644 --- a/qbsp/brush.cc +++ b/qbsp/brush.cc @@ -888,9 +888,6 @@ void Brush_LoadEntity(mapentity_t &entity, hull_index_t hullnum, bspbrush_t::con for (int i = 1; i < map.entities.size(); i++) { mapentity_t &source = map.entities.at(i); - /* Load external .map and change the classname, if needed */ - ProcessExternalMapEntity(source); - ProcessAreaPortal(source); if (IsWorldBrushEntity(source) || IsNonRemoveWorldBrushEntity(source)) { diff --git a/qbsp/map.cc b/qbsp/map.cc index 2e85301d..1f2f14a2 100644 --- a/qbsp/map.cc +++ b/qbsp/map.cc @@ -3104,6 +3104,11 @@ void ProcessMapBrushes() { logging::funcheader(); + // load external maps (needs to be before world extents are calculated) + for (auto &source : map.entities) { + ProcessExternalMapEntity(source); + } + // calculate extents, if required if (!qbsp_options.worldextent.value()) { CalculateWorldExtent(); diff --git a/testmaps/q1_external_map_base.map b/testmaps/q1_external_map_base.map new file mode 100644 index 00000000..655bed82 --- /dev/null +++ b/testmaps/q1_external_map_base.map @@ -0,0 +1,15 @@ +// Game: Quake +// Format: Valve +// entity 0 +{ +"mapversion" "220" +"classname" "worldspawn" +} +// entity 1 +{ +"classname" "misc_external_map" +"origin" "0 0 0" +"_external_map" "q1_external_map_included.map" +"_external_map_classname" "func_group" +"_external_map_angle" "180" +} diff --git a/testmaps/q1_external_map_included.map b/testmaps/q1_external_map_included.map new file mode 100644 index 00000000..d88dd381 --- /dev/null +++ b/testmaps/q1_external_map_included.map @@ -0,0 +1,17 @@ +// Game: Quake +// Format: Valve +// entity 0 +{ +"mapversion" "220" +"classname" "worldspawn" +"wad" "deprecated/free_wad.wad" +// brush 0 +{ +( -64 -64 -16 ) ( -64 -63 -16 ) ( -64 -64 -15 ) sand [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( -64 -64 -16 ) ( -64 -64 -15 ) ( -63 -64 -16 ) sand [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( -64 -64 -16 ) ( -63 -64 -16 ) ( -64 -63 -16 ) sand [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( 64 64 16 ) ( 64 65 16 ) ( 65 64 16 ) sand [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1 +( 64 64 16 ) ( 65 64 16 ) ( 64 64 17 ) sand [ -1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1 +( 64 64 16 ) ( 64 64 17 ) ( 64 65 16 ) sand [ 0 1 0 0 ] [ 0 0 -1 0 ] 0 1 1 +} +} diff --git a/tests/test_qbsp.cc b/tests/test_qbsp.cc index 6fd78505..b19f28d4 100644 --- a/tests/test_qbsp.cc +++ b/tests/test_qbsp.cc @@ -67,6 +67,7 @@ mapentity_t &LoadMapPath(const std::filesystem::path &name) } #include +#include std::tuple> LoadTestmap( const std::filesystem::path &name, std::vector extra_args) @@ -1992,3 +1993,26 @@ TEST_CASE("hl_basic") CHECK(64 == bsp.dtex.textures[1].width); CHECK(64 == bsp.dtex.textures[1].height); } + +TEST_CASE("wrbrushes + misc_external_map") +{ + const auto [bsp, bspx, prt] = LoadTestmap("q1_external_map_base.map", {"-wrbrushes"}); + + auto models_json = serialize_bspxbrushlist(bspx.at("BRUSHLIST")); + logging::print("{}\n", to_string(models_json)); + + REQUIRE(models_json.size() == 1); + + auto &model_json = models_json.at(0); + REQUIRE(model_json.at("brushes").size() == 1); + + auto &brush_json = model_json.at("brushes").at(0); + REQUIRE(brush_json.at("maxs") == nlohmann::json::array({nlohmann::json::number_float_t(64), + nlohmann::json::number_float_t(64), + nlohmann::json::number_float_t(16) + })); + REQUIRE(brush_json.at("mins") == nlohmann::json::array({nlohmann::json::number_float_t(-64), + nlohmann::json::number_float_t(-64), + nlohmann::json::number_float_t(-16) + })); +}