undo/redo for advanced town details
This commit is contained in:
@@ -287,4 +287,39 @@ bool cTown::cItem::operator==(const cTown::cItem& other) {
|
||||
CHECK_EQ(other, property);
|
||||
CHECK_EQ(other, contained);
|
||||
return true;
|
||||
}
|
||||
|
||||
town_advanced_t advanced_from_town(size_t which, cTown& town, cScenario& scenario) {
|
||||
town_advanced_t details = {
|
||||
town.exits,
|
||||
town.spec_on_entry,
|
||||
town.spec_on_entry_if_dead,
|
||||
town.spec_on_hostile,
|
||||
town.bg_town,
|
||||
town.bg_fight,
|
||||
town.is_hidden,
|
||||
town.defy_mapping,
|
||||
town.defy_scrying,
|
||||
town.strong_barriers,
|
||||
town.has_tavern
|
||||
};
|
||||
auto iter = scenario.store_item_rects.find(which);
|
||||
if(iter != scenario.store_item_rects.end()) details.store_item_rect = iter->second;
|
||||
return details;
|
||||
}
|
||||
|
||||
void town_set_advanced(size_t which, cTown& town, cScenario& scenario, const town_advanced_t& details) {
|
||||
town.exits = details.exits;
|
||||
town.spec_on_entry = details.spec_on_entry;
|
||||
town.spec_on_entry_if_dead = details.spec_on_entry_if_dead;
|
||||
town.spec_on_hostile = details.spec_on_hostile;
|
||||
town.bg_town = details.bg_town;
|
||||
town.bg_fight = details.bg_fight;
|
||||
town.is_hidden = details.is_hidden;
|
||||
town.defy_mapping = details.defy_mapping;
|
||||
town.defy_scrying = details.defy_scrying;
|
||||
town.strong_barriers = details.strong_barriers;
|
||||
town.has_tavern = details.has_tavern;
|
||||
if(details.store_item_rect) scenario.store_item_rects[which] = *details.store_item_rect;
|
||||
else scenario.store_item_rects.erase(which);
|
||||
}
|
@@ -181,4 +181,46 @@ inline void town_set_details(cTown& town, const town_details_t& details) {
|
||||
town.comment = details.comment;
|
||||
}
|
||||
|
||||
// Store a version of the advanced town details for undo history.
|
||||
// This could be made a struct that cTown contains, and that would eliminate the next 2 functions, but it would
|
||||
// require changing every reference to these detail values in the game and fileio code, making them more verbose. I don't know
|
||||
// if that's worth it.
|
||||
struct town_advanced_t {
|
||||
std::array<spec_loc_t, 4> exits;
|
||||
short spec_on_entry;
|
||||
short spec_on_entry_if_dead;
|
||||
short spec_on_hostile;
|
||||
int bg_town;
|
||||
int bg_fight;
|
||||
bool is_hidden;
|
||||
bool defy_mapping;
|
||||
bool defy_scrying;
|
||||
bool strong_barriers;
|
||||
bool has_tavern;
|
||||
boost::optional<rectangle> store_item_rect;
|
||||
|
||||
bool operator==(const town_advanced_t& other) const {
|
||||
for(int i = 0; i < exits.size(); ++i){
|
||||
if(other.exits[i].spec != exits[i].spec) return false;
|
||||
if(other.exits[i] != exits[i]) return false;
|
||||
}
|
||||
CHECK_EQ(other,spec_on_entry);
|
||||
CHECK_EQ(other,spec_on_entry_if_dead);
|
||||
CHECK_EQ(other,spec_on_hostile);
|
||||
CHECK_EQ(other,bg_town);
|
||||
CHECK_EQ(other,bg_fight);
|
||||
CHECK_EQ(other,is_hidden);
|
||||
CHECK_EQ(other,defy_mapping);
|
||||
CHECK_EQ(other,defy_scrying);
|
||||
CHECK_EQ(other,strong_barriers);
|
||||
CHECK_EQ(other,has_tavern);
|
||||
CHECK_EQ(other,store_item_rect);
|
||||
return true;
|
||||
}
|
||||
bool operator!=(const town_advanced_t& other) const { return !(*this == other); }
|
||||
};
|
||||
|
||||
town_advanced_t advanced_from_town(size_t which, cTown& town, cScenario& scenario);
|
||||
void town_set_advanced(size_t which, cTown& town, cScenario& scenario, const town_advanced_t& details);
|
||||
|
||||
#endif
|
||||
|
@@ -1027,9 +1027,19 @@ void edit_advanced_town() {
|
||||
|
||||
put_advanced_town_in_dlog(town_dlg);
|
||||
|
||||
town_advanced_t old_details = advanced_from_town(cur_town, *town, scenario);
|
||||
town_dlg.run();
|
||||
if(town_dlg.accepted() && delete_rect)
|
||||
scenario.store_item_rects.erase(cur_town);
|
||||
if(town_dlg.accepted()){
|
||||
if(delete_rect){
|
||||
scenario.store_item_rects.erase(cur_town);
|
||||
}
|
||||
|
||||
town_advanced_t new_details = advanced_from_town(cur_town, *town, scenario);
|
||||
if(new_details != old_details){
|
||||
undo_list.add(action_ptr(new aEditTownAdvancedDetails(cur_town, old_details, new_details)));
|
||||
update_edit_menu();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool save_town_wand(cDialog& me, std::string, eKeyMod) {
|
||||
|
@@ -950,4 +950,14 @@ bool aEditTownWandering::redo_me() {
|
||||
scenario.towns[which]->wandering = new_wandering;
|
||||
scenario.towns[which]->wandering_locs = new_wandering_locs;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aEditTownAdvancedDetails::undo_me() {
|
||||
town_set_advanced(which, *scenario.towns[which], scenario, old_details);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool aEditTownAdvancedDetails::redo_me() {
|
||||
town_set_advanced(which, *scenario.towns[which], scenario, new_details);
|
||||
return true;
|
||||
}
|
@@ -609,4 +609,15 @@ public:
|
||||
new_wandering(new_wandering), new_wandering_locs(new_wandering_locs) {}
|
||||
};
|
||||
|
||||
class aEditTownAdvancedDetails : public cAction {
|
||||
size_t which;
|
||||
town_advanced_t old_details;
|
||||
town_advanced_t new_details;
|
||||
bool undo_me() override;
|
||||
bool redo_me() override;
|
||||
public:
|
||||
aEditTownAdvancedDetails(size_t which, town_advanced_t old_details, town_advanced_t new_details) :
|
||||
cAction("Edit Town Advanced Details"), which(which), old_details(old_details), new_details(new_details) {}
|
||||
};
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user