Skip to content

Commit 8b3dac7

Browse files
committed
Write editor state to a new, separate xml file (fix #728)
1 parent 40ba853 commit 8b3dac7

File tree

6 files changed

+56
-11
lines changed

6 files changed

+56
-11
lines changed

src/fileio/fileio_scen.cpp

+34-3
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ static bool load_scenario_v2(fs::path file_to_load, cScenario& scenario, eLoadSc
4949
// Some of these are non-static so that the test cases can access them.
5050
ticpp::Document xmlDocFromStream(std::istream& stream, std::string name);
5151
void readScenarioFromXml(ticpp::Document&& data, cScenario& scenario);
52+
void readEditorStateFromXml(ticpp::Document&& data, cScenario& scenario);
5253
void readTerrainFromXml(ticpp::Document&& data, cScenario& scenario);
5354
void readItemsFromXml(ticpp::Document&& data, cScenario& scenario);
5455
void readMonstersFromXml(ticpp::Document&& data, cScenario& scenario);
@@ -932,19 +933,22 @@ void readScenarioFromXml(ticpp::Document&& data, cScenario& scenario) {
932933
if(!reqs.empty())
933934
throw xMissingElem("game", *reqs.begin(), elem->Row(), elem->Column(), fname);
934935
} else if(type == "editor") {
935-
std::set<std::string> reqs = {"default-ground", "last-out-section", "last-town"};
936+
std::set<std::string> reqs = {"default-ground"};
936937
Iterator<Element> edit;
937938
int num_storage = 0, num_pics = 0;
938939
for(edit = edit.begin(elem.Get()); edit != edit.end(); edit++) {
939940
edit->GetValue(&type);
940941
reqs.erase(type);
941942
if(type == "default-ground") {
942943
edit->GetText(&scenario.default_ground);
943-
} else if(type == "last-out-section") {
944+
}
945+
// Old scenario files may have last-out-section and last-town in scenario.xml
946+
else if(type == "last-out-section") {
944947
scenario.last_out_edited = readLocFromXml(*edit);
945948
} else if(type == "last-town") {
946949
edit->GetText(&scenario.last_town_edited);
947-
} else if(type == "sound") {
950+
}
951+
else if(type == "sound") {
948952
int sndnum = 0;
949953
edit->GetAttribute("id", &sndnum);
950954
if(sndnum < 100)
@@ -1066,6 +1070,23 @@ void readScenarioFromXml(ticpp::Document&& data, cScenario& scenario) {
10661070
throw xMissingElem("scenario", *reqs.begin(), data.FirstChildElement()->Row(), data.FirstChildElement()->Column(), fname);
10671071
}
10681072

1073+
void readEditorStateFromXml(ticpp::Document&& data, cScenario& scenario) {
1074+
using namespace ticpp;
1075+
int maj, min, rev;
1076+
std::string fname, type, name, val;
1077+
initialXmlRead(data, "editor", maj, min, rev, fname);
1078+
Iterator<Attribute> attr;
1079+
Iterator<Element> elem;
1080+
for(elem = elem.begin(data.FirstChildElement()); elem != elem.end(); elem++) {
1081+
elem->GetValue(&type);
1082+
if(type == "last-out-section") {
1083+
scenario.last_out_edited = readLocFromXml(*elem);
1084+
} else if(type == "last-town") {
1085+
elem->GetText(&scenario.last_town_edited);
1086+
}
1087+
}
1088+
}
1089+
10691090
void readTerrainFromXml(ticpp::Document&& data, cScenario& scenario) {
10701091
using namespace ticpp;
10711092
int maj, min, rev;
@@ -2187,6 +2208,10 @@ bool load_scenario_v2(fs::path file_to_load, cScenario& scenario, eLoadScenario
21872208
return false;
21882209
}
21892210
}
2211+
auto hasFile = [&](std::string relpath) -> bool {
2212+
if(is_packed) return pack.hasFile("scenario/" + relpath);
2213+
return fs::exists(file_to_load/relpath);
2214+
};
21902215
auto getFile = [&](std::string relpath) -> std::istream& {
21912216
if(is_packed) return pack.getFile("scenario/" + relpath);
21922217
if(fin.is_open()) fin.close();
@@ -2217,6 +2242,12 @@ bool load_scenario_v2(fs::path file_to_load, cScenario& scenario, eLoadScenario
22172242

22182243
if(load_type == eLoadScenario::ONLY_HEADER) return true;
22192244
if(load_type != eLoadScenario::SAVE_PREVIEW){
2245+
// Editor state, even though the game won't need it
2246+
if(hasFile("editor.xml")){
2247+
std::istream& editor = getFile("editor.xml");
2248+
readEditorStateFromXml(xmlDocFromStream(editor, "editor.xml"), scenario);
2249+
}
2250+
22202251
// Next, terrain types...
22212252
std::istream& terrain = getFile("terrain.xml");
22222253
readTerrainFromXml(xmlDocFromStream(terrain, "terrain.xml"), scenario);

src/scenedit/scen.actions.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -241,8 +241,7 @@ static bool handle_lb_action(location the_point) {
241241
case LB_LOAD_SCEN:
242242
file_to_load = nav_get_scenario();
243243
if(!file_to_load.empty() && load_scenario(file_to_load, scenario)) {
244-
set_current_town(scenario.last_town_edited);
245-
set_current_out(scenario.last_out_edited);
244+
restore_editor_state();
246245
} else if(!file_to_load.empty())
247246
// If we tried to load but failed, the scenario record is messed up, so boot to start screen.
248247
set_up_start_screen();
@@ -2881,3 +2880,8 @@ bool monst_on_space(location loc,short m_num) {
28812880
return false;
28822881

28832882
}
2883+
2884+
void restore_editor_state() {
2885+
set_current_town(scenario.last_town_edited);
2886+
set_current_out(scenario.last_out_edited);
2887+
}

src/scenedit/scen.actions.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "scen.global.hpp"
33
#include "tools/undo.hpp"
44

5+
void restore_editor_state();
56
void init_screen_locs();
67
void handle_action(location the_point,sf::Event event);
78
void flash_rect(rectangle to_flash);

src/scenedit/scen.appleevents.mm

+1-2
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,9 @@ -(BOOL)application:(NSApplication*) app openFile:(NSString*) file {
5151
std::copy(msg.get(), msg.get() + len, std::inserter(fileName, fileName.begin()));
5252

5353
if(load_scenario(fileName, scenario)) {
54-
set_current_town(scenario.last_town_edited);
54+
restore_editor_state();
5555
change_made = false;
5656
ae_loading = true;
57-
set_current_out(scenario.last_out_edited);
5857
}
5958
return TRUE;
6059
}

src/scenedit/scen.fileio.cpp

+13-2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ void load_spec_graphics();
4343

4444
// These aren't static solely so that the test cases can access them.
4545
void writeScenarioToXml(ticpp::Printer&& data, cScenario& scenario);
46+
void writeEditorStateToXml(ticpp::Printer&& data, cScenario& scenario);
4647
void writeTerrainToXml(ticpp::Printer&& data, cScenario& scenario);
4748
void writeItemsToXml(ticpp::Printer&& data, cScenario& scenario);
4849
void writeMonstersToXml(ticpp::Printer&& data, cScenario& scenario);
@@ -121,6 +122,14 @@ namespace ticpp {
121122
}
122123
}
123124

125+
void writeEditorStateToXml(ticpp::Printer&& data, cScenario& scenario) {
126+
data.OpenElement("editor");
127+
data.PushAttribute("boes", scenario.format_ed_version());
128+
data.PushElement("last-out-section", cur_out);
129+
data.PushElement("last-town", cur_town);
130+
data.CloseElement("editor");
131+
}
132+
124133
void writeScenarioToXml(ticpp::Printer&& data, cScenario& scenario) {
125134
data.OpenElement("scenario");
126135
data.PushAttribute("boes", scenario.format_ed_version());
@@ -357,8 +366,6 @@ void writeScenarioToXml(ticpp::Printer&& data, cScenario& scenario) {
357366
data.CloseElement("game");
358367
data.OpenElement("editor");
359368
data.PushElement("default-ground", scenario.default_ground);
360-
data.PushElement("last-out-section", cur_out);
361-
data.PushElement("last-town", cur_town);
362369
if(!scenario.custom_graphics.empty()) {
363370
data.OpenElement("graphics");
364371
for(size_t i = 0; i < scenario.custom_graphics.size(); i++) {
@@ -1075,6 +1082,10 @@ void save_scenario(bool rename) {
10751082
std::ostream& header = scen_file.newFile("scenario/header.exs");
10761083
header.write(reinterpret_cast<char*>(&scenario.format), sizeof(scenario_header_flags));
10771084

1085+
// Write scenario's editor state to a file that can be added to .gitignore
1086+
std::ostream& editor_data = scen_file.newFile("scenario/editor.xml");
1087+
writeEditorStateToXml(ticpp::Printer("scenario.xml", editor_data), scenario);
1088+
10781089
// Next, the bulk scenario data.
10791090
std::ostream& scen_data = scen_file.newFile("scenario/scenario.xml");
10801091
writeScenarioToXml(ticpp::Printer("scenario.xml", scen_data), scenario);

src/scenedit/scen.main.cpp

+1-2
Original file line numberDiff line numberDiff line change
@@ -301,10 +301,9 @@ static void process_args(int argc, char* argv[]) {
301301
}
302302
if(!file.empty()) {
303303
if(load_scenario(file, scenario)) {
304-
set_current_town(scenario.last_town_edited);
304+
restore_editor_state();
305305
change_made = false;
306306
ae_loading = true;
307-
set_current_out(scenario.last_out_edited);
308307
} else {
309308
std::cout << "Failed to load scenario: " << file << std::endl;
310309
}

0 commit comments

Comments
 (0)