Freeciv21
Develop your civilization from humble roots to a global empire
aiunit.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2020 Freeciv21 and Freeciv
3 \_ \ / __/ contributors. This file is part of Freeciv21.
4  _\ \ / /__ Freeciv21 is free software: you can redistribute it
5  \___ \____/ __/ and/or modify it under the terms of the GNU General
6  \_ _/ Public License as published by the Free Software
7  | @ @ \_ Foundation, either version 3 of the License,
8  | or (at your option) any later version.
9  _/ /\ You should have received a copy of the GNU
10  /o) (o/\ \_ General Public License along with Freeciv21.
11  \_____/ / If not, see https://www.gnu.org/licenses/.
12  \____/ ********************************************************/
13 
14 // utility
15 #include "bitvector.h"
16 #include "rand.h"
17 #include "registry.h"
18 #include "registry_ini.h"
19 
20 // common
21 #include "city.h"
22 #include "combat.h"
23 #include "game.h"
24 #include "map.h"
25 #include "movement.h"
26 #include "nation.h"
27 #include "specialist.h"
28 #include "traderoutes.h"
29 #include "unit.h"
30 #include "unitlist.h"
31 
32 /* common/aicore */
33 #include "caravan.h"
34 #include "pf_tools.h"
35 
36 // server
37 #include "barbarian.h"
38 #include "citytools.h"
39 #include "maphand.h"
40 #include "srv_log.h"
41 #include "unithand.h"
42 
43 /* server/advisors */
44 #include "advbuilding.h"
45 #include "advgoto.h"
46 #include "advtools.h"
47 #include "autoexplorer.h"
48 #include "autosettlers.h"
49 
50 // ai
51 #include "difficulty.h"
52 #include "handicaps.h"
53 
54 /* ai/default */
55 #include "aiair.h"
56 #include "aidata.h"
57 #include "aidiplomat.h"
58 #include "aiferry.h"
59 #include "aiguard.h"
60 #include "aihunt.h"
61 #include "ailog.h"
62 #include "aiparatrooper.h"
63 #include "aiplayer.h"
64 #include "aitools.h"
65 #include "daicity.h"
66 #include "daieffects.h"
67 #include "daimilitary.h"
68 
69 #include "aiunit.h"
70 
71 #define LOGLEVEL_RECOVERY LOG_DEBUG
72 #define LOG_CARAVAN LOG_DEBUG
73 #define LOG_CARAVAN2 LOG_DEBUG
74 #define LOG_CARAVAN3 LOG_DEBUG
75 
76 class PFPath;
77 
78 static bool dai_find_boat_for_unit(struct ai_type *ait, struct unit *punit);
79 static bool dai_caravan_can_trade_cities_diff_cont(struct player *pplayer,
80  struct unit *punit);
81 static void dai_manage_caravan(struct ai_type *ait, struct player *pplayer,
82  struct unit *punit);
83 static void dai_manage_barbarian_leader(struct ai_type *ait,
84  struct player *pplayer,
85  struct unit *leader);
86 
87 static void dai_military_findjob(struct ai_type *ait, struct player *pplayer,
88  struct unit *punit);
89 static void dai_military_defend(struct ai_type *ait, struct player *pplayer,
90  struct unit *punit);
91 static void dai_military_attack(struct ai_type *ait, struct player *pplayer,
92  struct unit *punit);
93 
94 static bool unit_role_defender(const struct unit_type *punittype);
95 static int unit_def_rating_squared(const struct unit *punit,
96  const struct unit *pdef);
97 
98 /*
99  * Cached values. Updated by update_simple_ai_types.
100  *
101  * This a hack to enable emulation of old loops previously hardwired
102  * as
103  * for (i = U_WARRIORS; i <= U_BATTLESHIP; i++)
104  *
105  * (Could probably just adjust the loops themselves fairly simply,
106  * but this is safer for regression testing.)
107  *
108  * Not dealing with planes yet.
109  *
110  * Terminated by nullptr.
111  */
113 
124 static struct city *find_neediest_airlift_city(struct ai_type *ait,
125  const struct player *pplayer)
126 {
127  struct city *neediest_city = nullptr;
128  int most_danger = 0;
129  int most_urgent = 0;
130 
131  city_list_iterate(pplayer->cities, pcity)
132  {
133  struct ai_city *city_data = def_ai_city_data(pcity, ait);
134 
135  if (pcity->airlift) {
136  if (city_data->urgency > most_urgent) {
137  most_urgent = city_data->urgency;
138  neediest_city = pcity;
139  } else if (0 == most_urgent // urgency trumps danger
140  && city_data->danger > most_danger) {
141  most_danger = city_data->danger;
142  neediest_city = pcity;
143  }
144  }
145  }
147 
148  return neediest_city;
149 }
150 
157 static void dai_airlift(struct ai_type *ait, struct player *pplayer)
158 {
159  struct city *most_needed;
160  int comparison;
161  struct unit *transported;
162 
163  do {
164  most_needed = find_neediest_airlift_city(ait, pplayer);
165  comparison = 0;
166  transported = nullptr;
167 
168  if (!most_needed) {
169  return;
170  }
171 
172  unit_list_iterate(pplayer->units, punit)
173  {
174  struct tile *ptile = (unit_tile(punit));
175  struct city *pcity = tile_city(ptile);
176 
177  if (pcity) {
178  struct ai_city *city_data = def_ai_city_data(pcity, ait);
179  struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
180  const struct unit_type *ptype = unit_type_get(punit);
181 
182  if (city_data->urgency == 0
183  && city_data->danger - DEFENSE_POWER(ptype) < comparison
184  && unit_can_airlift_to(punit, most_needed)
185  && DEFENSE_POWER(ptype) > 2
186  && (unit_data->task == AIUNIT_NONE
187  || unit_data->task == AIUNIT_DEFEND_HOME)
188  && IS_ATTACKER(ptype)) {
189  comparison = city_data->danger;
190  transported = punit;
191  }
192  }
193  }
195  if (!transported) {
196  return;
197  }
198  UNIT_LOG(LOG_DEBUG, transported, "airlifted to defend %s",
199  city_name_get(most_needed));
200  unit_do_action(pplayer, transported->id, most_needed->id, 0, "",
201  ACTION_AIRLIFT);
202  } while (true);
203 }
204 
211 static bool has_defense(struct city *pcity)
212 {
213  struct tile *ptile = city_tile(pcity);
214 
215  unit_list_iterate(ptile->units, punit)
216  {
217  if (is_military_unit(punit) && base_get_defense_power(punit) != 0
218  && punit->hp != 0) {
219  struct unit_class *pclass = unit_class_get(punit);
220 
221  if (pclass->non_native_def_pct > 0
222  || is_native_tile_to_class(pclass, ptile)) {
223  return true;
224  }
225  }
226  }
228 
229  return false;
230 }
231 
240 int build_cost_balanced(const struct unit_type *punittype)
241 {
242  return 2 * utype_build_shield_cost_base(punittype)
243  * punittype->attack_strength
244  / (punittype->attack_strength + punittype->defense_strength);
245 }
246 
250 static int unit_att_rating_now(const struct unit *punit)
251 {
252  return adv_unittype_att_rating(unit_type_get(punit), punit->veteran,
253  punit->moves_left, punit->hp);
254 }
255 
260 static int unit_att_rating_squared(const struct unit *punit)
261 {
262  int v = adv_unit_att_rating(punit);
263 
264  return v * v;
265 }
266 
270 static int unit_def_rating(const struct unit *attacker,
271  const struct unit *defender)
272 {
273  const struct unit_type *def_type = unit_type_get(defender);
274 
275  return (get_total_defense_power(attacker, defender)
276  * (attacker->id != 0 ? defender->hp : def_type->hp)
277  * def_type->firepower / POWER_DIVIDER);
278 }
279 
283 static int unit_def_rating_squared(const struct unit *attacker,
284  const struct unit *defender)
285 {
286  int v = unit_def_rating(attacker, defender);
287 
288  return v * v;
289 }
290 
296 int unittype_def_rating_squared(const struct unit_type *att_type,
297  const struct unit_type *def_type,
298  struct player *def_player,
299  struct tile *ptile, bool fortified,
300  int veteran)
301 {
302  int v = get_virtual_defense_power(att_type, def_type, def_player, ptile,
303  fortified, veteran)
304  * def_type->hp * def_type->firepower / POWER_DIVIDER;
305 
306  return v * v;
307 }
308 
334 int kill_desire(int benefit, int attack, int loss, int vuln,
335  int victim_count)
336 {
337  int desire;
338 
339  // attractiveness danger
340  desire = ((benefit * attack - loss * vuln) * victim_count
341  * SHIELD_WEIGHTING / (attack + vuln * victim_count));
342 
343  return desire;
344 }
345 
358 static int avg_benefit(int benefit, int loss, double chance)
359 {
360  return static_cast<int>(((benefit + loss) * chance - loss)
361  * SHIELD_WEIGHTING);
362 }
363 
368 static void reinforcements_cost_and_value(struct unit *punit,
369  struct tile *ptile0, int *value,
370  int *cost)
371 {
372  *cost = 0;
373  *value = 0;
374  square_iterate(&(wld.map), ptile0, 1, ptile)
375  {
376  unit_list_iterate(ptile->units, aunit)
377  {
378  if (aunit != punit
379  && pplayers_allied(unit_owner(punit), unit_owner(aunit))) {
380  int val = adv_unit_att_rating(aunit);
381 
382  if (val != 0) {
383  *value += val;
384  *cost += unit_build_shield_cost_base(aunit);
385  }
386  }
387  }
389  }
391 }
392 
397 static bool is_my_turn(struct unit *punit, struct unit *pdef)
398 {
399  int val = unit_att_rating_now(punit), cur, d;
400 
401  CHECK_UNIT(punit);
402 
403  square_iterate(&(wld.map), unit_tile(pdef), 1, ptile)
404  {
405  unit_list_iterate(ptile->units, aunit)
406  {
407  if (aunit == punit || unit_owner(aunit) != unit_owner(punit)) {
408  continue;
409  }
411  || unit_attack_unit_at_tile_result(aunit, pdef, unit_tile(pdef))
412  != ATT_OK) {
413  continue;
414  }
416  unit_type_get(pdef), unit_owner(pdef),
417  unit_tile(pdef), false, 0);
418  if (d == 0) {
419  return true; // Thanks, Markus -- Syela
420  }
421  cur = unit_att_rating_now(aunit)
423  unit_type_get(punit), unit_type_get(pdef), unit_owner(pdef),
424  unit_tile(pdef), false, 0)
425  / d;
426  if (cur > val && ai_fuzzy(unit_owner(punit), true)) {
427  return false;
428  }
429  }
431  }
433  return true;
434 }
435 
452 static int dai_rampage_want(struct unit *punit, struct tile *ptile)
453 {
454  struct player *pplayer = unit_owner(punit);
455  struct unit *pdef;
456 
457  CHECK_UNIT(punit);
458 
459  if (can_unit_attack_tile(punit, ptile)
460  && (pdef = get_defender(punit, ptile))) {
461  // See description of kill_desire() about these variables.
462  int attack = unit_att_rating_now(punit);
463  int benefit = stack_cost(punit, pdef);
464  int loss = unit_build_shield_cost_base(punit);
465 
466  attack *= attack;
467 
468  /* If the victim is in the city/fortress, we correct the benefit
469  * with our health because there could be reprisal attacks. We
470  * shouldn't send already injured units to useless suicide.
471  * Note that we do not specially encourage attacks against
472  * cities: rampage is a hit-n-run operation. */
473  if (!is_stack_vulnerable(ptile) && unit_list_size(ptile->units) > 1) {
474  benefit = (benefit * punit->hp) / unit_type_get(punit)->hp;
475  }
476 
477  // If we have non-zero attack rating...
478  if (attack > 0 && is_my_turn(punit, pdef)) {
479  double chance = unit_win_chance(punit, pdef);
480  int desire = avg_benefit(benefit, loss, chance);
481 
482  // No need to amortize, our operation takes one turn.
483  UNIT_LOG(LOG_DEBUG, punit, "Rampage: Desire %d to kill %s(%d,%d)",
484  desire, unit_rule_name(pdef), TILE_XY(unit_tile(pdef)));
485 
486  return MAX(0, desire);
487  }
488  } else if (0 == unit_list_size(ptile->units)) {
489  // No defender.
490  struct city *pcity = tile_city(ptile);
491 
492  // ...and free foreign city waiting for us. Who would resist!
493  if (nullptr != pcity && pplayers_at_war(pplayer, city_owner(pcity))
494  && unit_can_take_over(punit)) {
496  }
497 
498  // ...or tiny pleasant hut here!
499  // FIXME: unhardcode and variate the desire to enter a hut.
500  if (unit_can_enter_hut(punit, ptile) && !is_barbarian(pplayer)
501  && is_native_tile(unit_type_get(punit), ptile)) {
502  return -RAMPAGE_HUT_OR_BETTER;
503  }
504  }
505 
506  return 0;
507 }
508 
512 static PFPath find_rampage_target(struct unit *punit, int thresh_adj,
513  int thresh_move)
514 {
515  struct pf_map *tgt_map;
516  PFPath path;
517  struct pf_parameter parameter;
518  // Coordinates of the best target (initialize to silence compiler)
519  struct tile *ptile = unit_tile(punit);
520  // Want of the best target
521  int max_want = 0;
522  struct player *pplayer = unit_owner(punit);
523 
524  pft_fill_unit_attack_param(&parameter, punit);
525  parameter.omniscience = !has_handicap(pplayer, H_MAP);
526  /* When trying to find rampage targets we ignore risks such as
527  * enemy units because we are looking for trouble!
528  * Hence no call ai_avoid_risks()
529  */
530 
531  tgt_map = pf_map_new(&parameter);
532  pf_map_move_costs_iterate(tgt_map, iter_tile, move_cost, false)
533  {
534  int want;
535  bool move_needed;
536  int thresh;
537 
538  if (move_cost > punit->moves_left) {
539  // This is too far
540  break;
541  }
542 
543  if (has_handicap(pplayer, H_TARGETS)
544  && !map_is_known_and_seen(iter_tile, pplayer, V_MAIN)) {
545  // The target is under fog of war
546  continue;
547  }
548 
549  want = dai_rampage_want(punit, iter_tile);
550 
551  // Negative want means move needed even though the tiles are adjacent
552  move_needed =
553  (!is_tiles_adjacent(unit_tile(punit), iter_tile) || want < 0);
554  // Select the relevant threshold
555  thresh = (move_needed ? thresh_move : thresh_adj);
556  want = (want < 0 ? -want : want);
557 
558  if (want > max_want && want > thresh) {
559  /* The new want exceeds both the previous maximum
560  * and the relevant threshold, so it's worth recording */
561  max_want = want;
562  ptile = iter_tile;
563  }
564  }
566 
567  if (max_want > 0) {
568  // We found something
569  path = pf_map_path(tgt_map, ptile);
570  fc_assert(!path.empty());
571  }
572 
573  pf_map_destroy(tgt_map);
574 
575  return path;
576 }
577 
592 bool dai_military_rampage(struct unit *punit, int thresh_adj,
593  int thresh_move)
594 {
595  int count = punit->moves_left + 1; // break any infinite loops
596  PFPath path;
597 
599  CHECK_UNIT(punit);
600 
601  fc_assert_ret_val(thresh_adj <= thresh_move, true);
602  // This teaches the AI about the dangers inherent in occupychance.
603  thresh_adj +=
604  ((thresh_move - thresh_adj) * game.server.occupychance / 100);
605 
606  while (count-- > 0 && punit->moves_left > 0) {
607  path = find_rampage_target(punit, thresh_adj, thresh_move);
608  if (!path.empty() && !adv_unit_execute_path(punit, path)) {
609  // Died
610  count = -1;
611  }
612  }
613 
615  return (count >= 0);
616 }
617 
622 static void dai_military_bodyguard(struct ai_type *ait,
623  struct player *pplayer,
624  struct unit *punit)
625 {
626  struct unit *aunit = aiguard_charge_unit(ait, punit);
627  struct city *acity = aiguard_charge_city(ait, punit);
628  struct tile *ptile;
629 
630  CHECK_UNIT(punit);
631  CHECK_GUARD(ait, punit);
632 
633  if (aunit && unit_owner(aunit) == unit_owner(punit)) {
634  // protect a unit
635  if (aunit->goto_tile != nullptr) {
636  // Our charge is going somewhere: maybe we should meet them there
637  // FIXME: This probably isn't the best algorithm for this.
638  int me2them = real_map_distance(unit_tile(punit), unit_tile(aunit));
639  int me2goal = real_map_distance(unit_tile(punit), aunit->goto_tile);
640  int them2goal = real_map_distance(unit_tile(aunit), aunit->goto_tile);
641  int punit_mv_rate = unit_move_rate(punit);
642  int aunit_mv_rate = unit_move_rate(aunit);
643  fc_assert_ret_msg(punit_mv_rate, "div by zero");
644  fc_assert_ret_msg(aunit_mv_rate, "div by zero");
645  if (me2goal < me2them
646  || (me2goal / punit_mv_rate < them2goal / aunit_mv_rate
647  && me2goal / punit_mv_rate < me2them / punit_mv_rate
648  && punit_mv_rate > aunit_mv_rate)) {
649  ptile = aunit->goto_tile;
650  } else {
651  ptile = unit_tile(aunit);
652  }
653  } else {
654  ptile = unit_tile(aunit);
655  }
656  } else if (acity && city_owner(acity) == unit_owner(punit)) {
657  // protect a city
658  ptile = acity->tile;
659  } else {
660  // should be impossible
661  BODYGUARD_LOG(ait, LOG_DEBUG, punit, "we lost our charge");
662  dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
663  return;
664  }
665 
666  if (same_pos(unit_tile(punit), ptile)) {
667  BODYGUARD_LOG(ait, LOG_DEBUG, punit, "at RV");
668  } else {
669  if (goto_is_sane(punit, ptile)) {
670  BODYGUARD_LOG(ait, LOG_DEBUG, punit, "meeting charge");
671  if (!dai_gothere(ait, pplayer, punit, ptile)) {
672  // We died
673  return;
674  }
675  } else {
676  BODYGUARD_LOG(ait, LOG_DEBUG, punit, "can not meet charge");
677  dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
678  }
679  }
680  /* We might have stopped because of an enemy nearby.
681  * Perhaps we can kill it.*/
684  && same_pos(unit_tile(punit), ptile)) {
685  def_ai_unit_data(punit, ait)->done = true; // Stay with charge
686  }
687 }
688 
692 static bool unit_role_defender(const struct unit_type *punittype)
693 {
694  return (utype_has_role(punittype, L_DEFEND_GOOD));
695 }
696 
707 int look_for_charge(struct ai_type *ait, struct player *pplayer,
708  struct unit *punit, struct unit **aunit,
709  struct city **acity)
710 {
711  struct pf_parameter parameter;
712  struct pf_map *pfm;
713  struct city *pcity;
714  struct ai_city *data, *best_data = nullptr;
715  const int toughness = adv_unit_def_rating_basic_squared(punit);
716  int def, best_def = -1;
717  // Arbitrary: 3 turns.
718  const int max_move_cost = 3 * unit_move_rate(punit);
719 
720  *aunit = nullptr;
721  *acity = nullptr;
722 
723  if (0 == toughness) {
724  // useless
725  return 0;
726  }
727 
728  pft_fill_unit_parameter(&parameter, punit);
729  parameter.omniscience = !has_handicap(pplayer, H_MAP);
730  pfm = pf_map_new(&parameter);
731 
732  pf_map_move_costs_iterate(pfm, ptile, move_cost, true)
733  {
734  if (move_cost > max_move_cost) {
735  // Consider too far.
736  break;
737  }
738 
739  pcity = tile_city(ptile);
740 
741  // Consider unit bodyguard.
742  unit_list_iterate(ptile->units, buddy)
743  {
744  const struct unit_type *ptype = unit_type_get(punit);
745  const struct unit_type *buddy_type = unit_type_get(buddy);
746 
747  // TODO: allied unit bodyguard?
748  if (!dai_can_unit_type_follow_unit_type(ptype, buddy_type, ait)
749  || unit_owner(buddy) != pplayer || !aiguard_wanted(ait, buddy)
750  || unit_move_rate(buddy) > unit_move_rate(punit)
751  || DEFENSE_POWER(buddy_type) >= DEFENSE_POWER(ptype)
752  || (utype_can_do_action_result(buddy_type, ACTRES_ATTACK)
753  && 0 == get_transporter_capacity(buddy)
754  && ATTACK_POWER(buddy_type) <= ATTACK_POWER(ptype))) {
755  continue;
756  }
757 
758  def = (toughness - adv_unit_def_rating_basic_squared(buddy));
759  if (0 >= def) {
760  continue;
761  }
762 
763  if (0 == get_transporter_capacity(buddy)) {
764  /* Reduce want based on move cost. We can't do this for
765  * transports since they move around all the time, leading
766  * to hillarious flip-flops. */
767  int notzero = 2 * unit_move_rate(punit);
768  fc_assert_ret_val(notzero, 0);
769  def >>= move_cost / notzero;
770  }
771  if (def > best_def) {
772  *aunit = buddy;
773  *acity = nullptr;
774  best_def = def;
775  }
776  }
778 
779  // City bodyguard. TODO: allied city bodyguard?
780  if (ai_fuzzy(pplayer, true) && nullptr != pcity
781  && city_owner(pcity) == pplayer
782  && (data = def_ai_city_data(pcity, ait)) && 0 < data->urgency) {
783  if (nullptr != best_data
784  && (0 < best_data->grave_danger
785  || best_data->urgency > data->urgency
786  || ((best_data->danger > data->danger
788  == def_ai_unit_data(punit, ait)->task)
789  && 0 == data->grave_danger))) {
790  /* Chances are we'll be between cities when we are needed the most!
791  * Resuming pf_map_move_costs_iterate()... */
792  continue;
793  }
794  def = (data->danger - assess_defense_quadratic(ait, pcity));
795  if (def <= 0) {
796  continue;
797  }
798  // Reduce want based on move cost.
799  def >>= move_cost / (2 * std::min(1, unit_move_rate(punit)));
800  if (def > best_def && ai_fuzzy(pplayer, true)) {
801  *acity = pcity;
802  *aunit = nullptr;
803  best_def = def;
804  best_data = data;
805  }
806  }
807  }
809 
810  pf_map_destroy(pfm);
811 
812  UNIT_LOG(LOGLEVEL_BODYGUARD, punit, "%s(), best_def=%d, type=%s (%d, %d)",
813  __FUNCTION__, best_def * 100 / toughness,
814  (nullptr != *acity
815  ? city_name_get(*acity)
816  : (nullptr != *aunit ? unit_rule_name(*aunit) : "")),
817  (nullptr != *acity
819  : (nullptr != *aunit
821  : -1)),
822  (nullptr != *acity
824  : (nullptr != *aunit
826  : -1)));
827 
828  return ((best_def * 100) / toughness);
829 }
830 
834 bool dai_can_unit_type_follow_unit_type(const struct unit_type *follower,
835  const struct unit_type *followee,
836  struct ai_type *ait)
837 {
838  struct unit_type_ai *utai =
839  static_cast<unit_type_ai *>(utype_ai_data(follower, ait));
840 
842  {
843  if (pcharge == followee) {
844  return true;
845  }
846  }
848 
849  return false;
850 }
851 
855 static void dai_military_findjob(struct ai_type *ait, struct player *pplayer,
856  struct unit *punit)
857 {
858  const struct unit_type *punittype = unit_type_get(punit);
859  struct unit_ai *unit_data;
860 
861  CHECK_UNIT(punit);
862 
863  // keep barbarians aggresive and primitive
864  if (is_barbarian(pplayer)) {
865  if (can_unit_do_activity(punit, ACTIVITY_PILLAGE)
866  && is_land_barbarian(pplayer)) {
867  // land barbarians pillage
868  unit_activity_handling(punit, ACTIVITY_PILLAGE);
869  }
870  dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
871  return;
872  }
873 
874  unit_data = def_ai_unit_data(punit, ait);
875 
876  // If I am a bodyguard, check whether I can do my job.
877  if (unit_data->task == AIUNIT_ESCORT
878  || unit_data->task == AIUNIT_DEFEND_HOME) {
879  aiguard_update_charge(ait, punit);
880  }
881  if (aiguard_has_charge(ait, punit) && unit_data->task == AIUNIT_ESCORT) {
882  struct unit *aunit = aiguard_charge_unit(ait, punit);
883  struct city *acity = aiguard_charge_city(ait, punit);
884  struct ai_city *city_data = nullptr;
885 
886  if (acity != nullptr) {
887  city_data = def_ai_city_data(acity, ait);
888  }
889 
890  /* Check if the city we are on our way to rescue is still in danger,
891  * or the unit we should protect is still alive... */
892  if ((aunit
893  && (aiguard_has_guard(ait, aunit) || aiguard_wanted(ait, aunit))
894  && adv_unit_def_rating_basic(punit)
895  > adv_unit_def_rating_basic(aunit))
896  || (acity && city_owner(acity) == unit_owner(punit)
897  && city_data->urgency != 0
898  && city_data->danger > assess_defense_quadratic(ait, acity))) {
899  return; // Yep!
900  } else {
901  dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr); // Nope!
902  }
903  }
904 
905  // Is the unit badly damaged?
906  if ((unit_data->task == AIUNIT_RECOVER && punit->hp < punittype->hp)
907  || punit->hp < punittype->hp * 0.25) { // WAG
908  UNIT_LOG(LOGLEVEL_RECOVERY, punit, "set to hp recovery");
909  dai_unit_new_task(ait, punit, AIUNIT_RECOVER, nullptr);
910  return;
911  }
912 
914  if (unit_role_defender(unit_type_get(punit))) {
915  /* This is a defending unit that doesn't need to stay put.
916  * It needs to defend something, but not necessarily where it's at.
917  * Therefore, it will consider becoming a bodyguard. -- Syela */
918  struct city *acity;
919  struct unit *aunit;
920 
921  look_for_charge(ait, pplayer, punit, &aunit, &acity);
922  if (acity) {
923  dai_unit_new_task(ait, punit, AIUNIT_ESCORT, acity->tile);
924  aiguard_assign_guard_city(ait, acity, punit);
925  BODYGUARD_LOG(ait, LOG_DEBUG, punit, "going to defend city");
926  } else if (aunit) {
927  dai_unit_new_task(ait, punit, AIUNIT_ESCORT, unit_tile(aunit));
928  aiguard_assign_guard_unit(ait, aunit, punit);
929  BODYGUARD_LOG(ait, LOG_DEBUG, punit, "going to defend unit");
930  }
931  }
933 }
934 
944 static void dai_military_defend(struct ai_type *ait, struct player *pplayer,
945  struct unit *punit)
946 {
947  struct city *pcity = aiguard_charge_city(ait, punit);
948 
949  CHECK_UNIT(punit);
950 
951  if (!pcity || city_owner(pcity) != pplayer) {
952  pcity = tile_city(unit_tile(punit));
953  // Do not stay defending an allied city forever
954  aiguard_clear_charge(ait, punit);
955  }
956 
957  if (!pcity) {
958  /* Try to find a place to rest. Sitting duck out in the wilderness
959  * is generally a bad idea, since we protect no cities that way, and
960  * it looks silly. */
961  pcity =
962  find_closest_city(unit_tile(punit), nullptr, pplayer, false, false,
963  false, true, false, unit_class_get(punit));
964  }
965 
966  if (!pcity) {
967  pcity = game_city_by_number(punit->homecity);
968  }
969 
972  // ... we survived
973  if (pcity) {
974  UNIT_LOG(LOG_DEBUG, punit, "go to defend %s", city_name_get(pcity));
975  if (same_pos(unit_tile(punit), pcity->tile)) {
976  UNIT_LOG(LOG_DEBUG, punit, "go defend successful");
977  def_ai_unit_data(punit, ait)->done = true;
978  } else {
979  (void) dai_gothere(ait, pplayer, punit, pcity->tile);
980  }
981  } else {
982  UNIT_LOG(LOG_VERBOSE, punit, "defending nothing...?");
983  }
984  }
985 }
986 
997 static void invasion_funct(struct ai_type *ait, struct unit *punit,
998  bool dest, int radius, int which)
999 {
1000  struct tile *ptile;
1001  struct player *pplayer = unit_owner(punit);
1002 
1003  CHECK_UNIT(punit);
1004 
1005  if (dest) {
1006  ptile = punit->goto_tile;
1007  } else {
1008  ptile = unit_tile(punit);
1009  }
1010 
1011  square_iterate(&(wld.map), ptile, radius, tile1)
1012  {
1013  struct city *pcity = tile_city(tile1);
1014 
1015  if (pcity && POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, city_owner(pcity))
1016  && (dest || !has_defense(pcity))) {
1017  int attacks;
1018  struct ai_city *city_data = def_ai_city_data(pcity, ait);
1019 
1020  if (unit_has_type_flag(punit, UTYF_ONEATTACK)) {
1021  attacks = 1;
1022  } else {
1023  attacks = unit_type_get(punit)->move_rate;
1024  }
1025  city_data->invasion.attack += attacks;
1026  if (which == INVASION_OCCUPY) {
1027  city_data->invasion.occupy++;
1028  }
1029  }
1030  }
1032 }
1033 
1037 bool find_beachhead(const struct player *pplayer, struct pf_map *ferry_map,
1038  struct tile *dest_tile,
1039  const struct unit_type *cargo_type,
1040  struct tile **ferry_dest, struct tile **beachhead_tile)
1041 {
1042  if (nullptr == tile_city(dest_tile)
1043  || can_attack_from_non_native(cargo_type)) {
1044  // Unit can directly go to 'dest_tile'.
1045  struct tile *best_tile = nullptr;
1046  int best_cost = PF_IMPOSSIBLE_MC, cost;
1047 
1048  if (nullptr != beachhead_tile) {
1049  *beachhead_tile = dest_tile;
1050  }
1051 
1052  adjc_iterate(&(wld.map), dest_tile, ptile)
1053  {
1054  cost = pf_map_move_cost(ferry_map, ptile);
1055  if (cost != PF_IMPOSSIBLE_MC
1056  && (nullptr == best_tile || cost < best_cost)) {
1057  best_tile = ptile;
1058  best_cost = cost;
1059  }
1060  }
1062 
1063  if (nullptr != ferry_dest) {
1064  *ferry_dest = best_tile;
1065  }
1066 
1067  return (PF_IMPOSSIBLE_MC != best_cost);
1068  } else {
1069  // We need to find a beach around 'dest_tile'.
1070  struct tile *best_tile = nullptr, *best_beach = nullptr;
1071  struct tile_list *checked_tiles = tile_list_new();
1072  int best_cost = PF_IMPOSSIBLE_MC, cost;
1073 
1074  tile_list_append(checked_tiles, dest_tile);
1075  adjc_iterate(&(wld.map), dest_tile, beach)
1076  {
1077  if (is_native_tile(cargo_type, beach)) {
1078  // Can land there.
1079  adjc_iterate(&(wld.map), beach, ptile)
1080  {
1081  if (!tile_list_search(checked_tiles, ptile)
1082  && !is_non_allied_unit_tile(ptile, pplayer)) {
1083  tile_list_append(checked_tiles, ptile);
1084  cost = pf_map_move_cost(ferry_map, ptile);
1085  if (cost != PF_IMPOSSIBLE_MC
1086  && (nullptr == best_tile || cost < best_cost)) {
1087  best_beach = beach;
1088  best_tile = ptile;
1089  best_cost = cost;
1090  }
1091  }
1092  }
1094  }
1095  }
1097 
1098  tile_list_destroy(checked_tiles);
1099 
1100  if (nullptr != beachhead_tile) {
1101  *beachhead_tile = best_beach;
1102  }
1103  if (nullptr != ferry_dest) {
1104  *ferry_dest = best_tile;
1105  }
1106  return (PF_IMPOSSIBLE_MC != best_cost);
1107  }
1108 }
1109 
1118 int find_something_to_kill(struct ai_type *ait, struct player *pplayer,
1119  struct unit *punit, struct tile **pdest_tile,
1120  PFPath *ppath, struct pf_map **pferrymap,
1121  struct unit **pferryboat,
1122  const struct unit_type **pboattype,
1123  int *pmove_time)
1124 {
1125  const int attack_value = adv_unit_att_rating(punit); // basic attack.
1126  struct pf_parameter parameter;
1127  struct pf_map *punit_map, *ferry_map;
1128  struct pf_position pos;
1129  struct unit_class *punit_class = unit_class_get(punit);
1130  const struct unit_type *punit_type = unit_type_get(punit);
1131  struct tile *punit_tile = unit_tile(punit);
1132  // Type of our boat (a future one if ferryboat == nullptr).
1133  const struct unit_type *boattype = nullptr;
1134  struct unit *ferryboat = nullptr;
1135  struct city *pcity;
1136  struct ai_city *acity_data;
1137  int bcost, bcost_bal; // Build cost of the attacker (+adjustments).
1138  bool handicap = has_handicap(pplayer, H_TARGETS);
1139  bool unhap = false; // Do we make unhappy citizen.
1140  bool harbor = false; // Do we have access to sea?
1141  bool go_by_boat; // Whether we need a boat or not.
1142  int vulnerability; // Enemy defence rating.
1143  int benefit; // Benefit from killing the target.
1144  struct unit *pdefender; // Enemy city defender.
1145  int move_time; // Turns needed to target.
1146  int reserves;
1147  int attack; // Our total attack value with reinforcements.
1148  int victim_count; // Number of enemies there.
1149  int needferry; // Cost of building a ferry boat.
1150  /* This is a kluge, because if we don't set x and y with !punit->id,
1151  * p_a_w isn't called, and we end up not wanting ironclads and therefore
1152  * never learning steam engine, even though ironclads would be very
1153  * useful. -- Syela */
1154  int bk = 0;
1155  int want; // Want (amortized) of the operaton.
1156  int best = 0; // Best of all wants.
1157  struct tile *goto_dest_tile = nullptr;
1158  bool can_occupy;
1159 
1160  // Very preliminary checks.
1161  *pdest_tile = punit_tile;
1162  if (nullptr != pferrymap) {
1163  *pferrymap = nullptr;
1164  }
1165  if (nullptr != pferryboat) {
1166  *pferryboat = nullptr;
1167  }
1168  if (nullptr != pboattype) {
1169  *pboattype = nullptr;
1170  }
1171  if (nullptr != pmove_time) {
1172  *pmove_time = 0;
1173  }
1174  if (!ppath->empty()) {
1175  *ppath = PFPath();
1176  }
1177 
1178  if (0 == attack_value) {
1179  // A very poor attacker... probably low on HP.
1180  return 0;
1181  }
1182 
1184 
1185  /*** Part 1: Calculate targets ***/
1186 
1187  /* This horrible piece of code attempts to calculate the attractiveness of
1188  * enemy cities as targets for our units, by checking how many units are
1189  * going towards it or are near it already. */
1190 
1191  // Reset enemy cities data.
1192  players_iterate(aplayer)
1193  {
1194  // See comment below in next usage of POTENTIALLY_HOSTILE_PLAYER.
1195  if ((punit->id == 0
1196  && !POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer))
1197  || (punit->id != 0 && !pplayers_at_war(pplayer, aplayer))) {
1198  continue;
1199  }
1200  city_list_iterate(aplayer->cities, acity)
1201  {
1202  struct ai_city *city_data = def_ai_city_data(acity, ait);
1203 
1204  reinforcements_cost_and_value(punit, acity->tile, &city_data->attack,
1205  &city_data->bcost);
1206  city_data->invasion.attack = 0;
1207  city_data->invasion.occupy = 0;
1208  }
1210  }
1212 
1213  /* Second, calculate in units on their way there, and mark targets for
1214  * invasion */
1215  unit_list_iterate(pplayer->units, aunit)
1216  {
1217  const struct unit_type *atype;
1218 
1219  if (aunit == punit) {
1220  continue;
1221  }
1222 
1223  atype = unit_type_get(aunit);
1224 
1225  // dealing with invasion stuff
1226  if (IS_ATTACKER(atype)) {
1227  if (aunit->activity == ACTIVITY_GOTO) {
1229  ait, aunit, true, 0,
1231  if ((pcity = tile_city(aunit->goto_tile))) {
1232  struct ai_city *city_data = def_ai_city_data(pcity, ait);
1233 
1234  city_data->attack += adv_unit_att_rating(aunit);
1235  city_data->bcost += unit_build_shield_cost_base(aunit);
1236  }
1237  }
1239  ait, aunit, false, unit_move_rate(aunit) / SINGLE_MOVE,
1241  } else if (def_ai_unit_data(aunit, ait)->passenger != 0
1242  && !same_pos(unit_tile(aunit), unit_tile(punit))) {
1243  // It's a transport with reinforcements
1244  if (aunit->activity == ACTIVITY_GOTO) {
1245  invasion_funct(ait, aunit, true, 1, INVASION_OCCUPY);
1246  }
1247  invasion_funct(ait, aunit, false, 2, INVASION_OCCUPY);
1248  }
1249  }
1251  // end horrible initialization subroutine
1252 
1253  /*** Part 2: Now pick one target ***/
1254 
1255  /* We first iterate through all cities, then all units, looking
1256  * for a viable target. We also try to gang up on the target
1257  * to avoid spreading out attacks too widely to be inefficient.
1258  */
1259 
1260  pcity = tile_city(punit_tile);
1261  if (nullptr != pcity && (0 == punit->id || pcity->id == punit->homecity)) {
1262  /* I would have thought unhappiness should be taken into account
1263  * irrespectfully the city in which it will surface... -- GB */
1264  unhap = dai_assess_military_unhappiness(pcity);
1265  }
1266 
1268  bcost_bal = build_cost_balanced(punit_type);
1269 
1270  pft_fill_unit_attack_param(&parameter, punit);
1271  parameter.omniscience = !has_handicap(pplayer, H_MAP);
1272  punit_map = pf_map_new(&parameter);
1273 
1274  if (MOVE_NONE == punit_class->adv.sea_move) {
1275  // We need boat to move over sea.
1276  ferryboat = unit_transport_get(punit);
1277 
1278  // First check if we can use the boat we are currently loaded to.
1279  if (ferryboat == nullptr || !is_boat_free(ait, ferryboat, punit, 0)) {
1280  // No, we cannot control current boat
1281  ferryboat = nullptr;
1282  }
1283 
1284  if (nullptr == ferryboat) {
1285  // Try to find new boat
1286  auto path = PFPath();
1287  ferryboat = player_unit_by_number(
1288  pplayer, aiferry_find_boat(ait, punit, 1, &path));
1289  }
1290 
1291  if (0 == punit->id && is_terrain_class_near_tile(punit_tile, TC_OCEAN)) {
1292  harbor = true;
1293  }
1294  }
1295 
1296  if (nullptr != ferryboat) {
1297  boattype = unit_type_get(ferryboat);
1298  pft_fill_unit_overlap_param(&parameter, ferryboat);
1299  parameter.omniscience = !has_handicap(pplayer, H_MAP);
1300  ferry_map = pf_map_new(&parameter);
1301  } else {
1302  boattype = best_role_unit_for_player(pplayer, L_FERRYBOAT);
1303  if (nullptr == boattype) {
1304  // We pretend that we can have the simplest boat to stimulate tech.
1305  boattype = get_role_unit(L_FERRYBOAT, 0);
1306  }
1307  if (nullptr != boattype && harbor) {
1308  // Let's simulate a boat at 'punit' position.
1309  pft_fill_utype_overlap_param(&parameter, boattype, punit_tile,
1310  pplayer);
1311  parameter.omniscience = !has_handicap(pplayer, H_MAP);
1312  ferry_map = pf_map_new(&parameter);
1313  } else {
1314  ferry_map = nullptr;
1315  }
1316  }
1317 
1318  can_occupy = unit_can_take_over(punit);
1319 
1320  players_iterate(aplayer)
1321  {
1322  /* For the virtual unit case, which is when we are called to evaluate
1323  * which units to build, we want to calculate in danger and which
1324  * players we want to make war with in the future. We do _not_ want
1325  * to do this when actually making attacks. */
1326  if ((punit->id == 0
1327  && !POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer))
1328  || (punit->id != 0 && !pplayers_at_war(pplayer, aplayer))) {
1329  continue; // Not an enemy.
1330  }
1331 
1332  city_list_iterate(aplayer->cities, acity)
1333  {
1334  struct tile *atile = city_tile(acity);
1335 
1336  if (!is_native_tile(punit_type, atile)
1337  && !can_attack_non_native(punit_type)) {
1338  // Can't attack this city. It is on land.
1339  continue;
1340  }
1341 
1342  if (handicap && !map_is_known(atile, pplayer)) {
1343  // Can't see it
1344  continue;
1345  }
1346 
1347  if (pf_map_position(punit_map, atile, &pos)) {
1348  go_by_boat = false;
1349  move_time = pos.turn;
1350  } else if (nullptr == ferry_map) {
1351  continue; // Impossible to handle.
1352  } else {
1353  struct tile *dest, *beach;
1354 
1355  if (!find_beachhead(pplayer, ferry_map, atile, punit_type, &dest,
1356  &beach)) {
1357  continue; // Impossible to go by boat.
1358  }
1359  if (!pf_map_position(ferry_map, dest, &pos)) {
1360  fc_assert(pf_map_position(ferry_map, dest, &pos));
1361  continue;
1362  }
1363  move_time = pos.turn; // Sailing time.
1364  if (dest != beach) {
1365  move_time++; // Land time.
1366  }
1367  if (nullptr != ferryboat && unit_tile(ferryboat) != punit_tile) {
1368  if (pf_map_position(punit_map, unit_tile(ferryboat), &pos)) {
1369  move_time += pos.turn; // Time to reach the boat.
1370  } else {
1371  continue; // Cannot reach the boat.
1372  }
1373  }
1374  go_by_boat = true;
1375  }
1376 
1377  if (can_unit_attack_tile(punit, city_tile(acity))
1378  && (pdefender = get_defender(punit, city_tile(acity)))) {
1379  vulnerability = unit_def_rating_squared(punit, pdefender);
1380  benefit = unit_build_shield_cost_base(pdefender);
1381  } else {
1382  pdefender = nullptr;
1383  vulnerability = 0;
1384  benefit = 0;
1385  }
1386 
1387  if (1 < move_time) {
1388  struct unit_type *def_type =
1389  dai_choose_defender_versus(acity, punit);
1390 
1391  if (def_type) {
1393  punit_type, def_type, aplayer, atile, false,
1394  city_production_unit_veteran_level(acity, def_type));
1395  if (v > vulnerability) {
1396  // They can build a better defender!
1397  vulnerability = v;
1398  benefit = utype_build_shield_cost(acity, def_type);
1399  }
1400  }
1401  }
1402 
1403  acity_data = def_ai_city_data(acity, ait);
1404 
1405  reserves =
1406  (acity_data->invasion.attack - unit_list_size(acity->tile->units));
1407 
1408  if (punit->id == 0) {
1409  // Real unit would add 1 to reserves once built.
1410  reserves++;
1411  }
1412 
1413  if (0 < reserves && (can_occupy || 0 < acity_data->invasion.occupy)) {
1414  /* There are units able to occupy the city after all defenders
1415  * are killed! */
1416  benefit += acity_data->worth * reserves / 5;
1417  }
1418 
1419  attack = attack_value + acity_data->attack;
1420  attack *= attack;
1421  // Avoiding handling upkeep aggregation this way -- Syela
1422 
1423  /* AI was not sending enough reinforcements to totally wipe out a city
1424  * and conquer it in one turn.
1425  * This variable enables total carnage. -- Syela */
1426  victim_count = unit_list_size(atile->units);
1427 
1428  if (!can_occupy && nullptr == pdefender) {
1429  /* Nothing there to bash and we can't occupy!
1430  * Not having this check caused warships yoyoing */
1431  want = 0;
1432  } else if (10 < move_time) {
1433  // Too far!
1434  want = 0;
1435  } else if (can_occupy && 0 == acity_data->invasion.occupy
1436  && (0 < acity_data->invasion.attack || victim_count == 0)) {
1437  // Units able to occupy really needed there!
1438  want = bcost * SHIELD_WEIGHTING;
1439  } else {
1440  want = kill_desire(benefit, attack, bcost + acity_data->bcost,
1441  vulnerability, victim_count + 1);
1442  }
1443  want -= move_time
1444  * (unhap ? SHIELD_WEIGHTING + 2 * TRADE_WEIGHTING
1445  : SHIELD_WEIGHTING);
1446  // Build_cost of ferry.
1447  needferry = (go_by_boat && nullptr == ferryboat
1448  ? utype_build_shield_cost(acity, boattype)
1449  : 0);
1450  // FIXME: add time to build the ferry?
1451  want =
1453  want, MAX(1, move_time), bcost_bal + needferry);
1454 
1455  // BEGIN STEAM-ENGINES-ARE-OUR-FRIENDS KLUGE.
1456  if (0 >= want && 0 == punit->id && 0 == best) {
1457  int bk_e =
1459  benefit * SHIELD_WEIGHTING, MAX(1, move_time),
1460  bcost_bal + needferry);
1461 
1462  if (bk_e > bk) {
1463  *pdest_tile = atile;
1464  if (nullptr != pferrymap) {
1465  *pferrymap = go_by_boat ? ferry_map : nullptr;
1466  }
1467  if (nullptr != pferryboat) {
1468  *pferryboat = go_by_boat ? ferryboat : nullptr;
1469  }
1470  if (nullptr != pboattype) {
1471  *pboattype = go_by_boat ? boattype : nullptr;
1472  }
1473  if (nullptr != pmove_time) {
1474  *pmove_time = move_time;
1475  }
1476  goto_dest_tile =
1477  (go_by_boat && nullptr != ferryboat ? unit_tile(ferryboat)
1478  : atile);
1479  bk = bk_e;
1480  }
1481  }
1482  // END STEAM-ENGINES KLUGE
1483 
1484  if (0 != punit->id && nullptr != ferryboat
1485  && punit_class->adv.sea_move == MOVE_NONE) {
1486  UNIT_LOG(LOG_DEBUG, punit,
1487  "%s(): with boat %s@(%d, %d) -> %s@(%d, %d)"
1488  " (go_by_boat=%d, move_time=%d, want=%d, best=%d)",
1489  __FUNCTION__, unit_rule_name(ferryboat),
1490  TILE_XY(unit_tile(ferryboat)), city_name_get(acity),
1491  TILE_XY(atile), go_by_boat, move_time, want, best);
1492  }
1493 
1494  if (want > best && ai_fuzzy(pplayer, true)) {
1495  // Yes, we like this target
1496  best = want;
1497  *pdest_tile = atile;
1498  if (nullptr != pferrymap) {
1499  *pferrymap = go_by_boat ? ferry_map : nullptr;
1500  }
1501  if (nullptr != pferryboat) {
1502  *pferryboat = go_by_boat ? ferryboat : nullptr;
1503  }
1504  if (nullptr != pboattype) {
1505  *pboattype = go_by_boat ? boattype : nullptr;
1506  }
1507  if (nullptr != pmove_time) {
1508  *pmove_time = move_time;
1509  }
1510  goto_dest_tile =
1511  (go_by_boat && nullptr != ferryboat ? unit_tile(ferryboat)
1512  : atile);
1513  }
1514  }
1516 
1518  /* I'm not sure the following code is good but it seems to be adequate.
1519  * I am deliberately not adding ferryboat code to the unit_list_iterate.
1520  * -- Syela */
1521  unit_list_iterate(aplayer->units, aunit)
1522  {
1523  struct tile *atile = unit_tile(aunit);
1524 
1525  if (nullptr != tile_city(atile)) {
1526  // already dealt with it.
1527  continue;
1528  }
1529 
1530  if (handicap && !map_is_known(atile, pplayer)) {
1531  // Can't see the target.
1532  continue;
1533  }
1534 
1535  if (!utype_acts_hostile(unit_type_get(aunit)) && 0 == punit->id) {
1536  /* We will not build units just to chase caravans and
1537  * ambassadors. */
1538  continue;
1539  }
1540 
1541  /* We have to assume the attack is diplomatically ok.
1542  * We cannot use can_player_attack_tile, because we might not
1543  * be at war with aplayer yet */
1544  if (!can_unit_attack_tile(punit, atile)
1545  || aunit != get_defender(punit, atile)) {
1546  // We cannot attack it, or it is not the main defender.
1547  continue;
1548  }
1549 
1550  if (!pf_map_position(punit_map, atile, &pos)) {
1551  // Cannot reach it.
1552  continue;
1553  }
1554 
1555  vulnerability = unit_def_rating_squared(punit, aunit);
1556  benefit = unit_build_shield_cost_base(aunit);
1557 
1558  move_time = pos.turn;
1559  if (10 < move_time) {
1560  // Too far.
1561  want = 0;
1562  } else {
1563  want = kill_desire(benefit, attack, bcost, vulnerability, 1);
1564  // Take into account maintainance of the unit.
1565  // FIXME: Depends on the government.
1566  want -= move_time * SHIELD_WEIGHTING;
1567  /* Take into account unhappiness
1568  * (costs 2 luxuries to compensate). */
1569  want -= (unhap ? 2 * move_time * TRADE_WEIGHTING : 0);
1570  }
1571  want = military_amortize(pplayer, game_city_by_number(punit->homecity),
1572  want, MAX(1, move_time), bcost_bal);
1573  if (want > best && ai_fuzzy(pplayer, true)) {
1574  best = want;
1575  *pdest_tile = atile;
1576  if (nullptr != pferrymap) {
1577  *pferrymap = nullptr;
1578  }
1579  if (nullptr != pferryboat) {
1580  *pferryboat = nullptr;
1581  }
1582  if (nullptr != pboattype) {
1583  *pboattype = nullptr;
1584  }
1585  if (nullptr != pmove_time) {
1586  *pmove_time = move_time;
1587  }
1588  goto_dest_tile = atile;
1589  }
1590  }
1592  }
1594 
1595  if (!ppath->empty()) {
1596  *ppath = (nullptr != goto_dest_tile && goto_dest_tile != punit_tile
1597  ? pf_map_path(punit_map, goto_dest_tile)
1598  : PFPath());
1599  }
1600 
1601  pf_map_destroy(punit_map);
1602  if (nullptr != ferry_map
1603  && (nullptr == pferrymap || *pferrymap != ferry_map)) {
1604  pf_map_destroy(ferry_map);
1605  }
1606 
1608 
1609  return best;
1610 }
1611 
1620 struct city *find_nearest_safe_city(struct unit *punit)
1621 {
1622  struct pf_parameter parameter;
1623  struct pf_map *pfm;
1624  struct player *pplayer = unit_owner(punit);
1625  struct city *pcity, *best_city = nullptr;
1626  int best = FC_INFINITY, cur;
1627 
1628  pft_fill_unit_parameter(&parameter, punit);
1629  parameter.omniscience = !has_handicap(pplayer, H_MAP);
1630  pfm = pf_map_new(&parameter);
1631 
1632  pf_map_move_costs_iterate(pfm, ptile, move_cost, true)
1633  {
1634  if (move_cost > best) {
1635  // We already found a better city. No need to continue.
1636  break;
1637  }
1638 
1639  pcity = tile_city(ptile);
1640  if (nullptr == pcity || !pplayers_allied(pplayer, city_owner(pcity))) {
1641  continue;
1642  }
1643 
1644  // Score based on the move cost.
1645  cur = move_cost;
1646 
1647  // Note the unit owner may be different from the city owner.
1648  if (0
1649  == get_unittype_bonus(unit_owner(punit), ptile, unit_type_get(punit),
1650  EFT_HP_REGEN)) {
1651  /* If we cannot regen fast our hit points here, let's make some
1652  * penalty. */
1653  cur *= 3;
1654  }
1655 
1656  if (cur < best) {
1657  best_city = pcity;
1658  best = cur;
1659  }
1660  }
1662 
1663  pf_map_destroy(pfm);
1664  return best_city;
1665 }
1666 
1672 static void dai_military_attack_barbarian(struct ai_type *ait,
1673  struct player *pplayer,
1674  struct unit *punit)
1675 {
1676  struct city *pc;
1677  bool only_continent = true;
1678 
1679  if (unit_transported(punit)) {
1680  /* If we are in transport, we can go to any continent.
1681  * Actually, we are not currently in a continent where to stay. */
1682  only_continent = false;
1683  }
1684 
1685  if ((pc =
1686  find_closest_city(unit_tile(punit), nullptr, pplayer, false,
1687  only_continent, false, false, true, nullptr))) {
1688  if (can_unit_exist_at_tile(&(wld.map), punit, unit_tile(punit))) {
1689  UNIT_LOG(LOG_DEBUG, punit, "Barbarian heading to conquer %s",
1690  city_name_get(pc));
1691  (void) dai_gothere(ait, pplayer, punit, pc->tile);
1692  } else {
1693  struct unit *ferry = nullptr;
1694 
1695  if (unit_transported(punit)) {
1696  ferry = unit_transport_get(punit);
1697 
1698  /* We already are in a boat so it needs no
1699  * free capacity */
1700  if (!is_boat_free(ait, ferry, punit, 0)) {
1701  // We cannot control our ferry.
1702  ferry = nullptr;
1703  }
1704  } else {
1705  // We are not in a boat yet. Search for one.
1706  unit_list_iterate(unit_tile(punit)->units, aunit)
1707  {
1708  if (is_boat_free(ait, aunit, punit, 1)
1709  && unit_transport_load(punit, aunit, false)) {
1710  ferry = aunit;
1711  break;
1712  }
1713  }
1715  }
1716 
1717  if (ferry) {
1718  UNIT_LOG(LOG_DEBUG, punit, "Barbarian sailing to conquer %s",
1719  city_name_get(pc));
1720  (void) aiferry_goto_amphibious(ait, ferry, punit, pc->tile);
1721  } else {
1722  /* This is not an error. Somebody else might be in charge
1723  * of the ferry. */
1724  UNIT_LOG(LOG_DEBUG, punit, "unable to find barbarian ferry");
1725  }
1726  }
1727  } else {
1728  UNIT_LOG(LOG_DEBUG, punit, "Barbarian find no target city");
1729  }
1730 }
1731 
1738 static void dai_military_attack(struct ai_type *ait, struct player *pplayer,
1739  struct unit *punit)
1740 {
1741  struct tile *dest_tile;
1742  int id = punit->id;
1743  int ct = 10;
1744  struct city *pcity = nullptr;
1745 
1746  CHECK_UNIT(punit);
1747 
1748  /* Barbarians pillage, and might keep on doing that so they sometimes
1749  * even finish it. */
1750  if (punit->activity == ACTIVITY_PILLAGE && is_barbarian(pplayer)
1751  && fc_rand(2) == 1) {
1752  return;
1753  }
1754 
1755  /* First find easy nearby enemies, anything better than pillage goes.
1756  * NB: We do not need to repeat dai_military_rampage, it is repeats itself
1757  * until it runs out of targets. */
1758  /* FIXME: 1. dai_military_rampage never checks if it should defend newly
1759  * conquered cities.
1760  * FIXME: 2. would be more convenient if it returned FALSE if we run out
1761  * of moves too.*/
1763  return; // we died
1764  }
1765 
1766  if (punit->moves_left <= 0) {
1767  return;
1768  }
1769 
1770  // Main attack loop
1771  do {
1772  struct tile *start_tile = unit_tile(punit);
1773  PFPath path;
1774  struct unit *ferryboat;
1775 
1776  // Then find enemies the hard way
1777  find_something_to_kill(ait, pplayer, punit, &dest_tile, &path, nullptr,
1778  &ferryboat, nullptr, nullptr);
1779  if (!same_pos(unit_tile(punit), dest_tile)) {
1780  if (!is_tiles_adjacent(unit_tile(punit), dest_tile)
1781  || !can_unit_attack_tile(punit, dest_tile)) {
1782  /* Adjacent and can't attack usually means we are not marines
1783  * and on a ferry. This fixes the problem (usually). */
1784  UNIT_LOG(LOG_DEBUG, punit, "mil att gothere -> (%d, %d)",
1785  TILE_XY(dest_tile));
1786 
1787  /* Set ACTIVITY_GOTO more permanently than just inside
1788  * adv_follow_path(). This way other units will know we're
1789  * on our way even if we don't reach target yet. */
1790  punit->goto_tile = dest_tile;
1791  unit_activity_handling(punit, ACTIVITY_GOTO);
1792  if (!path.empty() && !adv_follow_path(punit, path, dest_tile)) {
1793  // Died.
1794  return;
1795  }
1796  if (nullptr != ferryboat) {
1797  // Need a boat.
1798  aiferry_gobyboat(ait, pplayer, punit, dest_tile, false);
1799  return;
1800  }
1801  if (0 >= punit->moves_left) {
1802  // No moves left.
1803  return;
1804  }
1805 
1806  /* Either we're adjacent or we sitting on the tile. We might be
1807  * sitting on the tile if the enemy that _was_ sitting there
1808  * attacked us and died _and_ we had enough movement to get there */
1809  if (same_pos(unit_tile(punit), dest_tile)) {
1810  UNIT_LOG(LOG_DEBUG, punit, "mil att made it -> (%d, %d)",
1811  TILE_XY(dest_tile));
1812  break;
1813  }
1814  }
1815 
1816  if (is_tiles_adjacent(unit_tile(punit), dest_tile)) {
1817  /* Close combat. fstk sometimes want us to attack an adjacent
1818  * enemy that rampage wouldn't */
1819  UNIT_LOG(LOG_DEBUG, punit, "mil att bash -> (%d, %d)",
1820  TILE_XY(dest_tile));
1821  if (!dai_unit_attack(ait, punit, dest_tile)) {
1822  // Died
1823  return;
1824  }
1825  } else if (!same_pos(start_tile, unit_tile(punit))) {
1826  /* Got stuck. Possibly because of adjacency to an
1827  * enemy unit. Perhaps we are in luck and are now next to a
1828  * tempting target? Let's find out... */
1829  (void) dai_military_rampage(punit, RAMPAGE_ANYTHING,
1831  return;
1832  }
1833 
1834  } else {
1835  // FIXME: This happens a bit too often!
1836  UNIT_LOG(LOG_DEBUG, punit, "fstk didn't find us a worthy target!");
1837  // No worthy enemies found, so abort loop
1838  ct = 0;
1839  }
1840 
1841  ct--; // infinite loops from railroads must be stopped
1842  } while (punit->moves_left > 0 && ct > 0);
1843 
1844  // Cleanup phase
1845  if (punit->moves_left == 0) {
1846  return;
1847  }
1848  pcity = find_nearest_safe_city(punit);
1849  if (pcity != nullptr
1850  && (dai_is_ferry(punit, ait)
1851  || punit->hp < unit_type_get(punit)->hp * 0.50)) { // WAG
1852  // Go somewhere safe
1853  UNIT_LOG(LOG_DEBUG, punit, "heading to nearest safe house.");
1854  (void) dai_unit_goto(ait, punit, pcity->tile);
1855  } else if (!is_barbarian(pplayer)) {
1856  // Nothing else to do, so try exploring.
1857  switch (manage_auto_explorer(punit)) {
1858  case MR_DEATH:
1859  // don't use punit!
1860  return;
1861  case MR_OK:
1862  UNIT_LOG(LOG_DEBUG, punit, "nothing else to do, so exploring");
1863  break;
1864  default:
1865  UNIT_LOG(LOG_DEBUG, punit, "nothing to do - no more exploring either");
1866  break;
1867  };
1868  } else {
1869  /* You can still have some moves left here, but barbarians should
1870  not sit helplessly, but advance towards nearest known enemy city */
1871  UNIT_LOG(LOG_DEBUG, punit, "attack: barbarian");
1872  dai_military_attack_barbarian(ait, pplayer, punit);
1873  }
1874  if ((punit = game_unit_by_number(id)) && punit->moves_left > 0) {
1875  UNIT_LOG(LOG_DEBUG, punit, "attack: giving up unit to defense");
1876  dai_military_defend(ait, pplayer, punit);
1877  }
1878 }
1879 
1884 static bool dai_find_boat_for_unit(struct ai_type *ait, struct unit *punit)
1885 {
1886  bool alive = true;
1887  int ferryboat = 0;
1888  PFPath path_to_ferry;
1889 
1890  UNIT_LOG(LOG_CARAVAN, punit, "requesting a boat!");
1891  ferryboat = aiferry_find_boat(ait, punit, 1, &path_to_ferry);
1892  // going to meet the boat
1893  if ((ferryboat <= 0)) {
1894  UNIT_LOG(LOG_CARAVAN, punit,
1895  "in find_boat_for_unit cannot find any boats.");
1896  // if we are undefended on the country side go to a city
1897  struct city *current_city = tile_city(unit_tile(punit));
1898  if (current_city == nullptr) {
1899  struct city *city_near = find_nearest_safe_city(punit);
1900  if (city_near != nullptr) {
1901  alive = dai_unit_goto(ait, punit, city_near->tile);
1902  }
1903  }
1904  } else {
1905  if (!path_to_ferry.empty()) {
1906  if (!adv_unit_execute_path(punit, path_to_ferry)) {
1907  // Died.
1908  alive = false;
1909  } else {
1910  alive = true;
1911  }
1912  }
1913  }
1914  return alive;
1915 }
1916 
1923 static void dai_caravan_goto(struct ai_type *ait, struct player *pplayer,
1924  struct unit *punit,
1925  const struct city *dest_city, bool help_wonder,
1926  bool required_boat, bool request_boat)
1927 {
1928  bool alive = true;
1929  struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
1930 
1931  fc_assert_ret(nullptr != dest_city);
1932 
1933  // if we're not there yet, and we can move, move...
1934  if (!same_pos(dest_city->tile, unit_tile(punit))
1935  && punit->moves_left != 0) {
1936  log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) task %s going to %s in %s %s",
1938  punit->id, TILE_XY(unit_tile(punit)),
1939  dai_unit_task_rule_name(unit_data->task),
1940  help_wonder ? "help a wonder" : "trade",
1941  city_name_get(dest_city), required_boat ? "with a boat" : "");
1942  if (required_boat) {
1943  // to trade with boat
1944  if (request_boat) {
1945  // Try to find new boat
1946  alive = dai_find_boat_for_unit(ait, punit);
1947  } else {
1948  // if we are not being transported then ask for a boat again
1949  alive = true;
1950  if (!unit_transported(punit)
1951  && (tile_continent(unit_tile(punit))
1952  != tile_continent(dest_city->tile))) {
1953  alive = dai_find_boat_for_unit(ait, punit);
1954  }
1955  }
1956  if (alive) {
1957  alive = dai_gothere(ait, pplayer, punit, dest_city->tile);
1958  }
1959  } else {
1960  // to trade without boat
1961  alive = dai_unit_goto(ait, punit, dest_city->tile);
1962  }
1963  }
1964 
1965  // if moving didn't kill us, and we got to the destination, handle it.
1966  if (alive && real_map_distance(dest_city->tile, unit_tile(punit)) <= 1) {
1967  // release the boat!
1968  if (unit_transported(punit)) {
1969  aiferry_clear_boat(ait, punit);
1970  }
1971  if (help_wonder
1972  && is_action_enabled_unit_on_city(ACTION_HELP_WONDER, punit,
1973  dest_city)) {
1974  /*
1975  * We really don't want to just drop all caravans in immediately.
1976  * Instead, we want to aggregate enough caravans to build instantly.
1977  * -AJS, 990704
1978  */
1979  log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) helps build wonder in %s",
1981  unit_rule_name(punit), punit->id, TILE_XY(unit_tile(punit)),
1982  city_name_get(dest_city));
1983  unit_do_action(pplayer, punit->id, dest_city->id, 0, "",
1984  ACTION_HELP_WONDER);
1985  } else if (is_action_enabled_unit_on_city(ACTION_TRADE_ROUTE, punit,
1986  dest_city)) {
1987  log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) creates trade route in %s",
1989  unit_rule_name(punit), punit->id, TILE_XY(unit_tile(punit)),
1990  city_name_get(dest_city));
1991  unit_do_action(pplayer, punit->id, dest_city->id, 0, "",
1992  ACTION_TRADE_ROUTE);
1993  } else if (is_action_enabled_unit_on_city(ACTION_MARKETPLACE, punit,
1994  dest_city)) {
1995  // Get the one time bonus.
1996  log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) enters marketplace of %s",
1998  unit_rule_name(punit), punit->id, TILE_XY(unit_tile(punit)),
1999  city_name_get(dest_city));
2000  unit_do_action(pplayer, punit->id, dest_city->id, 0, "",
2001  ACTION_MARKETPLACE);
2002  } else {
2003  QtMsgType level = LOG_NORMAL;
2004 
2005  if (help_wonder) {
2006  /* A Caravan ordered to help build wonder may arrive after
2007  * enough shields to build the wonder is produced. */
2008  level = LOG_VERBOSE;
2009  }
2010 
2011  log_base(level, "%s %s[%d](%d,%d) unable to trade with %s",
2013  unit_rule_name(punit), punit->id, TILE_XY(unit_tile(punit)),
2014  city_name_get(dest_city));
2015  }
2016  }
2017 }
2018 
2023 static void caravan_optimize_callback(const struct caravan_result *result,
2024  void *data)
2025 {
2026  const struct unit *caravan = static_cast<const unit *>(data);
2027 
2028  log_base(LOG_CARAVAN3, "%s %s[%d](%d,%d) %s: %s %s worth %g",
2029  nation_rule_name(nation_of_unit(caravan)),
2030  unit_rule_name(caravan), caravan->id, TILE_XY(unit_tile(caravan)),
2031  city_name_get(result->src),
2032  result->help_wonder ? "wonder in" : "trade to",
2033  city_name_get(result->dest), result->value);
2034 }
2035 
2039 static bool dai_is_unit_tired_waiting_boat(struct ai_type *ait,
2040  struct unit *punit)
2041 {
2042  struct tile *src = nullptr, *dest = nullptr, *src_home_city = nullptr;
2043  struct city *phome_city = nullptr;
2044  struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2045 
2046  if ((unit_data->task != AIUNIT_NONE)) {
2047  src = unit_tile(punit);
2048  phome_city = game_city_by_number(punit->homecity);
2049  if (phome_city != nullptr) {
2050  src_home_city = city_tile(phome_city);
2051  }
2052  dest = punit->goto_tile;
2053 
2054  if (src == nullptr || dest == nullptr || src_home_city == nullptr) {
2055  return false;
2056  }
2057  // if we're not at home continent
2058  if (tile_continent(src) != tile_continent(src_home_city)) {
2059  return false;
2060  }
2061 
2062  if (!goto_is_sane(punit, dest)) {
2063  if (unit_transported(punit)) {
2064  // if we're being transported
2065  return false;
2066  }
2067  if ((punit->server.birth_turn + 15 < game.info.turn)) {
2068  // we are tired of waiting
2069  int ferrys = aiferry_avail_boats(ait, punit->owner);
2070 
2071  if (ferrys <= 0) {
2072  // there are no ferrys available... give up
2073  return true;
2074  } else {
2075  if (punit->server.birth_turn + 20 < game.info.turn) {
2076  // we are feed up!
2077  return true;
2078  }
2079  }
2080  }
2081  }
2082  }
2083 
2084  return false;
2085 }
2086 
2092  struct unit *punit)
2093 {
2094  struct city *pcity = game_city_by_number(punit->homecity);
2095  Continent_id continent;
2096 
2097  fc_assert(pcity != nullptr);
2098 
2099  continent = tile_continent(pcity->tile);
2100 
2101  // Look for proper destination city at different continent.
2102  city_list_iterate(pplayer->cities, acity)
2103  {
2104  if (can_cities_trade(pcity, acity)) {
2105  if (tile_continent(acity->tile) != continent) {
2106  return true;
2107  }
2108  }
2109  }
2111 
2112  players_iterate(aplayer)
2113  {
2114  if (aplayer == pplayer || !aplayer->is_alive) {
2115  continue;
2116  }
2117  if (pplayers_allied(pplayer, aplayer)) {
2118  city_list_iterate(aplayer->cities, acity)
2119  {
2120  if (can_cities_trade(pcity, acity)) {
2121  if (tile_continent(acity->tile) != continent) {
2122  return true;
2123  }
2124  }
2125  }
2127  }
2129  }
2130 
2131  return false;
2132 }
2133 
2138 static bool search_homecity_for_caravan(struct ai_type *ait,
2139  struct unit *punit)
2140 {
2141  struct city *nearest = nullptr;
2142  int min_dist = FC_INFINITY;
2143  struct tile *current_loc = unit_tile(punit);
2144  Continent_id continent = tile_continent(current_loc);
2145  bool alive = true;
2146 
2147  city_list_iterate(punit->owner->cities, pcity)
2148  {
2149  struct tile *ctile = city_tile(pcity);
2150 
2151  if (tile_continent(ctile) == continent) {
2152  int this_dist = map_distance(current_loc, ctile);
2153 
2154  if (this_dist < min_dist) {
2155  min_dist = this_dist;
2156  nearest = pcity;
2157  }
2158  }
2159  }
2161 
2162  if (nearest != nullptr) {
2163  alive = dai_unit_goto(ait, punit, nearest->tile);
2164  if (alive && same_pos(unit_tile(punit), nearest->tile)) {
2165  dai_unit_make_homecity(punit, nearest);
2166  }
2167  }
2168 
2169  return alive;
2170 }
2171 
2178 static void dai_manage_caravan(struct ai_type *ait, struct player *pplayer,
2179  struct unit *punit)
2180 {
2181  struct caravan_parameter parameter;
2182  struct caravan_result result;
2183  const struct city *homecity;
2184  const struct city *dest = nullptr;
2185  struct unit_ai *unit_data;
2186  bool help_wonder = false;
2187  bool required_boat = false;
2188  bool request_boat = false;
2189  bool tired_of_waiting_boat = false;
2190 
2191  CHECK_UNIT(punit);
2192 
2193  if (!unit_can_do_action(punit, ACTION_TRADE_ROUTE)
2194  && !unit_can_do_action(punit, ACTION_MARKETPLACE)
2195  && !unit_can_do_action(punit, ACTION_HELP_WONDER)) {
2196  /* we only want units that can establish trade, enter marketplace or
2197  * help build wonders */
2198  return;
2199  }
2200 
2201  unit_data = def_ai_unit_data(punit, ait);
2202 
2203  log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d) task %s to (%d,%d)",
2205  punit->id, TILE_XY(unit_tile(punit)),
2206  dai_unit_task_rule_name(unit_data->task),
2207  TILE_XY(punit->goto_tile));
2208 
2209  homecity = game_city_by_number(punit->homecity);
2210  if (homecity == nullptr && unit_data->task == AIUNIT_TRADE) {
2211  if (!search_homecity_for_caravan(ait, punit)) {
2212  return;
2213  }
2214  homecity = game_city_by_number(punit->homecity);
2215  if (homecity == nullptr) {
2216  return;
2217  }
2218  }
2219 
2220  if ((unit_data->task == AIUNIT_TRADE
2221  || unit_data->task == AIUNIT_WONDER)) {
2222  // we are moving to our destination
2223  // we check to see if our current goal is feasible
2224  struct city *city_dest = tile_city(punit->goto_tile);
2225 
2226  if ((city_dest == nullptr)
2227  || !pplayers_allied(unit_owner(punit), city_dest->owner)
2228  || (unit_data->task == AIUNIT_TRADE
2229  && !(can_cities_trade(homecity, city_dest)
2230  && can_establish_trade_route(homecity, city_dest)))
2231  || (unit_data->task == AIUNIT_WONDER
2232  // Helping the (new) production is illegal.
2234  || (unit_data->task == AIUNIT_TRADE
2235  && real_map_distance(city_dest->tile, unit_tile(punit)) <= 1
2236  && !(is_action_enabled_unit_on_city(ACTION_TRADE_ROUTE, punit,
2237  city_dest)
2238  || is_action_enabled_unit_on_city(ACTION_MARKETPLACE, punit,
2239  city_dest)))
2240  || (unit_data->task == AIUNIT_WONDER
2241  && real_map_distance(city_dest->tile, unit_tile(punit)) <= 1
2242  && !is_action_enabled_unit_on_city(ACTION_HELP_WONDER, punit,
2243  city_dest))) {
2244  // destination invalid!
2245  dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
2246  log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d) destination invalid!",
2248  unit_rule_name(punit), punit->id, TILE_XY(unit_tile(punit)));
2249  } else {
2250  // destination valid, are we tired of waiting for a boat?
2251  if (dai_is_unit_tired_waiting_boat(ait, punit)) {
2252  aiferry_clear_boat(ait, punit);
2253  dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
2254  log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d) unit tired of waiting!",
2256  unit_rule_name(punit), punit->id,
2257  TILE_XY(unit_tile(punit)));
2258  tired_of_waiting_boat = true;
2259  } else {
2260  dest = city_dest;
2261  help_wonder = unit_data->task == AIUNIT_WONDER;
2262  required_boat =
2263  tile_continent(unit_tile(punit)) != tile_continent(dest->tile);
2264  request_boat = false;
2265  }
2266  }
2267  }
2268 
2269  if (unit_data->task == AIUNIT_NONE) {
2270  if (homecity == nullptr) {
2271  /* FIXME: We shouldn't bother in getting homecity for
2272  * caravan that will then be used for wonder building. */
2273  if (!search_homecity_for_caravan(ait, punit)) {
2274  return;
2275  }
2276  homecity = game_city_by_number(punit->homecity);
2277  if (homecity == nullptr) {
2278  return;
2279  }
2280  }
2281 
2282  caravan_parameter_init_from_unit(&parameter, punit);
2283  /* Make more trade with allies than other peaceful nations
2284  * by considering only allies 50% of the time.
2285  * (the other 50% allies are still considered, but so are other nations)
2286  */
2287  if (fc_rand(2)) {
2288  /* Be optimistic about development of relations with no-contact and
2289  * cease-fire nations. */
2290  parameter.allow_foreign_trade = FTL_NONWAR;
2291  } else {
2292  parameter.allow_foreign_trade = FTL_ALLIED;
2293  }
2294 
2295  parameter.callback = caravan_optimize_callback;
2296  parameter.callback_data = punit;
2297  if (dai_caravan_can_trade_cities_diff_cont(pplayer, punit)) {
2298  parameter.ignore_transit_time = true;
2299  }
2300  if (tired_of_waiting_boat) {
2302  parameter.ignore_transit_time = false;
2303  }
2304  caravan_find_best_destination(punit, &parameter, &result,
2305  !has_handicap(pplayer, H_MAP));
2306  if (result.dest != nullptr) {
2307  // we did find a new destination for the unit
2308  dest = result.dest;
2309  help_wonder = result.help_wonder;
2310  required_boat =
2311  tile_continent(unit_tile(punit)) != tile_continent(dest->tile);
2312  request_boat = required_boat;
2313  dai_unit_new_task(ait, punit,
2314  (help_wonder) ? AIUNIT_WONDER : AIUNIT_TRADE,
2315  dest->tile);
2316  } else {
2317  dest = nullptr;
2318  }
2319  }
2320 
2321  if (dest != nullptr) {
2322  dai_caravan_goto(ait, pplayer, punit, dest, help_wonder, required_boat,
2323  request_boat);
2324  return; // that may have clobbered the unit
2325  } else {
2326  // We have nowhere to go!
2327  log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d), nothing to do!",
2329  punit->id, TILE_XY(unit_tile(punit)));
2330  // Should we become a defensive unit?
2331  }
2332 }
2333 
2338 static void dai_manage_hitpoint_recovery(struct ai_type *ait,
2339  struct unit *punit)
2340 {
2341  struct player *pplayer = unit_owner(punit);
2342  struct city *pcity = tile_city(unit_tile(punit));
2343  struct city *safe = nullptr;
2344  const struct unit_type *punittype = unit_type_get(punit);
2345 
2346  CHECK_UNIT(punit);
2347 
2348  if (pcity) {
2349  /* rest in city until the hitpoints are recovered, but attempt
2350  to protect city from attack (and be opportunistic too)*/
2353  UNIT_LOG(LOGLEVEL_RECOVERY, punit, "recovering hit points.");
2354  } else {
2355  return; // we died heroically defending our city
2356  }
2357  } else {
2358  // goto to nearest city to recover hit points
2359  // just before, check to see if we can occupy an undefended enemy city
2362  return; // oops, we died
2363  }
2364 
2365  // find city to stay and go there
2366  safe = find_nearest_safe_city(punit);
2367  if (safe) {
2368  UNIT_LOG(LOGLEVEL_RECOVERY, punit, "going to %s to recover",
2369  city_name_get(safe));
2370  if (!dai_unit_goto(ait, punit, safe->tile)) {
2371  log_base(LOGLEVEL_RECOVERY, "died trying to hide and recover");
2372  return;
2373  }
2374  } else {
2375  // oops
2376  UNIT_LOG(LOGLEVEL_RECOVERY, punit,
2377  "didn't find a city to recover in!");
2378  dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
2379  dai_military_attack(ait, pplayer, punit);
2380  return;
2381  }
2382  }
2383 
2384  // is the unit still damaged? if true recover hit points, if not idle
2385  if (punit->hp == punittype->hp) {
2386  // we are ready to go out and kick ass again
2387  UNIT_LOG(LOGLEVEL_RECOVERY, punit, "ready to kick ass again!");
2388  dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
2389  return;
2390  } else {
2391  def_ai_unit_data(punit, ait)->done = true; // sit tight
2392  }
2393 }
2394 
2399 void dai_manage_military(struct ai_type *ait, struct player *pplayer,
2400  struct unit *punit)
2401 {
2402  struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2403  int id = punit->id;
2404 
2405  CHECK_UNIT(punit);
2406 
2407  /* "Escorting" aircraft should not do anything. They are activated
2408  * by their transport or charge. We do _NOT_ set them to 'done'
2409  * since they may need be activated once our charge moves. */
2410  if (unit_data->task == AIUNIT_ESCORT && utype_fuel(unit_type_get(punit))) {
2411  return;
2412  }
2413 
2414  if ((punit->activity == ACTIVITY_SENTRY
2415  || punit->activity == ACTIVITY_FORTIFIED)
2416  && has_handicap(pplayer, H_AWAY)) {
2417  /* Don't move sentried or fortified units controlled by a player
2418  * in away mode. */
2419  unit_data->done = true;
2420  return;
2421  }
2422 
2423  /* Since military units re-evaluate their actions every turn,
2424  we must make sure that previously reserved ferry is freed. */
2425  aiferry_clear_boat(ait, punit);
2426 
2428  // Try hunting with this unit
2429  if (dai_hunter_qualify(pplayer, punit)) {
2430  int result, sanity = punit->id;
2431 
2432  UNIT_LOG(LOGLEVEL_HUNT, punit, "is qualified as hunter");
2433  result = dai_hunter_manage(ait, pplayer, punit);
2434  if (nullptr == game_unit_by_number(sanity)) {
2436  return; // died
2437  }
2438  if (result == -1) {
2439  (void) dai_hunter_manage(ait, pplayer, punit); // More carnage
2441  return;
2442  } else if (result >= 1) {
2444  return; // Done moving
2445  } else if (unit_data->task == AIUNIT_HUNTER) {
2446  // This should be very rare
2447  dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
2448  }
2449  } else if (unit_data->task == AIUNIT_HUNTER) {
2450  dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
2451  }
2453 
2454  /* Do we have a specific job for this unit? If not, we default
2455  * to attack. */
2456  dai_military_findjob(ait, pplayer, punit);
2457 
2458  switch (unit_data->task) {
2459  case AIUNIT_AUTO_SETTLER:
2460  case AIUNIT_BUILD_CITY:
2461  fc_assert(false); // This is not the place for this role
2462  break;
2463  case AIUNIT_DEFEND_HOME:
2465  dai_military_defend(ait, pplayer, punit);
2467  break;
2468  case AIUNIT_ATTACK:
2469  case AIUNIT_NONE:
2471  dai_military_attack(ait, pplayer, punit);
2473  break;
2474  case AIUNIT_ESCORT:
2476  dai_military_bodyguard(ait, pplayer, punit);
2478  break;
2479  case AIUNIT_EXPLORE:
2480  switch (manage_auto_explorer(punit)) {
2481  case MR_DEATH:
2482  // don't use punit!
2483  return;
2484  case MR_OK:
2485  UNIT_LOG(LOG_DEBUG, punit, "more exploring");
2486  break;
2487  default:
2488  UNIT_LOG(LOG_DEBUG, punit, "no more exploring either");
2489  break;
2490  };
2491  def_ai_unit_data(punit, ait)->done = (punit->moves_left <= 0);
2492  break;
2493  case AIUNIT_RECOVER:
2495  dai_manage_hitpoint_recovery(ait, punit);
2497  break;
2498  case AIUNIT_HUNTER:
2499  fc_assert(false); // dealt with above
2500  break;
2501  default:
2502  fc_assert(false);
2503  }
2504 
2505  // If we are still alive, either sentry or fortify.
2506  if ((punit = game_unit_by_number(id))) {
2507  unit_data = def_ai_unit_data(punit, ait);
2508  struct city *pcity = tile_city(unit_tile(punit));
2509 
2510  if (unit_list_find(unit_tile(punit)->units, unit_data->ferryboat)) {
2511  unit_activity_handling(punit, ACTIVITY_SENTRY);
2512  } else if (pcity || punit->activity == ACTIVITY_IDLE) {
2513  /* We do not need to fortify in cities - we fortify and sentry
2514  * according to home defense setup, for easy debugging. */
2515  if (!pcity || unit_data->task == AIUNIT_DEFEND_HOME) {
2516  if (punit->activity == ACTIVITY_IDLE
2517  || punit->activity == ACTIVITY_SENTRY) {
2518  unit_activity_handling(punit, ACTIVITY_FORTIFYING);
2519  }
2520  } else {
2521  unit_activity_handling(punit, ACTIVITY_SENTRY);
2522  }
2523  }
2524  }
2525 }
2526 
2530 static void dai_manage_settler(struct ai_type *ait, struct player *pplayer,
2531  struct unit *punit)
2532 {
2533  struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2534 
2535  unit_server_side_agent_set(pplayer, punit, SSA_AUTOSETTLER);
2536  unit_data->done = true; // we will manage this unit later... ugh
2537  // if BUILD_CITY must remain BUILD_CITY, otherwise turn into autosettler
2538  if (unit_data->task == AIUNIT_NONE) {
2539  adv_unit_new_task(punit, AUT_AUTO_SETTLER, nullptr);
2540  }
2541 }
2542 
2551 void dai_manage_unit(struct ai_type *ait, struct player *pplayer,
2552  struct unit *punit)
2553 {
2554  struct unit_ai *unit_data;
2555  struct unit *bodyguard = aiguard_guard_of(ait, punit);
2556  bool is_ferry = false;
2557 
2558  CHECK_UNIT(punit);
2559 
2560  // Don't manage the unit if it is under human orders.
2561  if (unit_has_orders(punit)) {
2562  unit_data = def_ai_unit_data(punit, ait);
2563 
2564  UNIT_LOG(LOG_VERBOSE, punit,
2565  "is under human orders, aborting AI control.");
2566  dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
2567  unit_data->done = true;
2568  return;
2569  }
2570 
2571  /* Check if we have lost our bodyguard. If we never had one, all
2572  * fine. If we had one and lost it, ask for a new one. */
2573  if (!bodyguard && aiguard_has_guard(ait, punit)) {
2574  UNIT_LOG(LOGLEVEL_BODYGUARD, punit, "lost bodyguard, asking for new");
2575  aiguard_request_guard(ait, punit);
2576  }
2577 
2578  unit_data = def_ai_unit_data(punit, ait);
2579 
2580  if (punit->moves_left <= 0) {
2581  // Can do nothing
2582  unit_data->done = true;
2583  return;
2584  }
2585 
2586  is_ferry = dai_is_ferry(punit, ait);
2587 
2588  if (unit_has_type_flag(punit, UTYF_DIPLOMAT)) {
2590  dai_manage_diplomat(ait, pplayer, punit);
2592  return;
2593  } else if (unit_has_type_flag(punit, UTYF_SETTLERS)
2594  || unit_is_cityfounder(punit)) {
2595  dai_manage_settler(ait, pplayer, punit);
2596  return;
2597  } else if (unit_can_do_action(punit, ACTION_TRADE_ROUTE)
2598  || unit_can_do_action(punit, ACTION_MARKETPLACE)
2599  || unit_can_do_action(punit, ACTION_HELP_WONDER)) {
2601  dai_manage_caravan(ait, pplayer, punit);
2603  return;
2604  } else if (unit_has_type_role(punit, L_BARBARIAN_LEADER)) {
2605  dai_manage_barbarian_leader(ait, pplayer, punit);
2606  return;
2607  } else if (unit_can_do_action(punit, ACTION_PARADROP)) {
2608  dai_manage_paratrooper(ait, pplayer, punit);
2609  return;
2610  } else if (is_ferry && unit_data->task != AIUNIT_HUNTER) {
2612  dai_manage_ferryboat(ait, pplayer, punit);
2614  return;
2615  } else if (utype_fuel(unit_type_get(punit))
2616  && unit_data->task != AIUNIT_ESCORT) {
2618  dai_manage_airunit(ait, pplayer, punit);
2620  return;
2621  } else if (is_losing_hp(punit)) {
2622  // This unit is losing hitpoints over time
2623 
2624  /* TODO: We can try using air-unit code for helicopters, just
2625  * pretend they have fuel = HP / 3 or something. */
2626  unit_data->done = true; /* we did our best, which was ...
2627  nothing */
2628  return;
2629  } else if (is_military_unit(punit)) {
2631  UNIT_LOG(LOG_DEBUG, punit, "recruit unit for the military");
2632  dai_manage_military(ait, pplayer, punit);
2634  return;
2635  } else {
2636  // what else could this be? -- Syela
2637  switch (manage_auto_explorer(punit)) {
2638  case MR_DEATH:
2639  // don't use punit!
2640  break;
2641  case MR_OK:
2642  UNIT_LOG(LOG_DEBUG, punit, "now exploring");
2643  break;
2644  default:
2645  UNIT_LOG(LOG_DEBUG, punit, "fell through all unit tasks, defending");
2646  dai_unit_new_task(ait, punit, AIUNIT_DEFEND_HOME, nullptr);
2647  dai_military_defend(ait, pplayer, punit);
2648  break;
2649  };
2650  return;
2651  }
2652 }
2653 
2660 static void dai_set_defenders(struct ai_type *ait, struct player *pplayer)
2661 {
2662  city_list_iterate(pplayer->cities, pcity)
2663  {
2664  /* The idea here is that we should never keep more than two
2665  * units in permanent defense. */
2666  int total_defense = 0;
2667  int total_attack = def_ai_city_data(pcity, ait)->danger;
2668  bool emergency = false;
2669  int count = 0;
2670  int mart_max = get_city_bonus(pcity, EFT_MARTIAL_LAW_MAX);
2671  int mart_each = get_city_bonus(pcity, EFT_MARTIAL_LAW_EACH);
2672  int martless_unhappy = pcity->feel[CITIZEN_UNHAPPY][FEELING_NATIONALITY]
2673  + pcity->feel[CITIZEN_ANGRY][FEELING_NATIONALITY];
2674  int entertainers = 0;
2675  bool enough = false;
2676 
2678  {
2679  if (get_specialist_output(pcity, sp, O_LUXURY) > 0) {
2680  entertainers += pcity->specialists[sp];
2681  }
2682  }
2684 
2685  martless_unhappy += entertainers; /* We want to use martial law instead
2686  * of entertainers. */
2687 
2688  while (!enough
2689  && (total_defense <= total_attack
2690  || (count < mart_max && mart_each > 0
2691  && martless_unhappy > mart_each * count))) {
2692  int best_want = 0;
2693  struct unit *best = nullptr;
2694  bool defense_needed =
2695  total_defense <= total_attack; // Defense or martial
2696 
2697  unit_list_iterate(pcity->tile->units, punit)
2698  {
2699  struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2700 
2701  if ((unit_data->task == AIUNIT_NONE || emergency)
2702  && unit_data->task != AIUNIT_DEFEND_HOME
2703  && unit_owner(punit) == pplayer) {
2704  int want = assess_defense_unit(ait, pcity, punit, false);
2705 
2706  if (want > best_want) {
2707  best_want = want;
2708  best = punit;
2709  }
2710  }
2711  }
2713 
2714  if (best == nullptr) {
2715  if (defense_needed) {
2716  // Ooops - try to grab any unit as defender!
2717  if (emergency) {
2718  CITY_LOG(LOG_DEBUG, pcity, "Not defended properly");
2719  break;
2720  }
2721  emergency = true;
2722  } else {
2723  break;
2724  }
2725  } else {
2726  const struct unit_type *btype = unit_type_get(best);
2727 
2728  if ((martless_unhappy < mart_each * count || count >= mart_max
2729  || mart_each <= 0)
2730  && ((count >= 2
2731  && btype->attack_strength > btype->defense_strength)
2732  || (count >= 4
2733  && btype->attack_strength == btype->defense_strength))) {
2734  /* In this case attack would be better defense than fortifying
2735  * to city. */
2736  enough = true;
2737  } else {
2738  total_defense += best_want;
2739  dai_unit_new_task(ait, best, AIUNIT_DEFEND_HOME, pcity->tile);
2740  count++;
2741  }
2742  }
2743  }
2744  CITY_LOG(LOG_DEBUG, pcity,
2745  "Evaluating defense: %d defense, %d incoming"
2746  ", %d defenders (out of %d)",
2747  total_defense, total_attack, count,
2748  unit_list_size(pcity->tile->units));
2749  }
2751 }
2752 
2761 void dai_manage_units(struct ai_type *ait, struct player *pplayer)
2762 {
2764  dai_airlift(ait, pplayer);
2766 
2767  // Clear previous orders, if desirable, here.
2768  unit_list_iterate(pplayer->units, punit)
2769  {
2770  struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2771 
2772  unit_data->done = false;
2773  if (unit_data->task == AIUNIT_DEFEND_HOME) {
2774  dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
2775  }
2776  }
2778 
2779  /* Find and set city defenders first - figure out which units are
2780  * allowed to leave home. */
2781  dai_set_defenders(ait, pplayer);
2782 
2783  unit_list_iterate_safe(pplayer->units, punit)
2784  {
2785  if ((!unit_transported(punit)
2786  || unit_owner(unit_transport_get(punit)) != pplayer)
2787  && !def_ai_unit_data(punit, ait)->done) {
2788  /* Though it is usually the passenger who drives the transport,
2789  * the transporter is responsible for managing its passengers. */
2790  dai_manage_unit(ait, pplayer, punit);
2791  }
2792  }
2794 }
2795 
2801 const struct impr_type *
2802 utype_needs_improvement(const struct unit_type *putype,
2803  const struct city *pcity)
2804 {
2805  const struct impr_type *impr_req = nullptr;
2806 
2807  requirement_vector_iterate(&putype->build_reqs, preq)
2808  {
2809  if (is_req_active(city_owner(pcity), nullptr, pcity, nullptr,
2810  city_tile(pcity), nullptr, putype, nullptr, nullptr,
2811  nullptr, preq, RPT_CERTAIN)) {
2812  // Already there.
2813  continue;
2814  }
2816  pcity)) {
2817  // The unit type can't be built at all.
2818  return nullptr;
2819  }
2820  if (VUT_IMPROVEMENT == preq->source.kind && preq->present) {
2821  // This is (one of) the building(s) required.
2822  impr_req = preq->source.value.building;
2823  }
2824  }
2826 
2827  return impr_req;
2828 }
2829 
2835 static void dai_manage_barbarian_leader(struct ai_type *ait,
2836  struct player *pplayer,
2837  struct unit *leader)
2838 {
2839  struct tile *leader_tile = unit_tile(leader), *safest_tile;
2840  struct pf_parameter parameter;
2841  struct pf_map *pfm;
2842  struct pf_reverse_map *pfrm;
2843  struct unit *worst_danger;
2844  int move_cost, best_move_cost;
2845  int body_guards;
2846  bool alive = true;
2847 
2848  CHECK_UNIT(leader);
2849 
2850  if (0 == leader->moves_left
2851  || (can_unit_survive_at_tile(&(wld.map), leader, leader_tile)
2852  && 1 < unit_list_size(leader_tile->units))) {
2853  unit_activity_handling(leader, ACTIVITY_SENTRY);
2854  return;
2855  }
2856 
2857  if (is_boss_of_boat(ait, leader)) {
2858  /* We are in charge. Of course, since we are the leader...
2859  * But maybe somebody more militaristic should lead our ship to battle!
2860  */
2861 
2862  // First release boat from leaders lead
2863  aiferry_clear_boat(ait, leader);
2864 
2865  unit_list_iterate(leader_tile->units, warrior)
2866  {
2867  if (!unit_has_type_role(warrior, L_BARBARIAN_LEADER)
2868  && get_transporter_capacity(warrior) == 0
2869  && warrior->moves_left > 0) {
2870  // This seems like a good warrior to lead us in to conquest!
2871  dai_manage_unit(ait, pplayer, warrior);
2872 
2873  /* If we reached our destination, ferryboat already called
2874  * ai_manage_unit() for leader. So no need to continue here.
2875  * Leader might even be dead.
2876  * If this return is removed, surronding unit_list_iterate()
2877  * has to be replaced with unit_list_iterate_safe()*/
2878  return;
2879  }
2880  }
2882  }
2883 
2884  /* If we are not in charge of the boat, continue as if we
2885  * were not in a boat - we may want to leave the ship now. */
2886 
2887  // Check the total number of units able to protect our leader.
2888  body_guards = 0;
2889  unit_list_iterate(pplayer->units, punit)
2890  {
2891  if (!unit_has_type_role(punit, L_BARBARIAN_LEADER)
2892  && goto_is_sane(punit, leader_tile)) {
2893  body_guards++;
2894  }
2895  }
2897 
2898  if (0 < body_guards) {
2899  pft_fill_unit_parameter(&parameter, leader);
2900  parameter.omniscience = !has_handicap(pplayer, H_MAP);
2901  pfm = pf_map_new(&parameter);
2902 
2903  // Find the closest body guard. FIXME: maybe choose the strongest too?
2904  pf_map_tiles_iterate(pfm, ptile, false)
2905  {
2906  unit_list_iterate(ptile->units, punit)
2907  {
2908  if (unit_owner(punit) == pplayer
2909  && !unit_has_type_role(punit, L_BARBARIAN_LEADER)
2910  && goto_is_sane(punit, leader_tile)) {
2911  auto path = pf_map_path(pfm, ptile);
2912  adv_follow_path(leader, path, ptile);
2913  pf_map_destroy(pfm);
2914  return;
2915  }
2916  }
2918  }
2920 
2921  pf_map_destroy(pfm);
2922  }
2923 
2924  UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader needs to flee");
2925 
2926  // Check for units we could fear.
2927  pfrm = pf_reverse_map_new(pplayer, leader_tile, 3,
2928  !has_handicap(pplayer, H_MAP), &(wld.map));
2929  worst_danger = nullptr;
2930  best_move_cost = FC_INFINITY;
2931 
2932  players_iterate(other_player)
2933  {
2934  if (other_player == pplayer) {
2935  continue;
2936  }
2937 
2938  unit_list_iterate(other_player->units, punit)
2939  {
2940  move_cost = pf_reverse_map_unit_move_cost(pfrm, punit);
2941  if (PF_IMPOSSIBLE_MC != move_cost && move_cost < best_move_cost) {
2942  best_move_cost = move_cost;
2943  worst_danger = punit;
2944  }
2945  }
2947  }
2949 
2950  pf_reverse_map_destroy(pfrm);
2951 
2952  if (nullptr == worst_danger) {
2953  unit_activity_handling(leader, ACTIVITY_IDLE);
2954  UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader: no close enemy.");
2955  return;
2956  }
2957 
2958  pft_fill_unit_parameter(&parameter, worst_danger);
2959  parameter.omniscience = !has_handicap(pplayer, H_MAP);
2960  pfm = pf_map_new(&parameter);
2961  best_move_cost = pf_map_move_cost(pfm, leader_tile);
2962 
2963  // Try to escape.
2964  do {
2965  safest_tile = leader_tile;
2966 
2967  UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader: moves left: %d.",
2968  leader->moves_left);
2969 
2970  adjc_iterate(&(wld.map), leader_tile, near_tile)
2971  {
2972  if (adv_could_unit_move_to_tile(leader, near_tile) != 1) {
2973  continue;
2974  }
2975 
2976  move_cost = pf_map_move_cost(pfm, near_tile);
2977  if (PF_IMPOSSIBLE_MC != move_cost && move_cost > best_move_cost) {
2978  UNIT_LOG(LOG_DEBUG, leader,
2979  "Barbarian leader: safest is (%d, %d), safeness %d",
2980  TILE_XY(near_tile), best_move_cost);
2981  best_move_cost = move_cost;
2982  safest_tile = near_tile;
2983  }
2984  }
2986 
2987  UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader: fleeing to (%d, %d).",
2988  TILE_XY(safest_tile));
2989  if (same_pos(unit_tile(leader), safest_tile)) {
2990  UNIT_LOG(LOG_DEBUG, leader,
2991  "Barbarian leader: reached the safest position.");
2992  unit_activity_handling(leader, ACTIVITY_IDLE);
2993  pf_map_destroy(pfm);
2994  return;
2995  }
2996 
2997  alive = dai_unit_goto(ait, leader, safest_tile);
2998  if (alive) {
2999  if (same_pos(unit_tile(leader), leader_tile)) {
3000  // Didn't move. No point to retry.
3001  pf_map_destroy(pfm);
3002  return;
3003  }
3004  leader_tile = unit_tile(leader);
3005  }
3006  } while (alive && 0 < leader->moves_left);
3007 
3008  pf_map_destroy(pfm);
3009 }
3010 
3017 void dai_consider_tile_dangerous(struct ai_type *ait, struct tile *ptile,
3018  struct unit *punit,
3019  enum override_bool *result)
3020 {
3021  int a = 0, d, db;
3022  struct player *pplayer = unit_owner(punit);
3023  struct city *pcity = tile_city(ptile);
3024  int extras_bonus = 0;
3025 
3026  if (is_human(pplayer)) {
3027  // Use advisors code for humans.
3028  return;
3029  }
3030 
3031  if (pcity && pplayers_allied(city_owner(pcity), unit_owner(punit))
3032  && !is_non_allied_unit_tile(ptile, pplayer)) {
3033  // We will be safe in a friendly city
3034  *result = OVERRIDE_FALSE;
3035  return;
3036  }
3037 
3038  // Calculate how well we can defend at (x,y)
3039  db = 10 + tile_terrain(ptile)->defense_bonus / 10;
3040  extras_bonus += tile_extras_defense_bonus(ptile, unit_type_get(punit));
3041 
3042  db += (db * extras_bonus) / 100;
3043  d = adv_unit_def_rating_basic_squared(punit) * db;
3044 
3045  adjc_iterate(&(wld.map), ptile, ptile1)
3046  {
3047  if (has_handicap(pplayer, H_FOG)
3048  && !map_is_known_and_seen(ptile1, unit_owner(punit), V_MAIN)) {
3049  // We cannot see danger at (ptile1) => assume there is none
3050  continue;
3051  }
3052  unit_list_iterate(ptile1->units, enemy)
3053  {
3054  if (pplayers_at_war(unit_owner(enemy), unit_owner(punit))
3055  && unit_attack_unit_at_tile_result(enemy, punit, ptile) == ATT_OK
3056  && unit_attack_units_at_tile_result(enemy, ptile) == ATT_OK) {
3057  a += adv_unit_att_rating(enemy);
3058  if ((a * a * 10) >= d) {
3059  // The enemies combined strength is too big!
3060  *result = OVERRIDE_TRUE;
3061  return;
3062  }
3063  }
3064  }
3066  }
3068 
3069  *result = OVERRIDE_FALSE;
3070 }
3071 
3076 {
3077  int i = 0;
3078 
3079  unit_type_iterate(punittype)
3080  {
3081  struct unit_class *pclass = utype_class(punittype);
3082 
3083  if (A_NEVER != punittype->require_advance
3084  && !utype_has_flag(punittype, UTYF_CIVILIAN)
3085  && !utype_can_do_action(punittype, ACTION_SUICIDE_ATTACK)
3086  && !(pclass->adv.land_move == MOVE_NONE
3087  && !can_attack_non_native(punittype))
3088  && !utype_fuel(punittype) && punittype->transport_capacity < 8) {
3089  simple_ai_types[i] = punittype;
3090  i++;
3091  }
3092  }
3094 
3095  simple_ai_types[i] = nullptr;
3096 }
3097 
3102 {
3103  /* TODO: remove the simple_ai_types cache or merge it with a general ai
3104  * cache; see the comment to struct unit_type *simple_ai_types at
3105  * the beginning of this file. */
3107 
3108  unit_type_iterate(ptype)
3109  {
3110  struct unit_type_ai *utai = new unit_type_ai;
3111 
3112  utai->firepower1 = false;
3113  utai->ferry = false;
3114  utai->missile_platform = false;
3115  utai->carries_occupiers = false;
3116  utai->potential_charges = unit_type_list_new();
3117 
3118  utype_set_ai_data(ptype, ait, utai);
3119  }
3121 
3122  unit_type_iterate(punittype)
3123  {
3124  struct unit_class *pclass = utype_class(punittype);
3125 
3126  // Confirm firepower
3127  combat_bonus_list_iterate(punittype->bonuses, pbonus)
3128  {
3129  if (pbonus->type == CBONUS_FIREPOWER1) {
3130  unit_type_iterate(penemy)
3131  {
3132  if (utype_has_flag(penemy, pbonus->flag)) {
3133  struct unit_type_ai *utai =
3134  static_cast<unit_type_ai *>(utype_ai_data(penemy, ait));
3135 
3136  utai->firepower1 = true;
3137  }
3138  }
3140  }
3141  }
3143 
3144  // Consider potential cargo
3145  if (punittype->transport_capacity > 0) {
3146  struct unit_type_ai *utai =
3147  static_cast<unit_type_ai *>(utype_ai_data(punittype, ait));
3148 
3149  unit_type_iterate(pctype)
3150  {
3151  struct unit_class *pcargo = utype_class(pctype);
3152 
3153  if (can_unit_type_transport(punittype, pcargo)) {
3154  if (utype_can_do_action(pctype, ACTION_SUICIDE_ATTACK)) {
3155  utai->missile_platform = true;
3156  } else if (pclass->adv.sea_move != MOVE_NONE
3157  && pcargo->adv.land_move != MOVE_NONE) {
3158  if (pcargo->adv.sea_move != MOVE_FULL) {
3159  utai->ferry = true;
3160  } else {
3161  if (0 != utype_fuel(pctype)) {
3162  utai->ferry = true;
3163  }
3164  }
3165  }
3166 
3167  if (uclass_has_flag(pcargo, UCF_CAN_OCCUPY_CITY)) {
3168  utai->carries_occupiers = true;
3169  }
3170  }
3171  }
3173  }
3174 
3175  // Consider potential charges
3176  unit_type_iterate(pcharge)
3177  {
3178  bool can_move_like_charge = false;
3179 
3180  if (0 < utype_fuel(punittype)
3181  && (0 == utype_fuel(pcharge)
3182  || utype_fuel(pcharge) > utype_fuel(punittype))) {
3183  continue;
3184  }
3185 
3187  {
3188  if (chgcls == utype_class(pcharge)) {
3189  can_move_like_charge = true;
3190  }
3191  }
3193 
3194  if (can_move_like_charge) {
3195  struct unit_type_ai *utai =
3196  static_cast<unit_type_ai *>(utype_ai_data(punittype, ait));
3197  unit_type_list_append(utai->potential_charges, pcharge);
3198  }
3199  }
3201  }
3203 }
3204 
3209 {
3210  unit_type_iterate(ptype)
3211  {
3212  struct unit_type_ai *utai =
3213  static_cast<unit_type_ai *>(utype_ai_data(ptype, ait));
3214 
3215  if (utai == nullptr) {
3216  continue;
3217  }
3218  utype_set_ai_data(ptype, ait, nullptr);
3219 
3220  unit_type_list_destroy(utai->potential_charges);
3221  delete utai;
3222  }
3224 }
3225 
3229 void dai_unit_init(struct ai_type *ait, struct unit *punit)
3230 {
3231  /* Make sure that contents of unit_ai structure are correctly initialized,
3232  * if you ever allocate it by some other mean than new */
3233 
3234  struct unit_ai *unit_data = new unit_ai{};
3235 
3236  unit_data->done = false;
3237  unit_data->cur_pos = nullptr;
3238  unit_data->prev_pos = nullptr;
3239  unit_data->target = 0;
3240  BV_CLR_ALL(unit_data->hunted);
3241  unit_data->ferryboat = 0;
3242  unit_data->passenger = 0;
3243  unit_data->bodyguard = 0;
3244  unit_data->charge = 0;
3245 
3246  unit_set_ai_data(punit, ait, unit_data);
3247 }
3248 
3252 void dai_unit_turn_end(struct ai_type *ait, struct unit *punit)
3253 {
3254  struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3255 
3256  fc_assert_ret(unit_data != nullptr);
3257 
3258  BV_CLR_ALL(unit_data->hunted);
3259 }
3260 
3264 void dai_unit_close(struct ai_type *ait, struct unit *punit)
3265 {
3266  struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3267 
3268  fc_assert_ret(unit_data != nullptr);
3269 
3270  aiguard_clear_charge(ait, punit);
3271  aiguard_clear_guard(ait, punit);
3272 
3273  if (unit_data != nullptr) {
3274  unit_set_ai_data(punit, ait, nullptr);
3275  delete unit_data;
3276  unit_data = nullptr;
3277  }
3278 }
3279 
3283 void dai_unit_save(struct ai_type *ait, const char *aitstr,
3284  struct section_file *file, const struct unit *punit,
3285  const char *unitstr)
3286 {
3287  struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3288 
3289  secfile_insert_int(file, unit_data->passenger, "%s.%spassenger", unitstr,
3290  aitstr);
3291  secfile_insert_int(file, unit_data->ferryboat, "%s.%sferryboat", unitstr,
3292  aitstr);
3293  secfile_insert_int(file, unit_data->charge, "%s.%scharge", unitstr,
3294  aitstr);
3295  secfile_insert_int(file, unit_data->bodyguard, "%s.%sbodyguard", unitstr,
3296  aitstr);
3297 }
3298 
3302 void dai_unit_load(struct ai_type *ait, const char *aitstr,
3303  const struct section_file *file, struct unit *punit,
3304  const char *unitstr)
3305 {
3306  struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3307 
3308  unit_data->passenger =
3309  secfile_lookup_int_default(file, 0, "%s.%spassenger", unitstr, aitstr);
3310  unit_data->ferryboat =
3311  secfile_lookup_int_default(file, 0, "%s.%sferryboat", unitstr, aitstr);
3312  unit_data->charge =
3313  secfile_lookup_int_default(file, 0, "%s.%scharge", unitstr, aitstr);
3314  unit_data->bodyguard =
3315  secfile_lookup_int_default(file, 0, "%s.%sbodyguard", unitstr, aitstr);
3316 }
3317 
3319  enum terrain_class tc;
3320  struct city *build_city;
3321 };
3322 
3326 static bool role_unit_cb(struct unit_type *ptype, void *data)
3327 {
3328  struct role_unit_cb_data *cb_data =
3329  static_cast<struct role_unit_cb_data *>(data);
3330  struct unit_class *pclass = utype_class(ptype);
3331 
3332  if ((cb_data->tc == TC_LAND && pclass->adv.land_move == MOVE_NONE)
3333  || (cb_data->tc == TC_OCEAN && pclass->adv.sea_move == MOVE_NONE)) {
3334  return false;
3335  }
3336 
3337  return cb_data->build_city == nullptr
3338  || can_city_build_unit_now(cb_data->build_city, ptype);
3339 }
3340 
3345  int role,
3346  enum terrain_class tc)
3347 {
3348  struct role_unit_cb_data cb_data = {.tc = tc, .build_city = pcity};
3349 
3350  return role_units_iterate_backwards(role, role_unit_cb, &cb_data);
3351 }
3352 
3356 bool dai_unit_can_strike_my_unit(const struct unit *attacker,
3357  const struct unit *defender)
3358 {
3359  struct pf_parameter parameter;
3360  struct pf_map *pfm;
3361  const struct tile *ptarget = unit_tile(defender);
3362  int max_move_cost = attacker->moves_left;
3363  bool able_to_strike = false;
3364 
3365  pft_fill_unit_parameter(&parameter, attacker);
3366  parameter.omniscience = !has_handicap(unit_owner(defender), H_MAP);
3367  pfm = pf_map_new(&parameter);
3368 
3369  pf_map_move_costs_iterate(pfm, ptile, move_cost, false)
3370  {
3371  if (move_cost > max_move_cost) {
3372  break;
3373  }
3374 
3375  if (ptile == ptarget) {
3376  able_to_strike = true;
3377  break;
3378  }
3379  }
3381 
3382  pf_map_destroy(pfm);
3383 
3384  return able_to_strike;
3385 }
3386 
3390 void dai_switch_to_explore(struct ai_type *ait, struct unit *punit,
3391  struct tile *target, enum override_bool *allow)
3392 {
3393  struct unit_ai *udata = def_ai_unit_data(punit, ait);
3394 
3395  if (udata->task != AIUNIT_NONE && udata->task != AIUNIT_EXPLORE) {
3396  *allow = OVERRIDE_FALSE;
3397 
3398  return;
3399  }
3400 }
bool is_action_enabled_unit_on_city(const action_id wanted_action, const struct unit *actor_unit, const struct city *target_city)
Returns TRUE if actor_unit can do wanted_action to target_city as far as action enablers are concerne...
Definition: actions.cpp:3948
#define TRADE_WEIGHTING
Definition: advbuilding.h:18
#define SHIELD_WEIGHTING
Definition: advbuilding.h:17
int adv_unit_def_rating_basic_squared(const struct unit *punit)
Square of the previous function - used in actual computations.
Definition: advgoto.cpp:307
int adv_unit_def_rating_basic(const struct unit *punit)
Basic (i.e.
Definition: advgoto.cpp:298
bool adv_unit_execute_path(struct unit *punit, const PFPath &path)
This is a function to execute paths returned by the path-finding engine, for units controlled by advi...
Definition: advgoto.cpp:78
int adv_unittype_att_rating(const struct unit_type *punittype, int veteran, int moves_left, int hp)
Attack rating of this kind of unit.
Definition: advgoto.cpp:277
int adv_unit_att_rating(const struct unit *punit)
Attack rating of this particular unit assuming that it has a complete move left.
Definition: advgoto.cpp:288
bool adv_follow_path(struct unit *punit, const PFPath &path, struct tile *ptile)
Move a unit along a path without disturbing its activity, role or assigned destination Return FALSE i...
Definition: advgoto.cpp:43
int adv_could_unit_move_to_tile(struct unit *punit, struct tile *dest_tile)
returns: 0 if can't move 1 if zoc_ok -1 if zoc could be ok?
Definition: advgoto.cpp:252
#define POWER_DIVIDER
Definition: advtools.h:25
void dai_manage_airunit(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Trying to manage bombers and stuff.
Definition: aiair.cpp:334
void dai_manage_diplomat(struct ai_type *ait, struct player *pplayer, struct unit *punit)
If we are the only diplomat in a threatened city, defend against enemy actions.
Definition: aidiplomat.cpp:696
bool aiferry_gobyboat(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct tile *dest_tile, bool with_bodyguard)
This function is to be called if punit needs to use a boat to get to the destination.
Definition: aiferry.cpp:759
int aiferry_find_boat(struct ai_type *ait, struct unit *punit, int cap, PFPath *path)
Proper and real PF function for finding a boat.
Definition: aiferry.cpp:490
void dai_manage_ferryboat(struct ai_type *ait, struct player *pplayer, struct unit *punit)
It's about 12 feet square and has a capacity of almost 1000 pounds.
Definition: aiferry.cpp:1080
bool is_boat_free(struct ai_type *ait, struct unit *boat, struct unit *punit, int cap)
Runs a few checks to determine if "boat" is a free boat that can carry "cap" units of the same type a...
Definition: aiferry.cpp:438
bool aiferry_goto_amphibious(struct ai_type *ait, struct unit *ferry, struct unit *passenger, struct tile *ptile)
Move a passenger on a ferry to a specified destination.
Definition: aiferry.cpp:724
bool is_boss_of_boat(struct ai_type *ait, struct unit *punit)
Check if unit is boss in ferry.
Definition: aiferry.cpp:470
int aiferry_avail_boats(struct ai_type *ait, struct player *pplayer)
Returns the number of available boats.
Definition: aiferry.cpp:351
bool dai_is_ferry(struct unit *pferry, struct ai_type *ait)
Should unit be considered a ferry?
Definition: aiferry.cpp:157
void aiferry_clear_boat(struct ai_type *ait, struct unit *punit)
Use on a unit which no longer needs a boat.
Definition: aiferry.cpp:248
struct unit * aiguard_charge_unit(struct ai_type *ait, struct unit *guard)
Which unit (if any) has a guard been assigned to? Returns nullptr if the unit is not the guard for a ...
Definition: aiguard.cpp:270
void aiguard_clear_charge(struct ai_type *ait, struct unit *guard)
Remove the assignment of a charge to a guard.
Definition: aiguard.cpp:109
void aiguard_request_guard(struct ai_type *ait, struct unit *punit)
Request a (new) bodyguard for the unit.
Definition: aiguard.cpp:218
bool aiguard_has_guard(struct ai_type *ait, struct unit *charge)
Has a guard been assigned to a charge?
Definition: aiguard.cpp:250
void aiguard_assign_guard_unit(struct ai_type *ait, struct unit *charge, struct unit *guard)
Assign a bodyguard to a unit.
Definition: aiguard.cpp:165
bool aiguard_wanted(struct ai_type *ait, struct unit *charge)
Has a unit requested a guard and not (yet) been provided with one?
Definition: aiguard.cpp:232
void aiguard_assign_guard_city(struct ai_type *ait, struct city *charge, struct unit *guard)
Assign a guard to a city.
Definition: aiguard.cpp:188
struct city * aiguard_charge_city(struct ai_type *ait, struct unit *guard)
Which city (if any) has a guard been assigned to? Returns nullptr if the unit is not a guard for a ci...
Definition: aiguard.cpp:280
void aiguard_clear_guard(struct ai_type *ait, struct unit *charge)
Remove assignment of bodyguard for a unit.
Definition: aiguard.cpp:138
struct unit * aiguard_guard_of(struct ai_type *ait, struct unit *charge)
Which unit, if any, is the body guard of a unit? Returns nullptr if the unit has not been assigned a ...
Definition: aiguard.cpp:260
bool aiguard_has_charge(struct ai_type *ait, struct unit *guard)
Has a charge unit been assigned to a guard?
Definition: aiguard.cpp:241
void aiguard_update_charge(struct ai_type *ait, struct unit *guard)
Check whether the assignment of a guard is still sane, and fix and problems.
Definition: aiguard.cpp:291
#define CHECK_GUARD(ait, guard)
Definition: aiguard.h:16
bool dai_hunter_qualify(struct player *pplayer, struct unit *punit)
Does this unit qualify as a hunter?
Definition: aihunt.cpp:297
int dai_hunter_manage(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Manage a (possibly virtual) hunter.
Definition: aihunt.cpp:445
#define BODYGUARD_LOG(ait, loglevel, punit, msg,...)
Definition: ailog.h:65
void dai_manage_paratrooper(struct ai_type *ait, struct player *pplayer, struct unit *punit)
This function does manage the paratrooper units of the AI.
static struct ai_city * def_ai_city_data(const struct city *pcity, struct ai_type *deftype)
Definition: aiplayer.h:35
static struct unit_ai * def_ai_unit_data(const struct unit *punit, struct ai_type *deftype)
Definition: aiplayer.h:41
int stack_cost(struct unit *pattacker, struct unit *pdefender)
Calculate the value of the target unit including the other units which will die in a successful attac...
Definition: aitools.cpp:1072
bool goto_is_sane(struct unit *punit, struct tile *ptile)
Use pathfinding to determine whether a GOTO is possible, considering all aspects of the unit being mo...
Definition: aitools.cpp:436
bool dai_assess_military_unhappiness(struct city *pcity)
"The following evaluates the unhappiness caused by military units in the field (or aggressive) at a c...
Definition: aitools.cpp:1203
bool dai_unit_attack(struct ai_type *ait, struct unit *punit, struct tile *ptile)
Move and attack with an ai unit.
Definition: aitools.cpp:825
const char * dai_unit_task_rule_name(const enum ai_unit_task task)
Return the (untranslated) rule name of the ai_unit_task.
Definition: aitools.cpp:70
bool dai_unit_goto(struct ai_type *ait, struct unit *punit, struct tile *ptile)
Go to specified destination but do not disturb existing role or activity and do not clear the role's ...
Definition: aitools.cpp:609
void dai_unit_new_task(struct ai_type *ait, struct unit *punit, enum ai_unit_task task, struct tile *ptile)
Ensure unit sanity by telling charge that we won't bodyguard it anymore, tell bodyguard it can roam f...
Definition: aitools.cpp:648
bool dai_unit_make_homecity(struct unit *punit, struct city *pcity)
Try to make pcity our new homecity.
Definition: aitools.cpp:763
int military_amortize(struct player *pplayer, struct city *pcity, int value, int delay, int build_cost)
Amortize a want modified by the shields (build_cost) we risk losing.
Definition: aitools.cpp:132
bool dai_gothere(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct tile *dest_tile)
This is ferry-enabled goto.
Definition: aitools.cpp:258
int look_for_charge(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct unit **aunit, struct city **acity)
See if we can find something to defend.
Definition: aiunit.cpp:707
void dai_unit_save(struct ai_type *ait, const char *aitstr, struct section_file *file, const struct unit *punit, const char *unitstr)
Save AI data of a unit.
Definition: aiunit.cpp:3283
static bool has_defense(struct city *pcity)
This is a much simplified form of assess_defense (see daimilitary.c), but which doesn't use pcity->se...
Definition: aiunit.cpp:211
void dai_manage_military(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Decide what to do with a military unit.
Definition: aiunit.cpp:2399
static bool search_homecity_for_caravan(struct ai_type *ait, struct unit *punit)
Try to move caravan to suitable city and to make it caravan's homecity.
Definition: aiunit.cpp:2138
int find_something_to_kill(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct tile **pdest_tile, PFPath *ppath, struct pf_map **pferrymap, struct unit **pferryboat, const struct unit_type **pboattype, int *pmove_time)
Find something to kill! This function is called for units to find targets to destroy and for cities t...
Definition: aiunit.cpp:1118
static void dai_caravan_goto(struct ai_type *ait, struct player *pplayer, struct unit *punit, const struct city *dest_city, bool help_wonder, bool required_boat, bool request_boat)
Send the caravan to the specified city, or make it help the wonder / trade, if it's already there.
Definition: aiunit.cpp:1923
int unittype_def_rating_squared(const struct unit_type *att_type, const struct unit_type *def_type, struct player *def_player, struct tile *ptile, bool fortified, int veteran)
Defence rating of def_type unit against att_type unit, squared.
Definition: aiunit.cpp:296
static bool unit_role_defender(const struct unit_type *punittype)
Does the unit with the id given have the flag L_DEFEND_GOOD?
Definition: aiunit.cpp:692
void dai_units_ruleset_init(struct ai_type *ait)
Initialise the unit data from the ruleset for the AI.
Definition: aiunit.cpp:3101
struct city * find_nearest_safe_city(struct unit *punit)
Find safe city to recover in.
Definition: aiunit.cpp:1620
#define LOG_CARAVAN
Definition: aiunit.cpp:72
static int unit_att_rating_now(const struct unit *punit)
Attack rating of this particular unit right now.
Definition: aiunit.cpp:250
static void dai_military_attack_barbarian(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Go berserk, assuming there are no targets nearby.
Definition: aiunit.cpp:1672
static void invasion_funct(struct ai_type *ait, struct unit *punit, bool dest, int radius, int which)
Mark invasion possibilities of punit in the surrounding cities.
Definition: aiunit.cpp:997
void dai_switch_to_explore(struct ai_type *ait, struct unit *punit, struct tile *target, enum override_bool *allow)
Switch to autoexploring.
Definition: aiunit.cpp:3390
static int unit_def_rating_squared(const struct unit *punit, const struct unit *pdef)
Square of the previous function - used in actual computations.
Definition: aiunit.cpp:283
static bool dai_find_boat_for_unit(struct ai_type *ait, struct unit *punit)
Request a boat for a unit to transport it to another continent.
Definition: aiunit.cpp:1884
const struct impr_type * utype_needs_improvement(const struct unit_type *putype, const struct city *pcity)
Returns an improvement that will make it possible to build units of the specified type the specified ...
Definition: aiunit.cpp:2802
static void reinforcements_cost_and_value(struct unit *punit, struct tile *ptile0, int *value, int *cost)
Calculates the value and cost of nearby allied units to see if we can expect any help in our attack.
Definition: aiunit.cpp:368
struct unit_type * simple_ai_types[U_LAST]
Definition: aiunit.cpp:112
static void dai_airlift(struct ai_type *ait, struct player *pplayer)
Move defenders around with airports.
Definition: aiunit.cpp:157
int build_cost_balanced(const struct unit_type *punittype)
In the words of Syela: "Using funky fprime variable instead of f in the denom, so that def=1 units ar...
Definition: aiunit.cpp:240
bool dai_unit_can_strike_my_unit(const struct unit *attacker, const struct unit *defender)
Returns whether 'attacker' can attack 'defender' immediately.
Definition: aiunit.cpp:3356
static void dai_military_bodyguard(struct ai_type *ait, struct player *pplayer, struct unit *punit)
If we are not covering our charge's ass, go do it now.
Definition: aiunit.cpp:622
#define LOG_CARAVAN3
Definition: aiunit.cpp:74
void dai_manage_units(struct ai_type *ait, struct player *pplayer)
Master manage unit function.
Definition: aiunit.cpp:2761
static void dai_manage_caravan(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Use caravans for building wonders, or send caravans to establish trade with a city,...
Definition: aiunit.cpp:2178
static void dai_set_defenders(struct ai_type *ait, struct player *pplayer)
Master city defense function.
Definition: aiunit.cpp:2660
void dai_manage_unit(struct ai_type *ait, struct player *pplayer, struct unit *punit)
manage one unit Careful: punit may have been destroyed upon return from this routine!
Definition: aiunit.cpp:2551
struct unit_type * dai_role_utype_for_terrain_class(struct city *pcity, int role, enum terrain_class tc)
Get unit type player can build, suitable to role, with given move type.
Definition: aiunit.cpp:3344
static bool role_unit_cb(struct unit_type *ptype, void *data)
Filter callback for role unit iteration.
Definition: aiunit.cpp:3326
static void dai_military_attack(struct ai_type *ait, struct player *pplayer, struct unit *punit)
This does the attack until we have used up all our movement, unless we should safeguard a city.
Definition: aiunit.cpp:1738
void dai_unit_turn_end(struct ai_type *ait, struct unit *punit)
Free unit from use with default AI.
Definition: aiunit.cpp:3252
static void dai_manage_settler(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Manages settlers.
Definition: aiunit.cpp:2530
static int avg_benefit(int benefit, int loss, double chance)
Compute how much we want to kill certain victim we've chosen, counted in SHIELDs.
Definition: aiunit.cpp:358
#define LOG_CARAVAN2
Definition: aiunit.cpp:73
static int unit_def_rating(const struct unit *attacker, const struct unit *defender)
Defence rating of this particular unit against this attacker.
Definition: aiunit.cpp:270
static bool dai_is_unit_tired_waiting_boat(struct ai_type *ait, struct unit *punit)
Evaluate if a unit is tired of waiting for a boat at home continent.
Definition: aiunit.cpp:2039
static int dai_rampage_want(struct unit *punit, struct tile *ptile)
This function appraises the location (x, y) for a quick hit-n-run operation.
Definition: aiunit.cpp:452
bool dai_can_unit_type_follow_unit_type(const struct unit_type *follower, const struct unit_type *followee, struct ai_type *ait)
See if the follower can follow the followee.
Definition: aiunit.cpp:834
static void dai_manage_barbarian_leader(struct ai_type *ait, struct player *pplayer, struct unit *leader)
Barbarian leader tries to stack with other barbarian units, and if it's not possible it runs away.
Definition: aiunit.cpp:2835
static struct city * find_neediest_airlift_city(struct ai_type *ait, const struct player *pplayer)
Returns the city with the most need of an airlift.
Definition: aiunit.cpp:124
static void dai_manage_hitpoint_recovery(struct ai_type *ait, struct unit *punit)
This function goes wait a unit in a city for the hitpoints to recover.
Definition: aiunit.cpp:2338
static int unit_att_rating_squared(const struct unit *punit)
Square of the adv_unit_att_rating() function - used in actual computations.
Definition: aiunit.cpp:260
static bool is_my_turn(struct unit *punit, struct unit *pdef)
Is there another unit which really should be doing this attack? Checks all adjacent tiles and the til...
Definition: aiunit.cpp:397
void dai_unit_init(struct ai_type *ait, struct unit *punit)
Initialize unit for use with default AI.
Definition: aiunit.cpp:3229
void dai_consider_tile_dangerous(struct ai_type *ait, struct tile *ptile, struct unit *punit, enum override_bool *result)
Are there dangerous enemies at or adjacent to the tile 'ptile'?
Definition: aiunit.cpp:3017
static void dai_military_findjob(struct ai_type *ait, struct player *pplayer, struct unit *punit)
See if we have a specific job for the unit.
Definition: aiunit.cpp:855
static void update_simple_ai_types()
Updates the global array simple_ai_types.
Definition: aiunit.cpp:3075
void dai_unit_load(struct ai_type *ait, const char *aitstr, const struct section_file *file, struct unit *punit, const char *unitstr)
Load AI data of a unit.
Definition: aiunit.cpp:3302
static void caravan_optimize_callback(const struct caravan_result *result, void *data)
For debugging, print out information about every city we come to when optimizing the caravan.
Definition: aiunit.cpp:2023
#define LOGLEVEL_RECOVERY
Definition: aiunit.cpp:71
void dai_unit_close(struct ai_type *ait, struct unit *punit)
Free unit from use with default AI.
Definition: aiunit.cpp:3264
void dai_units_ruleset_close(struct ai_type *ait)
Close AI unit type data.
Definition: aiunit.cpp:3208
bool find_beachhead(const struct player *pplayer, struct pf_map *ferry_map, struct tile *dest_tile, const struct unit_type *cargo_type, struct tile **ferry_dest, struct tile **beachhead_tile)
Returns TRUE if a beachhead as been found to reach 'dest_tile'.
Definition: aiunit.cpp:1037
static void dai_military_defend(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Send a unit to the city it should defend.
Definition: aiunit.cpp:944
int kill_desire(int benefit, int attack, int loss, int vuln, int victim_count)
Compute how much we want to kill certain victim we've chosen, counted in SHIELDs.
Definition: aiunit.cpp:334
static PFPath find_rampage_target(struct unit *punit, int thresh_adj, int thresh_move)
Look for worthy targets within a one-turn horizon.
Definition: aiunit.cpp:512
bool dai_military_rampage(struct unit *punit, int thresh_adj, int thresh_move)
Find and kill anything reachable within this turn and worth more than the relevant of the given thres...
Definition: aiunit.cpp:592
static bool dai_caravan_can_trade_cities_diff_cont(struct player *pplayer, struct unit *punit)
Check if a caravan can make a trade route to a city on a different continent.
Definition: aiunit.cpp:2091
#define POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer)
Definition: aiunit.h:77
@ AIUNIT_BUILD_CITY
Definition: aiunit.h:28
@ AIUNIT_NONE
Definition: aiunit.h:26
@ AIUNIT_ATTACK
Definition: aiunit.h:30
@ AIUNIT_EXPLORE
Definition: aiunit.h:32
@ AIUNIT_HUNTER
Definition: aiunit.h:34
@ AIUNIT_RECOVER
Definition: aiunit.h:33
@ AIUNIT_TRADE
Definition: aiunit.h:35
@ AIUNIT_DEFEND_HOME
Definition: aiunit.h:29
@ AIUNIT_ESCORT
Definition: aiunit.h:31
@ AIUNIT_AUTO_SETTLER
Definition: aiunit.h:27
@ AIUNIT_WONDER
Definition: aiunit.h:36
#define RAMPAGE_ANYTHING
Definition: aiunit.h:90
#define RAMPAGE_FREE_CITY_OR_BETTER
Definition: aiunit.h:92
#define INVASION_ATTACK
Definition: aiunit.h:86
#define INVASION_OCCUPY
Definition: aiunit.h:85
#define RAMPAGE_HUT_OR_BETTER
Definition: aiunit.h:91
#define DEFENSE_POWER(ptype)
Definition: aiunit.h:71
#define IS_ATTACKER(ptype)
Definition: aiunit.h:75
#define BODYGUARD_RAMPAGE_THRESHOLD
Definition: aiunit.h:93
#define ATTACK_POWER(ptype)
Definition: aiunit.h:73
enum unit_move_result manage_auto_explorer(struct unit *punit)
Handle eXplore mode of a unit (explorers are always in eXplore mode for AI) - explores unknown territ...
void adv_unit_new_task(struct unit *punit, enum adv_unit_task task, struct tile *ptile)
Change unit's advisor task.
bool is_land_barbarian(struct player *pplayer)
Is player a land barbarian?
Definition: barbarian.cpp:60
#define BV_CLR_ALL(bv)
Definition: bitvector.h:62
void caravan_find_best_destination(const struct unit *caravan, const struct caravan_parameter *parameter, struct caravan_result *result, bool omniscient)
Find the best destination city for the caravan.
Definition: caravan.cpp:568
void caravan_parameter_init_from_unit(struct caravan_parameter *parameter, const struct unit *caravan)
Create a valid parameter with default values based on the caravan.
Definition: caravan.cpp:46
@ FTL_ALLIED
Definition: caravan.h:17
@ FTL_NATIONAL_ONLY
Definition: caravan.h:16
@ FTL_NONWAR
Definition: caravan.h:19
bool city_production_gets_caravan_shields(const struct universal *tgt)
Returns TRUE iff the specified production should get shields from units that has done ACTION_HELP_WON...
Definition: city.cpp:1752
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
Definition: city.cpp:1083
struct tile * city_tile(const struct city *pcity)
Return the tile location of the city.
Definition: city.cpp:1095
int city_production_unit_veteran_level(struct city *pcity, const struct unit_type *punittype)
How many veteran levels will created unit of this type get?
Definition: city.cpp:768
const char * city_name_get(const struct city *pcity)
Return the name of the city.
Definition: city.cpp:1077
bool can_city_build_unit_now(const struct city *pcity, const struct unit_type *punittype)
Return whether given city can build given unit; returns FALSE if unit is obsolete.
Definition: city.cpp:894
#define city_list_iterate(citylist, pcity)
Definition: city.h:482
@ CITIZEN_ANGRY
Definition: city.h:243
@ CITIZEN_UNHAPPY
Definition: city.h:242
#define city_list_iterate_end
Definition: city.h:484
@ FEELING_NATIONALITY
Definition: city.h:254
struct city * find_closest_city(const struct tile *ptile, const struct city *pexclcity, const struct player *pplayer, bool only_ocean, bool only_continent, bool only_known, bool only_player, bool only_enemy, const struct unit_class *pclass)
Find the city closest to 'ptile'.
Definition: citytools.cpp:849
bool empty() const
struct unit * get_defender(const struct unit *attacker, const struct tile *ptile)
Finds the best defender on the tile, given an attacker.
Definition: combat.cpp:721
enum unit_attack_result unit_attack_unit_at_tile_result(const struct unit *punit, const struct unit *pdefender, const struct tile *dest_tile)
Checks if a unit can physically attack pdefender at the tile (assuming it is adjacent and at war).
Definition: combat.cpp:121
enum unit_attack_result unit_attack_units_at_tile_result(const struct unit *punit, const struct tile *ptile)
Check if unit can attack unit stack at tile.
Definition: combat.cpp:237
bool is_stack_vulnerable(const struct tile *ptile)
Is it a city/fortress/air base or will the whole stack die in an attack.
Definition: combat.cpp:839
int get_total_defense_power(const struct unit *attacker, const struct unit *defender)
return the modified defense power of a unit.
Definition: combat.cpp:654
int get_virtual_defense_power(const struct unit_type *att_type, const struct unit_type *def_type, struct player *def_player, struct tile *ptile, bool fortified, int veteran)
May be called with a non-existing att_type to avoid any effects which depend on the attacker.
Definition: combat.cpp:601
int base_get_defense_power(const struct unit *punit)
Returns the defense power, modified by veteran status.
Definition: combat.cpp:487
double unit_win_chance(const struct unit *attacker, const struct unit *defender)
Returns a double in the range [0;1] indicating the attackers chance of winning.
Definition: combat.cpp:408
bool can_unit_attack_tile(const struct unit *punit, const struct tile *dest_tile)
Is unit (1) diplomatically allowed to attack and (2) physically able to do so?
Definition: combat.cpp:251
@ ATT_OK
Definition: combat.h:26
bool dai_can_requirement_be_met_in_city(const struct requirement *preq, const struct player *pplayer, const struct city *pcity)
Does the AI expect to ever be able to meet this requirement.
Definition: daieffects.cpp:723
struct unit_type * dai_choose_defender_versus(struct city *pcity, struct unit *attacker)
Choose the best unit the city can build to defend against attacker v.
Definition: daimilitary.cpp:72
int assess_defense_quadratic(struct ai_type *ait, struct city *pcity)
Need positive feedback in m_a_c_b and bodyguard routines.
int assess_defense_unit(struct ai_type *ait, struct city *pcity, struct unit *punit, bool igwall)
One unit only, mostly for findjob; handling boats correctly.
static void attack(QVariant data1, QVariant data2)
Action "Attack" for choice dialog.
Definition: dialogs.cpp:2464
bool ai_fuzzy(const struct player *pplayer, bool normal_decision)
Return the value normal_decision (a boolean), except if the AI is fuzzy, then sometimes flip the valu...
Definition: difficulty.cpp:318
int get_unittype_bonus(const struct player *pplayer, const struct tile *ptile, const struct unit_type *punittype, enum effect_type effect_type, enum vision_layer vision_layer)
Returns the effect bonus that applies at a tile for a given unittype.
Definition: effects.cpp:841
int get_city_bonus(const struct city *pcity, enum effect_type effect_type, enum vision_layer vlayer)
Returns the effect bonus at a city.
Definition: effects.cpp:688
bool unit_can_enter_hut(const struct unit *punit, const struct tile *ptile)
Returns TRUE iff the unit can enter any hut on the tile.
Definition: extras.cpp:643
@ RPT_CERTAIN
Definition: fc_types.h:568
@ AUT_AUTO_SETTLER
Definition: fc_types.h:287
@ O_LUXURY
Definition: fc_types.h:89
signed short Continent_id
Definition: fc_types.h:289
override_bool
Definition: fc_types.h:78
@ OVERRIDE_TRUE
Definition: fc_types.h:78
@ OVERRIDE_FALSE
Definition: fc_types.h:78
struct unit * game_unit_by_number(int id)
Find unit out of all units in game: now uses fast idex method, instead of looking through all units o...
Definition: game.cpp:112
struct civ_game game
Definition: game.cpp:47
struct world wld
Definition: game.cpp:48
struct city * game_city_by_number(int id)
Often used function to get a city pointer from a city ID.
Definition: game.cpp:103
bool has_handicap(const struct player *pplayer, enum handicap_type htype)
AI players may have handicaps - allowing them to cheat or preventing them from using certain algorith...
Definition: handicaps.cpp:62
@ H_MAP
Definition: handicaps.h:27
@ H_TARGETS
Definition: handicaps.h:23
@ H_AWAY
Definition: handicaps.h:18
@ H_FOG
Definition: handicaps.h:25
constexpr auto LOG_DEBUG
Definition: log.h:27
#define fc_assert_ret(condition)
Definition: log.h:112
constexpr auto LOG_VERBOSE
Definition: log.h:26
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_ret_msg(condition, message,...)
Definition: log.h:129
constexpr auto LOG_NORMAL
Definition: log.h:25
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
#define log_base(level, message,...)
Definition: log.h:41
bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
Are two tiles adjacent to each other.
Definition: map.cpp:878
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Are (x1,y1) and (x2,y2) really the same when adjusted? This function might be necessary ALOT of place...
Definition: map.cpp:887
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Return real distance between two tiles.
Definition: map.cpp:599
int map_distance(const struct tile *tile0, const struct tile *tile1)
Return Manhattan distance between two tiles.
Definition: map.cpp:623
#define adjc_iterate_end
Definition: map.h:358
static int index_to_map_pos_y(int mindex)
Definition: map.h:616
#define square_iterate(nmap, center_tile, radius, tile_itr)
Definition: map.h:312
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition: map.h:351
#define square_iterate_end
Definition: map.h:315
static int index_to_map_pos_x(int mindex)
Definition: map.h:607
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Return whether the player knows the tile.
Definition: maphand.cpp:884
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Returns whether the layer 'vlayer' of the tile 'ptile' is known and seen by the player 'pplayer'.
Definition: maphand.cpp:894
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Return TRUE iff the unit can "exist" at this location.
Definition: movement.cpp:267
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
This tile is native to unit.
Definition: movement.cpp:279
int unit_move_rate(const struct unit *punit)
This function calculates the move rate of the unit.
Definition: movement.cpp:78
bool can_attack_from_non_native(const struct unit_type *utype)
This unit can attack from non-native tiles (Marines can attack from transport, ships from harbour cit...
Definition: movement.cpp:177
bool can_unit_survive_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Return TRUE iff the unit can "survive" at this location.
Definition: movement.cpp:452
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Return TRUE iff transporter type has ability to transport transported class.
Definition: movement.cpp:698
bool can_attack_non_native(const struct unit_type *utype)
This unit can attack non-native tiles (eg.
Definition: movement.cpp:164
#define SINGLE_MOVE
Definition: movement.h:17
static bool is_native_tile_to_class(const struct unit_class *punitclass, const struct tile *ptile)
Definition: movement.h:73
@ MR_OK
Definition: movement.h:26
@ MR_DEATH
Definition: movement.h:27
const char * nation_rule_name(const struct nation_type *pnation)
Return the (untranslated) rule name of the nation (adjective form).
Definition: nation.cpp:115
struct nation_type * nation_of_unit(const struct unit *punit)
Return the nation of the player who owns the unit.
Definition: nation.cpp:438
bool pf_map_position(struct pf_map *pfm, struct tile *ptile, struct pf_position *pos)
Get info about position at ptile and put it in pos.
struct pf_map * pf_map_new(const struct pf_parameter *parameter)
Factory function to create a new map according to the parameter.
struct pf_reverse_map * pf_reverse_map_new(const struct player *pplayer, struct tile *target_tile, int max_turns, bool omniscient, const struct civ_map *map)
'pf_reverse_map' constructor.
PFPath pf_map_path(struct pf_map *pfm, struct tile *ptile)
CHECK DOCS AFTER FULL CONVERSTION OF pf_path to class PFPath Tries to find the best path in the given...
void pf_reverse_map_destroy(struct pf_reverse_map *pfrm)
'pf_reverse_map' destructor.
int pf_reverse_map_unit_move_cost(struct pf_reverse_map *pfrm, const struct unit *punit)
Get the move costs that a unit needs to reach the start tile.
void pf_map_destroy(struct pf_map *pfm)
After usage the map must be destroyed.
int pf_map_move_cost(struct pf_map *pfm, struct tile *ptile)
Tries to find the minimal move cost to reach ptile.
#define PF_IMPOSSIBLE_MC
Definition: path_finding.h:244
#define pf_map_move_costs_iterate_end
Definition: path_finding.h:542
#define pf_map_move_costs_iterate(ARG_pfm, NAME_tile, NAME_cost, COND_from_start)
Definition: path_finding.h:532
#define pf_map_tiles_iterate(ARG_pfm, NAME_tile, COND_from_start)
Definition: path_finding.h:509
#define pf_map_tiles_iterate_end
Definition: path_finding.h:516
void pft_fill_utype_overlap_param(struct pf_parameter *parameter, const struct unit_type *punittype, struct tile *pstart_tile, struct player *pplayer)
Switch on one tile overlapping into the non-native terrain.
Definition: pf_tools.cpp:857
void pft_fill_unit_overlap_param(struct pf_parameter *parameter, const struct unit *punit)
Switch on one tile overlapping into the non-native terrain.
Definition: pf_tools.cpp:871
void pft_fill_unit_parameter(struct pf_parameter *parameter, const struct unit *punit)
Fill classic parameters for an unit.
Definition: pf_tools.cpp:822
void pft_fill_unit_attack_param(struct pf_parameter *parameter, const struct unit *punit)
pft_fill_*_attack_param() base function.
Definition: pf_tools.cpp:913
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
If the specified player owns the unit with the specified id, return pointer to the unit struct.
Definition: player.cpp:1139
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Returns true iff players can attack each other.
Definition: player.cpp:1317
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Returns true iff players are allied.
Definition: player.cpp:1334
#define players_iterate_end
Definition: player.h:520
#define players_iterate(_pplayer)
Definition: player.h:514
static bool is_barbarian(const struct player *pplayer)
Definition: player.h:474
#define is_human(plr)
Definition: player.h:226
#define fc_rand(_size)
Definition: rand.h:16
int secfile_lookup_int_default(const struct section_file *secfile, int def, const char *path,...)
Lookup a integer value in the secfile.
#define secfile_insert_int(secfile, value, path,...)
Definition: registry_ini.h:116
bool is_req_active(const struct player *target_player, const struct player *other_player, const struct city *target_city, const struct impr_type *target_building, const struct tile *target_tile, const struct unit *target_unit, const struct unit_type *target_unittype, const struct output_type *target_output, const struct specialist *target_specialist, const struct action *target_action, const struct requirement *req, const enum req_problem_type prob_type, const enum vision_layer vision_layer, const enum national_intelligence nintel)
Checks the requirement to see if it is active on the given target.
#define requirement_vector_iterate_end
Definition: requirements.h:80
#define requirement_vector_iterate(req_vec, preq)
Definition: requirements.h:78
struct setting_list * level[OLEVELS_NUM]
Definition: settings.cpp:167
#define FC_INFINITY
Definition: shared.h:32
#define MAX(x, y)
Definition: shared.h:48
int get_specialist_output(const struct city *pcity, Specialist_type_id sp, Output_type_id otype)
Return the output for the specialist type with this output type.
Definition: specialist.cpp:218
#define specialist_type_iterate_end
Definition: specialist.h:73
#define specialist_type_iterate(sp)
Definition: specialist.h:67
#define LOGLEVEL_HUNT
Definition: srv_log.h:37
@ AIT_RECOVER
Definition: srv_log.h:70
@ AIT_FSTK
Definition: srv_log.h:56
@ AIT_CARAVAN
Definition: srv_log.h:58
@ AIT_RAMPAGE
Definition: srv_log.h:73
@ AIT_ATTACK
Definition: srv_log.h:68
@ AIT_HUNTER
Definition: srv_log.h:59
@ AIT_BODYGUARD
Definition: srv_log.h:71
@ AIT_DEFENDERS
Definition: srv_log.h:57
@ AIT_AIRUNIT
Definition: srv_log.h:62
@ AIT_FERRY
Definition: srv_log.h:72
@ AIT_MILITARY
Definition: srv_log.h:69
@ AIT_DIPLOMAT
Definition: srv_log.h:61
@ AIT_AIRLIFT
Definition: srv_log.h:60
#define UNIT_LOG(_, punit, msg,...)
Definition: srv_log.h:95
@ TIMER_STOP
Definition: srv_log.h:77
@ TIMER_START
Definition: srv_log.h:77
#define CITY_LOG(_, pcity, msg,...)
Definition: srv_log.h:80
#define TIMING_LOG(timer, activity)
Definition: srv_log.h:121
#define LOGLEVEL_BODYGUARD
Definition: srv_log.h:32
int urgency
Definition: daicity.h:46
int danger
Definition: daicity.h:44
int bcost
Definition: daicity.h:41
adv_want worth
Definition: daicity.h:32
int grave_danger
Definition: daicity.h:45
int attack
Definition: daicity.h:41
struct ai_invasion invasion
Definition: daicity.h:40
int attack
Definition: daicity.h:27
int occupy
Definition: daicity.h:28
Definition: ai.h:42
void(* callback)(const struct caravan_result *result, void *data)
Definition: caravan.h:108
enum foreign_trade_limit allow_foreign_trade
Definition: caravan.h:83
bool ignore_transit_time
Definition: caravan.h:92
void * callback_data
Definition: caravan.h:109
An advisor for using caravans optimally.
Definition: caravan.h:36
const struct city * src
Definition: caravan.h:37
const struct city * dest
Definition: caravan.h:38
bool help_wonder
Definition: caravan.h:42
double value
Definition: caravan.h:41
Definition: city.h:291
int id
Definition: city.h:296
struct player * owner
Definition: city.h:294
struct universal production
Definition: city.h:368
struct tile * tile
Definition: city.h:293
struct civ_game::@28::@32 server
struct packet_game_info info
Definition: game.h:80
Definition: player.h:231
struct city_list * cities
Definition: player.h:263
struct unit_list * units
Definition: player.h:264
bool is_alive
Definition: player.h:250
enum terrain_class tc
Definition: aiunit.cpp:3319
struct city * build_city
Definition: aiunit.cpp:3320
Definition: tile.h:42
struct unit_list * units
Definition: tile.h:50
Continent_id continent
Definition: tile.h:46
Definition: aiunit.h:39
struct tile ** prev_pos
Definition: aiunit.h:47
int bodyguard
Definition: aiunit.h:43
bv_player hunted
Definition: aiunit.h:50
bool done
Definition: aiunit.h:51
int ferryboat
Definition: aiunit.h:41
enum ai_unit_task task
Definition: aiunit.h:53
struct tile ** cur_pos
Definition: aiunit.h:47
int passenger
Definition: aiunit.h:42
int charge
Definition: aiunit.h:44
int target
Definition: aiunit.h:49
struct unit_class::@81 cache
int non_native_def_pct
Definition: unittype.h:128
struct unit_class::@80 adv
enum move_level sea_move
Definition: unittype.h:136
struct unit_class_list * subset_movers
Definition: unittype.h:143
enum move_level land_move
Definition: unittype.h:135
bool carries_occupiers
Definition: aiunit.h:60
struct unit_type_list * potential_charges
Definition: aiunit.h:61
bool ferry
Definition: aiunit.h:58
bool missile_platform
Definition: aiunit.h:59
bool firepower1
Definition: aiunit.h:57
struct requirement_vector build_reqs
Definition: unittype.h:485
int defense_strength
Definition: unittype.h:480
int firepower
Definition: unittype.h:490
struct veteran_system * veteran
Definition: unittype.h:509
int move_rate
Definition: unittype.h:481
int hp
Definition: unittype.h:489
int attack_strength
Definition: unittype.h:479
Definition: unit.h:134
enum unit_activity activity
Definition: unit.h:154
int moves_left
Definition: unit.h:147
int id
Definition: unit.h:141
int hp
Definition: unit.h:148
struct unit::@76::@79 server
struct tile * tile
Definition: unit.h:136
int homecity
Definition: unit.h:142
struct tile * goto_tile
Definition: unit.h:152
int veteran
Definition: unit.h:149
struct player * owner
Definition: unit.h:139
struct civ_map map
Definition: world_object.h:21
#define A_NEVER
Definition: tech.h:44
bool is_terrain_class_near_tile(const struct tile *ptile, enum terrain_class tclass)
Is there terrain of the given class near tile? (Does not check ptile itself.)
Definition: terrain.cpp:495
int tile_extras_defense_bonus(const struct tile *ptile, const struct unit_type *punittype)
Calculate defense bonus given for unit type by bases and roads.
Definition: tile.cpp:223
struct city * tile_city(const struct tile *ptile)
Return the city on this tile (or nullptr), checking for city center.
Definition: tile.cpp:72
#define tile_index(_pt_)
Definition: tile.h:70
#define tile_terrain(_tile)
Definition: tile.h:93
#define TILE_XY(ptile)
Definition: tile.h:36
#define tile_continent(_tile)
Definition: tile.h:74
bool can_cities_trade(const struct city *pc1, const struct city *pc2)
Return TRUE iff the two cities are capable of trade; i.e., if a caravan from one city can enter the o...
bool can_establish_trade_route(const struct city *pc1, const struct city *pc2)
Returns TRUE iff the two cities can establish a trade route.
void unit_set_ai_data(struct unit *punit, const struct ai_type *ai, void *data)
Attach ai data to unit.
Definition: unit.cpp:2047
bool unit_transport_load(struct unit *pcargo, struct unit *ptrans, bool force)
Load pcargo onto ptrans.
Definition: unit.cpp:2123
bool is_losing_hp(const struct unit *punit)
Does unit lose hitpoints each turn?
Definition: unit.cpp:1992
struct unit * is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer)
Is there an non-allied unit on this tile?
Definition: unit.cpp:1252
struct unit * unit_transport_get(const struct unit *pcargo)
Returns the transporter of the unit or nullptr if it is not transported.
Definition: unit.cpp:2189
bool is_military_unit(const struct unit *punit)
Military units are capable of enforcing martial law.
Definition: unit.cpp:300
bool unit_is_cityfounder(const struct unit *punit)
Is a cityfounder unit?
Definition: unit.cpp:2389
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Return TRUE iff this unit can do the specified generalized (ruleset defined) action enabler controlle...
Definition: unit.cpp:309
int get_transporter_capacity(const struct unit *punit)
Return the number of units the transporter can hold (or 0).
Definition: unit.cpp:280
bool unit_can_airlift_to(const struct unit *punit, const struct city *pdest_city)
Determines if punit can be airlifted to dest_city now! So punit needs to be in a city now.
Definition: unit.cpp:179
bool can_unit_do_activity(const struct unit *punit, enum unit_activity activity)
Return TRUE iff the unit can do the given untargeted activity at its current location.
Definition: unit.cpp:806
bool unit_transported(const struct unit *pcargo)
Returns TRUE iff the unit is transported.
Definition: unit.cpp:2176
bool unit_has_orders(const struct unit *punit)
Return TRUE iff the unit is following client-side orders.
Definition: unit.cpp:195
#define unit_tile(_pu)
Definition: unit.h:371
#define CHECK_UNIT(punit)
Definition: unit.h:264
#define unit_owner(_pu)
Definition: unit.h:370
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity)
Handle request for changing activity.
Definition: unithand.cpp:5485
void unit_do_action(struct player *pplayer, const int actor_id, const int target_id, const int sub_tgt_id, const char *name, const action_id action_type)
Handle unit action.
Definition: unithand.cpp:2718
bool unit_server_side_agent_set(struct player *pplayer, struct unit *punit, enum server_side_agent agent)
Change controlling server side agent.
Definition: unithand.cpp:5386
struct unit * unit_list_find(const struct unit_list *punitlist, int unit_id)
Look for a unit with the given ID in the unit list.
Definition: unitlist.cpp:24
#define unit_list_iterate(unitlist, punit)
Definition: unitlist.h:25
#define unit_list_iterate_safe(unitlist, _unit)
Definition: unitlist.h:33
#define unit_list_iterate_end
Definition: unitlist.h:27
#define unit_list_iterate_safe_end
Definition: unitlist.h:54
const char * unit_rule_name(const struct unit *punit)
Return the (untranslated) rule name of the unit.
Definition: unittype.cpp:1283
const struct unit_type * unit_type_get(const struct unit *punit)
Return the unit type for this unit.
Definition: unittype.cpp:114
struct unit_type * best_role_unit_for_player(const struct player *pplayer, int role)
Return "best" unit the player can build, with given role/flag.
Definition: unittype.cpp:1950
bool utype_has_role(const struct unit_type *punittype, int role)
Return whether the given unit type has the role.
Definition: unittype.cpp:186
int utype_build_shield_cost(const struct city *pcity, const struct unit_type *punittype)
Returns the number of shields it takes to build this unit type.
Definition: unittype.cpp:1141
int utype_build_shield_cost_base(const struct unit_type *punittype)
Returns the number of shields this unit type represents.
Definition: unittype.cpp:1168
int unit_build_shield_cost_base(const struct unit *punit)
Returns the number of shields this unit represents.
Definition: unittype.cpp:1185
struct unit_class * unit_class_get(const struct unit *punit)
Returns unit class pointer for a unit.
Definition: unittype.cpp:2151
bool utype_can_do_action_result(const struct unit_type *putype, enum action_result result)
Return TRUE iff units of the given type can do any enabler controlled action with the specified actio...
Definition: unittype.cpp:402
bool unit_has_type_role(const struct unit *punit, enum unit_role_id role)
Return whether the unit has the given role.
Definition: unittype.cpp:195
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Return whether the unit has the given flag.
Definition: unittype.cpp:176
bool unit_can_take_over(const struct unit *punit)
Return whether the unit can take over enemy cities.
Definition: unittype.cpp:203
struct unit_type * get_role_unit(int role, int role_index)
Return index-th unit with specified role/flag.
Definition: unittype.cpp:1900
void utype_set_ai_data(struct unit_type *ptype, const struct ai_type *ai, void *data)
Attach ai data to unit type.
Definition: unittype.cpp:2340
bool utype_acts_hostile(const struct unit_type *putype)
Return TRUE iff units of this type can do hostile actions controlled by generalized (ruleset defined)...
Definition: unittype.cpp:432
struct unit_type * role_units_iterate_backwards(int role, role_unit_callback cb, void *data)
Iterate over all the role units and feed them to callback, starting from the last one.
Definition: unittype.cpp:1883
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Return TRUE iff units of the given type can do the specified generalized (ruleset defined) action ena...
Definition: unittype.cpp:386
void * utype_ai_data(const struct unit_type *ptype, const struct ai_type *ai)
Return pointer to ai data of given unit type and ai type.
Definition: unittype.cpp:2332
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition: unittype.h:704
#define utype_class(_t_)
Definition: unittype.h:691
#define utype_fuel(ptype)
Definition: unittype.h:772
#define combat_bonus_list_iterate_end
Definition: unittype.h:447
#define combat_bonus_list_iterate(bonuslist, pbonus)
Definition: unittype.h:445
@ MOVE_FULL
Definition: unittype.h:115
@ MOVE_NONE
Definition: unittype.h:115
#define unit_type_list_iterate(utype_list, ptype)
Definition: unittype.h:856
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition: unittype.h:584
#define unit_class_list_iterate(uclass_list, pclass)
Definition: unittype.h:848
#define unit_type_iterate(_p)
Definition: unittype.h:785
#define unit_type_list_iterate_end
Definition: unittype.h:858
#define U_LAST
Definition: unittype.h:31
#define unit_type_iterate_end
Definition: unittype.h:791
#define unit_class_list_iterate_end
Definition: unittype.h:850