delete last town is just the inverse of create town

This commit is contained in:
2025-06-02 16:52:32 -05:00
parent 5452057b25
commit f4aa9780e0
6 changed files with 36 additions and 26 deletions

View File

@@ -8,12 +8,11 @@
<text top='6' left='49' width='271' height='66'> <text top='6' left='49' width='271' height='66'>
You are about to delete the last town in your scenario's town list You are about to delete the last town in your scenario's town list
(so if you have 10 towns in your scenario, the tenth will disappear). (so if you have 10 towns in your scenario, the tenth will disappear).
This change will immediately be saved, and can't be undone.
</text> </text>
<text top='127' left='49' width='268' height='14'>Are you sure you want to do this?</text>
<text top='73' left='49' width='276' height='53'> <text top='73' left='49' width='276' height='53'>
Make sure to remove all outdoor entrances to the deleted town, Make sure to remove all outdoor entrances to the deleted town,
as well as all references to it in special encounters. as well as all references to it in special encounters.
Failure to do so will result in scenario run-time errors. Failure to do so will result in scenario run-time errors.
</text> </text>
<text top='127' left='49' width='268' height='14'>Are you sure you want to do this?</text>
</dialog> </dialog>

View File

@@ -48,6 +48,7 @@ extern cUndoList undo_list;
extern std::string help_text_rsrc; extern std::string help_text_rsrc;
extern bool editing_town; extern bool editing_town;
extern bool last_shift_continuous; extern bool last_shift_continuous;
extern void update_edit_menu();
const char *day_str_1[] = {"Unused","Day creature appears","Day creature disappears", const char *day_str_1[] = {"Unused","Day creature appears","Day creature disappears",
"Unused","Unused","Unused","Unused","Unused","Unused"}; "Unused","Unused","Unused","Unused","Unused","Unused"};
@@ -1671,7 +1672,8 @@ bool new_town() {
for(short j = 0; j < town->max_dim; j++) for(short j = 0; j < town->max_dim; j++)
town->terrain(i,j) = preset; town->terrain(i,j) = preset;
undo_list.add(action_ptr(new aNewTown(scenario.towns.back()))); undo_list.add(action_ptr(new aCreateDeleteTown(true, scenario.towns.back())));
update_edit_menu();
change_made = true; change_made = true;
return true; return true;
@@ -1679,9 +1681,10 @@ bool new_town() {
// before calling this, be sure to do all checks to make sure it's safe. // before calling this, be sure to do all checks to make sure it's safe.
void delete_last_town() { void delete_last_town() {
cTown* last_town = scenario.towns.back(); undo_list.add(action_ptr(new aCreateDeleteTown(false, scenario.towns.back())));
update_edit_menu();
scenario.towns.pop_back(); scenario.towns.pop_back();
delete last_town;
change_made = true; change_made = true;
} }

View File

@@ -14,6 +14,7 @@ extern cArea* get_current_area();
extern void start_town_edit(); extern void start_town_edit();
extern void start_out_edit(); extern void start_out_edit();
extern void redraw_screen(); extern void redraw_screen();
extern void set_current_town(int,bool first_restore = false);
cTerrainAction::cTerrainAction(std::string name, short town_num, location where) : cAction(name) { cTerrainAction::cTerrainAction(std::string name, short town_num, location where) : cAction(name) {
area.is_town = true; area.is_town = true;
@@ -72,24 +73,25 @@ bool aEraseSpecial::redo_me() {
return true; return true;
} }
aNewTown::aNewTown(cTown* t) aCreateDeleteTown::aCreateDeleteTown(bool create, cTown* t)
: cAction("Add Town") : cAction(create ? "Create Town" : "Delete Last Town", !create)
, theTown(t) , theTown(t)
{} {}
bool aNewTown::undo_me() { bool aCreateDeleteTown::undo_me() {
scenario.towns.resize(scenario.towns.size() - 1); scenario.towns.resize(scenario.towns.size() - 1);
cur_town = min(cur_town, scenario.towns.size() - 1); set_current_town(min(cur_town, scenario.towns.size() - 1));
return true; return true;
} }
bool aNewTown::redo_me() { bool aCreateDeleteTown::redo_me() {
scenario.towns.push_back(theTown); scenario.towns.push_back(theTown);
set_current_town(scenario.towns.size() - 1);
return true; return true;
} }
aNewTown::~aNewTown() { aCreateDeleteTown::~aCreateDeleteTown() {
if(!isDone()) delete theTown; if(isDone() == reversed) delete theTown;
} }
bool aDrawTerrain::undo_me() { bool aDrawTerrain::undo_me() {

View File

@@ -19,7 +19,7 @@ struct ter_change_t {
typedef std::map<location,ter_change_t,loc_compare> stroke_ter_changes_t; typedef std::map<location,ter_change_t,loc_compare> stroke_ter_changes_t;
// Action that modified town or outdoor terrain, so we should show the modified area when undoing or redoing // Action that modified something in town or outdoor terrain, so we should show the modified area when undoing or redoing
class cTerrainAction : public cAction { class cTerrainAction : public cAction {
public: public:
cTerrainAction(std::string name, short town_num, location where); cTerrainAction(std::string name, short town_num, location where);
@@ -35,16 +35,7 @@ private:
area_ref_t area; area_ref_t area;
}; };
/// Represents the action of adding a new town to the end of the list /// Action that erased a special encounter from a spot
class aNewTown : public cAction {
class cTown* theTown;
bool undo_me() override;
bool redo_me() override;
public:
aNewTown(class cTown* t);
~aNewTown();
};
class aEraseSpecial : public cTerrainAction { class aEraseSpecial : public cTerrainAction {
public: public:
aEraseSpecial(spec_loc_t special) : cTerrainAction("Erase Special Encounter", special), for_redo(special) {} aEraseSpecial(spec_loc_t special) : cTerrainAction("Erase Special Encounter", special), for_redo(special) {}
@@ -55,6 +46,7 @@ private:
bool editing_town; bool editing_town;
}; };
/// Action which modifies terrain tiles (i.e. paintbrush, pencil, eraser)
class aDrawTerrain : public cTerrainAction { class aDrawTerrain : public cTerrainAction {
public: public:
aDrawTerrain(std::string name, stroke_ter_changes_t stroke_changes) : aDrawTerrain(std::string name, stroke_ter_changes_t stroke_changes) :
@@ -66,4 +58,16 @@ private:
const stroke_ter_changes_t changes; const stroke_ter_changes_t changes;
}; };
/// Action which adds a new town to the end of the list, or deletes the last one
class aCreateDeleteTown : public cAction {
bool created;
class cTown* theTown;
bool undo_me() override;
bool redo_me() override;
public:
aCreateDeleteTown(bool create, class cTown* t);
~aCreateDeleteTown();
};
#endif #endif

View File

@@ -23,13 +23,13 @@ cAction::~cAction() {}
void cAction::undo() { void cAction::undo() {
UNDO_LOG("Undoing " + actname); UNDO_LOG("Undoing " + actname);
if(done && undo_me()) if(done && reversed ? redo_me() : undo_me())
done = false; done = false;
} }
void cAction::redo() { void cAction::redo() {
UNDO_LOG("Redoing " + actname); UNDO_LOG("Redoing " + actname);
if(!done && redo_me()) if(!done && reversed ? undo_me() : redo_me())
done = true; done = true;
} }

View File

@@ -23,7 +23,9 @@ class cAction {
protected: protected:
/// Construct a named action /// Construct a named action
/// @param name The name of the action to show in the Edit menu /// @param name The name of the action to show in the Edit menu
cAction(std::string name) : actname(name) {} cAction(std::string name, bool reversed = false) : actname(name), reversed(reversed) {}
/// For actions that have an inverse, this flag inverts the action implementation (i.e. create/delete)
bool reversed = true;
public: public:
/// Undoes this action if it has not already been undone. /// Undoes this action if it has not already been undone.
/// If it has already been undone, does nothing. /// If it has already been undone, does nothing.