From 6f14c01487c271b422e55ecadacd827f217bb68f Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Sat, 15 Mar 2025 14:14:09 -0500 Subject: [PATCH] skip more for file load preview --- src/fileio/fileio.hpp | 7 ++- src/fileio/fileio_party.cpp | 24 ++++----- src/fileio/fileio_scen.cpp | 98 ++++++++++++++++++++----------------- src/game/boe.fileio.cpp | 2 +- src/game/boe.main.cpp | 2 +- test/town_legacy.cpp | 2 +- 6 files changed, 75 insertions(+), 60 deletions(-) diff --git a/src/fileio/fileio.hpp b/src/fileio/fileio.hpp index 902138c6..875e7059 100644 --- a/src/fileio/fileio.hpp +++ b/src/fileio/fileio.hpp @@ -22,9 +22,14 @@ class cUniverse; extern std::vector extra_scen_dirs; +enum class eLoadScenario { + ONLY_HEADER, + SAVE_PREVIEW, + FULL +}; std::vector all_scen_dirs(); fs::path locate_scenario(std::string scen_name); -bool load_scenario(fs::path file_to_load, cScenario& scenario, bool only_header = false); +bool load_scenario(fs::path file_to_load, cScenario& scenario, eLoadScenario load_type = eLoadScenario::FULL); fs::path nav_get_or_decode_party(); fs::path nav_put_or_temp_party(fs::path def = ""); diff --git a/src/fileio/fileio_party.cpp b/src/fileio/fileio_party.cpp index 18d63a58..1036395d 100644 --- a/src/fileio/fileio_party.cpp +++ b/src/fileio/fileio_party.cpp @@ -387,20 +387,9 @@ bool load_party_v2(fs::path file_to_load, cUniverse& real_univ, bool preview){ return false; } - if(!load_scenario(path, univ.scenario)) + if(!load_scenario(path, univ.scenario, preview ? eLoadScenario::SAVE_PREVIEW : eLoadScenario::FULL)) return false; - if(partyIn.hasFile("save/scenario.txt")) { - // Load scenario data - std::istream& fin = partyIn.getFile("save/scenario.txt"); - if(!fin) { - if(!preview) showError("Loading Blades of Exile save file failed."); - return false; - } - file.readFrom(fin); - univ.scenario.readFrom(file); - } - // We have all we need for the file picker preview. if(preview){ univ.file = file_to_load; @@ -410,6 +399,17 @@ bool load_party_v2(fs::path file_to_load, cUniverse& real_univ, bool preview){ // Below here, if(!preview) does not need to be checked before showing errors and warnings. + if(partyIn.hasFile("save/scenario.txt")) { + // Load scenario data + std::istream& fin = partyIn.getFile("save/scenario.txt"); + if(!fin) { + showError("Loading Blades of Exile save file failed."); + return false; + } + file.readFrom(fin); + univ.scenario.readFrom(file); + } + { // Then the "setup" array std::istream& fin = partyIn.getFile("save/setup.dat"); if(!fin) { diff --git a/src/fileio/fileio_scen.cpp b/src/fileio/fileio_scen.cpp index eab6980b..4d23324c 100644 --- a/src/fileio/fileio_scen.cpp +++ b/src/fileio/fileio_scen.cpp @@ -41,11 +41,11 @@ extern std::string last_load_file; void load_spec_graphics_v1(fs::path scen_file); void load_spec_graphics_v2(int num_sheets); // Load old scenarios (town talk is handled by the town loading function) -static bool load_scenario_v1(fs::path file_to_load, cScenario& scenario, bool only_header); +static bool load_scenario_v1(fs::path file_to_load, cScenario& scenario, eLoadScenario load_type); static bool load_outdoors_v1(fs::path scen_file, location which_out,cOutdoors& the_out, legacy::scenario_data_type& scenario); static bool load_town_v1(fs::path scen_file,short which_town,cTown& the_town,legacy::scenario_data_type& scenario,std::vector& shops); // Load new scenarios -static bool load_scenario_v2(fs::path file_to_load, cScenario& scenario, bool only_header); +static bool load_scenario_v2(fs::path file_to_load, cScenario& scenario, eLoadScenario load_type); // Some of these are non-static so that the test cases can access them. ticpp::Document xmlDocFromStream(std::istream& stream, std::string name); void readScenarioFromXml(ticpp::Document&& data, cScenario& scenario); @@ -134,7 +134,7 @@ fs::path locate_scenario(std::string scen_name) { bool cur_scen_pushed_paths = false; -bool load_scenario(fs::path file_to_load, cScenario& scenario, bool only_header) { +bool load_scenario(fs::path file_to_load, cScenario& scenario, eLoadScenario load_type) { // Before loading a scenario, we may need to pop scenario resource paths. if(cur_scen_pushed_paths){ @@ -163,13 +163,13 @@ bool load_scenario(fs::path file_to_load, cScenario& scenario, bool only_header) return false; } else try { if(fname.substr(dot) == ".boes"){ - if(load_scenario_v2(file_to_load, scenario, only_header)){ + if(load_scenario_v2(file_to_load, scenario, load_type)){ last_load_file = file_to_load.string(); return true; } return false; }else if(fname.substr(dot) == ".exs"){ - if(load_scenario_v1(file_to_load, scenario, only_header)){ + if(load_scenario_v1(file_to_load, scenario, load_type)){ last_load_file = file_to_load.string(); return true; } @@ -204,7 +204,7 @@ template static void port_shop_spec_node(cSpecial& spec, std } static const std::string err_prefix = "Error loading Blades of Exile Scenario: "; -bool load_scenario_v1(fs::path file_to_load, cScenario& scenario, bool only_header){ +bool load_scenario_v1(fs::path file_to_load, cScenario& scenario, eLoadScenario load_type){ bool file_ok = false; long len; char temp_str[256]; @@ -236,7 +236,7 @@ bool load_scenario_v1(fs::path file_to_load, cScenario& scenario, bool only_head file_ok = true; } else if(scenario.format.flag1 == 'O' && scenario.format.flag2 == 'B' && scenario.format.flag3 == 'O' && scenario.format.flag4 == 'E') { // This means we're looking at the scenario header file of an unpacked new-format scenario. - return load_scenario_v2(file_to_load.parent_path(), scenario, only_header); + return load_scenario_v2(file_to_load.parent_path(), scenario, load_type); } if(!file_ok) { fclose(file_id); @@ -290,7 +290,7 @@ bool load_scenario_v1(fs::path file_to_load, cScenario& scenario, bool only_head scenario.ter_types[23].fly_over = false; scenario.scen_file = file_to_load; - if(only_header) return true; + if(load_type == eLoadScenario::ONLY_HEADER) return true; load_spec_graphics_v1(scenario.scen_file); // Now load all the outdoor sectors @@ -318,6 +318,9 @@ bool load_scenario_v1(fs::path file_to_load, cScenario& scenario, bool only_head // Enable character creation in starting town scenario.towns[scenario.which_town_start]->has_tavern = true; + if(load_type == eLoadScenario::SAVE_PREVIEW) + return true; + // Check special nodes in case there were outdoor shops for(cSpecial& spec : scenario.scen_specials) { if(spec.type == eSpecType::ENTER_SHOP) @@ -2162,7 +2165,7 @@ static void readSpecialNodesFromStream(std::istream& stream, std::vectorspecials, file_basename + ".spec"); + if(load_type != eLoadScenario::SAVE_PREVIEW){ + // Then the map. + std::istream& out_map = getFile("out/" + file_basename + ".map"); + loadOutMapData(load_map(out_map, false, file_basename + ".map"), loc(x,y), scenario); + + // And the special nodes. + std::istream& out_spec = getFile("out/" + file_basename + ".spec"); + readSpecialNodesFromStream(out_spec, scenario.outdoors[x][y]->specials, file_basename + ".spec"); + } } } @@ -2254,19 +2260,23 @@ bool load_scenario_v2(fs::path file_to_load, cScenario& scenario, bool only_head std::istream& town = getFile("towns/" + file_basename + ".xml"); readTownFromXml(xmlDocFromStream(town, file_basename + ".xml"), scenario.towns[i], scenario); - // Then the map. - std::istream& town_map = getFile("towns/" + file_basename + ".map"); - loadTownMapData(load_map(town_map, true, file_basename + ".map"), i, scenario); - - // And the special nodes. - std::istream& town_spec = getFile("towns/" + file_basename + ".spec"); - readSpecialNodesFromStream(town_spec, scenario.towns[i]->specials, file_basename + ".spec"); - - // Don't forget the dialogue nodes. - std::istream& town_talk = getFile("towns/talk" + std::to_string(i) + ".xml"); - readDialogueFromXml(xmlDocFromStream(town_talk, "talk.xml"), scenario.towns[i]->talking, i); + if(load_type != eLoadScenario::SAVE_PREVIEW){ + // Then the map. + std::istream& town_map = getFile("towns/" + file_basename + ".map"); + loadTownMapData(load_map(town_map, true, file_basename + ".map"), i, scenario); + + // And the special nodes. + std::istream& town_spec = getFile("towns/" + file_basename + ".spec"); + readSpecialNodesFromStream(town_spec, scenario.towns[i]->specials, file_basename + ".spec"); + + // Don't forget the dialogue nodes. + std::istream& town_talk = getFile("towns/talk" + std::to_string(i) + ".xml"); + readDialogueFromXml(xmlDocFromStream(town_talk, "talk.xml"), scenario.towns[i]->talking, i); + } } + if(load_type == eLoadScenario::SAVE_PREVIEW) return true; + // One last thing - custom graphics and sounds. // First figure out where they are in the filesystem. The implementation of this depends on whether the scenario is packed. int num_graphic_sheets = 0; diff --git a/src/game/boe.fileio.cpp b/src/game/boe.fileio.cpp index 03fda0d2..c244aa91 100644 --- a/src/game/boe.fileio.cpp +++ b/src/game/boe.fileio.cpp @@ -441,7 +441,7 @@ bool load_scenario_header(fs::path file,scen_header_type& scen_head){ // So file is (probably) OK, so load in string data and close it. cScenario temp_scenario; - if(!load_scenario(file, temp_scenario, true)) + if(!load_scenario(file, temp_scenario, eLoadScenario::ONLY_HEADER)) return false; scen_head.name = temp_scenario.scen_name; diff --git a/src/game/boe.main.cpp b/src/game/boe.main.cpp index 69e00f3e..a0359198 100644 --- a/src/game/boe.main.cpp +++ b/src/game/boe.main.cpp @@ -442,7 +442,7 @@ static void handle_scenario_args() { } cScenario scenario; - if(load_scenario(path, scenario, false)){ + if(load_scenario(path, scenario)){ if(!party_in_memory){ start_new_game(true); } diff --git a/test/town_legacy.cpp b/test/town_legacy.cpp index 5dcb9694..ca394363 100644 --- a/test/town_legacy.cpp +++ b/test/town_legacy.cpp @@ -262,7 +262,7 @@ TEST_CASE("Converting legacy town data") { for(fs::path test_scenario : test_scenarios){ cScenario scen; - load_scenario(test_scenarios_dir / test_scenario, scen, false); + load_scenario(test_scenarios_dir / test_scenario, scen); CHECK(scen.towns[0]->in_town_rect.width() == 6); CHECK(scen.towns[0]->in_town_rect.height() == 4);