diff --git a/src/fileio/fileio_party.cpp b/src/fileio/fileio_party.cpp index 10e9e173..17f796d3 100644 --- a/src/fileio/fileio_party.cpp +++ b/src/fileio/fileio_party.cpp @@ -286,7 +286,7 @@ bool load_party_v2(fs::path file_to_load, cUniverse& real_univ){ showError("Loading Blades of Exile save file failed."); return false; } - univ.party.readFrom(fin, univ.scenario); + univ.party.readFrom(fin); } { // Then the "setup" array @@ -343,6 +343,16 @@ bool load_party_v2(fs::path file_to_load, cUniverse& real_univ){ if(!load_scenario(path, univ.scenario)) return false; + + 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; + } + univ.scenario.readFrom(fin); + } if(partyIn.hasFile("save/town.txt")) { // Load town data @@ -403,7 +413,8 @@ bool save_party(fs::path dest_file, const cUniverse& univ) { tarball partyOut; // First, write the main party data - univ.party.writeTo(partyOut.newFile("save/party.txt"), univ.scenario); + univ.party.writeTo(partyOut.newFile("save/party.txt")); + univ.scenario.writeTo(partyOut.newFile("save/scenario.txt")); { std::ostream& fout = partyOut.newFile("save/setup.dat"); static uint16_t magic = 0x0B0E; diff --git a/src/scenario/scenario.cpp b/src/scenario/scenario.cpp index 5d4ef5a7..a5893f17 100644 --- a/src/scenario/scenario.cpp +++ b/src/scenario/scenario.cpp @@ -537,3 +537,50 @@ bool cScenario::is_town_entrance_valid(spec_loc_t loc) const { auto towns_in_scenario = towns.size(); return loc.spec >= 0 && loc.spec < towns_in_scenario; } + +void cScenario::writeTo(std::ostream& file) const { + for(int i = 0; i < towns.size(); i++) { + if(towns[i]->item_taken.any()) + file << "ITEMTAKEN " << i << ' ' << towns[i]->item_taken << '\n'; + if(towns[i]->can_find) + file << "TOWNVISIBLE " << i << '\n'; + else file << "TOWNHIDDEN " << i << '\n'; + if(towns[i]->m_killed > 0) + file << "TOWNSLAUGHTER " << i << ' ' << towns[i]->m_killed << '\n'; + } +} + +void cScenario::readFrom(std::istream& file){ + // TODO: Error-check input + // TODO: Don't call this sin, it's a trig function + std::istringstream bin; + std::string cur; + getline(file, cur, '\f'); + bin.str(cur); + while(bin) { // continue as long as no error, such as eof, occurs + getline(bin, cur); + std::istringstream sin(cur); + sin >> cur; + if(cur == "ITEMTAKEN"){ + int i; + sin >> i; + if(i >= 0 && i < towns.size()) + sin >> towns[i]->item_taken; + } else if(cur == "TOWNVISIBLE") { + int i; + sin >> i; + if(i >= 0 && i < towns.size()) + towns[i]->can_find = true; + } else if(cur == "TOWNHIDDEN") { + int i; + sin >> i; + if(i >= 0 && i < towns.size()) + towns[i]->can_find = false; + } else if(cur == "TOWNSLAUGHTER"){ + int i; + sin >> i; + if(i >= 0 && i < towns.size()) + sin >> towns[i]->m_killed; + } + } +} diff --git a/src/scenario/scenario.hpp b/src/scenario/scenario.hpp index a34e101f..a141c813 100644 --- a/src/scenario/scenario.hpp +++ b/src/scenario/scenario.hpp @@ -97,6 +97,7 @@ public: void import_legacy(legacy::scenario_data_type& old); void import_legacy(legacy::scen_item_data_type& old); void writeTo(std::ostream& file) const; + void readFrom(std::istream& file); std::string format_scen_version(); std::string format_ed_version(); diff --git a/src/scenario/town.hpp b/src/scenario/town.hpp index be754ee4..cdcd9970 100644 --- a/src/scenario/town.hpp +++ b/src/scenario/town.hpp @@ -41,7 +41,7 @@ enum eLighting { class cScenario; class cTown : public cArea { // formerly town_record_type - friend class cParty; // so the read/save functions can access item_taken directly + friend class cScenario; // so the read/save functions can access item_taken directly protected: cScenario* scenario; public: diff --git a/src/universe/party.cpp b/src/universe/party.cpp index f8b54003..0b138864 100644 --- a/src/universe/party.cpp +++ b/src/universe/party.cpp @@ -669,7 +669,7 @@ bool cParty::start_timer(short time, short node, short type){ return(true); } -void cParty::writeTo(std::ostream& file, const cScenario& scen) const { +void cParty::writeTo(std::ostream& file) const { file << "CREATEVERSION " << std::hex << OBOE_CURRENT_VERSION << std::dec << '\n'; file << "AGE " << age << '\n'; file << "GOLD " << gold << '\n'; @@ -717,15 +717,6 @@ void cParty::writeTo(std::ostream& file, const cScenario& scen) const { for(int i = 0; i < alchemy.size(); i++) if(alchemy[i]) file << "ALCHEMY " << i << '\n'; - for(int i = 0; i < scen.towns.size(); i++) { - if(scen.towns[i]->item_taken.any()) - file << "ITEMTAKEN " << i << ' ' << scen.towns[i]->item_taken << '\n'; - if(scen.towns[i]->can_find) - file << "TOWNVISIBLE " << i << '\n'; - else file << "TOWNHIDDEN " << i << '\n'; - if(scen.towns[i]->m_killed > 0) - file << "TOWNSLAUGHTER " << i << ' ' << scen.towns[i]->m_killed << '\n'; - } for(auto key : key_times) file << "EVENT " << key.first << ' ' << key.second << '\n'; for(int i : spec_items) @@ -854,7 +845,7 @@ void cParty::writeTo(std::ostream& file, const cScenario& scen) const { } } -void cParty::readFrom(std::istream& file, cScenario& scen){ +void cParty::readFrom(std::istream& file){ // TODO: Error-check input // TODO: Don't call this sin, it's a trig function std::istringstream bin; @@ -910,11 +901,6 @@ void cParty::readFrom(std::istream& file, cScenario& scen){ int n; sin >> stat >> n; status[stat] = n; - }else if(cur == "ITEMTAKEN"){ - int i; - sin >> i; - if(i >= 0 && i < scen.towns.size()) - sin >> scen.towns[i]->item_taken; }else if(cur == "LIGHT") sin >> light_level; else if(cur == "OUTCORNER") @@ -960,16 +946,6 @@ void cParty::readFrom(std::istream& file, cScenario& scen){ if(i < 0 || i >= creature_save.size()) continue; sin >> creature_save[i].which_town >> str; creature_save[i].hostile = str == "HOSTILE"; - } else if(cur == "TOWNVISIBLE") { - int i; - sin >> i; - if(i >= 0 && i < scen.towns.size()) - scen.towns[i]->can_find = true; - } else if(cur == "TOWNHIDDEN") { - int i; - sin >> i; - if(i >= 0 && i < scen.towns.size()) - scen.towns[i]->can_find = false; }else if(cur == "EVENT"){ int i; sin >> i; @@ -978,11 +954,6 @@ void cParty::readFrom(std::istream& file, cScenario& scen){ int i; sin >> i; spec_items.insert(i); - }else if(cur == "TOWNSLAUGHTER"){ - int i; - sin >> i; - if(i >= 0 && i < scen.towns.size()) - sin >> scen.towns[i]->m_killed; } else if(cur == "QUEST") { int i; sin >> i; diff --git a/src/universe/party.hpp b/src/universe/party.hpp index 2e940af3..819435db 100644 --- a/src/universe/party.hpp +++ b/src/universe/party.hpp @@ -189,8 +189,8 @@ public: bool start_timer(short time, short node, short type); cPlayer& operator[](unsigned short n); const cPlayer& operator[](unsigned short n) const; - void writeTo(std::ostream& file, const cScenario& scen) const; - void readFrom(std::istream& file, cScenario& scen); + void writeTo(std::ostream& file) const; + void readFrom(std::istream& file); bool give_item(cItem item,int flags); bool forced_give(cItem item,eItemAbil abil,short dat = -1);