diff --git a/src/scenario/scenario.hpp b/src/scenario/scenario.hpp index f444c361..b61ca6ef 100644 --- a/src/scenario/scenario.hpp +++ b/src/scenario/scenario.hpp @@ -185,7 +185,7 @@ public: std::istream& operator>> (std::istream& in, eContentRating& rating); std::ostream& operator<< (std::ostream& out, eContentRating rating); -// Store a version the scenario details for undo history. +// Store a version of the scenario details for undo history. // This could be made a struct that cScenario contains, and that would eliminate the next 2 functions, but it would // require changing every reference to these detail values in the game and fileio code, making them more verbose. I don't know // if that's worth it. @@ -234,7 +234,7 @@ inline void scen_set_details(cScenario& scen, const scen_details_t& details) { scen.contact_info[i] = details.contact_info[i]; } -// Store a version the scenario intro text/icon# for undo history. +// Store a version of the scenario intro text/icon# for undo history. // This could be made a struct that cScenario contains, and that would eliminate the next 2 functions, but it would // require changing every reference to these detail values in the game and fileio code, making them more verbose. I don't know // if that's worth it. @@ -260,7 +260,7 @@ inline void scen_set_intro(cScenario& scen, const scen_intro_t& details) { scen.intro_strs = details.intro_strs; } -// Store a version the scenario advanced details for undo history. +// Store a version of the scenario advanced details for undo history. // This could be made a struct that cScenario contains, and that would eliminate the next 2 functions, but it would // require changing every reference to these detail values in the game and fileio code, making them more verbose. I don't know // if that's worth it. diff --git a/src/scenario/town.hpp b/src/scenario/town.hpp index 6c42f744..5bbd9455 100644 --- a/src/scenario/town.hpp +++ b/src/scenario/town.hpp @@ -132,4 +132,53 @@ public: std::ostream& operator<< (std::ostream& out, eLighting light); std::istream& operator>> (std::istream& in, eLighting& light); +// Store a version of the town details for undo history. +// This could be made a struct that cTown contains, and that would eliminate the next 2 functions, but it would +// require changing every reference to these detail values in the game and fileio code, making them more verbose. I don't know +// if that's worth it. +struct town_details_t { + std::string name; + short town_chop_time; + short town_chop_key; + long max_num_monst; + short difficulty; + eLighting lighting_type; + std::array comment; + + bool operator==(const town_details_t& other) const { + CHECK_EQ(other,name); + CHECK_EQ(other,town_chop_key); + CHECK_EQ(other,max_num_monst); + CHECK_EQ(other,difficulty); + CHECK_EQ(other,lighting_type); + for(int i = 0; i < comment.size(); ++i){ + if(other.comment[i] != comment[i]) return false; + } + return true; + } + bool operator!=(const town_details_t& other) const { return !(*this == other); } +}; + +inline town_details_t details_from_town(cTown& town) { + return { + town.name, + town.town_chop_time, + town.town_chop_key, + town.max_num_monst, + town.difficulty, + town.lighting_type, + town.comment + }; +} + +inline void town_set_details(cTown& town, const town_details_t& details) { + town.name = details.name; + town.town_chop_time = details.town_chop_time; + town.town_chop_key = details.town_chop_key; + town.max_num_monst = details.max_num_monst; + town.difficulty = details.difficulty; + town.lighting_type = details.lighting_type; + town.comment = details.comment; +} + #endif diff --git a/src/scenedit/scen.townout.cpp b/src/scenedit/scen.townout.cpp index 7ddf07c3..43c9469e 100644 --- a/src/scenedit/scen.townout.cpp +++ b/src/scenedit/scen.townout.cpp @@ -752,20 +752,29 @@ void edit_out_wand(short mode) { static bool save_town_details(cDialog& me, std::string, eKeyMod) { if(!me.toast(true)) return true; - town->name = me["name"].getText(); - town->town_chop_time = me["chop"].getTextAsNum(); - town->town_chop_key = me["key"].getTextAsNum(); - town->max_num_monst = me["population"].getTextAsNum(); - town->difficulty = me["difficulty"].getTextAsNum(); + town_details_t old_details = details_from_town(*town); + town_details_t new_details = old_details; + + new_details.name = me["name"].getText(); + new_details.town_chop_time = me["chop"].getTextAsNum(); + new_details.town_chop_key = me["key"].getTextAsNum(); + new_details.max_num_monst = me["population"].getTextAsNum(); + new_details.difficulty = me["difficulty"].getTextAsNum(); std::string lighting = dynamic_cast(me["lighting"]).getSelected(); - if(lighting == "lit") town->lighting_type = LIGHT_NORMAL; - else if(lighting == "dark") town->lighting_type = LIGHT_DARK; - else if(lighting == "drains") town->lighting_type = LIGHT_DRAINS; - else if(lighting == "no-light") town->lighting_type = LIGHT_NONE; + if(lighting == "lit") new_details.lighting_type = LIGHT_NORMAL; + else if(lighting == "dark") new_details.lighting_type = LIGHT_DARK; + else if(lighting == "drains") new_details.lighting_type = LIGHT_DRAINS; + else if(lighting == "no-light") new_details.lighting_type = LIGHT_NONE; cStack& comments = dynamic_cast(me["cmt"]); for(int i = 0; i < 3; i++) { comments.setPage(i); - town->comment[i] = comments["comment"].getText(); + new_details.comment[i] = comments["comment"].getText(); + } + + if(new_details != old_details){ + town_set_details(*town, new_details); + undo_list.add(action_ptr(new aEditTownDetails(cur_town, old_details, new_details))); + update_edit_menu(); } return true; } diff --git a/src/scenedit/scen.undo.cpp b/src/scenedit/scen.undo.cpp index c4a52b53..a1db6a46 100644 --- a/src/scenedit/scen.undo.cpp +++ b/src/scenedit/scen.undo.cpp @@ -928,4 +928,14 @@ bool aEditItemShortcut::undo_me() { bool aEditItemShortcut::redo_me() { scenario.storage_shortcuts[which] = new_shortcut; return true; +} + +bool aEditTownDetails::undo_me() { + town_set_details(*scenario.towns[which], old_details); + return true; +} + +bool aEditTownDetails::redo_me() { + town_set_details(*scenario.towns[which], new_details); + return true; } \ No newline at end of file diff --git a/src/scenedit/scen.undo.hpp b/src/scenedit/scen.undo.hpp index 99b9051c..0395daa9 100644 --- a/src/scenedit/scen.undo.hpp +++ b/src/scenedit/scen.undo.hpp @@ -583,4 +583,15 @@ public: cAction("Edit Item Placement Shortcut"), which(which), old_shortcut(old_shortcut), new_shortcut(new_shortcut) {} }; +class aEditTownDetails : public cAction { + size_t which; + town_details_t old_details; + town_details_t new_details; + bool undo_me() override; + bool redo_me() override; +public: + aEditTownDetails(size_t which, town_details_t old_details, town_details_t new_details) : + cAction("Edit Town Details"), which(which), old_details(old_details), new_details(new_details) {} +}; + #endif \ No newline at end of file