1 #include "construction_clear.h"
2 
3 #include "building/building.h"
4 #include "building/monument.h"
5 #include "city/warning.h"
6 #include "core/config.h"
7 #include "figuretype/migrant.h"
8 #include "game/undo.h"
9 #include "graphics/window.h"
10 #include "map/aqueduct.h"
11 #include "map/bridge.h"
12 #include "map/building.h"
13 #include "map/building_tiles.h"
14 #include "map/grid.h"
15 #include "map/property.h"
16 #include "map/routing_terrain.h"
17 #include "map/terrain.h"
18 #include "map/tiles.h"
19 #include "translation/translation.h"
20 #include "window/popup_dialog.h"
21 
22 static struct {
23     int x_start;
24     int y_start;
25     int x_end;
26     int y_end;
27     int bridge_confirmed;
28     int fort_confirmed;
29     int monument_confirmed;
30 } confirm;
31 
get_deletable_building(int grid_offset)32 static building *get_deletable_building(int grid_offset)
33 {
34     int building_id = map_building_at(grid_offset);
35     if (!building_id) {
36         return 0;
37     }
38     building *b = building_main(building_get(building_id));
39     if (b->type == BUILDING_BURNING_RUIN || b->type == BUILDING_NATIVE_CROPS ||
40         b->type == BUILDING_NATIVE_HUT || b->type == BUILDING_NATIVE_MEETING) {
41         return 0;
42     }
43     if (b->state == BUILDING_STATE_DELETED_BY_PLAYER || b->is_deleted) {
44         return 0;
45     }
46     return b;
47 }
48 
clear_land_confirmed(int measure_only,int x_start,int y_start,int x_end,int y_end)49 static int clear_land_confirmed(int measure_only, int x_start, int y_start, int x_end, int y_end)
50 {
51     int items_placed = 0;
52     game_undo_restore_building_state();
53     game_undo_restore_map(0);
54 
55     int x_min, x_max, y_min, y_max;
56     map_grid_start_end_to_area(x_start, y_start, x_end, y_end, &x_min, &y_min, &x_max, &y_max);
57 
58     int visual_feedback_on_delete = 1;
59 
60     for (int y = y_min; y <= y_max; y++) {
61         for (int x = x_min; x <= x_max; x++) {
62             int grid_offset = map_grid_offset(x, y);
63             if (measure_only && visual_feedback_on_delete) {
64                 building *b = get_deletable_building(grid_offset);
65                 if (map_property_is_deleted(grid_offset) || (b && map_property_is_deleted(b->grid_offset))) {
66                     continue;
67                 }
68                 map_building_tiles_mark_deleting(grid_offset);
69                 if (map_terrain_is(grid_offset, TERRAIN_BUILDING)) {
70                     if (b) {
71                         items_placed++;
72                     }
73                 } else if (map_terrain_is(grid_offset, TERRAIN_ROCK | TERRAIN_ELEVATION)) {
74                     continue;
75                 } else if (map_terrain_is(grid_offset, TERRAIN_WATER)) { // keep the "bridge is free" bug from C3
76                     continue;
77                 } else if (map_terrain_is(grid_offset, TERRAIN_AQUEDUCT)
78                     || map_terrain_is(grid_offset, TERRAIN_NOT_CLEAR)) {
79                     items_placed++;
80                 }
81                 continue;
82             }
83             if (map_terrain_is(grid_offset, TERRAIN_ROCK | TERRAIN_ELEVATION)) {
84                 continue;
85             }
86             if (map_terrain_is(grid_offset, TERRAIN_BUILDING)) {
87                 building *b = get_deletable_building(grid_offset);
88                 if (!b) {
89                     continue;
90                 }
91                 if (b->type == BUILDING_FORT_GROUND || b->type == BUILDING_FORT) {
92                     if (!measure_only && confirm.fort_confirmed != 1) {
93                         continue;
94                     }
95                     if (!measure_only && confirm.fort_confirmed == 1) {
96                         game_undo_disable();
97                     }
98                 }
99                 if (building_monument_is_monument(b)) {
100                     if (!measure_only && confirm.monument_confirmed != 1) {
101                         continue;
102                     }
103                     if (!measure_only && confirm.monument_confirmed == 1) {
104                         game_undo_disable();
105                     }
106                 }
107                 if (b->house_size && b->house_population && !measure_only) {
108                     figure *homeless = figure_create_homeless(b, b->house_population);
109                     b->house_population = 0;
110                     b->figure_id = homeless->id;
111                 }
112                 if (b->state != BUILDING_STATE_DELETED_BY_PLAYER) {
113                     items_placed++;
114                     game_undo_add_building(b);
115                 }
116                 b->state = BUILDING_STATE_DELETED_BY_PLAYER;
117                 b->is_deleted = 1;
118                 building *space = b;
119                 for (int i = 0; i < 9; i++) {
120                     if (space->prev_part_building_id <= 0) {
121                         break;
122                     }
123                     space = building_get(space->prev_part_building_id);
124                     game_undo_add_building(space);
125                     space->state = BUILDING_STATE_DELETED_BY_PLAYER;
126                 }
127                 space = b;
128                 for (int i = 0; i < 9; i++) {
129                     space = building_next(space);
130                     if (space->id <= 0) {
131                         break;
132                     }
133                     game_undo_add_building(space);
134                     space->state = BUILDING_STATE_DELETED_BY_PLAYER;
135                 }
136             } else if (map_terrain_is(grid_offset, TERRAIN_AQUEDUCT)) {
137                 map_terrain_remove(grid_offset, TERRAIN_CLEARABLE);
138                 items_placed++;
139                 map_aqueduct_remove(grid_offset);
140             } else if (map_terrain_is(grid_offset, TERRAIN_WATER)) {
141                 if (!measure_only && map_bridge_count_figures(grid_offset) > 0) {
142                     city_warning_show(WARNING_PEOPLE_ON_BRIDGE);
143                 } else if (confirm.bridge_confirmed == 1) {
144                     map_bridge_remove(grid_offset, measure_only);
145                     items_placed++;
146                 }
147             } else if (map_terrain_is(grid_offset, TERRAIN_NOT_CLEAR)) {
148                 if (map_terrain_is(grid_offset, TERRAIN_ROAD)) {
149                     map_property_clear_plaza_or_earthquake(grid_offset);
150                 }
151                 map_terrain_remove(grid_offset, TERRAIN_CLEARABLE);
152                 items_placed++;
153             }
154         }
155     }
156     if (!measure_only || !visual_feedback_on_delete) {
157         int radius;
158         if (x_max - x_min <= y_max - y_min) {
159             radius = y_max - y_min + 3;
160         } else {
161             radius = x_max - x_min + 3;
162         }
163         map_tiles_update_region_empty_land(x_min, y_min, x_max, y_max);
164         map_tiles_update_region_meadow(x_min, y_min, x_max, y_max);
165         map_tiles_update_region_rubble(x_min, y_min, x_max, y_max);
166         map_tiles_update_all_gardens();
167         map_tiles_update_area_roads(x_min, y_min, radius);
168         map_tiles_update_all_plazas();
169         map_tiles_update_area_walls(x_min, y_min, radius);
170         map_tiles_update_region_aqueducts(x_min - 3, y_min - 3, x_max + 3, y_max + 3);
171     }
172     if (!measure_only) {
173         map_routing_update_land();
174         map_routing_update_walls();
175         map_routing_update_water();
176         building_update_state();
177         window_invalidate();
178     }
179     return items_placed;
180 }
181 
confirm_delete_fort(int accepted,int checked)182 static void confirm_delete_fort(int accepted, int checked)
183 {
184     if (accepted == 1) {
185         confirm.fort_confirmed = 1;
186     } else {
187         confirm.fort_confirmed = -1;
188     }
189     clear_land_confirmed(0, confirm.x_start, confirm.y_start, confirm.x_end, confirm.y_end);
190 }
191 
confirm_delete_bridge(int accepted,int checked)192 static void confirm_delete_bridge(int accepted, int checked)
193 {
194     if (accepted == 1) {
195         confirm.bridge_confirmed = 1;
196     } else {
197         confirm.bridge_confirmed = -1;
198     }
199     clear_land_confirmed(0, confirm.x_start, confirm.y_start, confirm.x_end, confirm.y_end);
200 }
201 
confirm_delete_monument(int accepted,int checked)202 static void confirm_delete_monument(int accepted, int checked)
203 {
204     if (accepted == 1) {
205         confirm.monument_confirmed = 1;
206     } else {
207         confirm.monument_confirmed = -1;
208     }
209     clear_land_confirmed(0, confirm.x_start, confirm.y_start, confirm.x_end, confirm.y_end);
210 }
211 
building_construction_clear_land(int measure_only,int x_start,int y_start,int x_end,int y_end)212 int building_construction_clear_land(int measure_only, int x_start, int y_start, int x_end, int y_end)
213 {
214     confirm.fort_confirmed = 0;
215     confirm.bridge_confirmed = 0;
216     if (measure_only) {
217         return clear_land_confirmed(measure_only, x_start, y_start, x_end, y_end);
218     }
219 
220     int x_min, x_max, y_min, y_max;
221     map_grid_start_end_to_area(x_start, y_start, x_end, y_end, &x_min, &y_min, &x_max, &y_max);
222 
223     int ask_confirm_bridge = 0;
224     int ask_confirm_fort = 0;
225     int ask_confirm_monument = 0;
226     for (int y = y_min; y <= y_max; y++) {
227         for (int x = x_min; x <= x_max; x++) {
228             int grid_offset = map_grid_offset(x, y);
229             int building_id = map_building_at(grid_offset);
230             if (building_id) {
231                 building *b = building_get(building_id);
232                 if (b->type == BUILDING_FORT || b->type == BUILDING_FORT_GROUND) {
233                     ask_confirm_fort = 1;
234                 }
235                 if (building_monument_is_monument(b)) {
236                     if (building_monument_type_is_mini_monument(b->type)) {
237                         confirm.monument_confirmed = 1;
238                     } else {
239                         ask_confirm_monument = 1;
240                     }
241                 }
242             }
243             if (map_is_bridge(grid_offset)) {
244                 ask_confirm_bridge = 1;
245             }
246 
247         }
248     }
249     confirm.x_start = x_start;
250     confirm.y_start = y_start;
251     confirm.x_end = x_end;
252     confirm.y_end = y_end;
253     if (ask_confirm_fort) {
254         window_popup_dialog_show(POPUP_DIALOG_DELETE_FORT, confirm_delete_fort, 2);
255         return -1;
256     } else if (ask_confirm_monument) {
257         window_popup_dialog_show_confirmation(translation_for(TR_CONFIRM_DELETE_MONUMENT), 0, 0, confirm_delete_monument);
258         return -1;
259     } else if (ask_confirm_bridge) {
260         window_popup_dialog_show(POPUP_DIALOG_DELETE_BRIDGE, confirm_delete_bridge, 2);
261         return -1;
262     } else {
263         return clear_land_confirmed(measure_only, x_start, y_start, x_end, y_end);
264     }
265 }
266