undo/redo for scenario details, without changing cScenario
This commit is contained in:
@@ -182,4 +182,53 @@ 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.
|
||||
// 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 code, making them more verbose. I don't know
|
||||
// if that's worth it.
|
||||
struct scenario_details_t {
|
||||
unsigned short difficulty;
|
||||
eContentRating rating;
|
||||
std::string scen_name;
|
||||
unsigned char ver[3];
|
||||
std::string teaser_text[2];
|
||||
std::string contact_info[2];
|
||||
bool operator==(const scenario_details_t& other) const {
|
||||
CHECK_EQ(other, difficulty);
|
||||
CHECK_EQ(other, rating);
|
||||
CHECK_EQ(other, scen_name);
|
||||
for(short i = 0; i < 3; i++)
|
||||
if(this->ver[i] != other.ver[i]) return false;
|
||||
for(short i = 0; i < 2; i++)
|
||||
if(this->teaser_text[i] != other.teaser_text[i]) return false;
|
||||
for(short i = 0; i < 2; i++)
|
||||
if(this->contact_info[i] != other.contact_info[i]) return false;
|
||||
return true;
|
||||
}
|
||||
bool operator!=(const scenario_details_t& other) const { return !(*this == other); }
|
||||
};
|
||||
|
||||
inline scenario_details_t details_from_scen(cScenario& scen) {
|
||||
return {
|
||||
scen.difficulty,
|
||||
scen.rating,
|
||||
scen.scen_name,
|
||||
scen.format.ver[0],scen.format.ver[1],scen.format.ver[2],
|
||||
scen.teaser_text[0],scen.teaser_text[1],
|
||||
scen.contact_info[0],scen.contact_info[1],
|
||||
};
|
||||
}
|
||||
|
||||
inline void scen_set_details(cScenario& scen, scenario_details_t details) {
|
||||
scen.difficulty = details.difficulty;
|
||||
scen.rating = details.rating;
|
||||
scen.scen_name = details.scen_name;
|
||||
for(short i = 0; i < 3; i++)
|
||||
scen.format.ver[i] = details.ver[i];
|
||||
for(short i = 0; i < 2; i++)
|
||||
scen.teaser_text[i] = details.teaser_text[i];
|
||||
for(short i = 0; i < 2; i++)
|
||||
scen.contact_info[i] = details.contact_info[i];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -3061,25 +3061,35 @@ void edit_item_placement() {
|
||||
static bool save_scen_details(cDialog& me, std::string, eKeyMod) {
|
||||
if(!me.toast(true)) return true;
|
||||
|
||||
scenario_details_t old_details = details_from_scen(scenario);
|
||||
scenario_details_t new_details;
|
||||
|
||||
{
|
||||
cLedGroup& difficulty = dynamic_cast<cLedGroup&>(me["difficulty"]);
|
||||
scenario.difficulty = difficulty.getSelected()[3] - '1';
|
||||
new_details.difficulty = difficulty.getSelected()[3] - '1';
|
||||
}{
|
||||
cLedGroup& rating = dynamic_cast<cLedGroup&>(me["rating"]);
|
||||
switch(rating.getSelected()[4]) {
|
||||
case '1': scenario.rating = eContentRating::G; break;
|
||||
case '2': scenario.rating = eContentRating::PG; break;
|
||||
case '3': scenario.rating = eContentRating::R; break;
|
||||
case '4': scenario.rating = eContentRating::NC17; break;
|
||||
case '1': new_details.rating = eContentRating::G; break;
|
||||
case '2': new_details.rating = eContentRating::PG; break;
|
||||
case '3': new_details.rating = eContentRating::R; break;
|
||||
case '4': new_details.rating = eContentRating::NC17; break;
|
||||
}
|
||||
}
|
||||
scenario.scen_name = me["title"].getText();
|
||||
new_details.scen_name = me["title"].getText();
|
||||
for(short i = 0; i < 3; i++)
|
||||
scenario.format.ver[i] = me["ver" + std::to_string(i + 1)].getTextAsNum();
|
||||
scenario.teaser_text[0] = me["teaser1"].getText();
|
||||
scenario.teaser_text[1] = me["teaser2"].getText();
|
||||
scenario.contact_info[0] = me["author"].getText();
|
||||
scenario.contact_info[1] = me["contact"].getText();
|
||||
new_details.ver[i] = me["ver" + std::to_string(i + 1)].getTextAsNum();
|
||||
new_details.teaser_text[0] = me["teaser1"].getText();
|
||||
new_details.teaser_text[1] = me["teaser2"].getText();
|
||||
new_details.contact_info[0] = me["author"].getText();
|
||||
new_details.contact_info[1] = me["contact"].getText();
|
||||
|
||||
if(new_details != old_details){
|
||||
scen_set_details(scenario, new_details);
|
||||
undo_list.add(action_ptr(new aEditScenarioDetails(old_details, new_details)));
|
||||
update_edit_menu();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -858,4 +858,14 @@ bool aReplaceSound::undo_me() {
|
||||
bool aReplaceSound::redo_me() {
|
||||
ResMgr::sounds.free(sound_to_fname(index));
|
||||
return new_sound.saveToFile(get_snd_path(index).string());
|
||||
}
|
||||
|
||||
bool aEditScenarioDetails::undo_me() {
|
||||
scen_set_details(scenario, old_details);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aEditScenarioDetails::redo_me() {
|
||||
scen_set_details(scenario, new_details);
|
||||
return true;
|
||||
}
|
@@ -512,4 +512,14 @@ public:
|
||||
index(index), old_sound(old_sound), new_sound(new_sound) {}
|
||||
};
|
||||
|
||||
class aEditScenarioDetails : public cAction {
|
||||
scenario_details_t old_details;
|
||||
scenario_details_t new_details;
|
||||
bool undo_me() override;
|
||||
bool redo_me() override;
|
||||
public:
|
||||
aEditScenarioDetails(scenario_details_t old_details, scenario_details_t new_details) :
|
||||
cAction("Edit Scenario Details"), old_details(old_details), new_details(new_details) {}
|
||||
};
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user