undo/redo for placing and pasting specials

This commit is contained in:
2025-06-14 19:56:50 -05:00
parent eab83c2112
commit a3a10ca6e4
4 changed files with 25 additions and 12 deletions

View File

@@ -945,6 +945,8 @@ static bool handle_terrain_action(location the_point, bool ctrl_hit) {
if(specials[x].spec < 0) {
specials[x] = spot_hit;
specials[x].spec = spec->first;
undo_list.add(action_ptr(new aPlaceEraseSpecial("Paste Special Encounter", true, specials[x])));
update_edit_menu();
break;
}
}
@@ -1141,7 +1143,7 @@ static bool handle_terrain_action(location the_point, bool ctrl_hit) {
specials.pop_back();
} while(!specials.empty() && specials.back().spec < 0);
}
undo_action.reset(new aEraseSpecial(for_redo));
undo_action.reset(new aPlaceEraseSpecial("Erase Special", false, for_redo));
break;
}
overall_mode = MODE_DRAWING;
@@ -2774,6 +2776,7 @@ void place_edit_special(location loc) {
for(short i = 0; i < specials.size(); i++)
if(specials[i] == loc && specials[i].spec >= 0) {
edit_spec_enc(specials[i].spec, editing_town ? 2 : 1, nullptr);
// TODO add the edit specials actions
return;
}
// new special
@@ -2785,6 +2788,9 @@ void place_edit_special(location loc) {
if(edit_spec_enc(spec, editing_town ? 2: 1, nullptr)) {
specials[i] = loc;
specials[i].spec = spec;
undo_list.add(action_ptr(new aPlaceEraseSpecial("Place Special Encounter", true, specials[i])));
// TODO add the edit specials actions
update_edit_menu();
}
break;
}
@@ -2813,6 +2819,9 @@ void set_special(location spot_hit) {
if(spec >= 0) {
specials[x] = spot_hit;
specials[x].spec = spec;
undo_list.add(action_ptr(new aPlaceEraseSpecial("Place Special Encounter", true, specials[x])));
// TODO if create/edit was used, add those actions
update_edit_menu();
}
break;
}

View File

@@ -1380,6 +1380,7 @@ static bool edit_spec_enc_value(cDialog& me, std::string item_hit, node_stack_t&
}
// mode - 0 scen 1 - out 2 - town
// TODO collect a list of undo actions that can be committed to undo_list by the calling code
bool edit_spec_enc(short which_node,short mode,cDialog* parent) {
using namespace std::placeholders;
cSpecial the_node;
@@ -1653,7 +1654,7 @@ static bool edit_special_num_event_filter(cDialog& me, std::string item_hit, sho
short edit_special_num(short mode,short what_start) {
using namespace std::placeholders;
size_t num_specs = 0;
short num_specs = 0;
switch(mode) {
case 0: num_specs = scenario.scen_specials.size(); break;
case 1: num_specs = current_terrain->specials.size(); break;

View File

@@ -76,18 +76,19 @@ void cTerrainAction::redo() {
// Undo/Redo implementations for actions:
bool aEraseSpecial::undo_me() {
bool aPlaceEraseSpecial::undo_me() {
cArea* cur_area = get_current_area();
auto& specials = cur_area->special_locs;
specials.erase(std::remove(specials.begin(), specials.end(), for_redo));
return true;
}
bool aPlaceEraseSpecial::redo_me() {
cArea* cur_area = get_current_area();
auto& specials = cur_area->special_locs;
specials.push_back(for_redo);
return true;
}
bool aEraseSpecial::redo_me() {
cArea* cur_area = get_current_area();
auto& specials = cur_area->special_locs;
specials.pop_back();
return true;
}
aCreateDeleteTown::aCreateDeleteTown(bool create, cTown* t)
: cAction(create ? "Create Town" : "Delete Last Town", !create)

View File

@@ -63,10 +63,12 @@ public:
old_property(old_property) {}
};
/// Action that erased a special encounter from a spot
class aEraseSpecial : public cTerrainAction {
/// Action that places or erases a special encounter from a spot
class aPlaceEraseSpecial : public cTerrainAction {
public:
aEraseSpecial(spec_loc_t special) : cTerrainAction("Erase Special Encounter", special), for_redo(special) {}
aPlaceEraseSpecial(std::string name, bool place, spec_loc_t special) :
cTerrainAction(name, special, !place),
for_redo(special) {}
bool undo_me() override;
bool redo_me() override;
private: