1 /***********************************************************************
2  Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License as published by
5    the Free Software Foundation; either version 2, or (at your option)
6    any later version.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 ***********************************************************************/
13 
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
17 
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 
22 /* utility */
23 #include "bitvector.h"
24 #include "fcintl.h"
25 #include "log.h"
26 #include "mem.h"
27 #include "rand.h"
28 #include "shared.h"
29 #include "support.h"
30 
31 /* common */
32 #include "base.h"
33 #include "city.h"
34 #include "combat.h"
35 #include "events.h"
36 #include "game.h"
37 #include "government.h"
38 #include "idex.h"
39 #include "map.h"
40 #include "movement.h"
41 #include "packets.h"
42 #include "player.h"
43 #include "research.h"
44 #include "terrain.h"
45 #include "unit.h"
46 #include "unitlist.h"
47 #include "unittype.h"
48 
49 /* common/scriptcore */
50 #include "luascript_signal.h"
51 #include "luascript_types.h"
52 
53 /* aicore */
54 #include "path_finding.h"
55 #include "pf_tools.h"
56 
57 /* server/scripting */
58 #include "script_server.h"
59 
60 /* server */
61 #include "aiiface.h"
62 #include "barbarian.h"
63 #include "citytools.h"
64 #include "cityturn.h"
65 #include "diplhand.h"
66 #include "gamehand.h"
67 #include "maphand.h"
68 #include "notify.h"
69 #include "plrhand.h"
70 #include "sanitycheck.h"
71 #include "sernet.h"
72 #include "srv_main.h"
73 #include "techtools.h"
74 #include "unithand.h"
75 
76 /* server/advisors */
77 #include "advgoto.h"
78 #include "autoexplorer.h"
79 #include "autosettlers.h"
80 
81 /* ai */
82 #include "handicaps.h"
83 
84 #include "unittools.h"
85 
86 
87 /* Tools for controlling the client vision of every unit when a unit
88  * moves + script effects. See unit_move(). You can access this data with
89  * punit->server.moving; it may be NULL if the unit is not moving). */
90 struct unit_move_data {
91   int ref_count;
92   struct unit *punit; /* NULL for invalidating. */
93   struct player *powner;
94   bv_player can_see_unit;
95   bv_player can_see_move;
96   struct vision *old_vision;
97 };
98 
99 #define SPECLIST_TAG unit_move_data
100 #include "speclist.h"
101 #define unit_move_data_list_iterate(_plist, _pdata)                         \
102   TYPED_LIST_ITERATE(struct unit_move_data, _plist, _pdata)
103 #define unit_move_data_list_iterate_end LIST_ITERATE_END
104 #define unit_move_data_list_iterate_rev(_plist, _pdata)                     \
105   TYPED_LIST_ITERATE_REV(struct unit_move_data, _plist, _pdata)
106 #define unit_move_data_list_iterate_rev_end LIST_ITERATE_REV_END
107 
108 /* We need this global variable for our sort algorithm */
109 static struct tile *autoattack_target;
110 
111 static void unit_restore_hitpoints(struct unit *punit);
112 static void unit_restore_movepoints(struct player *pplayer, struct unit *punit);
113 static void update_unit_activity(struct unit *punit);
114 static bool try_to_save_unit(struct unit *punit, struct unit_type *pttype,
115                              bool helpless, bool teleporting,
116                              const struct city *pexclcity);
117 static void wakeup_neighbor_sentries(struct unit *punit);
118 static void do_upgrade_effects(struct player *pplayer);
119 
120 static bool maybe_cancel_patrol_due_to_enemy(struct unit *punit);
121 
122 static bool maybe_become_veteran_real(struct unit *punit, bool settler);
123 
124 static void unit_transport_load_tp_status(struct unit *punit,
125                                                struct unit *ptrans,
126                                                bool force);
127 
128 static void wipe_unit_full(struct unit *punit, bool transported,
129                            enum unit_loss_reason reason,
130                            struct player *killer);
131 static bool unit_enter_hut(struct unit *punit);
132 
133 /**************************************************************************
134   Returns a unit type that matches the role_tech or role roles.
135 
136   If role_tech is given, then we look at all units with this role
137   whose requirements are met by any player, and return a random one.  This
138   can be used to give a unit to barbarians taken from the set of most
139   advanced units researched by the 'real' players.
140 
141   If role_tech is not give (-1) or if there are no matching unit types,
142   then we look at 'role' value and return a random matching unit type.
143 
144   It is an error if there are no available units.  This function will
145   always return a valid unit.
146 **************************************************************************/
find_a_unit_type(enum unit_role_id role,enum unit_role_id role_tech)147 struct unit_type *find_a_unit_type(enum unit_role_id role,
148 				   enum unit_role_id role_tech)
149 {
150   struct unit_type *which[U_LAST];
151   int i, num=0;
152 
153   if (role_tech != -1) {
154     for(i=0; i<num_role_units(role_tech); i++) {
155       struct unit_type *iunit = get_role_unit(role_tech, i);
156       const int minplayers = 2;
157       int players = 0;
158 
159       /* Note, if there's only one player in the game this check will always
160        * fail. */
161       players_iterate(pplayer) {
162 	if (!is_barbarian(pplayer)
163 	    && can_player_build_unit_direct(pplayer, iunit)) {
164 	  players++;
165 	}
166       } players_iterate_end;
167       if (players > minplayers) {
168 	which[num++] = iunit;
169       }
170     }
171   }
172   if(num==0) {
173     for(i=0; i<num_role_units(role); i++) {
174       which[num++] = get_role_unit(role, i);
175     }
176   }
177 
178   /* Ruleset code should ensure there is at least one unit for each
179    * possibly-required role, or check before calling this function. */
180   fc_assert_exit_msg(0 < num, "No unit types in find_a_unit_type(%d, %d)!",
181                      role, role_tech);
182 
183   return which[fc_rand(num)];
184 }
185 
186 /*****************************************************************************
187   Unit has a chance to become veteran. This should not be used for settlers
188   for the work they do.
189 *****************************************************************************/
maybe_make_veteran(struct unit * punit)190 bool maybe_make_veteran(struct unit *punit)
191 {
192   return maybe_become_veteran_real(punit, FALSE);
193 }
194 
195 /*****************************************************************************
196   After a battle, after diplomatic aggression and after surviving trireme
197   loss chance, this routine is called to decide whether or not the unit
198   should become more experienced.
199 
200   There is a specified chance for it to happen, (+50% if player got SUNTZU)
201   the chances are specified in the units.ruleset file.
202 
203   If 'settler' is TRUE the veteran level is increased due to work done by
204   the unit.
205 *****************************************************************************/
maybe_become_veteran_real(struct unit * punit,bool settler)206 static bool maybe_become_veteran_real(struct unit *punit, bool settler)
207 {
208   const struct veteran_system *vsystem;
209   const struct veteran_level *vlevel;
210   int chance;
211 
212   fc_assert_ret_val(punit != NULL, FALSE);
213 
214   vsystem = utype_veteran_system(unit_type_get(punit));
215   fc_assert_ret_val(vsystem != NULL, FALSE);
216   fc_assert_ret_val(vsystem->levels > punit->veteran, FALSE);
217 
218   vlevel = utype_veteran_level(unit_type_get(punit), punit->veteran);
219   fc_assert_ret_val(vlevel != NULL, FALSE);
220 
221   if (punit->veteran + 1 >= vsystem->levels
222       || unit_has_type_flag(punit, UTYF_NO_VETERAN)) {
223     return FALSE;
224   } else if (!settler) {
225     int mod = 100 + get_unit_bonus(punit, EFT_VETERAN_COMBAT);
226 
227     /* The modification is tacked on as a multiplier to the base chance.
228      * For example with a base chance of 50% for green units and a modifier
229      * of +50% the end chance is 75%. */
230     chance = vlevel->raise_chance * mod / 100;
231   } else if (settler && unit_has_type_flag(punit, UTYF_SETTLERS)) {
232     chance = vlevel->work_raise_chance;
233   } else {
234     /* No battle and no work done. */
235     return FALSE;
236   }
237 
238   if (fc_rand(100) < chance) {
239     punit->veteran++;
240     return TRUE;
241   }
242 
243   return FALSE;
244 }
245 
246 /**************************************************************************
247   This is the basic unit versus unit combat routine.
248   1) ALOT of modifiers bonuses etc is added to the 2 units rates.
249   2) If the attack is a bombardment, do rate attacks and don't kill the
250      defender, then return.
251   3) the combat loop, which continues until one of the units are dead
252   4) the aftermath, the loser (and potentially the stack which is below it)
253      is wiped, and the winner gets a chance of gaining veteran status
254 **************************************************************************/
unit_versus_unit(struct unit * attacker,struct unit * defender,bool bombard,int * att_hp,int * def_hp)255 void unit_versus_unit(struct unit *attacker, struct unit *defender,
256 		      bool bombard, int *att_hp, int *def_hp)
257 {
258   int attackpower = get_total_attack_power(attacker, defender);
259   int defensepower = get_total_defense_power(attacker, defender);
260   int attack_firepower, defense_firepower;
261   struct player *plr1 = unit_owner(attacker);
262   struct player *plr2 = unit_owner(defender);
263 
264   *att_hp = attacker->hp;
265   *def_hp = defender->hp;
266   get_modified_firepower(attacker, defender,
267 			 &attack_firepower, &defense_firepower);
268 
269   log_verbose("attack:%d, defense:%d, attack firepower:%d, "
270               "defense firepower:%d", attackpower, defensepower,
271               attack_firepower, defense_firepower);
272 
273   player_update_last_war_action(plr1);
274   player_update_last_war_action(plr2);
275 
276   if (bombard) {
277     int i;
278     int rate = unit_type_get(attacker)->bombard_rate;
279 
280     for (i = 0; i < rate; i++) {
281       if (fc_rand(attackpower+defensepower) >= defensepower) {
282         *def_hp -= attack_firepower;
283       }
284     }
285 
286     /* Don't kill the target. */
287     if (*def_hp <= 0) {
288       *def_hp = 1;
289     }
290     return;
291   }
292 
293   if (attackpower == 0) {
294     *att_hp = 0;
295   } else if (defensepower == 0) {
296     *def_hp = 0;
297   }
298   while (*att_hp > 0 && *def_hp > 0) {
299     if (fc_rand(attackpower + defensepower) >= defensepower) {
300       *def_hp -= attack_firepower;
301     } else {
302       *att_hp -= defense_firepower;
303     }
304   }
305   if (*att_hp < 0) {
306     *att_hp = 0;
307   }
308   if (*def_hp < 0) {
309     *def_hp = 0;
310   }
311 }
312 
313 /***************************************************************************
314   Make maybe make either side of combat veteran
315 ****************************************************************************/
combat_veterans(struct unit * attacker,struct unit * defender)316 void combat_veterans(struct unit *attacker, struct unit *defender)
317 {
318   if (attacker->hp > 0) {
319     maybe_make_veteran(attacker);
320   } else if (defender->hp > 0) {
321     maybe_make_veteran(defender);
322   }
323 }
324 
325 /***************************************************************************
326   Do unit auto-upgrades to players with the EFT_UNIT_UPGRADE effect
327   (traditionally from Leonardo's Workshop).
328 ****************************************************************************/
do_upgrade_effects(struct player * pplayer)329 static void do_upgrade_effects(struct player *pplayer)
330 {
331   int upgrades = get_player_bonus(pplayer, EFT_UPGRADE_UNIT);
332   struct unit_list *candidates;
333 
334   if (upgrades <= 0) {
335     return;
336   }
337   candidates = unit_list_new();
338 
339   unit_list_iterate(pplayer->units, punit) {
340     /* We have to be careful not to strand units at sea, for example by
341      * upgrading a frigate to an ironclad while it was carrying a unit. */
342     if (UU_OK == unit_upgrade_test(punit, TRUE)) {
343       unit_list_prepend(candidates, punit);	/* Potential candidate :) */
344     }
345   } unit_list_iterate_end;
346 
347   while (upgrades > 0 && unit_list_size(candidates) > 0) {
348     /* Upgrade one unit.  The unit is chosen at random from the list of
349      * available candidates. */
350     int candidate_to_upgrade = fc_rand(unit_list_size(candidates));
351     struct unit *punit = unit_list_get(candidates, candidate_to_upgrade);
352     struct unit_type *type_from = unit_type_get(punit);
353     struct unit_type *type_to = can_upgrade_unittype(pplayer, type_from);
354 
355     transform_unit(punit, type_to, TRUE);
356     notify_player(pplayer, unit_tile(punit), E_UNIT_UPGRADED, ftc_server,
357                   _("%s was upgraded for free to %s."),
358                   utype_name_translation(type_from),
359                   unit_link(punit));
360     unit_list_remove(candidates, punit);
361     upgrades--;
362   }
363 
364   unit_list_destroy(candidates);
365 }
366 
367 /***************************************************************************
368   1. Do Leonardo's Workshop upgrade if applicable.
369 
370   2. Restore/decrease unit hitpoints.
371 
372   3. Kill dead units.
373 
374   4. Rescue airplanes by returning them to base automatically.
375 
376   5. Decrease fuel of planes in the air.
377 
378   6. Refuel planes that are in bases.
379 
380   7. Kill planes that are out of fuel.
381 ****************************************************************************/
player_restore_units(struct player * pplayer)382 void player_restore_units(struct player *pplayer)
383 {
384   /* 1) get Leonardo out of the way first: */
385   do_upgrade_effects(pplayer);
386 
387   unit_list_iterate_safe(pplayer->units, punit) {
388 
389     /* 2) Modify unit hitpoints. Helicopters can even lose them. */
390     unit_restore_hitpoints(punit);
391 
392     /* 3) Check that unit has hitpoints */
393     if (punit->hp <= 0) {
394       /* This should usually only happen for heli units, but if any other
395        * units get 0 hp somehow, catch them too.  --dwp  */
396       /* if 'game.server.killunhomed' is activated unhomed units are slowly
397        * killed; notify player here */
398       if (!punit->homecity && 0 < game.server.killunhomed) {
399         notify_player(pplayer, unit_tile(punit), E_UNIT_LOST_MISC,
400                       ftc_server, _("Your %s has run out of hit points "
401                                     "because it was not supported by a city."),
402                       unit_tile_link(punit));
403       } else {
404         notify_player(pplayer, unit_tile(punit), E_UNIT_LOST_MISC, ftc_server,
405                       _("Your %s has run out of hit points."),
406                       unit_tile_link(punit));
407       }
408 
409       wipe_unit(punit, ULR_HP_LOSS, NULL);
410       continue; /* Continue iterating... */
411     }
412 
413     /* 4) Rescue planes if needed */
414     if (utype_fuel(unit_type_get(punit))) {
415       /* Shall we emergency return home on the last vapors? */
416 
417       /* I think this is strongly against the spirit of client goto.
418        * The problem is (again) that here we know too much. -- Zamar */
419 
420       if (punit->fuel <= 1
421           && !is_unit_being_refueled(punit)) {
422         struct unit *carrier;
423 
424         carrier = transporter_for_unit(punit);
425         if (carrier) {
426           unit_transport_load_tp_status(punit, carrier, FALSE);
427         } else {
428           bool alive = true;
429 
430           struct pf_map *pfm;
431           struct pf_parameter parameter;
432 
433           pft_fill_unit_parameter(&parameter, punit);
434           parameter.omniscience = !has_handicap(pplayer, H_MAP);
435           pfm = pf_map_new(&parameter);
436 
437           pf_map_move_costs_iterate(pfm, ptile, move_cost, TRUE) {
438             if (move_cost > punit->moves_left) {
439               /* Too far */
440               break;
441             }
442 
443             if (is_airunit_refuel_point(ptile, pplayer, punit)) {
444               struct pf_path *path;
445               int id = punit->id;
446 
447               /* Client orders may be running for this unit - if so
448                * we free them before engaging goto. */
449               free_unit_orders(punit);
450 
451               path = pf_map_path(pfm, ptile);
452 
453               alive = adv_follow_path(punit, path, ptile);
454 
455               if (!alive) {
456                 log_error("rescue plane: unit %d died enroute!", id);
457               } else if (!same_pos(unit_tile(punit), ptile)) {
458                 /* Enemy units probably blocked our route
459                  * FIXME: We should try find alternative route around
460                  * the enemy unit instead of just giving up and crashing. */
461                 log_debug("rescue plane: unit %d could not move to "
462                           "refuel point!", punit->id);
463               }
464 
465               if (alive) {
466                 /* Clear activity. Unit info will be sent in the end of
467 	         * the function. */
468                 unit_activity_handling(punit, ACTIVITY_IDLE);
469                 adv_unit_new_task(punit, AUT_NONE, NULL);
470                 punit->goto_tile = NULL;
471 
472                 if (!is_unit_being_refueled(punit)) {
473                   carrier = transporter_for_unit(punit);
474                   if (carrier) {
475                     unit_transport_load_tp_status(punit, carrier, FALSE);
476                   }
477                 }
478 
479                 notify_player(pplayer, unit_tile(punit),
480                               E_UNIT_ORDERS, ftc_server,
481                               _("Your %s has returned to refuel."),
482                               unit_link(punit));
483 	      }
484               pf_path_destroy(path);
485               break;
486             }
487           } pf_map_move_costs_iterate_end;
488           pf_map_destroy(pfm);
489 
490           if (!alive) {
491             /* Unit died trying to move to refuel point. */
492             return;
493 	  }
494         }
495       }
496 
497       /* 5) Update fuel */
498       punit->fuel--;
499 
500       /* 6) Automatically refuel air units in cities, airbases, and
501        *    transporters (carriers). */
502       if (is_unit_being_refueled(punit)) {
503 	punit->fuel = utype_fuel(unit_type_get(punit));
504       }
505     }
506   } unit_list_iterate_safe_end;
507 
508   /* 7) Check if there are air units without fuel */
509   unit_list_iterate_safe(pplayer->units, punit) {
510     if (punit->fuel <= 0 && utype_fuel(unit_type_get(punit))) {
511       notify_player(pplayer, unit_tile(punit), E_UNIT_LOST_MISC, ftc_server,
512                     _("Your %s has run out of fuel."),
513                     unit_tile_link(punit));
514       wipe_unit(punit, ULR_FUEL, NULL);
515     }
516   } unit_list_iterate_safe_end;
517 
518   /* Send all updates. */
519   unit_list_iterate(pplayer->units, punit) {
520     send_unit_info(NULL, punit);
521   } unit_list_iterate_end;
522 }
523 
524 /****************************************************************************
525   add hitpoints to the unit, hp_gain_coord returns the amount to add
526   united nations will speed up the process by 2 hp's / turn, means helicopters
527   will actually not lose hp's every turn if player have that wonder.
528   Units which have moved don't gain hp, except the United Nations and
529   helicopter effects still occur.
530 
531   If 'game.server.killunhomed' is greater than 0, unhomed units lose
532   'game.server.killunhomed' hitpoints each turn, killing the unit at the end.
533 *****************************************************************************/
unit_restore_hitpoints(struct unit * punit)534 static void unit_restore_hitpoints(struct unit *punit)
535 {
536   bool was_lower;
537   int save_hp;
538   struct unit_class *pclass = unit_class_get(punit);
539   struct city *pcity = tile_city(unit_tile(punit));
540 
541   was_lower = (punit->hp < unit_type_get(punit)->hp);
542   save_hp = punit->hp;
543 
544   if (!punit->moved) {
545     punit->hp += hp_gain_coord(punit);
546   }
547 
548   /* Bonus recovery HP (traditionally from the United Nations) */
549   punit->hp += get_unit_bonus(punit, EFT_UNIT_RECOVER);
550 
551   if (!punit->homecity && 0 < game.server.killunhomed
552       && !unit_has_type_flag(punit, UTYF_GAMELOSS)) {
553     /* Hit point loss of units without homecity; at least 1 hp! */
554     /* Gameloss units are immune to this effect. */
555     int hp_loss = MAX(unit_type_get(punit)->hp * game.server.killunhomed / 100,
556                       1);
557     punit->hp = MIN(punit->hp - hp_loss, save_hp - 1);
558   }
559 
560   if (!pcity && !tile_has_native_base(unit_tile(punit), unit_type_get(punit))
561       && !unit_transported(punit)) {
562     punit->hp -= unit_type_get(punit)->hp * pclass->hp_loss_pct / 100;
563   }
564 
565   if (punit->hp >= unit_type_get(punit)->hp) {
566     punit->hp = unit_type_get(punit)->hp;
567     if (was_lower && punit->activity == ACTIVITY_SENTRY) {
568       set_unit_activity(punit, ACTIVITY_IDLE);
569     }
570   }
571 
572   if (punit->hp < 0) {
573     punit->hp = 0;
574   }
575 
576   punit->moved = FALSE;
577   punit->paradropped = FALSE;
578 }
579 
580 /***************************************************************************
581   Move points are trivial, only modifiers to the base value is if it's
582   sea units and the player has certain wonders/techs. Then add veteran
583   bonus, if any.
584 ***************************************************************************/
unit_restore_movepoints(struct player * pplayer,struct unit * punit)585 static void unit_restore_movepoints(struct player *pplayer, struct unit *punit)
586 {
587   punit->moves_left = unit_move_rate(punit);
588   punit->done_moving = FALSE;
589 }
590 
591 /****************************************************************************
592   Iterate through all units and update them.
593 ****************************************************************************/
update_unit_activities(struct player * pplayer)594 void update_unit_activities(struct player *pplayer)
595 {
596   unit_list_iterate_safe(pplayer->units, punit) {
597     update_unit_activity(punit);
598   } unit_list_iterate_safe_end;
599 }
600 
601 /****************************************************************************
602   Iterate through all units and execute their orders.
603 ****************************************************************************/
execute_unit_orders(struct player * pplayer)604 void execute_unit_orders(struct player *pplayer)
605 {
606   unit_list_iterate_safe(pplayer->units, punit) {
607     if (unit_has_orders(punit)) {
608       execute_orders(punit, FALSE);
609     }
610   } unit_list_iterate_safe_end;
611 }
612 
613 /****************************************************************************
614   Iterate through all units and remember their current activities.
615 ****************************************************************************/
finalize_unit_phase_beginning(struct player * pplayer)616 void finalize_unit_phase_beginning(struct player *pplayer)
617 {
618   /* Remember activities only after all knock-on effects of unit activities
619    * on other units have been resolved */
620   unit_list_iterate(pplayer->units, punit) {
621     punit->changed_from = punit->activity;
622     punit->changed_from_target = punit->activity_target;
623     punit->changed_from_count = punit->activity_count;
624     send_unit_info(NULL, punit);
625   } unit_list_iterate_end;
626 }
627 
628 /**************************************************************************
629   Calculate the total amount of activity performed by all units on a tile
630   for a given task and target.
631 **************************************************************************/
total_activity(struct tile * ptile,enum unit_activity act,struct extra_type * tgt)632 static int total_activity(struct tile *ptile, enum unit_activity act,
633                           struct extra_type *tgt)
634 {
635   int total = 0;
636   bool tgt_matters = activity_requires_target(act);
637 
638   unit_list_iterate (ptile->units, punit) {
639     if (punit->activity == act
640         && (!tgt_matters || punit->activity_target == tgt)) {
641       total += punit->activity_count;
642     }
643   } unit_list_iterate_end;
644 
645   return total;
646 }
647 
648 /**************************************************************************
649   Check the total amount of activity performed by all units on a tile
650   for a given task.
651 **************************************************************************/
total_activity_done(struct tile * ptile,enum unit_activity act,struct extra_type * tgt)652 static bool total_activity_done(struct tile *ptile, enum unit_activity act,
653                                 struct extra_type *tgt)
654 {
655   return total_activity(ptile, act, tgt) >= tile_activity_time(act, ptile, tgt);
656 }
657 
658 /**************************************************************************
659   Common notification for all experience levels.
660 **************************************************************************/
notify_unit_experience(struct unit * punit)661 void notify_unit_experience(struct unit *punit)
662 {
663   const struct veteran_system *vsystem;
664   const struct veteran_level *vlevel;
665 
666   if (!punit) {
667     return;
668   }
669 
670   vsystem = utype_veteran_system(unit_type_get(punit));
671   fc_assert_ret(vsystem != NULL);
672   fc_assert_ret(vsystem->levels > punit->veteran);
673 
674   vlevel = utype_veteran_level(unit_type_get(punit), punit->veteran);
675   fc_assert_ret(vlevel != NULL);
676 
677   notify_player(unit_owner(punit), unit_tile(punit),
678                 E_UNIT_BECAME_VET, ftc_server,
679                 /* TRANS: Your <unit> became ... rank of <veteran level>. */
680                 _("Your %s became more experienced and achieved the rank "
681                   "of %s."),
682                 unit_link(punit), name_translation_get(&vlevel->name));
683 }
684 
685 /**************************************************************************
686   Convert a single unit to another type.
687 **************************************************************************/
unit_convert(struct unit * punit)688 static void unit_convert(struct unit *punit)
689 {
690   struct unit_type *to_type, *from_type;
691 
692   from_type = unit_type_get(punit);
693   to_type = from_type->converted_to;
694 
695   if (unit_can_convert(punit)) {
696     transform_unit(punit, to_type, TRUE);
697     notify_player(unit_owner(punit), unit_tile(punit),
698                   E_UNIT_UPGRADED, ftc_server,
699                   _("%s converted to %s."),
700                   utype_name_translation(from_type),
701                   utype_name_translation(to_type));
702   } else {
703     notify_player(unit_owner(punit), unit_tile(punit),
704                   E_UNIT_UPGRADED, ftc_server,
705                   _("%s cannot be converted."),
706                   utype_name_translation(from_type));
707   }
708 }
709 
710 /**************************************************************************
711   progress settlers in their current tasks,
712   and units that is pillaging.
713   also move units that is on a goto.
714   restore unit move points (information needed for settler tasks)
715 **************************************************************************/
update_unit_activity(struct unit * punit)716 static void update_unit_activity(struct unit *punit)
717 {
718   const enum unit_activity tile_changing_actions[] =
719     { ACTIVITY_PILLAGE, ACTIVITY_GEN_ROAD, ACTIVITY_IRRIGATE, ACTIVITY_MINE,
720       ACTIVITY_BASE, ACTIVITY_TRANSFORM, ACTIVITY_POLLUTION,
721       ACTIVITY_FALLOUT, ACTIVITY_LAST };
722 
723   struct player *pplayer = unit_owner(punit);
724   bool unit_activity_done = FALSE;
725   enum unit_activity activity = punit->activity;
726   struct tile *ptile = unit_tile(punit);
727   int i;
728 
729   switch (activity) {
730   case ACTIVITY_IDLE:
731   case ACTIVITY_EXPLORE:
732   case ACTIVITY_FORTIFIED:
733   case ACTIVITY_SENTRY:
734   case ACTIVITY_GOTO:
735   case ACTIVITY_PATROL_UNUSED:
736   case ACTIVITY_UNKNOWN:
737   case ACTIVITY_LAST:
738     /*  We don't need the activity_count for the above */
739     break;
740 
741   case ACTIVITY_FORTIFYING:
742   case ACTIVITY_CONVERT:
743     punit->activity_count += get_activity_rate_this_turn(punit);
744     break;
745 
746   case ACTIVITY_POLLUTION:
747   case ACTIVITY_MINE:
748   case ACTIVITY_IRRIGATE:
749   case ACTIVITY_PILLAGE:
750   case ACTIVITY_TRANSFORM:
751   case ACTIVITY_FALLOUT:
752   case ACTIVITY_BASE:
753   case ACTIVITY_GEN_ROAD:
754     punit->activity_count += get_activity_rate_this_turn(punit);
755 
756     /* settler may become veteran when doing something useful */
757     if (maybe_become_veteran_real(punit, TRUE)) {
758       notify_unit_experience(punit);
759     }
760     break;
761   case ACTIVITY_OLD_ROAD:
762   case ACTIVITY_OLD_RAILROAD:
763   case ACTIVITY_FORTRESS:
764   case ACTIVITY_AIRBASE:
765     fc_assert(FALSE);
766     break;
767   };
768 
769   unit_restore_movepoints(pplayer, punit);
770 
771   switch (activity) {
772   case ACTIVITY_IDLE:
773   case ACTIVITY_FORTIFIED:
774   case ACTIVITY_SENTRY:
775   case ACTIVITY_GOTO:
776   case ACTIVITY_UNKNOWN:
777   case ACTIVITY_FORTIFYING:
778   case ACTIVITY_CONVERT:
779   case ACTIVITY_PATROL_UNUSED:
780   case ACTIVITY_LAST:
781     /* no default, ensure all handled */
782     break;
783 
784   case ACTIVITY_EXPLORE:
785     do_explore(punit);
786     return;
787 
788   case ACTIVITY_PILLAGE:
789     if (total_activity_done(ptile, ACTIVITY_PILLAGE,
790                             punit->activity_target)) {
791       struct player *victim = tile_owner(ptile); /* Owner before fortress gets destroyed */
792 
793       destroy_extra(ptile, punit->activity_target);
794       unit_activity_done = TRUE;
795 
796       bounce_units_on_terrain_change(ptile);
797 
798       call_incident(INCIDENT_PILLAGE, unit_owner(punit), victim);
799 
800       /* Change vision if effects have changed. */
801       unit_list_refresh_vision(ptile->units);
802     }
803     break;
804 
805   case ACTIVITY_POLLUTION:
806     /* TODO: Remove this fallback target setting when target always correctly
807      *       set */
808     if (punit->activity_target == NULL) {
809       punit->activity_target = prev_extra_in_tile(ptile, ERM_CLEANPOLLUTION,
810                                                   NULL, punit);
811     }
812     if (total_activity_done(ptile, ACTIVITY_POLLUTION, punit->activity_target)) {
813       destroy_extra(ptile, punit->activity_target);
814       unit_activity_done = TRUE;
815     }
816     break;
817 
818   case ACTIVITY_FALLOUT:
819     /* TODO: Remove this fallback target setting when target always correctly
820      *       set */
821     if (punit->activity_target == NULL) {
822       punit->activity_target = prev_extra_in_tile(ptile, ERM_CLEANFALLOUT,
823                                                   NULL, punit);
824     }
825     if (total_activity_done(ptile, ACTIVITY_FALLOUT, punit->activity_target)) {
826       destroy_extra(ptile, punit->activity_target);
827       unit_activity_done = TRUE;
828     }
829     break;
830 
831   case ACTIVITY_BASE:
832     {
833       if (total_activity(ptile, ACTIVITY_BASE, punit->activity_target)
834           >= tile_activity_time(ACTIVITY_BASE, ptile, punit->activity_target)) {
835         create_extra(ptile, punit->activity_target, unit_owner(punit));
836         unit_activity_done = TRUE;
837       }
838     }
839     break;
840 
841   case ACTIVITY_GEN_ROAD:
842     {
843       if (total_activity(ptile, ACTIVITY_GEN_ROAD, punit->activity_target)
844           >= tile_activity_time(ACTIVITY_GEN_ROAD, ptile, punit->activity_target)) {
845         create_extra(ptile, punit->activity_target, unit_owner(punit));
846         unit_activity_done = TRUE;
847       }
848     }
849     break;
850 
851   case ACTIVITY_IRRIGATE:
852   case ACTIVITY_MINE:
853   case ACTIVITY_TRANSFORM:
854     if (total_activity_done(ptile, activity, punit->activity_target)) {
855       struct terrain *old = tile_terrain(ptile);
856 
857       /* The function below could change the terrain. Therefore, we have to
858        * check the terrain (which will also do a sanity check for the tile). */
859       tile_apply_activity(ptile, activity, punit->activity_target);
860       check_terrain_change(ptile, old);
861       unit_activity_done = TRUE;
862     }
863     break;
864 
865   case ACTIVITY_OLD_ROAD:
866   case ACTIVITY_OLD_RAILROAD:
867   case ACTIVITY_FORTRESS:
868   case ACTIVITY_AIRBASE:
869     fc_assert(FALSE);
870     break;
871   }
872 
873   if (unit_activity_done) {
874     update_tile_knowledge(ptile);
875     if (ACTIVITY_IRRIGATE == activity
876         || ACTIVITY_MINE == activity
877         || ACTIVITY_TRANSFORM == activity) {
878       /* FIXME: As we might probably do the activity again, because of the
879        * terrain change cycles, we need to treat these cases separatly.
880        * Probably ACTIVITY_TRANSFORM should be associated to its terrain
881        * target, whereas ACTIVITY_IRRIGATE and ACTIVITY_MINE should only
882        * used for extras. */
883       unit_list_iterate(ptile->units, punit2) {
884         if (punit2->activity == activity) {
885           set_unit_activity(punit2, ACTIVITY_IDLE);
886           send_unit_info(NULL, punit2);
887         }
888       } unit_list_iterate_end;
889     } else {
890       unit_list_iterate(ptile->units, punit2) {
891         if (!can_unit_continue_current_activity(punit2)) {
892           set_unit_activity(punit2, ACTIVITY_IDLE);
893           send_unit_info(NULL, punit2);
894         }
895       } unit_list_iterate_end;
896     }
897 
898     for (i = 0; tile_changing_actions[i] != ACTIVITY_LAST; i++) {
899       if (tile_changing_actions[i] == activity) {
900         /* Some units nearby may not be able to continue their action,
901          * such as building irrigation if we removed the only source
902          * of water from them. */
903         adjc_iterate(ptile, ptile2) {
904           unit_list_iterate(ptile2->units, punit2) {
905             if (!can_unit_continue_current_activity(punit2)) {
906               if (unit_has_orders(punit2)) {
907                 notify_player(unit_owner(punit2), unit_tile(punit2),
908                               E_UNIT_ORDERS, ftc_server,
909                               _("Orders for %s aborted because activity "
910                                 "is no longer available."),
911                               unit_link(punit2));
912                 free_unit_orders(punit2);
913               }
914               set_unit_activity(punit2, ACTIVITY_IDLE);
915               send_unit_info(NULL, punit2);
916             }
917           } unit_list_iterate_end;
918         } adjc_iterate_end;
919         break;
920       }
921     }
922   }
923 
924   if (activity == ACTIVITY_FORTIFYING) {
925     if (punit->activity_count >= 1) {
926       set_unit_activity(punit, ACTIVITY_FORTIFIED);
927     }
928   }
929 
930   if (activity == ACTIVITY_CONVERT) {
931     if (punit->activity_count >= unit_type_get(punit)->convert_time * ACTIVITY_FACTOR) {
932       unit_convert(punit);
933       set_unit_activity(punit, ACTIVITY_IDLE);
934     }
935   }
936 }
937 
938 /**************************************************************************
939   Forget the unit's last activity so that it can't be resumed. This is
940   used for example when the unit moves or attacks.
941 **************************************************************************/
unit_forget_last_activity(struct unit * punit)942 void unit_forget_last_activity(struct unit *punit)
943 {
944   punit->changed_from = ACTIVITY_IDLE;
945 }
946 
947 /**************************************************************************
948   Return TRUE iff activity requires some sort of target to be specified by
949   the client.
950 **************************************************************************/
unit_activity_needs_target_from_client(enum unit_activity activity)951 bool unit_activity_needs_target_from_client(enum unit_activity activity)
952 {
953   switch (activity) {
954   case ACTIVITY_PILLAGE:
955     /* Can be set server side. */
956     return FALSE;
957   default:
958     return activity_requires_target(activity);
959   }
960 }
961 
962 /**************************************************************************
963   For some activities (currently only pillaging), the precise target can
964   be assigned by the server rather than explicitly requested by the client.
965   This function assigns a specific activity+target if the current
966   settings are open-ended (otherwise leaves them unchanged).
967 
968   Please update unit_activity_needs_target_from_client() if you add server
969   side unit activity target setting to more activities.
970 **************************************************************************/
unit_assign_specific_activity_target(struct unit * punit,enum unit_activity * activity,struct extra_type ** target)971 void unit_assign_specific_activity_target(struct unit *punit,
972                                           enum unit_activity *activity,
973                                           struct extra_type **target)
974 {
975   if (*activity == ACTIVITY_PILLAGE
976       && *target == NULL) {
977     struct tile *ptile = unit_tile(punit);
978     struct extra_type *tgt;
979 
980     bv_extras extras = *tile_extras(ptile);
981 
982     while ((tgt = get_preferred_pillage(extras))) {
983 
984       BV_CLR(extras, extra_index(tgt));
985 
986       if (can_unit_do_activity_targeted(punit, *activity, tgt)) {
987         *target = tgt;
988         return;
989       }
990     }
991     /* Nothing we can pillage here. */
992     *activity = ACTIVITY_IDLE;
993   }
994 }
995 
996 /**************************************************************************
997   Find place to place partisans. Returns whether such spot was found, and
998   if it has been found, dst_tile contains that tile.
999 **************************************************************************/
find_a_good_partisan_spot(struct tile * pcenter,struct player * powner,struct unit_type * u_type,int sq_radius,struct tile ** dst_tile)1000 static bool find_a_good_partisan_spot(struct tile *pcenter,
1001                                       struct player *powner,
1002                                       struct unit_type *u_type,
1003                                       int sq_radius,
1004                                       struct tile **dst_tile)
1005 {
1006   int bestvalue = 0;
1007 
1008   /* coords of best tile in arg pointers */
1009   circle_iterate(pcenter, sq_radius, ptile) {
1010     int value;
1011 
1012     if (!is_native_tile(u_type, ptile)) {
1013       continue;
1014     }
1015 
1016     if (NULL != tile_city(ptile)) {
1017       continue;
1018     }
1019 
1020     if (0 < unit_list_size(ptile->units)) {
1021       continue;
1022     }
1023 
1024     /* City may not have changed hands yet; see place_partisans(). */
1025     value = get_virtual_defense_power(NULL, u_type, powner,
1026 				      ptile, FALSE, 0);
1027     value *= 10;
1028 
1029     if (tile_continent(ptile) != tile_continent(pcenter)) {
1030       value /= 2;
1031     }
1032 
1033     value -= fc_rand(value/3);
1034 
1035     if (value > bestvalue) {
1036       *dst_tile = ptile;
1037       bestvalue = value;
1038     }
1039   } circle_iterate_end;
1040 
1041   return bestvalue > 0;
1042 }
1043 
1044 /**************************************************************************
1045   Place partisans for powner around pcenter (normally around a city).
1046 **************************************************************************/
place_partisans(struct tile * pcenter,struct player * powner,int count,int sq_radius)1047 void place_partisans(struct tile *pcenter, struct player *powner,
1048                      int count, int sq_radius)
1049 {
1050   struct tile *ptile = NULL;
1051   struct unit_type *u_type = get_role_unit(L_PARTISAN, 0);
1052 
1053   while (count-- > 0
1054          && find_a_good_partisan_spot(pcenter, powner, u_type,
1055                                       sq_radius, &ptile)) {
1056     struct unit *punit;
1057 
1058     punit = create_unit(powner, ptile, u_type, 0, 0, -1);
1059     if (can_unit_do_activity(punit, ACTIVITY_FORTIFYING)) {
1060       punit->activity = ACTIVITY_FORTIFIED; /* yes; directly fortified */
1061       send_unit_info(NULL, punit);
1062     }
1063   }
1064 }
1065 
1066 /**************************************************************************
1067 Teleport punit to city at cost specified. Returns success. Note that unit
1068 may die if it succesfully moves, i.e., even when return value is TRUE.
1069 (If specified cost is -1, then teleportation costs all movement.)
1070 **************************************************************************/
teleport_unit_to_city(struct unit * punit,struct city * pcity,int move_cost,bool verbose)1071 bool teleport_unit_to_city(struct unit *punit, struct city *pcity,
1072 			  int move_cost, bool verbose)
1073 {
1074   struct tile *src_tile = unit_tile(punit), *dst_tile = pcity->tile;
1075 
1076   if (city_owner(pcity) == unit_owner(punit)){
1077     log_verbose("Teleported %s %s from (%d,%d) to %s",
1078                 nation_rule_name(nation_of_unit(punit)),
1079                 unit_rule_name(punit), TILE_XY(src_tile), city_name_get(pcity));
1080     if (verbose) {
1081       notify_player(unit_owner(punit), city_tile(pcity),
1082                     E_UNIT_RELOCATED, ftc_server,
1083                     _("Teleported your %s to %s."),
1084                     unit_link(punit),
1085                     city_link(pcity));
1086     }
1087 
1088     /* Silently free orders since they won't be applicable anymore. */
1089     free_unit_orders(punit);
1090 
1091     if (move_cost == -1) {
1092       move_cost = punit->moves_left;
1093     }
1094     unit_move(punit, dst_tile, move_cost, NULL);
1095 
1096     return TRUE;
1097   }
1098   return FALSE;
1099 }
1100 
1101 /**************************************************************************
1102   Move or remove a unit due to stack conflicts. This function will try to
1103   find a random safe tile within a two tile distance of the unit's current
1104   tile and move the unit there. If no tiles are found, the unit is
1105   disbanded. If 'verbose' is TRUE, a message is sent to the unit owner
1106   regarding what happened.
1107 **************************************************************************/
bounce_unit(struct unit * punit,bool verbose)1108 void bounce_unit(struct unit *punit, bool verbose)
1109 {
1110   struct player *pplayer;
1111   struct tile *punit_tile;
1112   struct unit_list *pcargo_units;
1113   int count = 0;
1114 
1115   /* I assume that there are no topologies that have more than
1116    * (2d + 1)^2 tiles in the "square" of "radius" d. */
1117   const int DIST = 2;
1118   struct tile *tiles[(2 * DIST + 1) * (2 * DIST + 1)];
1119 
1120   if (!punit) {
1121     return;
1122   }
1123 
1124   pplayer = unit_owner(punit);
1125   punit_tile = unit_tile(punit);
1126 
1127   square_iterate(punit_tile, DIST, ptile) {
1128     if (count >= ARRAY_SIZE(tiles)) {
1129       break;
1130     }
1131 
1132     if (ptile == punit_tile) {
1133       continue;
1134     }
1135 
1136     if (can_unit_survive_at_tile(punit, ptile)
1137         && !is_non_allied_city_tile(ptile, pplayer)
1138         && !is_non_allied_unit_tile(ptile, pplayer)) {
1139       tiles[count++] = ptile;
1140     }
1141   } square_iterate_end;
1142 
1143   if (count > 0) {
1144     struct tile *ptile = tiles[fc_rand(count)];
1145 
1146     if (verbose) {
1147       notify_player(pplayer, ptile, E_UNIT_RELOCATED, ftc_server,
1148                     /* TRANS: A unit is moved to resolve stack conflicts. */
1149                     _("Moved your %s."),
1150                     unit_link(punit));
1151     }
1152     unit_move(punit, ptile, 0, NULL);
1153     return;
1154   }
1155 
1156   /* Didn't find a place to bounce the unit, going to disband it.
1157    * Try to bounce transported units. */
1158   if (0 < get_transporter_occupancy(punit)) {
1159     pcargo_units = unit_transport_cargo(punit);
1160     unit_list_iterate(pcargo_units, pcargo) {
1161       bounce_unit(pcargo, verbose);
1162     } unit_list_iterate_end;
1163   }
1164 
1165   if (verbose) {
1166     notify_player(pplayer, punit_tile, E_UNIT_LOST_MISC, ftc_server,
1167                   /* TRANS: A unit is disbanded to resolve stack conflicts. */
1168                   _("Disbanded your %s."),
1169                   unit_tile_link(punit));
1170   }
1171   wipe_unit(punit, ULR_STACK_CONFLICT, NULL);
1172 }
1173 
1174 
1175 /**************************************************************************
1176   Throw pplayer's units from non allied cities
1177 
1178   If verbose is true, pplayer gets messages about where each units goes.
1179 **************************************************************************/
throw_units_from_illegal_cities(struct player * pplayer,bool verbose)1180 static void throw_units_from_illegal_cities(struct player *pplayer,
1181                                             bool verbose)
1182 {
1183   struct tile *ptile;
1184   struct city *pcity;
1185   struct unit *ptrans;
1186   struct unit_list *pcargo_units;
1187 
1188   /* Unload undesired units from transports, if possible. */
1189   unit_list_iterate(pplayer->units, punit) {
1190     ptile = unit_tile(punit);
1191     pcity = tile_city(ptile);
1192     if (NULL != pcity
1193         && !pplayers_allied(city_owner(pcity), pplayer)
1194         && 0 < get_transporter_occupancy(punit)) {
1195       pcargo_units = unit_transport_cargo(punit);
1196       unit_list_iterate(pcargo_units, pcargo) {
1197         if (!pplayers_allied(unit_owner(pcargo), pplayer)) {
1198           if (can_unit_exist_at_tile(pcargo, ptile)) {
1199             unit_transport_unload_send(pcargo);
1200           }
1201         }
1202       } unit_list_iterate_end;
1203     }
1204   } unit_list_iterate_end;
1205 
1206   /* Bounce units except transported ones which will be bounced with their
1207    * transport. */
1208   unit_list_iterate_safe(pplayer->units, punit) {
1209     ptile = unit_tile(punit);
1210     pcity = tile_city(ptile);
1211     if (NULL != pcity
1212         && !pplayers_allied(city_owner(pcity), pplayer)) {
1213       ptrans = unit_transport_get(punit);
1214       if (NULL == ptrans || pplayer != unit_owner(ptrans)) {
1215         bounce_unit(punit, verbose);
1216       }
1217     }
1218   } unit_list_iterate_safe_end;
1219 
1220 #ifdef FREECIV_DEBUG
1221   /* Sanity check. */
1222   unit_list_iterate(pplayer->units, punit) {
1223     ptile = unit_tile(punit);
1224     pcity = tile_city(ptile);
1225     fc_assert_msg(NULL == pcity
1226                   || pplayers_allied(city_owner(pcity), pplayer),
1227                   "Failed to throw %s %d from %s %d (%d, %d)",
1228                   unit_rule_name(punit),
1229                   punit->id,
1230                   city_name_get(pcity),
1231                   pcity->id,
1232                   TILE_XY(ptile));
1233   } unit_list_iterate_end;
1234 #endif /* FREECIV_DEBUG */
1235 }
1236 
1237 /**************************************************************************
1238   For each pplayer's unit, check if we stack illegally, if so,
1239   bounce both players' units. If on ocean tile, bounce everyone but ships
1240   to avoid drowning. This function assumes that cities are clean.
1241 
1242   If verbose is true, the unit owner gets messages about where each
1243   units goes.
1244 **************************************************************************/
resolve_stack_conflicts(struct player * pplayer,struct player * aplayer,bool verbose)1245 static void resolve_stack_conflicts(struct player *pplayer,
1246                                     struct player *aplayer, bool verbose)
1247 {
1248   unit_list_iterate_safe(pplayer->units, punit) {
1249     struct tile *ptile = unit_tile(punit);
1250 
1251     if (is_non_allied_unit_tile(ptile, pplayer)) {
1252       unit_list_iterate_safe(ptile->units, aunit) {
1253         if (unit_owner(aunit) == pplayer
1254             || unit_owner(aunit) == aplayer
1255             || !can_unit_survive_at_tile(aunit, ptile)) {
1256           bounce_unit(aunit, verbose);
1257         }
1258       } unit_list_iterate_safe_end;
1259     }
1260   } unit_list_iterate_safe_end;
1261 }
1262 
1263 /**************************************************************************
1264   When in civil war or an alliance breaks there will potentially be units
1265   from both sides coexisting on the same squares.  This routine resolves
1266   this by first bouncing off non-allied units from their cities, then by
1267   bouncing both players' units in now illegal multiowner stacks.  To avoid
1268   drowning due to removal of transports, we bounce everyone (including
1269   third parties' units) from ocean tiles.
1270 
1271   If verbose is true, the unit owner gets messages about where each
1272   units goes.
1273 **************************************************************************/
resolve_unit_stacks(struct player * pplayer,struct player * aplayer,bool verbose)1274 void resolve_unit_stacks(struct player *pplayer, struct player *aplayer,
1275                          bool verbose)
1276 {
1277   throw_units_from_illegal_cities(pplayer, verbose);
1278   throw_units_from_illegal_cities(aplayer, verbose);
1279 
1280   resolve_stack_conflicts(pplayer, aplayer, verbose);
1281   resolve_stack_conflicts(aplayer, pplayer, verbose);
1282 }
1283 
1284 /****************************************************************************
1285   Returns the list of the units seen by 'pplayer' potentially seen only
1286   thanks to an alliance with 'aplayer'. The returned pointer is newly
1287   allocated and should be freed by the caller, using unit_list_destroy().
1288 ****************************************************************************/
get_units_seen_via_ally(const struct player * pplayer,const struct player * aplayer)1289 struct unit_list *get_units_seen_via_ally(const struct player *pplayer,
1290                                           const struct player *aplayer)
1291 {
1292   struct unit_list *seen_units = unit_list_new();
1293 
1294   /* Anybody's units inside ally's cities */
1295   city_list_iterate(aplayer->cities, pcity) {
1296     unit_list_iterate(city_tile(pcity)->units, punit) {
1297       if (can_player_see_unit(pplayer, punit)) {
1298         unit_list_append(seen_units, punit);
1299       }
1300     } unit_list_iterate_end;
1301   } city_list_iterate_end;
1302 
1303   /* Ally's own units inside transports */
1304   unit_list_iterate(aplayer->units, punit) {
1305     if (unit_transported(punit) && can_player_see_unit(pplayer, punit)) {
1306       unit_list_append(seen_units, punit);
1307     }
1308   } unit_list_iterate_end;
1309 
1310   /* Make sure the same unit is not added in multiple phases
1311    * (unit within transport in a city) */
1312   unit_list_unique(seen_units);
1313 
1314   return seen_units;
1315 }
1316 
1317 /****************************************************************************
1318   When two players cancel an alliance, a lot of units that were visible may
1319   no longer be visible (this includes units in transporters and cities).
1320   Call this function to inform the clients that these units are no longer
1321   visible. Pass the list of seen units returned by get_units_seen_via_ally()
1322   before alliance was broken up.
1323 ****************************************************************************/
remove_allied_visibility(struct player * pplayer,struct player * aplayer,const struct unit_list * seen_units)1324 void remove_allied_visibility(struct player *pplayer, struct player *aplayer,
1325                               const struct unit_list *seen_units)
1326 {
1327   unit_list_iterate(seen_units, punit) {
1328     /* We need to hide units previously seen by the client. */
1329     if (!can_player_see_unit(pplayer, punit)) {
1330       unit_goes_out_of_sight(pplayer, punit);
1331     }
1332   } unit_list_iterate_end;
1333 
1334   city_list_iterate(aplayer->cities, pcity) {
1335     /* The player used to know what units were in these cities.  Now that he
1336      * doesn't, he needs to get a new short city packet updating the
1337      * occupied status. */
1338     if (map_is_known_and_seen(pcity->tile, pplayer, V_MAIN)) {
1339       send_city_info(pplayer, pcity);
1340     }
1341   } city_list_iterate_end;
1342 }
1343 
1344 /****************************************************************************
1345   Refresh units visibility of 'aplayer' for 'pplayer' after alliance have
1346   been contracted.
1347 ****************************************************************************/
give_allied_visibility(struct player * pplayer,struct player * aplayer)1348 void give_allied_visibility(struct player *pplayer,
1349                             struct player *aplayer)
1350 {
1351   unit_list_iterate(aplayer->units, punit) {
1352     if (can_player_see_unit(pplayer, punit)) {
1353       send_unit_info(pplayer->connections, punit);
1354     }
1355   } unit_list_iterate_end;
1356 }
1357 
1358 /**************************************************************************
1359  Is unit being refueled in its current position
1360 **************************************************************************/
is_unit_being_refueled(const struct unit * punit)1361 bool is_unit_being_refueled(const struct unit *punit)
1362 {
1363   return (unit_transported(punit)           /* Carrier */
1364           || tile_city(unit_tile(punit))              /* City    */
1365           || tile_has_refuel_extra(unit_tile(punit),
1366                                    unit_type_get(punit))); /* Airbase */
1367 }
1368 
1369 /**************************************************************************
1370   Can unit refuel on tile. Considers also carrier capacity on tile.
1371 **************************************************************************/
is_airunit_refuel_point(const struct tile * ptile,const struct player * pplayer,const struct unit * punit)1372 bool is_airunit_refuel_point(const struct tile *ptile,
1373                              const struct player *pplayer,
1374                              const struct unit *punit)
1375 {
1376   const struct unit_class *pclass;
1377 
1378   if (NULL != is_non_allied_unit_tile(ptile, pplayer)) {
1379     return FALSE;
1380   }
1381 
1382   if (NULL != is_allied_city_tile(ptile, pplayer)) {
1383     return TRUE;
1384   }
1385 
1386   pclass = unit_class_get(punit);
1387   if (NULL != pclass->cache.refuel_bases) {
1388     const struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
1389 
1390     extra_type_list_iterate(pclass->cache.refuel_bases, pextra) {
1391       if (BV_ISSET(plrtile->extras, extra_index(pextra))) {
1392         return TRUE;
1393       }
1394     } extra_type_list_iterate_end;
1395   }
1396 
1397   return unit_could_load_at(punit, ptile);
1398 }
1399 
1400 /**************************************************************************
1401   Really transforms a single unit to another type.
1402 
1403   This function performs no checks. You should perform the appropriate
1404   test first to check that the transformation is legal (test_unit_upgrade()
1405   or test_unit_convert()).
1406 
1407   is_free: Does unit owner need to pay upgrade price.
1408 
1409   Note that this function is strongly tied to unit.c:test_unit_upgrade().
1410 **************************************************************************/
transform_unit(struct unit * punit,struct unit_type * to_unit,bool is_free)1411 void transform_unit(struct unit *punit, struct unit_type *to_unit,
1412                     bool is_free)
1413 {
1414   struct player *pplayer = unit_owner(punit);
1415   struct unit_type *old_type = punit->utype;
1416   int old_mr = unit_move_rate(punit);
1417   int old_hp = unit_type_get(punit)->hp;
1418 
1419   if (!is_free) {
1420     pplayer->economic.gold -=
1421 	unit_upgrade_price(pplayer, unit_type_get(punit), to_unit);
1422   }
1423 
1424   punit->utype = to_unit;
1425 
1426   /* New type may not have the same veteran system, and we may want to
1427    * knock some levels off. */
1428   punit->veteran = MIN(punit->veteran,
1429                        utype_veteran_system(to_unit)->levels - 1);
1430   if (is_free) {
1431     punit->veteran = MAX(punit->veteran
1432                          - game.server.autoupgrade_veteran_loss, 0);
1433   } else {
1434     punit->veteran = MAX(punit->veteran
1435                          - game.server.upgrade_veteran_loss, 0);
1436   }
1437 
1438   /* Scale HP and MP, rounding down. Be careful with integer arithmetic,
1439    * and don't kill the unit. unit_move_rate() is used to take into account
1440    * global effects like Magellan's Expedition. */
1441   punit->hp = MAX(punit->hp * unit_type_get(punit)->hp / old_hp, 1);
1442   if (old_mr == 0) {
1443     punit->moves_left = unit_move_rate(punit);
1444   } else {
1445     punit->moves_left = punit->moves_left * unit_move_rate(punit) / old_mr;
1446   }
1447 
1448   unit_forget_last_activity(punit);
1449 
1450   /* update unit upkeep */
1451   city_units_upkeep(game_city_by_number(punit->homecity));
1452 
1453   conn_list_do_buffer(pplayer->connections);
1454 
1455   unit_refresh_vision(punit);
1456 
1457   CALL_PLR_AI_FUNC(unit_transformed, pplayer, punit, old_type);
1458 
1459   send_unit_info(NULL, punit);
1460   conn_list_do_unbuffer(pplayer->connections);
1461 }
1462 
1463 /*************************************************************************
1464   Wrapper of the below
1465 *************************************************************************/
create_unit(struct player * pplayer,struct tile * ptile,struct unit_type * type,int veteran_level,int homecity_id,int moves_left)1466 struct unit *create_unit(struct player *pplayer, struct tile *ptile,
1467 			 struct unit_type *type, int veteran_level,
1468                          int homecity_id, int moves_left)
1469 {
1470   return create_unit_full(pplayer, ptile, type, veteran_level, homecity_id,
1471                           moves_left, -1, NULL);
1472 }
1473 
1474 /**************************************************************************
1475   Creates a unit, and set it's initial values, and put it into the right
1476   lists.
1477   If moves_left is less than zero, unit will get max moves.
1478 **************************************************************************/
create_unit_full(struct player * pplayer,struct tile * ptile,struct unit_type * type,int veteran_level,int homecity_id,int moves_left,int hp_left,struct unit * ptrans)1479 struct unit *create_unit_full(struct player *pplayer, struct tile *ptile,
1480 			      struct unit_type *type, int veteran_level,
1481                               int homecity_id, int moves_left, int hp_left,
1482 			      struct unit *ptrans)
1483 {
1484   struct unit *punit = unit_virtual_create(pplayer, NULL, type, veteran_level);
1485   struct city *pcity;
1486 
1487   /* Register unit */
1488   punit->id = identity_number();
1489   idex_register_unit(punit);
1490 
1491   fc_assert_ret_val(ptile != NULL, NULL);
1492   unit_tile_set(punit, ptile);
1493 
1494   pcity = game_city_by_number(homecity_id);
1495   if (utype_has_flag(type, UTYF_NOHOME)) {
1496     punit->homecity = 0; /* none */
1497   } else {
1498     punit->homecity = homecity_id;
1499   }
1500 
1501   if (hp_left >= 0) {
1502     /* Override default full HP */
1503     punit->hp = hp_left;
1504   }
1505 
1506   if (moves_left >= 0) {
1507     /* Override default full MP */
1508     punit->moves_left = MIN(moves_left, unit_move_rate(punit));
1509   }
1510 
1511   if (ptrans) {
1512     /* Set transporter for unit. */
1513     unit_transport_load_tp_status(punit, ptrans, FALSE);
1514   } else {
1515     fc_assert_ret_val(!ptile || can_unit_exist_at_tile(punit, ptile), NULL);
1516   }
1517 
1518   /* Assume that if moves_left < 0 then the unit is "fresh",
1519    * and not moved; else the unit has had something happen
1520    * to it (eg, bribed) which we treat as equivalent to moved.
1521    * (Otherwise could pass moved arg too...)  --dwp */
1522   punit->moved = (moves_left >= 0);
1523 
1524   unit_list_prepend(pplayer->units, punit);
1525   unit_list_prepend(ptile->units, punit);
1526   if (pcity && !utype_has_flag(type, UTYF_NOHOME)) {
1527     fc_assert(city_owner(pcity) == pplayer);
1528     unit_list_prepend(pcity->units_supported, punit);
1529     /* Refresh the unit's homecity. */
1530     city_refresh(pcity);
1531     send_city_info(pplayer, pcity);
1532   }
1533 
1534   punit->server.vision = vision_new(pplayer, ptile);
1535   unit_refresh_vision(punit);
1536 
1537   send_unit_info(NULL, punit);
1538   maybe_make_contact(ptile, unit_owner(punit));
1539   wakeup_neighbor_sentries(punit);
1540 
1541   /* update unit upkeep */
1542   city_units_upkeep(game_city_by_number(homecity_id));
1543 
1544   /* The unit may have changed the available tiles in nearby cities. */
1545   city_map_update_tile_now(ptile);
1546   sync_cities();
1547 
1548   CALL_PLR_AI_FUNC(unit_got, pplayer, punit);
1549 
1550   return punit;
1551 }
1552 
1553 /****************************************************************************
1554   We remove the unit and see if it's disappearance has affected the homecity
1555   and the city it was in.
1556 ****************************************************************************/
server_remove_unit_full(struct unit * punit,bool transported,enum unit_loss_reason reason)1557 static void server_remove_unit_full(struct unit *punit, bool transported,
1558                                     enum unit_loss_reason reason)
1559 {
1560   struct packet_unit_remove packet;
1561   struct tile *ptile = unit_tile(punit);
1562   struct city *pcity = tile_city(ptile);
1563   struct city *phomecity = game_city_by_number(punit->homecity);
1564   struct unit *ptrans;
1565   struct player *pplayer = unit_owner(punit);
1566 
1567   /* The unit is doomed. */
1568   punit->server.dying = TRUE;
1569 
1570 #ifdef DEBUG
1571   unit_list_iterate(ptile->units, pcargo) {
1572     fc_assert(unit_transport_get(pcargo) != punit);
1573   } unit_list_iterate_end;
1574 #endif
1575 
1576   CALL_PLR_AI_FUNC(unit_lost, pplayer, punit);
1577 
1578   /* Save transporter for updating below. */
1579   ptrans = unit_transport_get(punit);
1580   /* Unload unit. */
1581   unit_transport_unload(punit);
1582 
1583   /* Since settlers plot in new cities in the minimap before they
1584      are built, so that no two settlers head towards the same city
1585      spot, we need to ensure this reservation is cleared should
1586      the settler disappear on the way. */
1587   adv_unit_new_task(punit, AUT_NONE, NULL);
1588 
1589   /* Clear the vision before sending unit remove. Else, we might duplicate
1590    * the PACKET_UNIT_REMOVE if we lose vision of the unit tile. */
1591   vision_clear_sight(punit->server.vision);
1592   vision_free(punit->server.vision);
1593   punit->server.vision = NULL;
1594 
1595   packet.unit_id = punit->id;
1596   /* Send to onlookers. */
1597   players_iterate(aplayer) {
1598     if (can_player_see_unit_at(aplayer, punit, unit_tile(punit),
1599                                transported)) {
1600       lsend_packet_unit_remove(aplayer->connections, &packet);
1601     }
1602   } players_iterate_end;
1603   /* Send to global observers. */
1604   conn_list_iterate(game.est_connections, pconn) {
1605     if (conn_is_global_observer(pconn)) {
1606       send_packet_unit_remove(pconn, &packet);
1607     }
1608   } conn_list_iterate_end;
1609 
1610   if (punit->server.moving != NULL) {
1611     /* Do not care of this unit for running moves. */
1612     punit->server.moving->punit = NULL;
1613   }
1614 
1615   /* check if this unit had UTYF_GAMELOSS flag */
1616   if (unit_has_type_flag(punit, UTYF_GAMELOSS) && unit_owner(punit)->is_alive) {
1617     notify_conn(game.est_connections, ptile, E_UNIT_LOST_MISC, ftc_server,
1618                 _("Unable to defend %s, %s has lost the game."),
1619                 unit_link(punit),
1620                 player_name(pplayer));
1621     notify_player(pplayer, ptile, E_GAME_END, ftc_server,
1622                   _("Losing %s meant losing the game! "
1623                   "Be more careful next time!"),
1624                   unit_link(punit));
1625     player_status_add(unit_owner(punit), PSTATUS_DYING);
1626   }
1627 
1628   script_server_signal_emit("unit_lost", 3,
1629                             API_TYPE_UNIT, punit,
1630                             API_TYPE_PLAYER, unit_owner(punit),
1631                             API_TYPE_STRING, unit_loss_reason_name(reason));
1632 
1633   script_server_remove_exported_object(punit);
1634   game_remove_unit(punit);
1635   punit = NULL;
1636 
1637   if (NULL != ptrans) {
1638     /* Update the occupy info. */
1639     send_unit_info(NULL, ptrans);
1640   }
1641 
1642   /* This unit may have blocked tiles of adjacent cities. Update them. */
1643   city_map_update_tile_now(ptile);
1644   sync_cities();
1645 
1646   if (phomecity) {
1647     city_refresh(phomecity);
1648     send_city_info(city_owner(phomecity), phomecity);
1649   }
1650 
1651   if (pcity && pcity != phomecity) {
1652     city_refresh(pcity);
1653     send_city_info(city_owner(pcity), pcity);
1654   }
1655 
1656   if (pcity && unit_list_size(ptile->units) == 0) {
1657     /* The last unit in the city was killed: update the occupied flag. */
1658     send_city_info(NULL, pcity);
1659   }
1660 }
1661 
1662 /****************************************************************************
1663   We remove the unit and see if it's disappearance has affected the homecity
1664   and the city it was in.
1665 ****************************************************************************/
server_remove_unit(struct unit * punit,enum unit_loss_reason reason)1666 static void server_remove_unit(struct unit *punit,
1667                                enum unit_loss_reason reason)
1668 {
1669   server_remove_unit_full(punit, unit_transported(punit), reason);
1670 }
1671 
1672 /**************************************************************************
1673   Handle units destroyed when their transport is destroyed
1674 **************************************************************************/
unit_lost_with_transport(const struct player * pplayer,struct unit * pcargo,struct unit_type * ptransport,struct player * killer)1675 static void unit_lost_with_transport(const struct player *pplayer,
1676                                      struct unit *pcargo,
1677                                      struct unit_type *ptransport,
1678                                      struct player *killer)
1679 {
1680   notify_player(pplayer, unit_tile(pcargo), E_UNIT_LOST_MISC, ftc_server,
1681                 _("%s lost when %s was lost."),
1682                 unit_tile_link(pcargo),
1683                 utype_name_translation(ptransport));
1684   /* Unit is not transported any more at this point, but it has jumped
1685    * off the transport and drowns outside. So it must be removed from
1686    * all clients.
1687    * However, we don't know if given client has received ANY updates
1688    * about the swimming unit, and we can't remove it if it's not there
1689    * in the first place -> we send it once here just to be sure it's
1690    * there. */
1691   send_unit_info(NULL, pcargo);
1692   wipe_unit_full(pcargo, FALSE, ULR_TRANSPORT_LOST, killer);
1693 }
1694 
1695 /****************************************************************************
1696   Remove the unit, and passengers if it is a carrying any. Remove the
1697   _minimum_ number, eg there could be another boat on the square.
1698 ****************************************************************************/
wipe_unit_full(struct unit * punit,bool transported,enum unit_loss_reason reason,struct player * killer)1699 static void wipe_unit_full(struct unit *punit, bool transported,
1700                            enum unit_loss_reason reason,
1701                            struct player *killer)
1702 {
1703   struct tile *ptile = unit_tile(punit);
1704   struct player *pplayer = unit_owner(punit);
1705   struct unit_type *putype_save = unit_type_get(punit); /* for notify messages */
1706   struct unit_list *helpless = unit_list_new();
1707   struct unit_list *imperiled = unit_list_new();
1708   struct unit_list *unsaved = unit_list_new();
1709   struct unit *ptrans = unit_transport_get(punit);
1710   struct city *pexclcity;
1711 
1712   /* The unit is doomed. */
1713   punit->server.dying = TRUE;
1714 
1715   /* If a unit is being lost due to loss of its city, ensure that we don't
1716    * try to teleport any of its cargo to that city (which may not yet
1717    * have changed hands or disappeared). (It is assumed that the unit's
1718    * home city is always the one that is being lost/transferred/etc.) */
1719   if (reason == ULR_CITY_LOST) {
1720     pexclcity = unit_home(punit);
1721   } else {
1722     pexclcity = NULL;
1723   }
1724 
1725   /* Remove unit itself from its transport */
1726   if (ptrans != NULL) {
1727     unit_transport_unload(punit);
1728     send_unit_info(NULL, ptrans);
1729   }
1730 
1731   /* First pull all units off of the transporter. */
1732   if (get_transporter_occupancy(punit) > 0) {
1733     /* Use iterate_safe as unloaded units will be removed from the list
1734      * while iterating. */
1735     unit_list_iterate_safe(unit_transport_cargo(punit), pcargo) {
1736       bool healthy = FALSE;
1737 
1738       if (!can_unit_unload(pcargo, punit)) {
1739         unit_list_prepend(helpless, pcargo);
1740       } else {
1741         if (!can_unit_exist_at_tile(pcargo, ptile)) {
1742           unit_list_prepend(imperiled, pcargo);
1743         } else {
1744         /* These units do not need to be saved. */
1745           healthy = TRUE;
1746         }
1747       }
1748 
1749       /* Could use unit_transport_unload_send here, but that would
1750        * call send_unit_info for the transporter unnecessarily.
1751        * Note that this means that unit might to get seen briefly
1752        * by clients other than owner's, for example as a result of
1753        * update of homecity common to this cargo and some other
1754        * destroyed unit. */
1755       unit_transport_unload(pcargo);
1756       if (pcargo->activity == ACTIVITY_SENTRY) {
1757         /* Activate sentried units - like planes on a disbanded carrier.
1758          * Note this will activate ground units even if they just change
1759          * transporter. */
1760         set_unit_activity(pcargo, ACTIVITY_IDLE);
1761       }
1762 
1763       /* Unit info for unhealthy units will be sent when they are
1764        * assigned new transport or removed. */
1765       if (healthy) {
1766         send_unit_info(NULL, pcargo);
1767       }
1768     } unit_list_iterate_safe_end;
1769   }
1770 
1771   /* Now remove the unit. */
1772   server_remove_unit_full(punit, transported, reason);
1773 
1774   switch (reason) {
1775   case ULR_KILLED:
1776   case ULR_EXECUTED:
1777   case ULR_SDI:
1778   case ULR_NUKE:
1779   case ULR_BRIBED:
1780   case ULR_CAPTURED:
1781   case ULR_CAUGHT:
1782   case ULR_ELIMINATED:
1783   case ULR_TRANSPORT_LOST:
1784     if (killer != NULL) {
1785       killer->score.units_killed++;
1786     }
1787     pplayer->score.units_lost++;
1788     break;
1789   case ULR_BARB_UNLEASH:
1790   case ULR_CITY_LOST:
1791   case ULR_STARVED:
1792   case ULR_NONNATIVE_TERR:
1793   case ULR_ARMISTICE:
1794   case ULR_HP_LOSS:
1795   case ULR_FUEL:
1796   case ULR_STACK_CONFLICT:
1797   case ULR_SOLD:
1798     pplayer->score.units_lost++;
1799     break;
1800   case ULR_RETIRED:
1801   case ULR_DISBANDED:
1802   case ULR_USED:
1803   case ULR_EDITOR:
1804   case ULR_PLAYER_DIED:
1805   case ULR_DETONATED:
1806   case ULR_MISSILE:
1807     break;
1808   }
1809 
1810   /* First, sort out helpless cargo. */
1811   if (unit_list_size(helpless) > 0) {
1812     struct unit_list *remaining = unit_list_new();
1813 
1814     /* Grant priority to undisbandable and gameloss units. */
1815     unit_list_iterate_safe(helpless, pcargo) {
1816       if (unit_has_type_flag(pcargo, UTYF_UNDISBANDABLE)
1817           || unit_has_type_flag(pcargo, UTYF_GAMELOSS)) {
1818         if (!try_to_save_unit(pcargo, putype_save, TRUE,
1819                               unit_has_type_flag(pcargo,
1820                                                  UTYF_UNDISBANDABLE),
1821                               pexclcity)) {
1822           unit_list_prepend(unsaved, pcargo);
1823         }
1824       } else {
1825         unit_list_prepend(remaining, pcargo);
1826       }
1827     } unit_list_iterate_safe_end;
1828 
1829     /* Handle non-priority units. */
1830     unit_list_iterate_safe(remaining, pcargo) {
1831       if (!try_to_save_unit(pcargo, putype_save, TRUE, FALSE, pexclcity)) {
1832         unit_list_prepend(unsaved, pcargo);
1833       }
1834     } unit_list_iterate_safe_end;
1835 
1836     unit_list_destroy(remaining);
1837   }
1838   unit_list_destroy(helpless);
1839 
1840   /* Then, save any imperiled cargo. */
1841   if (unit_list_size(imperiled) > 0) {
1842     struct unit_list *remaining = unit_list_new();
1843 
1844     /* Grant priority to undisbandable and gameloss units. */
1845     unit_list_iterate_safe(imperiled, pcargo) {
1846       if (unit_has_type_flag(pcargo, UTYF_UNDISBANDABLE)
1847           || unit_has_type_flag(pcargo, UTYF_GAMELOSS)) {
1848         if (!try_to_save_unit(pcargo, putype_save, FALSE,
1849                               unit_has_type_flag(pcargo,
1850                                                  UTYF_UNDISBANDABLE),
1851                               pexclcity)) {
1852           unit_list_prepend(unsaved, pcargo);
1853         }
1854       } else {
1855         unit_list_prepend(remaining, pcargo);
1856       }
1857     } unit_list_iterate_safe_end;
1858 
1859     /* Handle non-priority units. */
1860     unit_list_iterate_safe(remaining, pcargo) {
1861       if (!try_to_save_unit(pcargo, putype_save, FALSE, FALSE, pexclcity)) {
1862         unit_list_prepend(unsaved, pcargo);
1863       }
1864     } unit_list_iterate_safe_end;
1865 
1866     unit_list_destroy(remaining);
1867   }
1868   unit_list_destroy(imperiled);
1869 
1870   /* Finally, kill off the unsaved units. */
1871   if (unit_list_size(unsaved) > 0) {
1872     unit_list_iterate_safe(unsaved, dying_unit) {
1873       unit_lost_with_transport(pplayer, dying_unit, putype_save, killer);
1874     } unit_list_iterate_safe_end;
1875   }
1876   unit_list_destroy(unsaved);
1877 }
1878 
1879 /****************************************************************************
1880   Remove the unit, and passengers if it is a carrying any. Remove the
1881   _minimum_ number, eg there could be another boat on the square.
1882 ****************************************************************************/
wipe_unit(struct unit * punit,enum unit_loss_reason reason,struct player * killer)1883 void wipe_unit(struct unit *punit, enum unit_loss_reason reason,
1884                struct player *killer)
1885 {
1886   wipe_unit_full(punit, unit_transported(punit), reason, killer);
1887 }
1888 
1889 /****************************************************************************
1890   Determine if it is possible to save a given unit, and if so, save them.
1891   'pexclcity' is a city to avoid teleporting to, if 'teleporting' is set.
1892   Note that despite being saved from drowning, teleporting the units to
1893   "safety" may have killed them in the end.
1894 ****************************************************************************/
try_to_save_unit(struct unit * punit,struct unit_type * pttype,bool helpless,bool teleporting,const struct city * pexclcity)1895 static bool try_to_save_unit(struct unit *punit, struct unit_type *pttype,
1896                              bool helpless, bool teleporting,
1897                              const struct city *pexclcity)
1898 {
1899   struct tile *ptile = unit_tile(punit);
1900   struct player *pplayer = unit_owner(punit);
1901   struct unit *ptransport = transporter_for_unit(punit);
1902 
1903   /* Helpless units cannot board a transport in their current state. */
1904   if (!helpless
1905       && ptransport != NULL) {
1906     unit_transport_load_tp_status(punit, ptransport, FALSE);
1907     send_unit_info(NULL, punit);
1908     return TRUE;
1909   } else {
1910     /* Only units that cannot find transport are considered for teleport. */
1911     if (teleporting) {
1912       struct city *pcity = find_closest_city(ptile, pexclcity,
1913                                              unit_owner(punit),
1914                                              FALSE, FALSE, FALSE, TRUE, FALSE,
1915                                              utype_class(pttype));
1916       if (pcity != NULL) {
1917         char tplink[MAX_LEN_LINK]; /* In case unit dies when teleported */
1918 
1919         sz_strlcpy(tplink, unit_link(punit));
1920 
1921         if (teleport_unit_to_city(punit, pcity, 0, FALSE)) {
1922           notify_player(pplayer, ptile, E_UNIT_RELOCATED, ftc_server,
1923                         _("%s escaped the destruction of %s, and fled to %s."),
1924                         tplink,
1925                         utype_name_translation(pttype),
1926                         city_link(pcity));
1927           return TRUE;
1928         }
1929       }
1930     }
1931   }
1932   /* The unit could not use transport on the tile, and could not teleport. */
1933   return FALSE;
1934 }
1935 
1936 /****************************************************************************
1937   We don't really change owner of the unit, but create completely new
1938   unit as its copy. The new pointer to 'punit' is returned.
1939 ****************************************************************************/
unit_change_owner(struct unit * punit,struct player * pplayer,int homecity,enum unit_loss_reason reason)1940 struct unit *unit_change_owner(struct unit *punit, struct player *pplayer,
1941                                int homecity, enum unit_loss_reason reason)
1942 {
1943   struct unit *gained_unit;
1944 
1945   fc_assert(!utype_player_already_has_this_unique(pplayer,
1946                                                   unit_type_get(punit)));
1947 
1948   /* Convert the unit to your cause. Fog is lifted in the create algorithm. */
1949   gained_unit = create_unit_full(pplayer, unit_tile(punit),
1950                                  unit_type_get(punit), punit->veteran,
1951                                  homecity, punit->moves_left,
1952                                  punit->hp, NULL);
1953 
1954   /* Owner changes, nationality not. */
1955   gained_unit->nationality = punit->nationality;
1956 
1957   /* Copy some more unit fields */
1958   gained_unit->fuel = punit->fuel;
1959   gained_unit->paradropped = punit->paradropped;
1960   gained_unit->server.birth_turn = punit->server.birth_turn;
1961 
1962   send_unit_info(NULL, gained_unit);
1963 
1964   /* update unit upkeep in the homecity of the victim */
1965   if (punit->homecity > 0) {
1966     /* update unit upkeep */
1967     city_units_upkeep(game_city_by_number(punit->homecity));
1968   }
1969   /* update unit upkeep in the new homecity */
1970   if (homecity > 0) {
1971     city_units_upkeep(game_city_by_number(homecity));
1972   }
1973 
1974   /* Be sure to wipe the converted unit! */
1975   wipe_unit(punit, reason, NULL);
1976 
1977   return gained_unit;   /* Returns the replacement. */
1978 }
1979 
1980 /**************************************************************************
1981   Called when one unit kills another in combat (this function is only
1982   called in one place).  It handles all side effects including
1983   notifications and killstack.
1984 **************************************************************************/
kill_unit(struct unit * pkiller,struct unit * punit,bool vet)1985 void kill_unit(struct unit *pkiller, struct unit *punit, bool vet)
1986 {
1987   char pkiller_link[MAX_LEN_LINK], punit_link[MAX_LEN_LINK];
1988   struct player *pvictim = unit_owner(punit);
1989   struct player *pvictor = unit_owner(pkiller);
1990   int ransom, unitcount = 0;
1991 
1992   sz_strlcpy(pkiller_link, unit_link(pkiller));
1993   sz_strlcpy(punit_link, unit_tile_link(punit));
1994 
1995   /* The unit is doomed. */
1996   punit->server.dying = TRUE;
1997 
1998   if ((game.info.gameloss_style & GAMELOSS_STYLE_LOOT)
1999       && unit_has_type_flag(punit, UTYF_GAMELOSS)) {
2000     ransom = fc_rand(1 + pvictim->economic.gold);
2001     int n;
2002 
2003     /* give map */
2004     give_distorted_map(pvictim, pvictor, 1, 1, TRUE);
2005 
2006     log_debug("victim has money: %d", pvictim->economic.gold);
2007     pvictor->economic.gold += ransom;
2008     pvictim->economic.gold -= ransom;
2009 
2010     n = 1 + fc_rand(3);
2011 
2012     while (n > 0) {
2013       Tech_type_id ttid = steal_a_tech(pvictor, pvictim, A_UNSET);
2014 
2015       if (ttid == A_NONE) {
2016         log_debug("Worthless enemy doesn't have more techs to steal.");
2017         break;
2018       } else {
2019         log_debug("Pressed tech %s from captured enemy",
2020                   research_advance_rule_name(research_get(pvictor), ttid));
2021         if (!fc_rand(3)) {
2022           break; /* out of luck */
2023         }
2024         n--;
2025       }
2026     }
2027 
2028     { /* try to submit some cities */
2029       int vcsize = city_list_size(pvictim->cities);
2030       int evcsize = vcsize;
2031       int conqsize = evcsize;
2032 
2033       if (evcsize < 3) {
2034         evcsize = 0;
2035       } else {
2036         evcsize -=3;
2037       }
2038       /* about a quarter on average with high numbers less probable */
2039       conqsize = fc_rand(fc_rand(evcsize));
2040 
2041       log_debug("conqsize=%d", conqsize);
2042 
2043       if (conqsize > 0) {
2044         bool palace = game.server.savepalace;
2045         bool submit = FALSE;
2046 
2047         game.server.savepalace = FALSE; /* moving it around is dumb */
2048 
2049         city_list_iterate_safe(pvictim->cities, pcity) {
2050           /* kindly ask the citizens to submit */
2051           if (fc_rand(vcsize) < conqsize) {
2052             submit = TRUE;
2053           }
2054           vcsize--;
2055           if (submit) {
2056             conqsize--;
2057             /* Transfer city to the victorious player
2058              * kill all its units outside of a radius of 7,
2059              * give verbose messages of every unit transferred,
2060              * and raze buildings according to raze chance
2061              * (also removes palace) */
2062             (void) transfer_city(pvictor, pcity, 7, TRUE, TRUE, TRUE,
2063                                  !is_barbarian(pvictor));
2064             submit = FALSE;
2065           }
2066           if (conqsize <= 0) {
2067             break;
2068           }
2069         } city_list_iterate_safe_end;
2070         game.server.savepalace = palace;
2071       }
2072     }
2073   }
2074 
2075   /* barbarian leader ransom hack */
2076   if( is_barbarian(pvictim) && unit_has_type_role(punit, L_BARBARIAN_LEADER)
2077       && (unit_list_size(unit_tile(punit)->units) == 1)
2078       && uclass_has_flag(unit_class_get(pkiller), UCF_COLLECT_RANSOM)) {
2079     /* Occupying units can collect ransom if leader is alone in the tile */
2080     ransom = (pvictim->economic.gold >= game.server.ransom_gold)
2081              ? game.server.ransom_gold : pvictim->economic.gold;
2082     notify_player(pvictor, unit_tile(pkiller), E_UNIT_WIN_ATT, ftc_server,
2083                   PL_("Barbarian leader captured; %d gold ransom paid.",
2084                       "Barbarian leader captured; %d gold ransom paid.",
2085                       ransom),
2086                   ransom);
2087     pvictor->economic.gold += ransom;
2088     pvictim->economic.gold -= ransom;
2089     send_player_info_c(pvictor, NULL);   /* let me see my new gold :-) */
2090     unitcount = 1;
2091   }
2092 
2093   if (unitcount == 0) {
2094     unit_list_iterate(unit_tile(punit)->units, vunit) {
2095       if (pplayers_at_war(pvictor, unit_owner(vunit))) {
2096 	unitcount++;
2097       }
2098     } unit_list_iterate_end;
2099   }
2100 
2101   if (!is_stack_vulnerable(unit_tile(punit)) || unitcount == 1) {
2102     if (vet) {
2103       notify_unit_experience(pkiller);
2104     }
2105     wipe_unit(punit, ULR_KILLED, pvictor);
2106   } else { /* unitcount > 1 */
2107     int i;
2108     int num_killed[player_slot_count()];
2109     struct unit *other_killed[player_slot_count()];
2110     struct tile *ptile = unit_tile(punit);
2111 
2112     fc_assert(unitcount > 1);
2113 
2114     /* initialize */
2115     for (i = 0; i < player_slot_count(); i++) {
2116       num_killed[i] = 0;
2117       other_killed[i] = NULL;
2118     }
2119 
2120     /* count killed units */
2121     unit_list_iterate(ptile->units, vunit) {
2122       struct player *vplayer = unit_owner(vunit);
2123       if (pplayers_at_war(pvictor, vplayer)
2124           && is_unit_reachable_at(vunit, pkiller, ptile)) {
2125 	num_killed[player_index(vplayer)]++;
2126 	if (vunit != punit) {
2127 	  other_killed[player_index(vplayer)] = vunit;
2128 	  other_killed[player_index(pvictor)] = vunit;
2129 	}
2130       }
2131     } unit_list_iterate_end;
2132 
2133     /* Inform the destroyer again if more than one unit was killed */
2134     if (unitcount > 1) {
2135       notify_player(pvictor, unit_tile(pkiller), E_UNIT_WIN_ATT, ftc_server,
2136                     /* TRANS: "... Cannon ... the Polish Destroyer ...." */
2137                     PL_("Your attacking %s succeeded against the %s %s "
2138                         "(and %d other unit)!",
2139                         "Your attacking %s succeeded against the %s %s "
2140                         "(and %d other units)!", unitcount - 1),
2141                     pkiller_link,
2142                     nation_adjective_for_player(pvictim),
2143                     punit_link,
2144                     unitcount - 1);
2145     }
2146     if (vet) {
2147       notify_unit_experience(pkiller);
2148     }
2149 
2150     /* inform the owners: this only tells about owned units that were killed.
2151      * there may have been 20 units who died but if only 2 belonged to the
2152      * particular player they'll only learn about those.
2153      *
2154      * Also if a large number of units die you don't find out what type
2155      * they all are. */
2156     for (i = 0; i < player_slot_count(); i++) {
2157       if (num_killed[i] == 1) {
2158         if (i == player_index(pvictim)) {
2159           fc_assert(other_killed[i] == NULL);
2160           notify_player(player_by_number(i), ptile,
2161                         E_UNIT_LOST_DEF, ftc_server,
2162                         /* TRANS: "Cannon ... the Polish Destroyer." */
2163                         _("%s lost to an attack by the %s %s."),
2164                         punit_link,
2165                         nation_adjective_for_player(pvictor),
2166                         pkiller_link);
2167         } else {
2168           fc_assert(other_killed[i] != punit);
2169           notify_player(player_by_number(i), ptile,
2170                         E_UNIT_LOST_DEF, ftc_server,
2171                         /* TRANS: "Cannon lost when the Polish Destroyer
2172                          * attacked the German Musketeers." */
2173                         _("%s lost when the %s %s attacked the %s %s."),
2174                         unit_link(other_killed[i]),
2175                         nation_adjective_for_player(pvictor),
2176                         pkiller_link,
2177                         nation_adjective_for_player(pvictim),
2178                         punit_link);
2179         }
2180       } else if (num_killed[i] > 1) {
2181         if (i == player_index(pvictim)) {
2182           int others = num_killed[i] - 1;
2183 
2184           if (others == 1) {
2185             notify_player(player_by_number(i), ptile,
2186                           E_UNIT_LOST_DEF, ftc_server,
2187                           /* TRANS: "Musketeers (and Cannon) lost to an
2188                            * attack from the Polish Destroyer." */
2189                           _("%s (and %s) lost to an attack from the %s %s."),
2190                           punit_link,
2191                           unit_link(other_killed[i]),
2192                           nation_adjective_for_player(pvictor),
2193                           pkiller_link);
2194           } else {
2195             notify_player(player_by_number(i), ptile,
2196                           E_UNIT_LOST_DEF, ftc_server,
2197                           /* TRANS: "Musketeers and 3 other units lost to
2198                            * an attack from the Polish Destroyer."
2199                            * (only happens with at least 2 other units) */
2200                           PL_("%s and %d other unit lost to an attack "
2201                               "from the %s %s.",
2202                               "%s and %d other units lost to an attack "
2203                               "from the %s %s.", others),
2204                           punit_link,
2205                           others,
2206                           nation_adjective_for_player(pvictor),
2207                           pkiller_link);
2208           }
2209         } else {
2210           notify_player(player_by_number(i), ptile,
2211                         E_UNIT_LOST_DEF, ftc_server,
2212                         /* TRANS: "2 units lost when the Polish Destroyer
2213                          * attacked the German Musketeers."
2214                          * (only happens with at least 2 other units) */
2215                         PL_("%d unit lost when the %s %s attacked the %s %s.",
2216                             "%d units lost when the %s %s attacked the %s %s.",
2217                             num_killed[i]),
2218                         num_killed[i],
2219                         nation_adjective_for_player(pvictor),
2220                         pkiller_link,
2221                         nation_adjective_for_player(pvictim),
2222                         punit_link);
2223         }
2224       }
2225     }
2226 
2227     /* remove the units - note the logic of which units actually die
2228      * must be mimiced exactly in at least one place up above. */
2229     punit = NULL; /* wiped during following iteration so unsafe to use */
2230 
2231     unit_list_iterate_safe(ptile->units, punit2) {
2232       if (pplayers_at_war(pvictor, unit_owner(punit2))
2233 	  && is_unit_reachable_at(punit2, pkiller, ptile)) {
2234         wipe_unit(punit2, ULR_KILLED, pvictor);
2235       }
2236     } unit_list_iterate_safe_end;
2237   }
2238 }
2239 
2240 /**************************************************************************
2241   Package a unit_info packet.  This packet contains basically all
2242   information about a unit.
2243 **************************************************************************/
package_unit(struct unit * punit,struct packet_unit_info * packet)2244 void package_unit(struct unit *punit, struct packet_unit_info *packet)
2245 {
2246   packet->id = punit->id;
2247   packet->owner = player_number(unit_owner(punit));
2248   packet->nationality = player_number(unit_nationality(punit));
2249   packet->tile = tile_index(unit_tile(punit));
2250   packet->facing = punit->facing;
2251   packet->homecity = punit->homecity;
2252   output_type_iterate(o) {
2253     packet->upkeep[o] = punit->upkeep[o];
2254   } output_type_iterate_end;
2255   packet->veteran = punit->veteran;
2256   packet->type = utype_number(unit_type_get(punit));
2257   packet->movesleft = punit->moves_left;
2258   packet->hp = punit->hp;
2259   packet->activity = punit->activity;
2260   packet->activity_count = punit->activity_count;
2261 
2262   if (punit->activity_target != NULL) {
2263     packet->activity_tgt = extra_index(punit->activity_target);
2264   } else {
2265     packet->activity_tgt = EXTRA_NONE;
2266   }
2267 
2268   packet->changed_from = punit->changed_from;
2269   packet->changed_from_count = punit->changed_from_count;
2270 
2271   if (punit->changed_from_target != NULL) {
2272     packet->changed_from_tgt = extra_index(punit->changed_from_target);
2273   } else {
2274     packet->changed_from_tgt = EXTRA_NONE;
2275   }
2276 
2277   packet->ai = punit->ai_controlled;
2278   packet->fuel = punit->fuel;
2279   packet->goto_tile = (NULL != punit->goto_tile
2280                        ? tile_index(punit->goto_tile) : -1);
2281   packet->paradropped = punit->paradropped;
2282   packet->done_moving = punit->done_moving;
2283   if (!unit_transported(punit)) {
2284     packet->transported = FALSE;
2285     packet->transported_by = 0;
2286   } else {
2287     packet->transported = TRUE;
2288     packet->transported_by = unit_transport_get(punit)->id;
2289   }
2290   packet->occupied = (get_transporter_occupancy(punit) > 0);
2291   packet->battlegroup = punit->battlegroup;
2292   packet->has_orders = punit->has_orders;
2293   if (punit->has_orders) {
2294     int i;
2295 
2296     packet->orders_length = punit->orders.length;
2297     packet->orders_index = punit->orders.index;
2298     packet->orders_repeat = punit->orders.repeat;
2299     packet->orders_vigilant = punit->orders.vigilant;
2300     for (i = 0; i < punit->orders.length; i++) {
2301       packet->orders[i] = punit->orders.list[i].order;
2302       packet->orders_dirs[i] = punit->orders.list[i].dir;
2303       packet->orders_activities[i] = punit->orders.list[i].activity;
2304       packet->orders_targets[i] = punit->orders.list[i].target;
2305     }
2306   } else {
2307     packet->orders_length = packet->orders_index = 0;
2308     packet->orders_repeat = packet->orders_vigilant = FALSE;
2309     /* No need to initialize array. */
2310   }
2311 
2312   packet->action_decision_want = punit->action_decision_want;
2313   packet->action_decision_tile = (punit->action_decision_tile
2314                                   ? tile_index(punit->action_decision_tile)
2315                                   : IDENTITY_NUMBER_ZERO);
2316 }
2317 
2318 /**************************************************************************
2319   Package a short_unit_info packet.  This contains a limited amount of
2320   information about the unit, and is sent to players who shouldn't know
2321   everything (like the unit's owner's enemies).
2322 **************************************************************************/
package_short_unit(struct unit * punit,struct packet_unit_short_info * packet,enum unit_info_use packet_use,int info_city_id)2323 void package_short_unit(struct unit *punit,
2324 			struct packet_unit_short_info *packet,
2325                         enum unit_info_use packet_use, int info_city_id)
2326 {
2327   packet->packet_use = packet_use;
2328   packet->info_city_id = info_city_id;
2329 
2330   packet->id = punit->id;
2331   packet->owner = player_number(unit_owner(punit));
2332   packet->tile = tile_index(unit_tile(punit));
2333   packet->facing = punit->facing;
2334   packet->veteran = punit->veteran;
2335   packet->type = utype_number(unit_type_get(punit));
2336   packet->hp = punit->hp;
2337   packet->occupied = (get_transporter_occupancy(punit) > 0);
2338   if (punit->activity == ACTIVITY_EXPLORE
2339       || punit->activity == ACTIVITY_GOTO) {
2340     packet->activity = ACTIVITY_IDLE;
2341   } else {
2342     packet->activity = punit->activity;
2343   }
2344 
2345   if (punit->activity_target == NULL) {
2346     packet->activity_tgt = EXTRA_NONE;
2347   } else {
2348     packet->activity_tgt = extra_index(punit->activity_target);
2349   }
2350 
2351   /* Transported_by information is sent to the client even for units that
2352    * aren't fully known.  Note that for non-allied players, any transported
2353    * unit can't be seen at all.  For allied players we have to know if
2354    * transporters have room in them so that we can load units properly. */
2355   if (!unit_transported(punit)) {
2356     packet->transported = FALSE;
2357     packet->transported_by = 0;
2358   } else {
2359     packet->transported = TRUE;
2360     packet->transported_by = unit_transport_get(punit)->id;
2361   }
2362 }
2363 
2364 /**************************************************************************
2365   Handle situation where unit goes out of player sight.
2366 **************************************************************************/
unit_goes_out_of_sight(struct player * pplayer,struct unit * punit)2367 void unit_goes_out_of_sight(struct player *pplayer, struct unit *punit)
2368 {
2369   dlsend_packet_unit_remove(pplayer->connections, punit->id);
2370   if (punit->server.moving != NULL) {
2371     /* Update status of 'pplayer' vision for 'punit'. */
2372     BV_CLR(punit->server.moving->can_see_unit, player_index(pplayer));
2373   }
2374 }
2375 
2376 /****************************************************************************
2377   send the unit to the players who need the info.
2378   dest = NULL means all connections (game.est_connections)
2379 ****************************************************************************/
send_unit_info(struct conn_list * dest,struct unit * punit)2380 void send_unit_info(struct conn_list *dest, struct unit *punit)
2381 {
2382   const struct player *powner;
2383   struct packet_unit_info info;
2384   struct packet_unit_short_info sinfo;
2385   struct unit_move_data *pdata;
2386 
2387   if (dest == NULL) {
2388     dest = game.est_connections;
2389   }
2390 
2391   CHECK_UNIT(punit);
2392 
2393   powner = unit_owner(punit);
2394   package_unit(punit, &info);
2395   package_short_unit(punit, &sinfo, UNIT_INFO_IDENTITY, 0);
2396   pdata = punit->server.moving;
2397 
2398   conn_list_iterate(dest, pconn) {
2399     struct player *pplayer = conn_get_player(pconn);
2400 
2401     /* Be careful to consider all cases where pplayer is NULL... */
2402     if (pplayer == NULL) {
2403       if (pconn->observer) {
2404         send_packet_unit_info(pconn, &info);
2405       }
2406     } else if (pplayer == powner) {
2407       send_packet_unit_info(pconn, &info);
2408       if (pdata != NULL) {
2409         BV_SET(pdata->can_see_unit, player_index(pplayer));
2410       }
2411     } else if (can_player_see_unit(pplayer, punit)) {
2412       send_packet_unit_short_info(pconn, &sinfo, FALSE);
2413       if (pdata != NULL) {
2414         BV_SET(pdata->can_see_unit, player_index(pplayer));
2415       }
2416     }
2417   } conn_list_iterate_end;
2418 }
2419 
2420 /**************************************************************************
2421   For each specified connections, send information about all the units
2422   known to that player/conn.
2423 **************************************************************************/
send_all_known_units(struct conn_list * dest)2424 void send_all_known_units(struct conn_list *dest)
2425 {
2426   conn_list_do_buffer(dest);
2427   conn_list_iterate(dest, pconn) {
2428     struct player *pplayer = pconn->playing;
2429 
2430     if (NULL == pplayer && !pconn->observer) {
2431       continue;
2432     }
2433 
2434     players_iterate(unitowner) {
2435       unit_list_iterate(unitowner->units, punit) {
2436         send_unit_info(dest, punit);
2437       } unit_list_iterate_end;
2438     } players_iterate_end;
2439   }
2440   conn_list_iterate_end;
2441   conn_list_do_unbuffer(dest);
2442   flush_packets();
2443 }
2444 
2445 /**************************************************************************
2446   Nuke a square: 1) remove all units on the square, and 2) halve the
2447   size of the city on the square.
2448 
2449   If it isn't a city square or an ocean square then with 50% chance add
2450   some fallout, then notify the client about the changes.
2451 **************************************************************************/
do_nuke_tile(struct player * pplayer,struct tile * ptile)2452 static void do_nuke_tile(struct player *pplayer, struct tile *ptile)
2453 {
2454   struct city *pcity = NULL;
2455 
2456   unit_list_iterate_safe(ptile->units, punit) {
2457     notify_player(unit_owner(punit), ptile, E_UNIT_LOST_MISC, ftc_server,
2458                   _("Your %s was nuked by %s."),
2459                   unit_tile_link(punit),
2460                   pplayer == unit_owner(punit)
2461                   ? _("yourself")
2462                   : nation_plural_for_player(pplayer));
2463     if (unit_owner(punit) != pplayer) {
2464       notify_player(pplayer, ptile, E_UNIT_WIN_ATT, ftc_server,
2465                     _("The %s %s was nuked."),
2466                     nation_adjective_for_player(unit_owner(punit)),
2467                     unit_tile_link(punit));
2468     }
2469     wipe_unit(punit, ULR_NUKE, pplayer);
2470   } unit_list_iterate_safe_end;
2471 
2472   pcity = tile_city(ptile);
2473 
2474   if (pcity) {
2475     notify_player(city_owner(pcity), ptile, E_CITY_NUKED, ftc_server,
2476                   _("%s was nuked by %s."),
2477                   city_link(pcity),
2478                   pplayer == city_owner(pcity)
2479                   ? _("yourself")
2480                   : nation_plural_for_player(pplayer));
2481 
2482     if (city_owner(pcity) != pplayer) {
2483       notify_player(pplayer, ptile, E_CITY_NUKED, ftc_server,
2484                     _("You nuked %s."),
2485                     city_link(pcity));
2486     }
2487 
2488     if (city_reduce_size(pcity, city_size_get(pcity) / 2, pplayer, "nuke")) {
2489       /* Send city size reduction to everyone seeing it */
2490       send_city_info(NULL, pcity);
2491     }
2492   }
2493 
2494   if (fc_rand(2) == 1) {
2495     struct extra_type *pextra;
2496 
2497     pextra = rand_extra_for_tile(ptile, EC_FALLOUT);
2498     if (pextra != NULL && !tile_has_extra(ptile, pextra)) {
2499       tile_add_extra(ptile, pextra);
2500       update_tile_knowledge(ptile);
2501     }
2502   }
2503 }
2504 
2505 /**************************************************************************
2506   Nuke all the squares in a 3x3 square around the center of the explosion
2507   pplayer is the player that caused the explosion.
2508 **************************************************************************/
do_nuclear_explosion(struct player * pplayer,struct tile * ptile)2509 void do_nuclear_explosion(struct player *pplayer, struct tile *ptile)
2510 {
2511   struct player *victim = tile_owner(ptile);
2512 
2513   call_incident(INCIDENT_NUCLEAR, pplayer, victim);
2514 
2515   if (pplayer == victim) {
2516     players_iterate(oplayer) {
2517       if (victim != oplayer) {
2518         call_incident(INCIDENT_NUCLEAR_SELF, pplayer, oplayer);
2519       }
2520     } players_iterate_end;
2521   } else {
2522     players_iterate(oplayer) {
2523       if (victim != oplayer) {
2524         call_incident(INCIDENT_NUCLEAR_NOT_TARGET, pplayer, oplayer);
2525       }
2526     } players_iterate_end;
2527   }
2528 
2529   square_iterate(ptile, 1, ptile1) {
2530     do_nuke_tile(pplayer, ptile1);
2531   } square_iterate_end;
2532 
2533   notify_conn(NULL, ptile, E_NUKE, ftc_server,
2534               _("The %s detonated a nuke!"),
2535               nation_plural_for_player(pplayer));
2536 }
2537 
2538 /**************************************************************************
2539   go by airline, if both cities have an airport and neither has been used this
2540   turn the unit will be transported by it and have its moves set to 0
2541 **************************************************************************/
do_airline(struct unit * punit,struct city * pdest_city)2542 bool do_airline(struct unit *punit, struct city *pdest_city)
2543 {
2544   struct city *psrc_city = tile_city(unit_tile(punit));
2545 
2546   {
2547     enum unit_airlift_result result =
2548       test_unit_can_airlift_to(NULL, punit, pdest_city);
2549     if (!is_successful_airlift_result(result)) {
2550       switch (result) {
2551       /* These two can happen through no fault of the client (for allied
2552        * airlifts), so we give useful messages. */
2553       case AR_SRC_NO_FLIGHTS:
2554         notify_player(unit_owner(punit), unit_tile(punit),
2555                       E_UNIT_RELOCATED, ftc_server,
2556                       /* TRANS: Airlift failure message.
2557                        * "Paris has no capacity to transport Warriors." */
2558                       _("%s has no capacity to transport %s."),
2559                       city_link(psrc_city), unit_link(punit));
2560         break;
2561       case AR_DST_NO_FLIGHTS:
2562         notify_player(unit_owner(punit), unit_tile(punit),
2563                       E_UNIT_RELOCATED, ftc_server,
2564                       /* TRANS: Airlift failure message.
2565                        * "Paris has no capacity to transport Warriors." */
2566                       _("%s has no capacity to transport %s."),
2567                       city_link(pdest_city), unit_link(punit));
2568         break;
2569       default:
2570         /* The client should have been able to foresee all the other
2571          * causes of failure, so it's not worth having specific messages for
2572          * all of them. */
2573         notify_player(unit_owner(punit), unit_tile(punit),
2574                       E_UNIT_RELOCATED, ftc_server,
2575                       /* TRANS: Airlift failure message.
2576                        * "Warriors cannot be transported to Paris." */
2577                       _("%s cannot be transported to %s."),
2578                       unit_link(punit), city_link(pdest_city));
2579         break;
2580       }
2581       return FALSE;
2582     }
2583   }
2584 
2585   notify_player(unit_owner(punit), city_tile(pdest_city),
2586                 E_UNIT_RELOCATED, ftc_server,
2587                 _("%s transported successfully."),
2588                 unit_link(punit));
2589 
2590   unit_move(punit, pdest_city->tile, punit->moves_left, NULL);
2591 
2592   /* Update airlift fields. */
2593   if (!(game.info.airlifting_style & AIRLIFTING_UNLIMITED_SRC)) {
2594     psrc_city->airlift--;
2595     send_city_info(city_owner(psrc_city), psrc_city);
2596   }
2597   if (!(game.info.airlifting_style & AIRLIFTING_UNLIMITED_DEST)) {
2598     pdest_city->airlift--;
2599     send_city_info(city_owner(pdest_city), pdest_city);
2600   }
2601 
2602   return TRUE;
2603 }
2604 
2605 /**************************************************************************
2606   Autoexplore with unit.
2607 **************************************************************************/
do_explore(struct unit * punit)2608 void do_explore(struct unit *punit)
2609 {
2610   switch (manage_auto_explorer(punit)) {
2611    case MR_DEATH:
2612      /* don't use punit! */
2613      return;
2614    case MR_NOT_ALLOWED:
2615      /* Needed for something else */
2616      return;
2617    case MR_OK:
2618      /* FIXME: manage_auto_explorer() isn't supposed to change the activity,
2619       * but don't count on this.  See PR#39792.
2620       */
2621      if (punit->activity == ACTIVITY_EXPLORE) {
2622        break;
2623      }
2624      /* fallthru */
2625    default:
2626      unit_activity_handling(punit, ACTIVITY_IDLE);
2627 
2628      /* FIXME: When the manage_auto_explorer() call changes the activity from
2629       * EXPLORE to IDLE, in unit_activity_handling() ai.control is left
2630       * alone.  We reset it here.  See PR#12931. */
2631      punit->ai_controlled = FALSE;
2632      break;
2633   }
2634 
2635   send_unit_info(NULL, punit); /* probably duplicate */
2636 }
2637 
2638 /**************************************************************************
2639   Returns whether the drop was made or not. Note that it also returns 1
2640   in the case where the drop was succesful, but the unit was killed by
2641   barbarians in a hut.
2642 **************************************************************************/
do_paradrop(struct unit * punit,struct tile * ptile)2643 bool do_paradrop(struct unit *punit, struct tile *ptile)
2644 {
2645   struct player *pplayer = unit_owner(punit);
2646   int range, distance;
2647 
2648   if (!unit_has_type_flag(punit, UTYF_PARATROOPERS)) {
2649     notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
2650                   _("This unit type can not be paradropped."));
2651     return FALSE;
2652   }
2653 
2654   if (!can_unit_paradrop(punit)) {
2655     return FALSE;
2656   }
2657 
2658   if (get_transporter_occupancy(punit) > 0) {
2659     notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
2660                   _("You cannot paradrop a unit that is "
2661                     "transporting other units."));
2662     return FALSE;
2663   }
2664 
2665   if (!map_is_known(ptile, pplayer)) {
2666     notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server,
2667                   _("The destination location is not known."));
2668     return FALSE;
2669   }
2670 
2671   range = unit_type_get(punit)->paratroopers_range;
2672   distance = real_map_distance(unit_tile(punit), ptile);
2673   if (distance > range) {
2674     notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server,
2675                   _("The distance to the target (%i) "
2676                     "is greater than the unit's range (%i)."),
2677                   distance, range);
2678     return FALSE;
2679   } else if (distance < 1) {
2680     notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server,
2681                   _("Already there."));
2682     return FALSE;
2683   }
2684 
2685   if (map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
2686     if (!can_unit_exist_at_tile(punit, ptile)
2687         && (!game.info.paradrop_to_transport
2688             || !unit_could_load_at(punit, ptile))) {
2689       notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server,
2690                     _("This unit cannot paradrop into %s."),
2691                     terrain_name_translation(tile_terrain(ptile)));
2692       return FALSE;
2693     }
2694 
2695     if (NULL != is_non_attack_city_tile(ptile, pplayer)) {
2696       notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server,
2697                     _("Cannot attack unless you declare war first."));
2698       return FALSE;
2699     }
2700 
2701     unit_list_iterate(ptile->units, pother) {
2702       if (can_player_see_unit(pplayer, pother)
2703           && !pplayers_allied(pplayer, unit_owner(pother))) {
2704         notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server,
2705                       /* TRANS: Paratroopers ... Drop Paratrooper */
2706                       _("Your %s can't do %s to tiles with non allied"
2707                         " units."),
2708                       unit_name_translation(punit),
2709                       _("Drop Paratrooper"));
2710         return FALSE;
2711       }
2712     } unit_list_iterate_end;
2713 
2714     if (is_military_unit(punit)
2715         && !player_can_invade_tile(pplayer, ptile)) {
2716       notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server,
2717                     _("Cannot invade unless you break peace with "
2718                       "%s first."),
2719                     player_name(tile_owner(ptile)));
2720       return FALSE;
2721     }
2722   } else {
2723     /* Only take in account values from player map. */
2724     const struct player_tile *plrtile = map_get_player_tile(ptile, pplayer);
2725 
2726     if (NULL == plrtile->site
2727         && !is_native_to_class(unit_class_get(punit), plrtile->terrain,
2728                                &(plrtile->extras))) {
2729       notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server,
2730                     _("This unit cannot paradrop into %s."),
2731                     terrain_name_translation(plrtile->terrain));
2732       return FALSE;
2733     }
2734 
2735     if (NULL != plrtile->site
2736         && plrtile->owner != NULL
2737         && pplayers_non_attack(pplayer, plrtile->owner)) {
2738       notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server,
2739                     _("Cannot attack unless you declare war first."));
2740       return FALSE;
2741     }
2742 
2743     if (is_military_unit(punit)
2744         && NULL != plrtile->owner
2745         && players_non_invade(pplayer, plrtile->owner)) {
2746       notify_player(pplayer, ptile, E_BAD_COMMAND, ftc_server,
2747                     _("Cannot invade unless you break peace with "
2748                       "%s first."),
2749                     player_name(plrtile->owner));
2750       return FALSE;
2751     }
2752 
2753     /* Safe terrain, really? Not transformed since player last saw it. */
2754     if (!can_unit_exist_at_tile(punit, ptile)
2755         && (!game.info.paradrop_to_transport
2756             || !unit_could_load_at(punit, ptile))) {
2757       map_show_circle(pplayer, ptile, unit_type_get(punit)->vision_radius_sq);
2758       notify_player(pplayer, ptile, E_UNIT_LOST_MISC, ftc_server,
2759                     _("Your %s paradropped into the %s and was lost."),
2760                     unit_tile_link(punit),
2761                     terrain_name_translation(tile_terrain(ptile)));
2762       pplayer->score.units_lost++;
2763       server_remove_unit(punit, ULR_NONNATIVE_TERR);
2764       return TRUE;
2765     }
2766   }
2767 
2768   if (is_non_attack_city_tile(ptile, pplayer)
2769       || (is_non_allied_city_tile(ptile, pplayer)
2770           && (pplayer->ai_common.barbarian_type == ANIMAL_BARBARIAN
2771               || !uclass_has_flag(unit_class_get(punit),
2772                                UCF_CAN_OCCUPY_CITY)
2773               || unit_has_type_flag(punit, UTYF_CIVILIAN)))
2774       || is_non_allied_unit_tile(ptile, pplayer)) {
2775     map_show_circle(pplayer, ptile, unit_type_get(punit)->vision_radius_sq);
2776     maybe_make_contact(ptile, pplayer);
2777     notify_player(pplayer, ptile, E_UNIT_LOST_MISC, ftc_server,
2778                   _("Your %s was killed by enemy units at the "
2779                     "paradrop destination."),
2780                   unit_tile_link(punit));
2781     /* TODO: Should defender score.units_killed get increased too?
2782      * What if there's units of several allied players? Should the
2783      * city owner or owner of the first/random unit get the kill? */
2784     pplayer->score.units_lost++;
2785     server_remove_unit(punit, ULR_KILLED);
2786     return TRUE;
2787   }
2788 
2789   /* All ok */
2790   punit->paradropped = TRUE;
2791   if (unit_move(punit, ptile, unit_type_get(punit)->paratroopers_mr_sub, NULL)) {
2792     /* Ensure we finished on valid state. */
2793     fc_assert(can_unit_exist_at_tile(punit, unit_tile(punit))
2794               || unit_transported(punit));
2795   }
2796   return TRUE;
2797 }
2798 
2799 /**************************************************************************
2800   Give 25 Gold or kill the unit. For H_LIMITEDHUTS
2801   Return TRUE if unit is alive, and FALSE if it was killed
2802 **************************************************************************/
hut_get_limited(struct unit * punit)2803 static bool hut_get_limited(struct unit *punit)
2804 {
2805   bool ok = TRUE;
2806   int hut_chance = fc_rand(12);
2807   struct player *pplayer = unit_owner(punit);
2808   /* 1 in 12 to get barbarians */
2809   if (hut_chance != 0) {
2810     int cred = 25;
2811     notify_player(pplayer, unit_tile(punit), E_HUT_GOLD, ftc_server,
2812                   PL_("You found %d gold.",
2813                       "You found %d gold.", cred), cred);
2814     pplayer->economic.gold += cred;
2815   } else if (city_exists_within_max_city_map(unit_tile(punit), TRUE)
2816              || unit_has_type_flag(punit, UTYF_GAMELOSS)) {
2817     notify_player(pplayer, unit_tile(punit),
2818                   E_HUT_BARB_CITY_NEAR, ftc_server,
2819                   _("An abandoned village is here."));
2820   } else {
2821     notify_player(pplayer, unit_tile(punit), E_HUT_BARB_KILLED, ftc_server,
2822                   _("Your %s has been killed by barbarians!"),
2823                   unit_tile_link(punit));
2824     wipe_unit(punit, ULR_BARB_UNLEASH, NULL);
2825     ok = FALSE;
2826   }
2827   return ok;
2828 }
2829 
2830 /**************************************************************************
2831   Enter huts in iteration order as long as unit lives.
2832   Iff survived to the last one, return TRUE.
2833 **************************************************************************/
unit_enter_hut(struct unit * punit)2834 static bool unit_enter_hut(struct unit *punit)
2835 {
2836   struct player *pplayer = unit_owner(punit);
2837   int id = punit->id;
2838   enum hut_behavior behavior = unit_class_get(punit)->hut_behavior;
2839   struct tile *ptile = unit_tile(punit);
2840   bool hut = FALSE, res = TRUE;
2841 
2842   /* FIXME: Should we still run "hut_enter" script when
2843    *        hut_behavior is HUT_NOTHING or HUT_FRIGHTEN? */
2844   if (behavior == HUT_NOTHING) {
2845     return TRUE;
2846   }
2847 
2848   extra_type_by_cause_iterate(EC_HUT, pextra) {
2849     if (tile_has_extra(ptile, pextra)) {
2850       hut = TRUE;
2851       pplayer->server.huts++;
2852 
2853       destroy_extra(ptile, pextra);
2854       update_tile_knowledge(unit_tile(punit));
2855 
2856       if (behavior == HUT_FRIGHTEN) {
2857         notify_player(pplayer, unit_tile(punit), E_HUT_BARB, ftc_server,
2858                       _("Your overflight frightens the tribe;"
2859                         " they scatter in terror."));
2860       } else if (pplayer->ai_controlled
2861                  && has_handicap(pplayer, H_LIMITEDHUTS)) {
2862         /* AI with H_LIMITEDHUTS only gets 25 gold (or barbs if unlucky) */
2863         (void) hut_get_limited(punit);
2864       } else {
2865         script_server_signal_emit("hut_enter", 1,
2866                                   API_TYPE_UNIT, punit);
2867       }
2868 
2869       /* We need punit for the callbacks, can't continue if the unit died */
2870       if (!unit_is_alive(id)) {
2871         res = FALSE;
2872         break;
2873       }
2874     }
2875   } extra_type_by_cause_iterate_end;
2876 
2877   if (hut) {
2878     send_player_info_c(pplayer, pplayer->connections); /* eg, gold */
2879   }
2880 
2881   return res;
2882 }
2883 
2884 /****************************************************************************
2885   Put the unit onto the transporter, and tell everyone.
2886 ****************************************************************************/
unit_transport_load_send(struct unit * punit,struct unit * ptrans)2887 void unit_transport_load_send(struct unit *punit, struct unit *ptrans)
2888 {
2889   bv_player can_see_unit;
2890 
2891   fc_assert_ret(punit != NULL);
2892   fc_assert_ret(ptrans != NULL);
2893 
2894   BV_CLR_ALL(can_see_unit);
2895   players_iterate(pplayer) {
2896     if (can_player_see_unit(pplayer, punit)) {
2897       BV_SET(can_see_unit, player_index(pplayer));
2898     }
2899   } players_iterate_end;
2900 
2901   unit_transport_load(punit, ptrans, FALSE);
2902 
2903   players_iterate(pplayer) {
2904     if (BV_ISSET(can_see_unit, player_index(pplayer))
2905         && !can_player_see_unit(pplayer, punit)) {
2906       unit_goes_out_of_sight(pplayer, punit);
2907     }
2908   } players_iterate_end;
2909 
2910   send_unit_info(NULL, punit);
2911   send_unit_info(NULL, ptrans);
2912 }
2913 
2914 /****************************************************************************
2915   Load unit to transport, send transport's loaded status to everyone.
2916 ****************************************************************************/
unit_transport_load_tp_status(struct unit * punit,struct unit * ptrans,bool force)2917 static void unit_transport_load_tp_status(struct unit *punit,
2918                                           struct unit *ptrans,
2919                                           bool force)
2920 {
2921   bool had_cargo;
2922 
2923   fc_assert_ret(punit != NULL);
2924   fc_assert_ret(ptrans != NULL);
2925 
2926   had_cargo = get_transporter_occupancy(ptrans) > 0;
2927 
2928   unit_transport_load(punit, ptrans, force);
2929 
2930   if (!had_cargo) {
2931     /* Transport's loaded status changed */
2932     send_unit_info(NULL, ptrans);
2933   }
2934 }
2935 
2936 /****************************************************************************
2937   Pull the unit off of the transporter, and tell everyone.
2938 ****************************************************************************/
unit_transport_unload_send(struct unit * punit)2939 void unit_transport_unload_send(struct unit *punit)
2940 {
2941   struct unit *ptrans;
2942 
2943   fc_assert_ret(punit);
2944 
2945   ptrans = unit_transport_get(punit);
2946 
2947   fc_assert_ret(ptrans);
2948 
2949   unit_transport_unload(punit);
2950 
2951   send_unit_info(NULL, punit);
2952   send_unit_info(NULL, ptrans);
2953 }
2954 
2955 /**************************************************************************
2956   This function is passed to unit_list_sort() to sort a list of units
2957   according to their win chance against autoattack_target, modified by
2958   transportation relationships.
2959 
2960   The reason for making sure that a cargo unit is ahead of its
2961   transporter(s) is to leave transports out of combat if at all possible.
2962   (The transport could be destroyed during combat.)
2963 **************************************************************************/
compare_units(const struct unit * const * p1,const struct unit * const * q1)2964 static int compare_units(const struct unit *const *p1,
2965                          const struct unit *const *q1)
2966 {
2967   struct unit *p1def = get_defender(*p1, autoattack_target);
2968   struct unit *q1def = get_defender(*q1, autoattack_target);
2969   int p1uwc = unit_win_chance(*p1, p1def);
2970   int q1uwc = unit_win_chance(*q1, q1def);
2971 
2972   /* Sort by transport depth first. This makes sure that no transport
2973    * attacks before its cargo does -- cargo sorts earlier in the list. */
2974   {
2975     const struct unit *p1trans = *p1, *q1trans = *q1;
2976 
2977     /* Walk the transport stacks in parallel, so as to bail out as soon as
2978      * one of them is empty (avoid walking deep stacks more often than
2979      * necessary). */
2980     while (p1trans && q1trans) {
2981       p1trans = unit_transport_get(p1trans);
2982       q1trans = unit_transport_get(q1trans);
2983     }
2984     if (!p1trans && q1trans) {
2985       /* q1 is at greater depth (perhaps it's p1's cargo). It should sort
2986        * earlier in the list (p1 > q1). */
2987       return 1;
2988     } else if (p1trans && !q1trans) {
2989       /* p1 is at greater depth, so should sort earlier (p1 < q1). */
2990       return -1;
2991     }
2992     /* else same depth, so move on to checking win chance: */
2993   }
2994 
2995   /* Put the units with the highest probability of success first. The up
2996    * side of this is that units with bonuses against the victim attacks
2997    * before other units. The downside is that strong units can be lead
2998    * away by sacrificial units. */
2999   if (p1uwc < q1uwc) {
3000     return +1; /* q is better */
3001   } else if (p1uwc == q1uwc) {
3002     return 0;
3003   } else {
3004     return -1; /* p is better */
3005   }
3006 }
3007 
3008 /*****************************************************************
3009   Can this unit be used in autoattack
3010 *****************************************************************/
is_suitable_autoattack_unit(struct unit * punit)3011 static bool is_suitable_autoattack_unit(struct unit *punit)
3012 {
3013   if (unit_has_type_flag(punit, UTYF_NUCLEAR)) {
3014     /* Not a good idea to nuke our own area */
3015     return FALSE;
3016   }
3017 
3018   return TRUE;
3019 }
3020 
3021 /*****************************************************************
3022   Check if unit survives enemy autoattacks. We assume that any
3023   unit that is adjacent to us can see us.
3024 *****************************************************************/
unit_survive_autoattack(struct unit * punit)3025 static bool unit_survive_autoattack(struct unit *punit)
3026 {
3027   struct unit_list *autoattack;
3028   int moves = punit->moves_left;
3029   int sanity1 = punit->id;
3030 
3031   if (!game.server.autoattack) {
3032     return TRUE;
3033   }
3034 
3035   autoattack = unit_list_new();
3036 
3037   /* Kludge to prevent attack power from dropping to zero during calc */
3038   punit->moves_left = MAX(punit->moves_left, 1);
3039 
3040   adjc_iterate(unit_tile(punit), ptile) {
3041     /* First add all eligible units to a unit list */
3042     unit_list_iterate(ptile->units, penemy) {
3043       struct player *enemyplayer = unit_owner(penemy);
3044       enum diplstate_type ds =
3045             player_diplstate_get(unit_owner(punit), enemyplayer)->type;
3046 
3047       if (penemy->moves_left > 0
3048           && ds == DS_WAR
3049           && is_suitable_autoattack_unit(penemy)
3050           && (unit_attack_unit_at_tile_result(penemy, punit, unit_tile(punit))
3051               == ATT_OK)) {
3052         unit_list_prepend(autoattack, penemy);
3053       }
3054     } unit_list_iterate_end;
3055   } adjc_iterate_end;
3056 
3057   /* Sort the potential attackers from highest to lowest success
3058    * probability. */
3059   autoattack_target = unit_tile(punit); /* global variable */
3060   if (unit_list_size(autoattack) >= 2) {
3061     unit_list_sort(autoattack, &compare_units);
3062   }
3063 
3064   unit_list_iterate_safe(autoattack, penemy) {
3065     int sanity2 = penemy->id;
3066     struct tile *ptile = unit_tile(penemy);
3067     struct unit *enemy_defender = get_defender(punit, ptile);
3068     struct unit *punit_defender = get_defender(penemy, unit_tile(punit));
3069     double punitwin, penemywin;
3070     double threshold = 0.25;
3071 
3072     fc_assert_action(NULL != punit_defender, continue);
3073 
3074     if (tile_city(ptile) && unit_list_size(ptile->units) == 1) {
3075       /* Don't leave city defenseless */
3076       threshold = 0.90;
3077     }
3078 
3079     if (NULL != enemy_defender) {
3080       punitwin = unit_win_chance(punit, enemy_defender);
3081     } else {
3082       /* 'penemy' can attack 'punit' but it may be not reciproque. */
3083       punitwin = 1.0;
3084     }
3085     penemywin = unit_win_chance(penemy, punit_defender);
3086 
3087     if ((penemywin > 1.0 - punitwin
3088          || utype_acts_hostile(unit_type_get(punit))
3089          || get_transporter_capacity(punit) > 0)
3090         && penemywin > threshold) {
3091 #ifdef REALLY_DEBUG_THIS
3092       log_test("AA %s -> %s (%d,%d) %.2f > %.2f && > %.2f",
3093                unit_rule_name(penemy), unit_rule_name(punit),
3094                TILE_XY(unit_tile(punit)), penemywin,
3095                1.0 - punitwin, threshold);
3096 #endif
3097 
3098       unit_activity_handling(penemy, ACTIVITY_IDLE);
3099       /* Attack */
3100       (void) unit_move_handling(penemy, unit_tile(punit),
3101                                 FALSE, TRUE, NULL);
3102     } else {
3103 #ifdef REALLY_DEBUG_THIS
3104       log_test("!AA %s -> %s (%d,%d) %.2f > %.2f && > %.2f",
3105                unit_rule_name(penemy), unit_rule_name(punit),
3106                TILE_XY(unit_tile(punit)), penemywin,
3107                1.0 - punitwin, threshold);
3108 #endif
3109       continue;
3110     }
3111 
3112     if (game_unit_by_number(sanity2)) {
3113       send_unit_info(NULL, penemy);
3114     }
3115     if (game_unit_by_number(sanity1)) {
3116       send_unit_info(NULL, punit);
3117     } else {
3118       unit_list_destroy(autoattack);
3119       return FALSE; /* moving unit dead */
3120     }
3121   } unit_list_iterate_safe_end;
3122 
3123   unit_list_destroy(autoattack);
3124   if (game_unit_by_number(sanity1)) {
3125     /* We could have lost movement in combat */
3126     punit->moves_left = MIN(punit->moves_left, moves);
3127     send_unit_info(NULL, punit);
3128     return TRUE;
3129   } else {
3130     return FALSE;
3131   }
3132 }
3133 
3134 /****************************************************************************
3135   Cancel orders for the unit.
3136 ****************************************************************************/
cancel_orders(struct unit * punit,char * dbg_msg)3137 static void cancel_orders(struct unit *punit, char *dbg_msg)
3138 {
3139   free_unit_orders(punit);
3140   send_unit_info(NULL, punit);
3141   log_debug("%s", dbg_msg);
3142 }
3143 
3144 /*****************************************************************
3145   Will wake up any neighboring enemy sentry units or patrolling
3146   units.
3147 *****************************************************************/
wakeup_neighbor_sentries(struct unit * punit)3148 static void wakeup_neighbor_sentries(struct unit *punit)
3149 {
3150   bool alone_in_city;
3151 
3152   if (NULL != tile_city(unit_tile(punit))) {
3153     int count = 0;
3154 
3155     unit_list_iterate(unit_tile(punit)->units, aunit) {
3156       /* Consider only units not transported. */
3157       if (!unit_transported(aunit)) {
3158         count++;
3159       }
3160     } unit_list_iterate_end;
3161 
3162     alone_in_city = (1 == count);
3163   } else {
3164     alone_in_city = FALSE;
3165   }
3166 
3167   /* There may be sentried units with a sightrange > 3, but we don't
3168      wake them up if the punit is farther away than 3. */
3169   square_iterate(unit_tile(punit), 3, ptile) {
3170     unit_list_iterate(ptile->units, penemy) {
3171       int distance_sq = sq_map_distance(unit_tile(punit), ptile);
3172       int radius_sq = get_unit_vision_at(penemy, unit_tile(penemy), V_MAIN);
3173 
3174       if (!pplayers_allied(unit_owner(punit), unit_owner(penemy))
3175           && penemy->activity == ACTIVITY_SENTRY
3176           && radius_sq >= distance_sq
3177           /* If the unit moved on a city, and the unit is alone, consider
3178            * it is visible. */
3179           && (alone_in_city
3180               || can_player_see_unit(unit_owner(penemy), punit))
3181           /* on board transport; don't awaken */
3182           && can_unit_exist_at_tile(penemy, unit_tile(penemy))) {
3183         set_unit_activity(penemy, ACTIVITY_IDLE);
3184         send_unit_info(NULL, penemy);
3185       }
3186     } unit_list_iterate_end;
3187   } square_iterate_end;
3188 
3189   /* Wakeup patrolling units we bump into.
3190      We do not wakeup units further away than 3 squares... */
3191   square_iterate(unit_tile(punit), 3, ptile) {
3192     unit_list_iterate(ptile->units, ppatrol) {
3193       if (punit != ppatrol
3194 	  && unit_has_orders(ppatrol)
3195 	  && ppatrol->orders.vigilant) {
3196 	if (maybe_cancel_patrol_due_to_enemy(ppatrol)) {
3197 	  cancel_orders(ppatrol, "  stopping because of nearby enemy");
3198           notify_player(unit_owner(ppatrol), unit_tile(ppatrol),
3199                         E_UNIT_ORDERS, ftc_server,
3200                         _("Orders for %s aborted after enemy movement was "
3201                           "spotted."),
3202                         unit_link(ppatrol));
3203         }
3204       }
3205     } unit_list_iterate_end;
3206   } square_iterate_end;
3207 }
3208 
3209 /**************************************************************************
3210 Does: 1) updates the unit's homecity and the city it enters/leaves (the
3211          city's happiness varies). This also takes into account when the
3212 	 unit enters/leaves a fortress.
3213       2) updates adjacent cities' unavailable tiles.
3214 
3215 FIXME: Sometimes it is not necessary to send cities because the goverment
3216        doesn't care whether a unit is away or not.
3217 **************************************************************************/
unit_move_consequences(struct unit * punit,struct tile * src_tile,struct tile * dst_tile,bool passenger)3218 static bool unit_move_consequences(struct unit *punit,
3219                                    struct tile *src_tile,
3220                                    struct tile *dst_tile,
3221                                    bool passenger)
3222 {
3223   struct city *fromcity = tile_city(src_tile);
3224   struct city *tocity = tile_city(dst_tile);
3225   struct city *homecity_start_pos = NULL;
3226   struct city *homecity_end_pos = NULL;
3227   int homecity_id_start_pos = punit->homecity;
3228   int homecity_id_end_pos = punit->homecity;
3229   struct player *pplayer_start_pos = unit_owner(punit);
3230   struct player *pplayer_end_pos = pplayer_start_pos;
3231   struct unit_type *type_start_pos = unit_type_get(punit);
3232   struct unit_type *type_end_pos = type_start_pos;
3233   bool refresh_homecity_start_pos = FALSE;
3234   bool refresh_homecity_end_pos = FALSE;
3235   int saved_id = punit->id;
3236   bool alive = TRUE;
3237 
3238   if (tocity) {
3239     unit_enter_city(punit, tocity, passenger);
3240 
3241     alive = unit_is_alive(saved_id);
3242     if (alive) {
3243       /* In case script has changed something about unit */
3244       pplayer_end_pos = unit_owner(punit);
3245       type_end_pos = unit_type_get(punit);
3246       homecity_id_end_pos = punit->homecity;
3247     }
3248   }
3249 
3250   if (homecity_id_start_pos != 0) {
3251     homecity_start_pos = game_city_by_number(homecity_id_start_pos);
3252   }
3253   if (homecity_id_start_pos != homecity_id_end_pos) {
3254     homecity_end_pos = game_city_by_number(homecity_id_end_pos);
3255   } else {
3256     homecity_end_pos = homecity_start_pos;
3257   }
3258 
3259   /* We only do refreshes for non-AI players to now make sure the AI turns
3260      doesn't take too long. Perhaps we should make a special refresh_city
3261      functions that only refreshed happines. */
3262 
3263   /* might have changed owners or may be destroyed */
3264   tocity = tile_city(dst_tile);
3265 
3266   if (tocity) { /* entering a city */
3267     if (tocity->owner == pplayer_end_pos) {
3268       if (tocity != homecity_end_pos && !pplayer_end_pos->ai_controlled) {
3269         city_refresh(tocity);
3270         send_city_info(pplayer_end_pos, tocity);
3271       }
3272     }
3273     if (homecity_start_pos) {
3274       refresh_homecity_start_pos = TRUE;
3275     }
3276   }
3277 
3278   if (fromcity) { /* leaving a city */
3279     if (homecity_start_pos) {
3280       refresh_homecity_start_pos = TRUE;
3281     }
3282     if (fromcity != homecity_start_pos
3283         && fromcity->owner == pplayer_start_pos
3284         && !pplayer_start_pos->ai_controlled) {
3285       city_refresh(fromcity);
3286       send_city_info(pplayer_start_pos, fromcity);
3287     }
3288   }
3289 
3290   /* entering/leaving a fortress or friendly territory */
3291   if (homecity_start_pos || homecity_end_pos) {
3292     if ((game.info.happyborders != HB_DISABLED && tile_owner(src_tile) != tile_owner(dst_tile))
3293         || (tile_has_base_flag_for_unit(dst_tile,
3294                                         type_end_pos,
3295                                         BF_NOT_AGGRESSIVE)
3296             && is_friendly_city_near(pplayer_end_pos, dst_tile))
3297         || (tile_has_base_flag_for_unit(src_tile,
3298                                         type_start_pos,
3299                                         BF_NOT_AGGRESSIVE)
3300             && is_friendly_city_near(pplayer_start_pos, src_tile))) {
3301       refresh_homecity_start_pos = TRUE;
3302       refresh_homecity_end_pos = TRUE;
3303     }
3304   }
3305 
3306   if (refresh_homecity_start_pos && !pplayer_start_pos->ai_controlled) {
3307     city_refresh(homecity_start_pos);
3308     send_city_info(pplayer_start_pos, homecity_start_pos);
3309   }
3310   if (refresh_homecity_end_pos
3311       && (!refresh_homecity_start_pos
3312           || homecity_start_pos != homecity_end_pos)
3313       && !pplayer_end_pos->ai_controlled) {
3314     city_refresh(homecity_end_pos);
3315     send_city_info(pplayer_end_pos, homecity_end_pos);
3316   }
3317 
3318   city_map_update_tile_now(dst_tile);
3319   sync_cities();
3320 
3321   return alive;
3322 }
3323 
3324 /**************************************************************************
3325 Check if the units activity is legal for a move , and reset it if it isn't.
3326 **************************************************************************/
check_unit_activity(struct unit * punit)3327 static void check_unit_activity(struct unit *punit)
3328 {
3329   switch (punit->activity) {
3330   case ACTIVITY_IDLE:
3331   case ACTIVITY_SENTRY:
3332   case ACTIVITY_EXPLORE:
3333   case ACTIVITY_GOTO:
3334     break;
3335   case ACTIVITY_POLLUTION:
3336   case ACTIVITY_MINE:
3337   case ACTIVITY_IRRIGATE:
3338   case ACTIVITY_FORTIFIED:
3339   case ACTIVITY_FORTRESS:
3340   case ACTIVITY_PILLAGE:
3341   case ACTIVITY_TRANSFORM:
3342   case ACTIVITY_UNKNOWN:
3343   case ACTIVITY_AIRBASE:
3344   case ACTIVITY_FORTIFYING:
3345   case ACTIVITY_FALLOUT:
3346   case ACTIVITY_PATROL_UNUSED:
3347   case ACTIVITY_BASE:
3348   case ACTIVITY_GEN_ROAD:
3349   case ACTIVITY_CONVERT:
3350   case ACTIVITY_OLD_ROAD:
3351   case ACTIVITY_OLD_RAILROAD:
3352   case ACTIVITY_LAST:
3353     set_unit_activity(punit, ACTIVITY_IDLE);
3354     break;
3355   };
3356 }
3357 
3358 /****************************************************************************
3359   Create a new unit move data, or use previous one if available.
3360 ****************************************************************************/
unit_move_data(struct unit * punit,struct tile * psrctile,struct tile * pdesttile)3361 static struct unit_move_data *unit_move_data(struct unit *punit,
3362                                              struct tile *psrctile,
3363                                              struct tile *pdesttile)
3364 {
3365   struct unit_move_data *pdata;
3366   struct player *powner = unit_owner(punit);
3367   const v_radius_t radius_sq =
3368         V_RADIUS(get_unit_vision_at(punit, pdesttile, V_MAIN),
3369                  get_unit_vision_at(punit, pdesttile, V_INVIS));
3370   struct vision *new_vision;
3371   bool success;
3372 
3373   if (punit->server.moving) {
3374     /* Recursive moving (probably due to a script). */
3375     pdata = punit->server.moving;
3376     pdata->ref_count++;
3377     fc_assert_msg(pdata->punit == punit,
3378                   "Unit number %d (%p) was going to die, but "
3379                   "server attempts to move it.",
3380                   punit->id, punit);
3381     fc_assert_msg(pdata->old_vision == NULL,
3382                   "Unit number %d (%p) has done an incomplete move.",
3383                   punit->id, punit);
3384   } else {
3385     pdata = fc_malloc(sizeof(*pdata));
3386     pdata->ref_count = 1;
3387     pdata->punit = punit;
3388     punit->server.moving = pdata;
3389     BV_CLR_ALL(pdata->can_see_unit);
3390   }
3391   pdata->powner = powner;
3392   BV_CLR_ALL(pdata->can_see_move);
3393   pdata->old_vision = punit->server.vision;
3394 
3395   /* Remove unit from the source tile. */
3396   fc_assert(unit_tile(punit) == psrctile);
3397   success = unit_list_remove(psrctile->units, punit);
3398   fc_assert(success == TRUE);
3399 
3400   /* Set new tile. */
3401   unit_tile_set(punit, pdesttile);
3402   unit_list_prepend(pdesttile->units, punit);
3403 
3404   if (unit_transported(punit)) {
3405     /* Silently free orders since they won't be applicable anymore. */
3406     free_unit_orders(punit);
3407   }
3408 
3409   /* Check unit activity. */
3410   check_unit_activity(punit);
3411   unit_did_action(punit);
3412   unit_forget_last_activity(punit);
3413 
3414   /* We first unfog the destination, then send the move,
3415    * and then fog the old territory. This means that the player
3416    * gets a chance to see the newly explored territory while the
3417    * client moves the unit, and both areas are visible during the
3418    * move */
3419 
3420   /* Enhance vision if unit steps into a fortress */
3421   new_vision = vision_new(powner, pdesttile);
3422   punit->server.vision = new_vision;
3423   vision_change_sight(new_vision, radius_sq);
3424   ASSERT_VISION(new_vision);
3425 
3426   return pdata;
3427 }
3428 
3429 /****************************************************************************
3430   Decrease the reference counter and destroy if needed.
3431 ****************************************************************************/
unit_move_data_unref(struct unit_move_data * pdata)3432 static void unit_move_data_unref(struct unit_move_data *pdata)
3433 {
3434   fc_assert_ret(pdata != NULL);
3435   fc_assert_ret(pdata->ref_count > 0);
3436   fc_assert_msg(pdata->old_vision == NULL,
3437                 "Unit number %d (%p) has done an incomplete move.",
3438                 pdata->punit != NULL ? pdata->punit->id : -1, pdata->punit);
3439 
3440   pdata->ref_count--;
3441   if (pdata->ref_count == 0) {
3442     if (pdata->punit != NULL) {
3443       fc_assert(pdata->punit->server.moving == pdata);
3444       pdata->punit->server.moving = NULL;
3445     }
3446     free(pdata);
3447   }
3448 }
3449 
3450 /*****************************************************************************
3451   Moves a unit. No checks whatsoever! This is meant as a practical
3452   function for other functions, like do_airline, which do the checking
3453   themselves.
3454 
3455   If you move a unit you should always use this function, as it also sets
3456   the transport status of the unit correctly. Note that the source tile (the
3457   current tile of the unit) and pdesttile need not be adjacent.
3458 
3459   Returns TRUE iff unit still alive.
3460 *****************************************************************************/
unit_move(struct unit * punit,struct tile * pdesttile,int move_cost,struct unit * embark_to)3461 bool unit_move(struct unit *punit, struct tile *pdesttile, int move_cost,
3462                struct unit *embark_to)
3463 {
3464   struct player *pplayer;
3465   struct tile *psrctile;
3466   struct city *pcity;
3467   struct unit *ptransporter;
3468   struct packet_unit_info src_info, dest_info;
3469   struct packet_unit_short_info src_sinfo, dest_sinfo;
3470   struct unit_move_data_list *plist =
3471       unit_move_data_list_new_full(unit_move_data_unref);
3472   struct unit_move_data *pdata;
3473   int saved_id;
3474   bool unit_lives;
3475   bool adj;
3476   enum direction8 facing;
3477   struct player *bowner;
3478 
3479   /* Some checks. */
3480   fc_assert_ret_val(punit != NULL, FALSE);
3481   fc_assert_ret_val(pdesttile != NULL, FALSE);
3482 
3483   pplayer = unit_owner(punit);
3484   saved_id = punit->id;
3485   psrctile = unit_tile(punit);
3486   adj = base_get_direction_for_step(psrctile, pdesttile, &facing);
3487 
3488   conn_list_do_buffer(game.est_connections);
3489 
3490   /* Unload the unit if on a transport. */
3491   ptransporter = unit_transport_get(punit);
3492   if (ptransporter != NULL) {
3493     /* Unload unit _before_ setting the new tile! */
3494     unit_transport_unload(punit);
3495     /* Send updated information to anyone watching that transporter
3496      * was unloading cargo. */
3497     send_unit_info(NULL, ptransporter);
3498   }
3499 
3500   /* Wakup units next to us before we move. */
3501   wakeup_neighbor_sentries(punit);
3502 
3503   /* Make info packets at 'psrctile'. */
3504   if (adj) {
3505     /* If tiles are adjacent, we will show the move to users able
3506      * to see it. */
3507     package_unit(punit, &src_info);
3508     package_short_unit(punit, &src_sinfo, UNIT_INFO_IDENTITY, 0);
3509   }
3510 
3511   /* Make new data for 'punit'. */
3512   pdata = unit_move_data(punit, psrctile, pdesttile);
3513   unit_move_data_list_prepend(plist, pdata);
3514 
3515   /* Set unit orientation */
3516   if (adj) {
3517     /* Only change orientation when moving to adjacent tile */
3518     punit->facing = facing;
3519   }
3520 
3521   /* Move magic. */
3522   punit->moved = TRUE;
3523   punit->moves_left = MAX(0, punit->moves_left - move_cost);
3524   if (punit->moves_left == 0 && !unit_has_orders(punit)) {
3525     /* The next order may not require any remaining move fragments. */
3526     punit->done_moving = TRUE;
3527   }
3528 
3529   /* No longer relevant. */
3530   punit->action_decision_tile = NULL;
3531   punit->action_decision_want = ACT_DEC_NOTHING;
3532 
3533   if (!adj
3534       && action_tgt_city(punit, pdesttile)) {
3535     /* The unit can perform an action to the city at the destination tile.
3536      * A long distance move (like an airlift) doesn't ask what action to
3537      * perform before moving. Ask now. */
3538 
3539     punit->action_decision_want = ACT_DEC_PASSIVE;
3540     punit->action_decision_tile = pdesttile;
3541   }
3542 
3543   /* Claim ownership of fortress? */
3544   bowner = extra_owner(pdesttile);
3545   if ((bowner == NULL || pplayers_at_war(bowner, pplayer))
3546       && tile_has_claimable_base(pdesttile, unit_type_get(punit))) {
3547     /* Yes. We claim *all* bases if there's *any* claimable base(s).
3548      * Even if original unit cannot claim other kind of bases, the
3549      * first claimed base will have influence over other bases,
3550      * or something like that. */
3551     tile_claim_bases(pdesttile, pplayer);
3552   }
3553 
3554   /* Move all contained units. */
3555   unit_cargo_iterate(punit, pcargo) {
3556     pdata = unit_move_data(pcargo, psrctile, pdesttile);
3557     unit_move_data_list_append(plist, pdata);
3558   } unit_cargo_iterate_end;
3559 
3560   /* Get data for 'punit'. */
3561   pdata = unit_move_data_list_front(plist);
3562 
3563   /* Determine the players able to see the move(s), now that the player
3564    * vision has been increased. */
3565   if (adj) {
3566     /*  Main unit for adjacent move: the move is visible for every player
3567      * able to see on the matching unit layer. */
3568     enum vision_layer vlayer = is_hiding_unit(punit) ? V_INVIS : V_MAIN;
3569 
3570     players_iterate(oplayer) {
3571       if (map_is_known_and_seen(psrctile, oplayer, vlayer)
3572           || map_is_known_and_seen(pdesttile, oplayer, vlayer)) {
3573         BV_SET(pdata->can_see_unit, player_index(oplayer));
3574         BV_SET(pdata->can_see_move, player_index(oplayer));
3575       }
3576     } players_iterate_end;
3577   }
3578   unit_move_data_list_iterate(plist, pmove_data) {
3579     if (adj && pmove_data == pdata) {
3580       /* If positions are adjacent, we have already handled 'punit'. See
3581        * above. */
3582       continue;
3583     }
3584 
3585     players_iterate(oplayer) {
3586       if ((adj
3587            && can_player_see_unit_at(oplayer, pmove_data->punit, psrctile,
3588                                      pmove_data != pdata))
3589           || can_player_see_unit_at(oplayer, pmove_data->punit, pdesttile,
3590                                     pmove_data != pdata)) {
3591         BV_SET(pmove_data->can_see_unit, player_index(oplayer));
3592         BV_SET(pmove_data->can_see_move, player_index(oplayer));
3593       }
3594       if (can_player_see_unit_at(oplayer, pmove_data->punit, psrctile,
3595                                  pmove_data != pdata)) {
3596         /* The unit was seen with its source tile even if it was
3597          * teleported. */
3598         BV_SET(pmove_data->can_see_unit, player_index(oplayer));
3599       }
3600     } players_iterate_end;
3601   } unit_move_data_list_iterate_end;
3602 
3603   /* Check timeout settings. */
3604   if (current_turn_timeout() != 0 && game.server.timeoutaddenemymove > 0) {
3605     bool new_information_for_enemy = FALSE;
3606 
3607     phase_players_iterate(penemy) {
3608       /* Increase the timeout if an enemy unit moves and the
3609        * timeoutaddenemymove setting is in use. */
3610       if (penemy->is_connected
3611           && pplayer != penemy
3612           && pplayers_at_war(pplayer, penemy)
3613           && BV_ISSET(pdata->can_see_move, player_index(penemy))) {
3614         new_information_for_enemy = TRUE;
3615         break;
3616       }
3617     } phase_players_iterate_end;
3618 
3619     if (new_information_for_enemy) {
3620       increase_timeout_because_unit_moved();
3621     }
3622   }
3623 
3624   /* Notifications of the move to the clients. */
3625   if (adj) {
3626     /* Special case: 'punit' is moving to adjacent position. Then we show
3627      * 'punit' move to all users able to see 'psrctile' or 'pdesttile'. */
3628 
3629     /* Make info packets at 'pdesttile'. */
3630     package_unit(punit, &dest_info);
3631     package_short_unit(punit, &dest_sinfo, UNIT_INFO_IDENTITY, 0);
3632 
3633     conn_list_iterate(game.est_connections, pconn) {
3634       struct player *aplayer = conn_get_player(pconn);
3635 
3636       if (aplayer == NULL) {
3637         if (pconn->observer) {
3638           /* Global observers see all... */
3639           send_packet_unit_info(pconn, &src_info);
3640           send_packet_unit_info(pconn, &dest_info);
3641         }
3642       } else if (BV_ISSET(pdata->can_see_move, player_index(aplayer))) {
3643         if (aplayer == pplayer) {
3644           send_packet_unit_info(pconn, &src_info);
3645           send_packet_unit_info(pconn, &dest_info);
3646         } else {
3647           send_packet_unit_short_info(pconn, &src_sinfo, FALSE);
3648           send_packet_unit_short_info(pconn, &dest_sinfo, FALSE);
3649         }
3650       }
3651     } conn_list_iterate_end;
3652   }
3653 
3654   /* Other moves. */
3655   unit_move_data_list_iterate(plist, pmove_data) {
3656     if (adj && pmove_data == pdata) {
3657       /* If positions are adjacent, we have already shown 'punit' move.
3658        * See above. */
3659       continue;
3660     }
3661 
3662     /* Make info packets at 'pdesttile'. */
3663     package_unit(pmove_data->punit, &dest_info);
3664     package_short_unit(pmove_data->punit, &dest_sinfo,
3665                        UNIT_INFO_IDENTITY, 0);
3666 
3667     conn_list_iterate(game.est_connections, pconn) {
3668       struct player *aplayer = conn_get_player(pconn);
3669 
3670       if (aplayer == NULL) {
3671         if (pconn->observer) {
3672           /* Global observers see all... */
3673           send_packet_unit_info(pconn, &dest_info);
3674         }
3675       } else if (BV_ISSET(pmove_data->can_see_move, player_index(aplayer))) {
3676         if (aplayer == pmove_data->powner) {
3677           send_packet_unit_info(pconn, &dest_info);
3678         } else {
3679           send_packet_unit_short_info(pconn, &dest_sinfo, FALSE);
3680         }
3681       }
3682     } conn_list_iterate_end;
3683   } unit_move_data_list_iterate_end;
3684 
3685   /* Clear old vision. */
3686   unit_move_data_list_iterate(plist, pmove_data) {
3687     vision_clear_sight(pmove_data->old_vision);
3688     vision_free(pmove_data->old_vision);
3689     pmove_data->old_vision = NULL;
3690   } unit_move_data_list_iterate_end;
3691 
3692   /* Move consequences. */
3693   unit_move_data_list_iterate(plist, pmove_data) {
3694     struct unit *aunit = pmove_data->punit;
3695 
3696     if (aunit != NULL
3697         && unit_owner(aunit) == pmove_data->powner
3698         && unit_tile(aunit) == pdesttile) {
3699       (void) unit_move_consequences(aunit, psrctile, pdesttile,
3700                                     pdata != pmove_data);
3701     }
3702   } unit_move_data_list_iterate_end;
3703 
3704   unit_lives = (pdata->punit == punit);
3705 
3706   /* Wakeup units and make contact. */
3707   if (unit_lives) {
3708     wakeup_neighbor_sentries(punit);
3709   }
3710   maybe_make_contact(pdesttile, pplayer);
3711 
3712   if (unit_lives) {
3713     /* Special checks for ground units in the ocean. */
3714     if (embark_to || !can_unit_survive_at_tile(punit, pdesttile)) {
3715       if (embark_to != NULL) {
3716         ptransporter = embark_to;
3717       } else {
3718         ptransporter = transporter_for_unit(punit);
3719       }
3720       if (ptransporter) {
3721         unit_transport_load_tp_status(punit, ptransporter, FALSE);
3722 
3723         /* Set activity to sentry if boarding a ship. */
3724         if (!pplayer->ai_controlled
3725             && !unit_has_orders(punit)
3726             && !punit->ai_controlled
3727             && !can_unit_exist_at_tile(punit, pdesttile)) {
3728           set_unit_activity(punit, ACTIVITY_SENTRY);
3729         }
3730 
3731         send_unit_info(NULL, punit);
3732       }
3733     }
3734   }
3735 
3736   /* Remove units going out of sight. */
3737   unit_move_data_list_iterate_rev(plist, pmove_data) {
3738     struct unit *aunit = pmove_data->punit;
3739 
3740     if (aunit == NULL) {
3741       continue; /* Died! */
3742     }
3743 
3744     players_iterate(aplayer) {
3745       if (BV_ISSET(pmove_data->can_see_unit, player_index(aplayer))
3746           && !can_player_see_unit(aplayer, aunit)) {
3747         unit_goes_out_of_sight(aplayer, aunit);
3748       }
3749     } players_iterate_end;
3750   } unit_move_data_list_iterate_rev_end;
3751 
3752   /* Inform the owner's client about actor unit arrival. Can, depending on
3753    * the client settings, cause the client to start the process that makes
3754    * the action selection dialog pop up. */
3755   if ((pcity = tile_city(pdesttile))) {
3756     /* Arrival in a city counts. */
3757 
3758     unit_move_data_list_iterate(plist, pmove_data) {
3759       struct unit *ptrans;
3760       bool ok;
3761       struct unit *act_unit;
3762       struct player *act_player;
3763 
3764       act_unit = pmove_data->punit;
3765       act_player = unit_owner(act_unit);
3766 
3767       if (act_unit == NULL
3768           || !unit_is_alive(act_unit->id)) {
3769         /* The unit died before reaching this point. */
3770         continue;
3771       }
3772 
3773       if (unit_tile(act_unit) != pdesttile) {
3774         /* The unit didn't arrive at the destination tile. */
3775         continue;
3776       }
3777 
3778       if (act_player->ai_controlled) {
3779         /* The AI doesn't need reminders. */
3780         continue;
3781       }
3782 
3783       if (!unit_transported(act_unit)) {
3784         /* Don't show the action selection dialog again. Non transported
3785          * units are handled before they move to the tile.  */
3786         continue;
3787       }
3788 
3789       /* Open action dialog only if 'act_unit' and all its transporters
3790        * (recursively) don't have orders. */
3791       if (unit_has_orders(act_unit)) {
3792         /* The unit it self has orders. */
3793         continue;
3794       }
3795 
3796       for (ptrans = unit_transport_get(act_unit);;
3797            ptrans = unit_transport_get(ptrans)) {
3798         if (NULL == ptrans) {
3799           /* No (recursive) transport has orders. */
3800           ok = TRUE;
3801           break;
3802         } else if (unit_has_orders(ptrans)) {
3803           /* A unit transporting the unit has orders */
3804           ok = FALSE;
3805           break;
3806         }
3807       }
3808 
3809       if (!ok) {
3810         /* A unit transporting act_unit has orders. */
3811         continue;
3812       }
3813 
3814       if (action_tgt_city(act_unit, pdesttile)) {
3815         /* There is a valid target. */
3816 
3817         act_unit->action_decision_want = ACT_DEC_PASSIVE;
3818         act_unit->action_decision_tile = pdesttile;
3819 
3820         /* Let the client know that this unit wants the player to decide
3821          * what to do. */
3822         send_unit_info(player_reply_dest(act_player), act_unit);
3823       }
3824     } unit_move_data_list_iterate_end;
3825   }
3826 
3827   unit_move_data_list_destroy(plist);
3828 
3829   /* Check cities at source and destination. */
3830   if ((pcity = tile_city(psrctile))) {
3831     refresh_dumb_city(pcity);
3832   }
3833   if ((pcity = tile_city(pdesttile))) {
3834     refresh_dumb_city(pcity);
3835   }
3836 
3837   if (unit_lives) {
3838     /* Let the scripts run ... */
3839     script_server_signal_emit("unit_moved", 3,
3840                               API_TYPE_UNIT, punit,
3841                               API_TYPE_TILE, psrctile,
3842                               API_TYPE_TILE, pdesttile);
3843     unit_lives = unit_is_alive(saved_id);
3844   }
3845 
3846   if (unit_lives) {
3847     /* Autoattack. */
3848     unit_lives = unit_survive_autoattack(punit);
3849   }
3850 
3851   if (unit_lives) {
3852     /* Entering huts */
3853     unit_lives = unit_enter_hut(punit);
3854   }
3855 
3856   conn_list_do_unbuffer(game.est_connections);
3857 
3858   return unit_lives;
3859 }
3860 
3861 /**************************************************************************
3862   Maybe cancel the goto if there is an enemy in the way
3863 **************************************************************************/
maybe_cancel_goto_due_to_enemy(struct unit * punit,struct tile * ptile)3864 static bool maybe_cancel_goto_due_to_enemy(struct unit *punit,
3865                                            struct tile *ptile)
3866 {
3867   return (is_non_allied_unit_tile(ptile, unit_owner(punit))
3868 	  || is_non_allied_city_tile(ptile, unit_owner(punit)));
3869 }
3870 
3871 /**************************************************************************
3872   Maybe cancel the patrol as there is an enemy near.
3873 
3874   If you modify the wakeup range you should change it in
3875   wakeup_neighbor_sentries() too.
3876 **************************************************************************/
maybe_cancel_patrol_due_to_enemy(struct unit * punit)3877 static bool maybe_cancel_patrol_due_to_enemy(struct unit *punit)
3878 {
3879   bool cancel = FALSE;
3880   int radius_sq = get_unit_vision_at(punit, unit_tile(punit), V_MAIN);
3881   struct player *pplayer = unit_owner(punit);
3882 
3883   circle_iterate(unit_tile(punit), radius_sq, ptile) {
3884     struct unit *penemy = is_non_allied_unit_tile(ptile, pplayer);
3885 
3886     struct vision_site *pdcity = map_get_player_site(ptile, pplayer);
3887 
3888     if ((penemy && can_player_see_unit(pplayer, penemy))
3889 	|| (pdcity && !pplayers_allied(pplayer, vision_site_owner(pdcity))
3890 	    && pdcity->occupied)) {
3891       cancel = TRUE;
3892       break;
3893     }
3894   } circle_iterate_end;
3895 
3896   return cancel;
3897 }
3898 
3899 /**************************************************************************
3900   Returns the action id corresponding to the specified order id.
3901 **************************************************************************/
order_to_action(struct unit * punit,enum unit_orders order)3902 static int order_to_action(struct unit *punit, enum unit_orders order)
3903 {
3904   switch (order) {
3905   case ORDER_BUILD_WONDER:
3906     return ACTION_HELP_WONDER;
3907   case ORDER_TRADE_ROUTE:
3908     return ACTION_TRADE_ROUTE;
3909   case ORDER_MOVE:
3910   case ORDER_ACTION_MOVE:
3911   case ORDER_FULL_MP:
3912   case ORDER_BUILD_CITY:
3913   case ORDER_ACTIVITY:
3914   case ORDER_DISBAND:
3915   case ORDER_HOMECITY:
3916   case ORDER_LAST:
3917     /* Not action enabler controlled. */
3918     break;
3919   }
3920 
3921   fc_assert_msg(FALSE, "No action to map order to.");
3922   return ACTION_COUNT;
3923 }
3924 
3925 /**************************************************************************
3926   Returns TRUE iff it is reasonable to assume that the player is wathing
3927   the unit.
3928 
3929   Since the player is watching the unit there is no need to inform him
3930   about things he could see happening. Remember that it still may
3931   be necessary to explain why something happened.
3932 **************************************************************************/
player_is_watching(struct unit * punit,const bool fresh)3933 static inline bool player_is_watching(struct unit *punit, const bool fresh)
3934 {
3935   /* The player just sent the orders to the unit. The unit has moves left.
3936    * It is therefore safe to assume that the player already is paying
3937    * attention to the unit. */
3938   return fresh && punit->moves_left > 0;
3939 }
3940 
3941 /****************************************************************************
3942   Executes a unit's orders stored in punit->orders.  The unit is put on idle
3943   if an action fails or if "patrol" is set and an enemy unit is encountered.
3944 
3945   The return value will be TRUE if the unit lives, FALSE otherwise.  (This
3946   function used to return a goto_result enumeration, declared in gotohand.h.
3947   But this enumeration was never checked by the caller and just lead to
3948   confusion.  All the caller really needs to know is if the unit lived or
3949   died; everything else is handled internally within execute_orders.)
3950 
3951   If the orders are repeating the loop starts over at the beginning once it
3952   completes.  To avoid infinite loops on railroad we stop for this
3953   turn when the unit is back where it started, even if it have moves left.
3954 
3955   A unit will attack under orders only on its final action.
3956 
3957   The fresh parameter is true if the order execution happens because the
3958   orders just were received.
3959 ****************************************************************************/
execute_orders(struct unit * punit,const bool fresh)3960 bool execute_orders(struct unit *punit, const bool fresh)
3961 {
3962   struct tile *dst_tile;
3963   bool res, last_order;
3964   int unitid = punit->id;
3965   struct player *pplayer = unit_owner(punit);
3966   int moves_made = 0;
3967   enum unit_activity activity;
3968 
3969   fc_assert_ret_val(unit_has_orders(punit), TRUE);
3970 
3971   if (punit->activity != ACTIVITY_IDLE) {
3972     /* Unit's in the middle of an activity; wait for it to finish. */
3973     punit->done_moving = TRUE;
3974     return TRUE;
3975   }
3976 
3977   log_debug("Executing orders for %s %d", unit_rule_name(punit), punit->id);
3978 
3979   /* Any time the orders are canceled we should give the player a message. */
3980 
3981   while (TRUE) {
3982     struct unit_order order;
3983 
3984     if (punit->done_moving) {
3985       log_debug("  stopping because we're done this turn");
3986       return TRUE;
3987     }
3988 
3989     if (punit->orders.vigilant && maybe_cancel_patrol_due_to_enemy(punit)) {
3990       /* "Patrol" orders are stopped if an enemy is near. */
3991       cancel_orders(punit, "  stopping because of nearby enemy");
3992       notify_player(pplayer, unit_tile(punit), E_UNIT_ORDERS, ftc_server,
3993                     _("Orders for %s aborted as there are units nearby."),
3994                     unit_link(punit));
3995       return TRUE;
3996     }
3997 
3998     if (moves_made == punit->orders.length) {
3999       /* For repeating orders, don't repeat more than once per turn. */
4000       log_debug("  stopping because we ran a round");
4001       punit->done_moving = TRUE;
4002       send_unit_info(NULL, punit);
4003       return TRUE;
4004     }
4005     moves_made++;
4006 
4007     order = punit->orders.list[punit->orders.index];
4008 
4009     switch (order.order) {
4010     case ORDER_MOVE:
4011     case ORDER_ACTION_MOVE:
4012     case ORDER_FULL_MP:
4013     case ORDER_BUILD_CITY:
4014       if (0 == punit->moves_left) {
4015         log_debug("  stopping because of no more move points");
4016         return TRUE;
4017       }
4018       break;
4019     case ORDER_BUILD_WONDER:
4020     case ORDER_TRADE_ROUTE:
4021       if (action_mp_full_makes_legal(punit, order_to_action(punit, order.order))) {
4022         log_debug("  stopping. Not enough move points this turn");
4023         return TRUE;
4024       }
4025       break;
4026     case ORDER_ACTIVITY:
4027     case ORDER_DISBAND:
4028     case ORDER_HOMECITY:
4029     case ORDER_LAST:
4030       /* Those actions don't require moves left. */
4031       break;
4032     }
4033 
4034     last_order = (!punit->orders.repeat
4035 		  && punit->orders.index + 1 == punit->orders.length);
4036 
4037     if (last_order) {
4038       /* Clear the orders before we engage in the move.  That way any
4039        * has_orders checks will yield FALSE and this will be treated as
4040        * a normal move.  This is important: for instance a caravan goto
4041        * will popup the caravan dialog on the last move only. */
4042       free_unit_orders(punit);
4043     }
4044 
4045     /* Advance the orders one step forward.  This is needed because any
4046      * updates sent to the client as a result of the action should include
4047      * the new index value.  Note that we have to send_unit_info somewhere
4048      * after this point so that the client is properly updated. */
4049     punit->orders.index++;
4050 
4051     switch (order.order) {
4052     case ORDER_FULL_MP:
4053       if (punit->moves_left < unit_move_rate(punit)) {
4054 	/* If the unit doesn't have full MP then it just waits until the
4055 	 * next turn.  We assume that the next turn it will have full MP
4056 	 * (there's no check for that). */
4057 	punit->done_moving = TRUE;
4058         log_debug("  waiting this turn");
4059 	send_unit_info(NULL, punit);
4060       }
4061       break;
4062     case ORDER_BUILD_CITY:
4063       unit_build_city(pplayer, punit,
4064                       city_name_suggestion(pplayer, unit_tile(punit)));
4065       log_debug("  building city");
4066       if (player_unit_by_number(pplayer, unitid)) {
4067 	/* Build failed. */
4068 	cancel_orders(punit, " orders canceled; failed to build city");
4069         notify_player(pplayer, unit_tile(punit), E_UNIT_ORDERS, ftc_server,
4070                       _("Orders for %s aborted because building "
4071                         "of city failed."),
4072                       unit_link(punit));
4073 	return TRUE;
4074       } else {
4075 	/* Build succeeded => unit "died" */
4076 	return FALSE;
4077       }
4078     case ORDER_ACTIVITY:
4079       activity = order.activity;
4080       {
4081         struct extra_type *pextra = (order.target == EXTRA_NONE ?
4082                                        NULL :
4083                                        extra_by_number(order.target));
4084 
4085         if (pextra == NULL && activity_requires_target(order.activity)) {
4086           /* Try to find a target extra before giving up this order or, if
4087            * serious enough, all orders. */
4088 
4089           enum unit_activity new_activity = order.activity;
4090 
4091           unit_assign_specific_activity_target(punit,
4092                                                &new_activity, &pextra);
4093 
4094           if (new_activity != order.activity) {
4095             /* At the time this code was written the only possible activity
4096              * change from unit_assign_specific_activity_target() was from
4097              * ACTIVITY_PILLAGE to ACTIVITY_IDLE. That would only happen
4098              * when a target extra couldn't be found. -- Sveinung */
4099             fc_assert_msg((order.activity == ACTIVITY_PILLAGE
4100                            && new_activity == ACTIVITY_IDLE),
4101                           "Skipping an order when canceling all orders may"
4102                           " have been the correct thing to do.");
4103 
4104             /* Already removed, let's continue. */
4105             break;
4106           }
4107 
4108           /* Should have given up or, if supported, changed the order's
4109            * activity to the activity suggested by
4110            * unit_activity_handling_targeted() before this line was
4111            * reached.
4112            * Remember that unit_activity_handling_targeted() has the power
4113            * to change the order's target extra directly. */
4114           fc_assert_msg(new_activity == order.activity,
4115                         "Activity not updated. Target may have changed.");
4116 
4117           /* Should have found a target or given up before reaching this
4118            * line. */
4119           fc_assert_msg((pextra != NULL
4120                          || !activity_requires_target(order.activity)),
4121                         "Activity requires a target. No target found.");
4122         }
4123 
4124         if (can_unit_do_activity_targeted(punit, activity, pextra)) {
4125           punit->done_moving = TRUE;
4126           set_unit_activity_targeted(punit, activity, pextra);
4127           send_unit_info(NULL, punit);
4128           break;
4129         } else {
4130           if ((activity == ACTIVITY_BASE
4131                || activity == ACTIVITY_GEN_ROAD
4132                || activity == ACTIVITY_IRRIGATE
4133                || activity == ACTIVITY_MINE)
4134               && tile_has_extra(unit_tile(punit), pextra)) {
4135             break; /* Already built, let's continue. */
4136           } else if ((activity == ACTIVITY_POLLUTION
4137                       || activity == ACTIVITY_FALLOUT
4138                       || activity == ACTIVITY_PILLAGE)
4139                      && !tile_has_extra(unit_tile(punit), pextra)) {
4140             break; /* Already removed, let's continue. */
4141           }
4142         }
4143       }
4144 
4145       cancel_orders(punit, "  orders canceled because of failed activity");
4146       notify_player(pplayer, unit_tile(punit), E_UNIT_ORDERS, ftc_server,
4147                     _("Orders for %s aborted since they "
4148                       "give an invalid activity."),
4149                     unit_link(punit));
4150       return TRUE;
4151     case ORDER_MOVE:
4152     case ORDER_ACTION_MOVE:
4153       /* Move unit */
4154       if (!(dst_tile = mapstep(unit_tile(punit), order.dir))) {
4155         cancel_orders(punit, "  move order sent us to invalid location");
4156         notify_player(pplayer, unit_tile(punit), E_UNIT_ORDERS, ftc_server,
4157                       _("Orders for %s aborted since they "
4158                         "give an invalid location."),
4159                       unit_link(punit));
4160         return TRUE;
4161       }
4162 
4163       if (order.order != ORDER_ACTION_MOVE
4164           && maybe_cancel_goto_due_to_enemy(punit, dst_tile)) {
4165         /* Plain move required: no attack, trade route etc. */
4166         cancel_orders(punit, "  orders canceled because of enemy");
4167         notify_player(pplayer, unit_tile(punit), E_UNIT_ORDERS, ftc_server,
4168                       _("Orders for %s aborted as there "
4169                         "are units in the way."),
4170                       unit_link(punit));
4171         return TRUE;
4172       }
4173 
4174       log_debug("  moving to %d,%d", TILE_XY(dst_tile));
4175       res = unit_move_handling(punit, dst_tile, FALSE,
4176                                order.order != ORDER_ACTION_MOVE, NULL);
4177       if (!player_unit_by_number(pplayer, unitid)) {
4178         log_debug("  unit died while moving.");
4179         /* A player notification should already have been sent. */
4180         return FALSE;
4181       }
4182 
4183       if (res && !same_pos(dst_tile, unit_tile(punit))) {
4184         /* Movement succeeded but unit didn't move. */
4185         log_debug("  orders resulted in combat.");
4186         send_unit_info(NULL, punit);
4187         return TRUE;
4188       }
4189 
4190       if (!res) {
4191         fc_assert(0 <= punit->moves_left);
4192 
4193         /* Movement failed (ZOC, etc.) */
4194         cancel_orders(punit, "  attempt to move failed.");
4195 
4196         if (!player_is_watching(punit, fresh)
4197             /* The final move "failed" because the unit needs to ask the
4198              * player what action it should take.
4199              *
4200              * The action decision request notifies the player. Its
4201              * location at the unit's last order makes it clear to the
4202              * player who the decision is for. ("The Spy I sent to Berlin
4203              * has arrived.")
4204              *
4205              * A notification message is therefore redundant. */
4206             && !(last_order
4207                  && punit->action_decision_want == ACT_DEC_ACTIVE
4208                  && punit->action_decision_tile == dst_tile)) {
4209           /* The player may have missed this. No one else will announce it
4210            * in a satisfying manner. Inform the player. */
4211           notify_player(pplayer, unit_tile(punit),
4212                         E_UNIT_ORDERS, ftc_server,
4213                         _("Orders for %s aborted because of failed move."),
4214                         unit_link(punit));
4215         }
4216 
4217         return TRUE;
4218       }
4219       break;
4220     case ORDER_DISBAND:
4221       log_debug("  orders: disbanding");
4222       handle_unit_disband(pplayer, unitid);
4223       return FALSE;
4224     case ORDER_HOMECITY:
4225       log_debug("  orders: changing homecity");
4226       if (tile_city(unit_tile(punit))) {
4227         handle_unit_change_homecity(pplayer, unitid,
4228                                     tile_city(unit_tile(punit))->id);
4229       } else {
4230         cancel_orders(punit, "  no homecity");
4231         notify_player(pplayer, unit_tile(punit), E_UNIT_ORDERS, ftc_server,
4232                       _("Attempt to change homecity for %s failed."),
4233                       unit_link(punit));
4234         return TRUE;
4235       }
4236       break;
4237     case ORDER_TRADE_ROUTE:
4238       log_debug("  orders: establishing trade route.");
4239       dst_tile = unit_tile(punit);
4240 
4241       fc_assert_ret_val_msg(dst_tile, FALSE, "No tile for ordered unit");
4242 
4243       if (tile_city(dst_tile) == NULL) {
4244         cancel_orders(punit, "  trade route order with no city");
4245         notify_player(pplayer, unit_tile(punit), E_UNIT_ORDERS, ftc_server,
4246                       _("Orders for %s aborted since they "
4247                         "give a location without a city."),
4248                       unit_link(punit));
4249         return TRUE;
4250       }
4251 
4252       handle_unit_do_action(pplayer,
4253                             unitid, tile_city(dst_tile)->id,
4254                             0, ACTION_TRADE_ROUTE);
4255       if (player_unit_by_number(pplayer, unitid)) {
4256         cancel_orders(punit, "  no trade route city");
4257         notify_player(pplayer, unit_tile(punit), E_UNIT_ORDERS, ftc_server,
4258                       _("Attempt to establish trade route for %s failed."),
4259                       unit_link(punit));
4260         return TRUE;
4261       } else {
4262 	return FALSE;
4263       }
4264     case ORDER_BUILD_WONDER:
4265       log_debug("  orders: building wonder");
4266       dst_tile = unit_tile(punit);
4267 
4268       fc_assert_ret_val_msg(dst_tile, FALSE, "No tile for ordered unit");
4269 
4270       if (tile_city(dst_tile) == NULL) {
4271         cancel_orders(punit, "  build wonder order with no city");
4272         notify_player(pplayer, unit_tile(punit), E_UNIT_ORDERS, ftc_server,
4273                       _("Orders for %s aborted since they "
4274                         "give a location without a city."),
4275                       unit_link(punit));
4276         return TRUE;
4277       }
4278 
4279       handle_unit_do_action(pplayer,
4280                             unitid,
4281                             tile_city(dst_tile)->id,
4282                             0, ACTION_HELP_WONDER);
4283       if (player_unit_by_number(pplayer, unitid)) {
4284         cancel_orders(punit, "  no wonder city");
4285         notify_player(pplayer, unit_tile(punit), E_UNIT_ORDERS, ftc_server,
4286                       _("Attempt to build wonder for %s failed."),
4287                       unit_link(punit));
4288         return TRUE;
4289       } else {
4290 	return FALSE;
4291       }
4292     case ORDER_LAST:
4293       cancel_orders(punit, "  client sent invalid order!");
4294       notify_player(pplayer, unit_tile(punit), E_UNIT_ORDERS, ftc_server,
4295                     _("Your %s has invalid orders."),
4296                     unit_link(punit));
4297       return TRUE;
4298     }
4299 
4300     if (last_order) {
4301       fc_assert(punit->has_orders == FALSE);
4302       log_debug("  stopping because orders are complete");
4303       return TRUE;
4304     }
4305 
4306     if (punit->orders.index == punit->orders.length) {
4307       fc_assert(punit->orders.repeat);
4308       /* Start over. */
4309       log_debug("  repeating orders.");
4310       punit->orders.index = 0;
4311     }
4312   } /* end while */
4313 }
4314 
4315 /****************************************************************************
4316   Return the vision the unit will have at the given tile.  The base vision
4317   range may be modified by effects.
4318 
4319   Note that vision MUST be independent of transported_by for this to work
4320   properly.
4321 ****************************************************************************/
get_unit_vision_at(struct unit * punit,struct tile * ptile,enum vision_layer vlayer)4322 int get_unit_vision_at(struct unit *punit, struct tile *ptile,
4323                        enum vision_layer vlayer)
4324 {
4325   const int base = (unit_type_get(punit)->vision_radius_sq
4326                     + get_unittype_bonus(unit_owner(punit), ptile,
4327                                          unit_type_get(punit),
4328                                          EFT_UNIT_VISION_RADIUS_SQ));
4329   switch (vlayer) {
4330   case V_MAIN:
4331     return MAX(0, base);
4332   case V_INVIS:
4333     return CLIP(0, base, 2);
4334   case V_COUNT:
4335     break;
4336   }
4337 
4338   log_error("Unsupported vision layer variant: %d.", vlayer);
4339   return 0;
4340 }
4341 
4342 /****************************************************************************
4343   Refresh the unit's vision.
4344 
4345   This function has very small overhead and can be called any time effects
4346   may have changed the vision range of the city.
4347 ****************************************************************************/
unit_refresh_vision(struct unit * punit)4348 void unit_refresh_vision(struct unit *punit)
4349 {
4350   struct vision *uvision = punit->server.vision;
4351   const v_radius_t radius_sq =
4352       V_RADIUS(get_unit_vision_at(punit, unit_tile(punit), V_MAIN),
4353                get_unit_vision_at(punit, unit_tile(punit), V_INVIS));
4354 
4355   vision_change_sight(uvision, radius_sq);
4356   ASSERT_VISION(uvision);
4357 }
4358 
4359 /****************************************************************************
4360   Refresh the vision of all units in the list - see unit_refresh_vision.
4361 ****************************************************************************/
unit_list_refresh_vision(struct unit_list * punitlist)4362 void unit_list_refresh_vision(struct unit_list *punitlist)
4363 {
4364   unit_list_iterate(punitlist, punit) {
4365     unit_refresh_vision(punit);
4366   } unit_list_iterate_end;
4367 }
4368 
4369 /****************************************************************************
4370   Used to implement the game rule controlled by the unitwaittime setting.
4371   Notifies the unit owner if the unit is unable to act.
4372 ****************************************************************************/
unit_can_do_action_now(const struct unit * punit)4373 bool unit_can_do_action_now(const struct unit *punit)
4374 {
4375   time_t dt;
4376 
4377   if (!punit) {
4378     return FALSE;
4379   }
4380 
4381   if (game.server.unitwaittime <= 0) {
4382     return TRUE;
4383   }
4384 
4385   if (punit->server.action_turn != game.info.turn - 1) {
4386     return TRUE;
4387   }
4388 
4389   dt = time(NULL) - punit->server.action_timestamp;
4390   if (dt < game.server.unitwaittime) {
4391     char buf[64];
4392     format_time_duration(game.server.unitwaittime - dt, buf, sizeof(buf));
4393     notify_player(unit_owner(punit), unit_tile(punit), E_BAD_COMMAND,
4394                   ftc_server, _("Your unit may not act for another %s "
4395                                 "this turn. See /help unitwaittime."), buf);
4396     return FALSE;
4397   }
4398 
4399   return TRUE;
4400 }
4401 
4402 /****************************************************************************
4403   Mark a unit as having done something at the current time. This is used
4404   in conjunction with unit_can_do_action_now() and the unitwaittime setting.
4405 ****************************************************************************/
unit_did_action(struct unit * punit)4406 void unit_did_action(struct unit *punit)
4407 {
4408   if (!punit) {
4409     return;
4410   }
4411 
4412   punit->server.action_timestamp = time(NULL);
4413   punit->server.action_turn = game.info.turn;
4414 }
4415 
4416 /**************************************************************************
4417   Units (usually barbarian units) may disband spontaneously if they are
4418   far from any enemy units or cities. It is to remove barbarians that do
4419   not engage into any activity for a long time.
4420 **************************************************************************/
unit_can_be_retired(struct unit * punit)4421 bool unit_can_be_retired(struct unit *punit)
4422 {
4423   /* check if there is enemy nearby */
4424   square_iterate(unit_tile(punit), 3, ptile) {
4425     if (is_enemy_city_tile(ptile, unit_owner(punit))
4426         || is_enemy_unit_tile(ptile, unit_owner(punit))) {
4427       return FALSE;
4428     }
4429   }
4430   square_iterate_end;
4431 
4432   return TRUE;
4433 }
4434