undo/redo for editing/clearing monster types

This commit is contained in:
2025-06-05 11:30:27 -05:00
parent 721cc3ab6c
commit 2c3751284d
7 changed files with 201 additions and 7 deletions

View File

@@ -1320,8 +1320,12 @@ static bool handle_terpal_action(location cur_point, bool option_hit) {
// option-click type that can't be deleted (because it would break other types' numbers, or is in use somewhere):
// reset type info
else{
scenario.scen_monsters[i] = cMonster();
scenario.scen_monsters[i].m_name = "Unused Monster";
cMonster before = scenario.scen_monsters[i];
cMonster after;
after.m_name = "Unused Monster";
scenario.scen_monsters[i] = after;
undo_list.add(action_ptr(new aEditClearMonster("Clear Monster Type", i, before, after)));
update_edit_menu();
}
break;
case DRAW_ITEM:

View File

@@ -823,28 +823,63 @@ static bool save_monst_info(cDialog& me, cMonster& monst) {
static bool edit_monst_type_event_filter(cDialog& me,std::string hit,cMonster& monst,short& which) {
short i;
short which_before = which;
cMonster temp_monst;
bool commit_changes = false;
if(hit == "okay") {
if(save_monst_info(me,monst)) {
scenario.scen_monsters[which] = monst;
if(monst != scenario.scen_monsters[which]){
commit_changes = true;
}
me.toast(true);
}
} else if(hit == "abils") {
if(!save_monst_info(me,monst)) return false;
temp_monst = edit_monst_abil(monst,which,me);
if(temp_monst.level < 255)
bool abil_changed = (temp_monst != monst);
// Canceling the monster abilities editor sets the temp monster level to 255 as a flag.
// This should be fine unless we ever increase the max monster level (40) by a LOT.
if(abil_changed && temp_monst.level < 255){
monst = temp_monst;
put_monst_info_in_dlog(me,monst,which);
put_monst_info_in_dlog(me,monst,which);
// TODO should probably show in the monster editor that there are now unsaved ability changes.
}
} else if(hit == "left") {
if(!save_monst_info(me,monst)) return false;
scenario.scen_monsters[which] = monst;
// TODO run focus handlers!
if(monst != scenario.scen_monsters[which]){
// Confirm keeping changes
cChoiceDlog dlog("confirm-edit-monst", {"keep","revert","cancel"}, &me);
dlog->getControl("keep-msg").replaceText("{{monst}}", monst.m_name);
std::string choice = dlog.show();
if(choice == "keep"){
commit_changes = true;
}else if(choice == "cancel"){
return true;
}
}
which--;
if(which < 1) which = scenario.scen_monsters.size() - 1;
monst = scenario.scen_monsters[which];
put_monst_info_in_dlog(me,monst,which);
} else if(hit == "right") {
if(!save_monst_info(me,monst)) return false;
// TODO run focus handlers!
if(monst != scenario.scen_monsters[which]){
// Confirm keeping changes
cChoiceDlog dlog("confirm-edit-monst", {"keep","revert","cancel"}, &me);
dlog->getControl("keep-msg").replaceText("{{monst}}", monst.m_name);
std::string choice = dlog.show();
if(choice == "keep"){
commit_changes = true;
}else if(choice == "cancel"){
return true;
}
}
scenario.scen_monsters[which] = monst;
which++;
if(which >= scenario.scen_monsters.size()) which = 1;
@@ -891,6 +926,13 @@ static bool edit_monst_type_event_filter(cDialog& me,std::string hit,cMonster& m
put_monst_info(monstInfo, monst, scenario);
monstInfo.run();
}
if(commit_changes){
undo_list.add(action_ptr(new aEditClearMonster("Edit Monster Type", which_before, scenario.scen_monsters[which_before], monst)));
update_edit_menu();
scenario.scen_monsters[which_before] = monst;
}
return true;
}

View File

@@ -122,6 +122,18 @@ bool aEditClearTerrain::redo_me() {
return true;
}
bool aEditClearMonster::undo_me() {
// TODO show the type
scenario.scen_monsters[which] = before;
return true;
}
bool aEditClearMonster::redo_me() {
// TODO show the type
scenario.scen_monsters[which] = after;
return true;
}
bool aCreateDeleteMonster::undo_me() {
// TODO if not in MODE_EDIT_TYPES, show it
for(cMonster monst : monsters){

View File

@@ -157,4 +157,16 @@ public:
cAction(name), which(which), before(before), after(after) {}
};
/// Action which edits or clears a monster type
class aEditClearMonster : public cAction {
mon_num_t which;
cMonster before;
cMonster after;
bool undo_me() override;
bool redo_me() override;
public:
aEditClearMonster(std::string name, mon_num_t which, cMonster before, cMonster after) :
cAction(name), which(which), before(before), after(after) {}
};
#endif