Fix improper loading order with saved games

This commit is contained in:
2020-01-02 00:28:52 -05:00
parent b6aee36a0c
commit 479cfb75f6
6 changed files with 66 additions and 36 deletions

View File

@@ -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;

View File

@@ -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;
}
}
}

View File

@@ -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();

View File

@@ -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:

View File

@@ -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;

View File

@@ -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);