From 978af61054e49388e0cb2a3205540991b07484da Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Sat, 14 Jun 2025 10:03:16 -0500 Subject: [PATCH] Safely import towns of different size. fix #760 --- rsrc/dialogs/select-import-town.xml | 6 ++---- src/scenedit/scen.main.cpp | 3 +++ src/scenedit/scen.townout.cpp | 6 ++++++ src/scenedit/scen.undo.cpp | 5 +++++ 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/rsrc/dialogs/select-import-town.xml b/rsrc/dialogs/select-import-town.xml index 88034f58..4e94c189 100644 --- a/rsrc/dialogs/select-import-town.xml +++ b/rsrc/dialogs/select-import-town.xml @@ -9,13 +9,11 @@ Importing a town What town do you wish to import? (0 - {{max-num}}) - Enter a town number and hit OK, and you will be asked to select a scenario file. - The town with that number in the selected scenario will then be loaded in over the current town. + The town with this number in the selected scenario be imported. - Warning: This will write over the town currently in memory. - Also, the town you select must be the same size (large/medium/small) as the town currently in memory. + Warning: This will overwrite over the town currently in memory. diff --git a/src/scenedit/scen.main.cpp b/src/scenedit/scen.main.cpp index f578b2ca..a82e9cd9 100644 --- a/src/scenedit/scen.main.cpp +++ b/src/scenedit/scen.main.cpp @@ -97,6 +97,8 @@ rectangle search_field_rect; extern void set_up_apple_events(); +extern void clamp_view_center(cTown* town); + // TODO: these should be members of some global entity instead of being here std::unordered_map> event_listeners; cDrawableManager drawable_mgr; @@ -654,6 +656,7 @@ void handle_menu_choice(eMenu item_hit) { scenario.towns[cur_town] = town; ::town = town; change_made = true; + clamp_view_center(town); redraw_screen(); } break; diff --git a/src/scenedit/scen.townout.cpp b/src/scenedit/scen.townout.cpp index c6cf2f4c..2962c71b 100644 --- a/src/scenedit/scen.townout.cpp +++ b/src/scenedit/scen.townout.cpp @@ -1896,3 +1896,9 @@ cOutdoors* pick_import_out() { temp_scenario.outdoors[sector.x][sector.y] = nullptr; return out; } + +// after importing a town, the view center might be out-of-bounds +void clamp_view_center(cTown* town) { + cen_x = min(cen_x, town->max_dim - 5); + cen_y = min(cen_y, town->max_dim - 5); +} \ No newline at end of file diff --git a/src/scenedit/scen.undo.cpp b/src/scenedit/scen.undo.cpp index 63433a54..87e02334 100644 --- a/src/scenedit/scen.undo.cpp +++ b/src/scenedit/scen.undo.cpp @@ -20,6 +20,7 @@ extern eScenMode overall_mode; extern eDrawMode draw_mode; extern void apply_outdoor_shift(rectangle mod); extern void clamp_current_section(); +extern void clamp_view_center(cTown* town); cTerrainAction::cTerrainAction(std::string name, short town_num, location where, bool reversed) : cAction(name, reversed) { area.is_town = true; @@ -556,12 +557,16 @@ aImportTown::~aImportTown() { bool aImportTown::undo_me() { scenario.towns[which] = old_town; + clamp_view_center(old_town); set_current_town(which); + start_town_edit(); return true; } bool aImportTown::redo_me() { scenario.towns[which] = new_town; + clamp_view_center(new_town); set_current_town(which); + start_town_edit(); return true; } \ No newline at end of file