undo/redo for outdoor encounters

This commit is contained in:
2025-06-19 21:22:13 -05:00
parent 855310c516
commit 00a1d8f889
6 changed files with 98 additions and 4 deletions

View File

@@ -647,7 +647,9 @@ static void put_out_wand_in_dlog(cDialog& me, short which, const cOutdoors::cWan
me["location"].setText(boost::lexical_cast<std::string>(current_terrain->wandering_locs[which]));
}
// mode 0 - wandering, 1 - special, 100 - do not commit changes to the scenario yet
static void save_out_wand(cDialog& me, short which, cOutdoors::cWandering& wand, short mode) {
cOutdoors::cWandering old_wand = (mode == 0 ? current_terrain->wandering[which] : current_terrain->special_enc[which]);
wand.spec_on_meet = me["onmeet"].getTextAsNum();
wand.spec_on_win = me["onwin"].getTextAsNum();
wand.spec_on_flee = me["onflee"].getTextAsNum();
@@ -658,19 +660,45 @@ static void save_out_wand(cDialog& me, short which, cOutdoors::cWandering& wand,
wand.cant_flee = dynamic_cast<cLed&>(me["no-flee"]).getState() != led_off;
switch(mode) {
case 0:
case 0:{
current_terrain->wandering[which] = wand;
current_terrain->wandering_locs[which] = boost::lexical_cast<location>(me["location"].getText());
break;
location old_loc = current_terrain->wandering_locs[which];
location new_loc = boost::lexical_cast<location>(me["location"].getText());
current_terrain->wandering_locs[which] = new_loc;
undo_list.add(action_ptr(new aEditOutEncounter(cur_out, which, old_wand, old_loc, wand, new_loc)));
}break;
case 1:
current_terrain->special_enc[which] = wand;
undo_list.add(action_ptr(new aEditOutEncounter(cur_out, which, old_wand, wand)));
break;
}
update_edit_menu();
}
static bool edit_out_wand_event_filter(cDialog& me, std::string hit, short& which, cOutdoors::cWandering& wand, short mode) {
if(!me.toast(true)) return true;
save_out_wand(me, which, wand, mode);
bool loc_changed = (mode == 0 && current_terrain->wandering_locs[which] != boost::lexical_cast<location>(me["location"].getText()));
cOutdoors::cWandering old_wand = (mode == 0 ? current_terrain->wandering[which] : current_terrain->special_enc[which]);
if((loc_changed || wand != old_wand)){
// Confirm before moving left/right and committing changes
if(hit == "left" || hit == "right"){
cChoiceDlog dlog("confirm-edit-out-wand", {"keep","revert","cancel"}, &me);
dlog->getControl("keep-msg").replaceText("{{enc-type}}", (mode == 0 ? "Wandering Monster Group" : "Special Encounter"));
dlog->getControl("keep-msg").replaceText("{{num}}", std::to_string(which));
std::string choice = dlog.show();
if(choice == "keep"){
save_out_wand(me, which, wand, mode);
}else if(choice == "cancel"){
return true;
}
}
// Okay pressed
else{
save_out_wand(me, which, wand, mode);
}
}
size_t num_enc = (mode == 0) ? current_terrain->wandering.size() : current_terrain->special_enc.size();
if(hit == "left") {
me.untoast();

View File

@@ -981,3 +981,19 @@ bool aEditOutDetails::redo_me() {
out_set_details(*scenario.outdoors[out_sec.x][out_sec.y], new_details);
return true;
}
bool aEditOutEncounter::undo_me() {
cOutdoors& outdoors = *scenario.outdoors[out_sec.x][out_sec.y];
auto& encounters = (mode == 0 ? outdoors.wandering : outdoors.special_enc);
encounters[which] = old_enc;
if(mode == 0) outdoors.wandering_locs[which] = old_loc;
return true;
}
bool aEditOutEncounter::redo_me() {
cOutdoors& outdoors = *scenario.outdoors[out_sec.x][out_sec.y];
auto& encounters = (mode == 0 ? outdoors.wandering : outdoors.special_enc);
encounters[which] = new_enc;
if(mode == 0) outdoors.wandering_locs[which] = new_loc;
return true;
}

View File

@@ -642,4 +642,24 @@ public:
cAction("Edit Outdoor Details"), out_sec(out_sec), old_details(old_details), new_details(new_details) {}
};
class aEditOutEncounter : public cAction {
location out_sec;
short mode;
size_t which;
cOutdoors::cWandering old_enc;
cOutdoors::cWandering new_enc;
// Ignored for special encounters:
location old_loc;
location new_loc;
bool undo_me() override;
bool redo_me() override;
public:
aEditOutEncounter(location out_sec, size_t which, cOutdoors::cWandering old_enc, location old_loc, cOutdoors::cWandering new_enc, location new_loc) :
cAction("Edit Outdoor Wandering Encounter"),
out_sec(out_sec), mode(0), which(which), old_enc(old_enc), old_loc(old_loc), new_enc(new_enc), new_loc(new_loc) {}
aEditOutEncounter(location out_sec, size_t which, cOutdoors::cWandering old_enc, cOutdoors::cWandering new_enc) :
cAction("Edit Outdoor Special Encounter"),
out_sec(out_sec), mode(1), which(which), old_enc(old_enc), new_enc(new_enc) {}
};
#endif