undo/redo edit town entrance
This commit is contained in:
@@ -2296,6 +2296,37 @@ static const std::array<location,5> trim_diffs = {{
|
|||||||
loc(0,0), loc(-1,0), loc(1,0), loc(0,-1), loc(0,1)
|
loc(0,0), loc(-1,0), loc(1,0), loc(0,-1), loc(0,1)
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
long get_town_entrance(location l) {
|
||||||
|
auto& city_locs = current_terrain->city_locs;
|
||||||
|
auto iter = std::find(city_locs.begin(), city_locs.end(), l);
|
||||||
|
if(iter != city_locs.end()) return iter->spec;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set, create, or delete the current outdoor section's city_loc for a given location
|
||||||
|
// Pass town_num -1 to remove the entrance from city_locs
|
||||||
|
void set_town_entrance(location l, long town_num) {
|
||||||
|
auto& city_locs = current_terrain->city_locs;
|
||||||
|
auto iter = std::find(city_locs.begin(), city_locs.end(), l);
|
||||||
|
if(iter != city_locs.end()){
|
||||||
|
// Erase town entrance:
|
||||||
|
if(town_num < 0){
|
||||||
|
city_locs.erase(iter);
|
||||||
|
}
|
||||||
|
// Overwrite town entrance:
|
||||||
|
else{
|
||||||
|
iter->spec = town_num;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
// Add new town entrance:
|
||||||
|
if(town_num >= 0){
|
||||||
|
spec_loc_t loc = l;
|
||||||
|
loc.spec = town_num;
|
||||||
|
city_locs.push_back(loc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void set_terrain(location l,ter_num_t terrain_type,stroke_ter_changes_t& stroke_changes, bool handle_special) {
|
void set_terrain(location l,ter_num_t terrain_type,stroke_ter_changes_t& stroke_changes, bool handle_special) {
|
||||||
cArea* cur_area = get_current_area();
|
cArea* cur_area = get_current_area();
|
||||||
|
|
||||||
@@ -2317,10 +2348,10 @@ void set_terrain(location l,ter_num_t terrain_type,stroke_ter_changes_t& stroke_
|
|||||||
if(!editing_town) {
|
if(!editing_town) {
|
||||||
// Implicitly erase town entrances when a space is set from a town terrain to a non-town terrain
|
// Implicitly erase town entrances when a space is set from a town terrain to a non-town terrain
|
||||||
if(old_ter.special == eTerSpec::TOWN_ENTRANCE && new_ter.special != eTerSpec::TOWN_ENTRANCE){
|
if(old_ter.special == eTerSpec::TOWN_ENTRANCE && new_ter.special != eTerSpec::TOWN_ENTRANCE){
|
||||||
for(short i = current_terrain->city_locs.size() - 1; i >= 0; i--) {
|
long old_town_num = get_town_entrance(l);
|
||||||
if(current_terrain->city_locs[i] == l)
|
undo_list.add(action_ptr(new aEditTownEntrance(spot_hit, old_town_num, -1)));
|
||||||
current_terrain->city_locs.erase(current_terrain->city_locs.begin() + i);
|
update_edit_menu();
|
||||||
}
|
set_town_entrance(l, -1);
|
||||||
}
|
}
|
||||||
// Don't implicitly erase signs, because the designer may have entered text in them
|
// Don't implicitly erase signs, because the designer may have entered text in them
|
||||||
}
|
}
|
||||||
@@ -2664,44 +2695,13 @@ void town_entry(location spot_hit) {
|
|||||||
showError("This space isn't a town entrance. Town entrances are marked by a small brown castle icon.");
|
showError("This space isn't a town entrance. Town entrances are marked by a small brown castle icon.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// clean up old town entries
|
long old_town_num = get_town_entrance(spot_hit);
|
||||||
for(short i = 0; i < current_terrain->city_locs.size(); i++){
|
long town_num = pick_town_num("select-town-enter",old_town_num,scenario);
|
||||||
if(current_terrain->city_locs[i].spec >= 0) {
|
|
||||||
auto& city_loc = current_terrain->city_locs[i];
|
if(town_num >= 0 && town_num != old_town_num){
|
||||||
if(!get_current_area()->is_on_map(city_loc))
|
undo_list.add(action_ptr(new aEditTownEntrance(spot_hit, old_town_num, town_num)));
|
||||||
city_loc.spec = -1;
|
update_edit_menu();
|
||||||
else{
|
set_town_entrance(spot_hit, town_num);
|
||||||
ter = current_terrain->terrain[city_loc.x][city_loc.y];
|
|
||||||
if(scenario.ter_types[ter].special != eTerSpec::TOWN_ENTRANCE)
|
|
||||||
city_loc.spec = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto iter = std::find(current_terrain->city_locs.begin(), current_terrain->city_locs.end(), spot_hit);
|
|
||||||
// Edit existing town entrance
|
|
||||||
if(iter != current_terrain->city_locs.end()) {
|
|
||||||
int town = pick_town_num("select-town-enter",iter->spec,scenario);
|
|
||||||
if(town >= 0) iter->spec = town;
|
|
||||||
} else {
|
|
||||||
iter = std::find_if(current_terrain->city_locs.begin(), current_terrain->city_locs.end(), [](const spec_loc_t& loc) {
|
|
||||||
return loc.spec < 0;
|
|
||||||
});
|
|
||||||
// Find unused town entrance and fill it
|
|
||||||
if(iter != current_terrain->city_locs.end()) {
|
|
||||||
int town = pick_town_num("select-town-enter",0,scenario);
|
|
||||||
if(town >= 0) {
|
|
||||||
*iter = spot_hit;
|
|
||||||
iter->spec = town;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Add new town entrance at the back of list
|
|
||||||
else {
|
|
||||||
int town = pick_town_num("select-town-enter",0,scenario);
|
|
||||||
if(town >= 0) {
|
|
||||||
current_terrain->city_locs.emplace_back(spot_hit);
|
|
||||||
current_terrain->city_locs.back().spec = town;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -23,6 +23,8 @@ void change_rect_terrain(rectangle r,ter_num_t terrain_type,short probability,bo
|
|||||||
void flood_fill_terrain(location start, ter_num_t terrain_type);
|
void flood_fill_terrain(location start, ter_num_t terrain_type);
|
||||||
void frill_up_terrain();
|
void frill_up_terrain();
|
||||||
void unfrill_terrain();
|
void unfrill_terrain();
|
||||||
|
long get_town_entrance(location l);
|
||||||
|
void set_town_entrance(location l, long town_num);
|
||||||
void set_terrain(location l,ter_num_t terrain_type,stroke_ter_changes_t& stroke_changes,bool handle_special=true);
|
void set_terrain(location l,ter_num_t terrain_type,stroke_ter_changes_t& stroke_changes,bool handle_special=true);
|
||||||
void adjust_space(location l,stroke_ter_changes_t& stroke_changes);
|
void adjust_space(location l,stroke_ter_changes_t& stroke_changes);
|
||||||
void commit_stroke();
|
void commit_stroke();
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "scenario/scenario.hpp"
|
#include "scenario/scenario.hpp"
|
||||||
#include "scenario/area.hpp"
|
#include "scenario/area.hpp"
|
||||||
|
#include "scen.actions.hpp"
|
||||||
|
|
||||||
extern bool editing_town;
|
extern bool editing_town;
|
||||||
extern short cur_town;
|
extern short cur_town;
|
||||||
@@ -259,4 +260,15 @@ bool aEditSignText::redo_me() {
|
|||||||
auto iter = std::find(signs.begin(), signs.end(), area.where);
|
auto iter = std::find(signs.begin(), signs.end(), area.where);
|
||||||
iter->text = new_text;
|
iter->text = new_text;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cTerrainAction makes sure current_terrain properly references the outdoor section where the edit happened
|
||||||
|
bool aEditTownEntrance::undo_me() {
|
||||||
|
set_town_entrance(area.where, old_town);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool aEditTownEntrance::redo_me() {
|
||||||
|
set_town_entrance(area.where, new_town);
|
||||||
|
return true;
|
||||||
}
|
}
|
@@ -105,6 +105,17 @@ public:
|
|||||||
cTerrainAction("Edit Sign Text", loc), old_text(old_text), new_text(new_text) {}
|
cTerrainAction("Edit Sign Text", loc), old_text(old_text), new_text(new_text) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Action which edits town entrance
|
||||||
|
class aEditTownEntrance : public cTerrainAction {
|
||||||
|
long old_town;
|
||||||
|
long new_town;
|
||||||
|
bool undo_me() override;
|
||||||
|
bool redo_me() override;
|
||||||
|
public:
|
||||||
|
aEditTownEntrance(location loc, long old_town, long new_town) :
|
||||||
|
cTerrainAction("Edit Town Entrance", loc), old_town(old_town), new_town(new_town) {}
|
||||||
|
};
|
||||||
|
|
||||||
/// Action which adds a new town to the end of the list, or deletes the last one
|
/// Action which adds a new town to the end of the list, or deletes the last one
|
||||||
class aCreateDeleteTown : public cAction {
|
class aCreateDeleteTown : public cAction {
|
||||||
bool created;
|
bool created;
|
||||||
|
Reference in New Issue
Block a user