1 #include "formation_enemy.h"
2 
3 #include "building/building.h"
4 #include "city/buildings.h"
5 #include "city/figures.h"
6 #include "city/gods.h"
7 #include "city/message.h"
8 #include "core/calc.h"
9 #include "core/random.h"
10 #include "figure/enemy_army.h"
11 #include "figure/figure.h"
12 #include "figure/formation.h"
13 #include "figure/formation_layout.h"
14 #include "figure/route.h"
15 #include "map/figure.h"
16 #include "map/grid.h"
17 #include "map/routing.h"
18 #include "map/routing_path.h"
19 #include "map/soldier_strength.h"
20 #include "map/terrain.h"
21 
22 #define INFINITE 10000
23 
24 static const int ENEMY_ATTACK_PRIORITY[4][100] = {
25     {
26         BUILDING_GRANARY, BUILDING_WAREHOUSE, BUILDING_MARKET,
27         BUILDING_WHEAT_FARM, BUILDING_VEGETABLE_FARM, BUILDING_FRUIT_FARM,
28         BUILDING_OLIVE_FARM, BUILDING_VINES_FARM, BUILDING_PIG_FARM, 0
29     },
30     {
31         BUILDING_SENATE_UPGRADED, BUILDING_SENATE,
32         BUILDING_FORUM_UPGRADED, BUILDING_FORUM, 0
33     },
34     {
35         BUILDING_GOVERNORS_PALACE, BUILDING_GOVERNORS_VILLA, BUILDING_GOVERNORS_HOUSE,
36         BUILDING_HOUSE_LUXURY_PALACE, BUILDING_HOUSE_LARGE_PALACE,
37         BUILDING_HOUSE_MEDIUM_PALACE, BUILDING_HOUSE_SMALL_PALACE,
38         BUILDING_HOUSE_GRAND_VILLA, BUILDING_HOUSE_LARGE_VILLA,
39         BUILDING_HOUSE_MEDIUM_VILLA, BUILDING_HOUSE_SMALL_VILLA,
40         BUILDING_HOUSE_GRAND_INSULA, BUILDING_HOUSE_LARGE_INSULA,
41         BUILDING_HOUSE_MEDIUM_INSULA, BUILDING_HOUSE_SMALL_INSULA,
42         BUILDING_HOUSE_LARGE_CASA, BUILDING_HOUSE_SMALL_CASA,
43         BUILDING_HOUSE_LARGE_HOVEL, BUILDING_HOUSE_SMALL_HOVEL,
44         BUILDING_HOUSE_LARGE_SHACK, BUILDING_HOUSE_SMALL_SHACK,
45         BUILDING_HOUSE_LARGE_TENT, BUILDING_HOUSE_SMALL_TENT, 0
46     },
47     {
48         BUILDING_MILITARY_ACADEMY, BUILDING_PREFECTURE, 0
49     }
50 };
51 
52 static const int RIOTER_ATTACK_PRIORITY[29] = {
53     BUILDING_GOVERNORS_PALACE,
54     BUILDING_GOVERNORS_VILLA,
55     BUILDING_GOVERNORS_HOUSE,
56     BUILDING_AMPHITHEATER,
57     BUILDING_THEATER,
58     BUILDING_HOSPITAL,
59     BUILDING_ACADEMY,
60     BUILDING_BATHHOUSE,
61     BUILDING_LIBRARY,
62     BUILDING_SCHOOL,
63     BUILDING_DOCTOR,
64     BUILDING_GLADIATOR_SCHOOL,
65     BUILDING_ACTOR_COLONY,
66     BUILDING_CHARIOT_MAKER,
67     BUILDING_LION_HOUSE,
68     BUILDING_BARBER,
69     BUILDING_TAVERN,
70     BUILDING_ARENA,
71     BUILDING_HORSE_STATUE,
72     BUILDING_LEGION_STATUE,
73     BUILDING_LARGE_STATUE,
74     BUILDING_MEDIUM_STATUE,
75     BUILDING_OBELISK,
76     BUILDING_HOUSE_LUXURY_PALACE,
77     BUILDING_HOUSE_LARGE_PALACE,
78     BUILDING_HOUSE_MEDIUM_PALACE,
79     BUILDING_HOUSE_SMALL_PALACE,
80     BUILDING_HOUSE_GRAND_VILLA,
81     BUILDING_HOUSE_LARGE_VILLA,
82 };
83 
84 static const int LAYOUT_ORIENTATION_OFFSETS[13][4][40] = {
85     {
86         {0, 0, -3, 0, 3, 0, -8, 0, 8, 0, -3, 8, 3, 8, 0},
87         {0, 0, 0, -3, 0, 3, 0, -8, 0, 8, 8, -3, 8, 3, 0},
88         {0, 0, -3, 0, 3, 0, -8, 0, 8, 0, -3, -8, 3, -8, 0},
89         {0, 0, 0, -3, 0, 3, 0, -8, 0, 8, -8, -3, -8, 3, 0},
90     },
91     {
92         {0, 0, -6, 0, 6, 0, -6, 2, 6, 2, -2, 4, 4, 6, 0},
93         {0, 0, 0, -6, 0, 6, 2, -6, 2, 6, 4, -2, 6, 4, 0},
94         {0, 0, -6, 0, 6, 0, -6, -2, 6, -2, -4, -6, 4, -6, 0},
95         {0, 0, 0, -6, 0, 6, -2, -6, -2, 6, -6, -4, -6, 4, 0},
96     },
97     {
98         {0, 0, -6, 0, 6, 0, -6, 2, 6, 2, -2, 4, 4, 6, 0},
99         {0, 0, 0, -6, 0, 6, 2, -6, 2, 6, 4, -2, 6, 4, 0},
100         {0, 0, -6, 0, 6, 0, -6, -2, 6, -2, -4, -6, 4, -6, 0},
101         {0, 0, 0, -6, 0, 6, -2, -6, -2, 6, -6, -4, -6, 4, 0},
102     },
103     {
104         {0, 0, -6, 0, 6, 0, -6, 2, 6, 2, -2, 4, 4, 6, 0},
105         {0, 0, 0, -6, 0, 6, 2, -6, 2, 6, 4, -2, 6, 4, 0},
106         {0, 0, -6, 0, 6, 0, -6, -2, 6, -2, -4, -6, 4, -6, 0},
107         {0, 0, 0, -6, 0, 6, -2, -6, -2, 6, -6, -4, -6, 4, 0},
108     },
109     {
110         {0, 0, -6, 0, 6, 0, -6, 2, 6, 2, -2, 4, 4, 6, 0},
111         {0, 0, 0, -6, 0, 6, 2, -6, 2, 6, 4, -2, 6, 4, 0},
112         {0, 0, -6, 0, 6, 0, -6, -2, 6, -2, -4, -6, 4, -6, 0},
113         {0, 0, 0, -6, 0, 6, -2, -6, -2, 6, -6, -4, -6, 4, 0},
114     },
115     {
116         {0, 0, -3, 0, 3, 0, -8, 0, 8, 0, -3, 8, 3, 8, 0},
117         {0, 0, 0, -3, 0, 3, 0, -8, 0, 8, 8, -3, 8, 3, 0},
118         {0, 0, -3, 0, 3, 0, -8, 0, 8, 0, -3, -8, 3, -8, 0},
119         {0, 0, 0, -3, 0, 3, 0, -8, 0, 8, -8, -3, -8, 3, 0},
120     },
121     {
122         {0, 0, -3, 0, 3, 0, -8, 0, 8, 0, -3, 8, 3, 8, 0},
123         {0, 0, 0, -3, 0, 3, 0, -8, 0, 8, 8, -3, 8, 3, 0},
124         {0, 0, -3, 0, 3, 0, -8, 0, 8, 0, -3, -8, 3, -8, 0},
125         {0, 0, 0, -3, 0, 3, 0, -8, 0, 8, -8, -3, -8, 3, 0},
126     },
127     {
128         {0, 0, -3, 0, 3, 0, -8, 0, 8, 0, -3, 8, 3, 8, 0},
129         {0, 0, 0, -3, 0, 3, 0, -8, 0, 8, 8, -3, 8, 3, 0},
130         {0, 0, -3, 0, 3, 0, -8, 0, 8, 0, -3, -8, 3, -8, 0},
131         {0, 0, 0, -3, 0, 3, 0, -8, 0, 8, -8, -3, -8, 3, 0},
132     },
133     {
134         {0, 0, -3, 0, 3, 0, -8, 0, 8, 0, -3, 8, 3, 8, 0},
135         {0, 0, 0, -3, 0, 3, 0, -8, 0, 8, 8, -3, 8, 3, 0},
136         {0, 0, -3, 0, 3, 0, -8, 0, 8, 0, -3, -8, 3, -8, 0},
137         {0, 0, 0, -3, 0, 3, 0, -8, 0, 8, -8, -3, -8, 3, 0},
138     },
139     {
140         {0, 0, -3, 0, 3, 0, -8, 0, 8, 0, -3, 8, 3, 8, 0},
141         {0, 0, 0, -3, 0, 3, 0, -8, 0, 8, 8, -3, 8, 3, 0},
142         {0, 0, -3, 0, 3, 0, -8, 0, 8, 0, -3, -8, 3, -8, 0},
143         {0, 0, 0, -3, 0, 3, 0, -8, 0, 8, -8, -3, -8, 3, 0},
144     },
145     {
146         {0, 0, -3, 0, 3, 0, -8, 0, 8, 0, -3, 8, 3, 8, 0},
147         {0, 0, 0, -3, 0, 3, 0, -8, 0, 8, 8, -3, 8, 3, 0},
148         {0, 0, -3, 0, 3, 0, -8, 0, 8, 0, -3, -8, 3, -8, 0},
149         {0, 0, 0, -3, 0, 3, 0, -8, 0, 8, -8, -3, -8, 3, 0},
150     },
151     {
152         {0, 0, -4, 0, 4, 0, -12, 0, 12, 0, -4, 12, 4, 12, 0},
153         {0, 0, 0, -4, 0, 4, 0, -12, 0, 12, 12, -4, 12, 4, 0},
154         {0, 0, -4, 0, 4, 0, -12, 0, 12, 0, -4, -12, 4, -12, 0},
155         {0, 0, 0, -4, 0, 4, 0, -12, 0, 12, -12, -4, -12, 4, 0},
156     },
157     {
158         {0, 0, -3, 0, 3, 0, -8, 0, 8, 0, -3, 8, 3, 8, 0},
159         {0, 0, 0, -3, 0, 3, 0, -8, 0, 8, 8, -3, 8, 3, 0},
160         {0, 0, -3, 0, 3, 0, -8, 0, 8, 0, -3, -8, 3, -8, 0},
161         {0, 0, 0, -3, 0, 3, 0, -8, 0, 8, -8, -3, -8, 3, 0},
162     }
163 };
164 
get_best_building(const int * priority_order,int max)165 static building *get_best_building(const int *priority_order, int max)
166 {
167     for (int i = 0; i < max; i++) {
168         building_type type = priority_order[i];
169         for (building *b = building_first_of_type(type); b; b = b->next_of_type) {
170             if (b->state == BUILDING_STATE_IN_USE) {
171                 return b;
172             }
173         }
174     }
175     return 0;
176 }
177 
get_best_and_closest_building(int x,int y,const int * priority_order,int max)178 static building *get_best_and_closest_building(int x, int y, const int *priority_order, int max)
179 {
180     int min_distance = INFINITE;
181     for (int i = 0; i < max; i++) {
182         building_type type = priority_order[i];
183         building *best_building = 0;
184         for (building *b = building_first_of_type(type); b; b = b->next_of_type) {
185             if (b->state != BUILDING_STATE_IN_USE) {
186                 continue;
187             }
188             int distance = calc_maximum_distance(x, y, b->x, b->y);
189             if (distance < min_distance) {
190                 best_building = b;
191                 min_distance = distance;
192             }
193         }
194         if (best_building) {
195             return best_building;
196         }
197     }
198     return 0;
199 }
200 
formation_rioter_get_target_building(int * x_tile,int * y_tile)201 int formation_rioter_get_target_building(int *x_tile, int *y_tile)
202 {
203     building *best_building = get_best_building(RIOTER_ATTACK_PRIORITY, 29);
204     if (!best_building) {
205         return 0;
206     }
207     *x_tile = best_building->x;
208     *y_tile = best_building->y;
209     return best_building->id;
210 }
211 
formation_rioter_get_target_building_for_robbery(int x,int y,int * x_tile,int * y_tile)212 int formation_rioter_get_target_building_for_robbery(int x, int y, int *x_tile, int *y_tile)
213 {
214     building *best_building = 0;
215     int closest = INFINITE;
216 
217     static const building_type building_targets[] = { BUILDING_SENATE, BUILDING_FORUM };
218     for (int i = 0; i < 2; i++) {
219         building_type type = building_targets[i];
220         for (building *b = building_first_of_type(type); b; b = b->next_of_type) {
221             if (b->state != BUILDING_STATE_IN_USE) {
222                 continue;
223             }
224             int distance = calc_maximum_distance(x, y, b->x, b->y);
225             if (distance >= 150) {
226                 continue;
227             }
228             if (distance < closest) {
229                 closest = distance;
230                 best_building = b;
231             }
232         }
233     }
234     if (!best_building) {
235         return 0;
236     }
237 
238     *x_tile = best_building->road_access_x;
239     *y_tile = best_building->road_access_y;
240 
241     return best_building->id;
242 }
243 
set_enemy_target_building(formation * m)244 static void set_enemy_target_building(formation *m)
245 {
246     int attack = m->attack_type;
247     if (attack == FORMATION_ATTACK_RANDOM) {
248         attack = random_byte() & 3;
249     }
250     building *best_building = get_best_and_closest_building(m->x_home, m->y_home, ENEMY_ATTACK_PRIORITY[attack], 100);
251 
252     if (!best_building) {
253         // no target buildings left: take rioter attack priority
254         best_building = get_best_and_closest_building(m->x_home, m->y_home, RIOTER_ATTACK_PRIORITY, 29);
255     }
256     if (best_building) {
257         if (best_building->type == BUILDING_WAREHOUSE) {
258             formation_set_destination_building(m, best_building->x + 1, best_building->y, best_building->id + 1);
259         } else {
260             formation_set_destination_building(m, best_building->x, best_building->y, best_building->id);
261         }
262     }
263 }
264 
set_native_target_building(formation * m)265 static void set_native_target_building(formation *m)
266 {
267     int meeting_x, meeting_y;
268     city_buildings_main_native_meeting_center(&meeting_x, &meeting_y);
269     building *min_building = 0;
270     int min_distance = INFINITE;
271     for (int i = 1; i < building_count(); i++) {
272         building *b = building_get(i);
273         if (b->state != BUILDING_STATE_IN_USE) {
274             continue;
275         }
276         switch (b->type) {
277             case BUILDING_MISSION_POST:
278             case BUILDING_NATIVE_HUT:
279             case BUILDING_NATIVE_CROPS:
280             case BUILDING_NATIVE_MEETING:
281             case BUILDING_WAREHOUSE:
282             case BUILDING_FORT:
283             case BUILDING_ROADBLOCK:
284             case BUILDING_GARDEN_WALL_GATE:
285                 break;
286             default:
287                 {
288                     int distance = calc_maximum_distance(meeting_x, meeting_y, b->x, b->y);
289                     if (distance < min_distance) {
290                         min_building = b;
291                         min_distance = distance;
292                     }
293                 }
294                 break;
295         }
296     }
297     if (min_building) {
298         formation_set_destination_building(m, min_building->x, min_building->y, min_building->id);
299     }
300 }
301 
set_figures_to_initial(const formation * m)302 static void set_figures_to_initial(const formation *m)
303 {
304     for (int i = 0; i < MAX_FORMATION_FIGURES; i++) {
305         if (m->figures[i] > 0) {
306             figure *f = figure_get(m->figures[i]);
307             if (f->action_state != FIGURE_ACTION_149_CORPSE &&
308                 f->action_state != FIGURE_ACTION_150_ATTACK) {
309                 f->action_state = FIGURE_ACTION_151_ENEMY_INITIAL;
310                 f->wait_ticks = 0;
311             }
312         }
313     }
314 }
315 
formation_enemy_move_formation_to(const formation * m,int x,int y,int * x_tile,int * y_tile)316 int formation_enemy_move_formation_to(const formation *m, int x, int y, int *x_tile, int *y_tile)
317 {
318     int base_offset = map_grid_offset(
319         formation_layout_position_x(m->layout, 0),
320         formation_layout_position_y(m->layout, 0));
321     int figure_offsets[50];
322     figure_offsets[0] = 0;
323     for (int i = 1; i < m->num_figures; i++) {
324         figure_offsets[i] = map_grid_offset(
325             formation_layout_position_x(m->layout, i),
326             formation_layout_position_y(m->layout, i)) - base_offset;
327     }
328     map_routing_noncitizen_can_travel_over_land(x, y, -1, -1, 0, 600);
329     for (int r = 0; r <= 10; r++) {
330         int x_min, y_min, x_max, y_max;
331         map_grid_get_area(x, y, 1, r, &x_min, &y_min, &x_max, &y_max);
332         for (int yy = y_min; yy <= y_max; yy++) {
333             for (int xx = x_min; xx <= x_max; xx++) {
334                 int can_move = 1;
335                 for (int fig = 0; fig < m->num_figures; fig++) {
336                     int grid_offset = map_grid_offset(xx, yy) + figure_offsets[fig];
337                     if (!map_grid_is_valid_offset(grid_offset)) {
338                         can_move = 0;
339                         break;
340                     }
341                     if (map_terrain_is(grid_offset, TERRAIN_IMPASSABLE_ENEMY)) {
342                         can_move = 0;
343                         break;
344                     }
345                     if (map_routing_distance(grid_offset) <= 0) {
346                         can_move = 0;
347                         break;
348                     }
349                     if (map_has_figure_at(grid_offset) &&
350                         figure_get(map_figure_at(grid_offset))->formation_id != m->id) {
351                         can_move = 0;
352                         break;
353                     }
354                 }
355                 if (can_move) {
356                     *x_tile = xx;
357                     *y_tile = yy;
358                     return 1;
359                 }
360             }
361         }
362     }
363     return 0;
364 }
365 
mars_kill_enemies(void)366 static void mars_kill_enemies(void)
367 {
368     int to_kill = city_god_spirit_of_mars_power();
369     if (to_kill <= 0) {
370         return;
371     }
372     int grid_offset = 0;
373     for (int i = 1; i < figure_count() && to_kill > 0; i++) {
374         figure *f = figure_get(i);
375         if (f->state != FIGURE_STATE_ALIVE) {
376             continue;
377         }
378         if (figure_is_enemy(f) && f->type != FIGURE_ENEMY54_GLADIATOR) {
379             f->action_state = FIGURE_ACTION_149_CORPSE;
380             to_kill--;
381             if (!grid_offset) {
382                 grid_offset = f->grid_offset;
383             }
384         }
385     }
386     city_god_spirit_of_mars_mark_used();
387     city_message_post(1, MESSAGE_SPIRIT_OF_MARS, 0, grid_offset);
388 }
389 
update_enemy_movement(formation * m,int roman_distance)390 static void update_enemy_movement(formation *m, int roman_distance)
391 {
392     const enemy_army *army = enemy_army_get(m->invasion_id);
393     formation_state *state = &m->enemy_state;
394     int regroup = 0;
395     int halt = 0;
396     int pursue_target = 0;
397     int advance = 0;
398     int target_formation_id = 0;
399     if (m->missile_fired) {
400         halt = 1;
401     } else if (m->missile_attack_timeout) {
402         pursue_target = 1;
403         target_formation_id = m->missile_attack_formation_id;
404     } else if (m->wait_ticks < 32) {
405         regroup = 1;
406         state->duration_advance = 4;
407     } else if (army->ignore_roman_soldiers) {
408         halt = 0;
409         regroup = 0;
410         advance = 1;
411     } else {
412         int halt_duration, advance_duration, regroup_duration;
413         if (army->layout == FORMATION_ENEMY_MOB || army->layout == FORMATION_ENEMY12) {
414             switch (m->enemy_legion_index) {
415                 case 0:
416                 case 1:
417                     regroup_duration = 2;
418                     advance_duration = 4;
419                     halt_duration = 2;
420                     break;
421                 case 2:
422                 case 3:
423                     regroup_duration = 2;
424                     advance_duration = 5;
425                     halt_duration = 3;
426                     break;
427                 default:
428                     regroup_duration = 2;
429                     advance_duration = 6;
430                     halt_duration = 4;
431                     break;
432             }
433             if (!roman_distance) {
434                 advance_duration += 6;
435                 halt_duration--;
436                 regroup_duration--;
437             }
438         } else {
439             if (roman_distance) {
440                 regroup_duration = 6;
441                 advance_duration = 4;
442                 halt_duration = 2;
443             } else {
444                 regroup_duration = 1;
445                 advance_duration = 12;
446                 halt_duration = 1;
447             }
448         }
449         if (state->duration_halt) {
450             state->duration_advance = 0;
451             state->duration_regroup = 0;
452             halt = 1;
453             state->duration_halt--;
454             if (state->duration_halt <= 0) {
455                 state->duration_regroup = regroup_duration;
456                 set_figures_to_initial(m);
457                 regroup = 0;
458                 halt = 1;
459             }
460         } else if (state->duration_regroup) {
461             state->duration_advance = 0;
462             state->duration_halt = 0;
463             regroup = 1;
464             state->duration_regroup--;
465             if (state->duration_regroup <= 0) {
466                 state->duration_advance = advance_duration;
467                 set_figures_to_initial(m);
468                 advance = 1;
469                 regroup = 0;
470             }
471         } else {
472             state->duration_regroup = 0;
473             state->duration_halt = 0;
474             advance = 1;
475             state->duration_advance--;
476             if (state->duration_advance <= 0) {
477                 state->duration_halt = halt_duration;
478                 set_figures_to_initial(m);
479                 halt = 1;
480                 advance = 0;
481             }
482         }
483     }
484 
485     if (m->wait_ticks > 32) {
486         mars_kill_enemies();
487     }
488     if (halt) {
489         formation_set_destination(m, m->x_home, m->y_home);
490     } else if (pursue_target) {
491         if (target_formation_id > 0) {
492             const formation *target = formation_get(target_formation_id);
493             if (target->num_figures > 0) {
494                 formation_set_destination(m, target->x_home, target->y_home);
495             }
496         } else {
497             formation_set_destination(m, army->destination_x, army->destination_y);
498         }
499     } else if (regroup) {
500         int layout = army->layout;
501         int x_offset = LAYOUT_ORIENTATION_OFFSETS[layout][m->orientation / 2][2 * m->enemy_legion_index] +
502             army->home_x;
503         int y_offset = LAYOUT_ORIENTATION_OFFSETS[layout][m->orientation / 2][2 * m->enemy_legion_index + 1] +
504             army->home_y;
505         int x_tile, y_tile;
506         if (formation_enemy_move_formation_to(m, x_offset, y_offset, &x_tile, &y_tile)) {
507             formation_set_destination(m, x_tile, y_tile);
508         }
509     } else if (advance) {
510         int layout = army->layout;
511         int x_offset = LAYOUT_ORIENTATION_OFFSETS[layout][m->orientation / 2][2 * m->enemy_legion_index] +
512             army->destination_x;
513         int y_offset = LAYOUT_ORIENTATION_OFFSETS[layout][m->orientation / 2][2 * m->enemy_legion_index + 1] +
514             army->destination_y;
515         int x_tile, y_tile;
516         if (formation_enemy_move_formation_to(m, x_offset, y_offset, &x_tile, &y_tile)) {
517             formation_set_destination(m, x_tile, y_tile);
518         }
519     }
520 }
521 
update_enemy_formation(formation * m,int * roman_distance)522 static void update_enemy_formation(formation *m, int *roman_distance)
523 {
524     enemy_army *army = enemy_army_get_editable(m->invasion_id);
525     if (enemy_army_is_stronger_than_legions()) {
526         if (m->figure_type != FIGURE_FORT_JAVELIN) {
527             army->ignore_roman_soldiers = 1;
528         }
529     }
530     formation_decrease_monthly_counters(m);
531     if (city_figures_soldiers() <= 0) {
532         formation_clear_monthly_counters(m);
533     }
534     for (int n = 0; n < MAX_FORMATION_FIGURES; n++) {
535         figure *f = figure_get(m->figures[n]);
536         if (f->action_state == FIGURE_ACTION_150_ATTACK) {
537             figure *opponent = figure_get(f->opponent_id);
538             if (!figure_is_dead(opponent) && figure_is_legion(opponent)) {
539                 formation_record_fight(m);
540             }
541         }
542     }
543     if (formation_has_low_morale(m)) {
544         for (int n = 0; n < MAX_FORMATION_FIGURES; n++) {
545             figure *f = figure_get(m->figures[n]);
546             if (f->action_state != FIGURE_ACTION_150_ATTACK &&
547                 f->action_state != FIGURE_ACTION_149_CORPSE &&
548                 f->action_state != FIGURE_ACTION_148_FLEEING) {
549                 f->action_state = FIGURE_ACTION_148_FLEEING;
550                 figure_route_remove(f);
551             }
552         }
553         return;
554     }
555     if (m->figures[0]) {
556         figure *f = figure_get(m->figures[0]);
557         if (f->state == FIGURE_STATE_ALIVE) {
558             formation_set_home(m, f->x, f->y);
559         }
560     }
561     if (!army->formation_id) {
562         army->formation_id = m->id;
563         army->home_x = m->x_home;
564         army->home_y = m->y_home;
565         army->layout = m->layout;
566         *roman_distance = 0;
567         map_routing_noncitizen_can_travel_over_land(m->x_home, m->y_home, -2, -2, 100000, 300);
568         int x_tile, y_tile;
569         if (map_soldier_strength_get_max(m->x_home, m->y_home, 16, &x_tile, &y_tile)) {
570             *roman_distance = 1;
571         } else if (map_soldier_strength_get_max(m->x_home, m->y_home, 32, &x_tile, &y_tile)) {
572             *roman_distance = 2;
573         }
574         if (army->ignore_roman_soldiers) {
575             *roman_distance = 0;
576         }
577         if (*roman_distance == 1) {
578             // attack roman legion
579             army->destination_x = x_tile;
580             army->destination_y = y_tile;
581             army->destination_building_id = 0;
582         } else {
583             set_enemy_target_building(m);
584             army->destination_x = m->destination_x;
585             army->destination_y = m->destination_y;
586             army->destination_building_id = m->destination_building_id;
587         }
588     }
589     m->enemy_legion_index = army->num_legions++;
590     m->wait_ticks++;
591     formation_set_destination_building(m,
592         army->destination_x, army->destination_y, army->destination_building_id
593     );
594 
595     update_enemy_movement(m, *roman_distance);
596 }
597 
formation_enemy_update(void)598 void formation_enemy_update(void)
599 {
600     if (enemy_army_total_enemy_formations() <= 0) {
601         enemy_armies_clear_ignore_roman_soldiers();
602     } else {
603         enemy_army_calculate_roman_influence();
604         enemy_armies_clear_formations();
605         int roman_distance = 0;
606         for (int i = 1; i < formation_count(); i++) {
607             formation *m = formation_get(i);
608             if (m->in_use && !m->is_herd && !m->is_legion) {
609                 update_enemy_formation(m, &roman_distance);
610             }
611         }
612     }
613     set_native_target_building(formation_get(0));
614 }
615