Freeciv-3.4
Loading...
Searching...
No Matches
daiunit.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <math.h>
19
20/* utility */
21#include "bitvector.h"
22#include "log.h"
23#include "mem.h"
24#include "nation.h"
25#include "rand.h"
26#include "registry.h"
27#include "shared.h"
28#include "timing.h"
29
30/* common */
31#include "city.h"
32#include "combat.h"
33#include "game.h"
34#include "government.h"
35#include "map.h"
36#include "movement.h"
37#include "packets.h"
38#include "specialist.h"
39#include "traderoutes.h"
40#include "unit.h"
41#include "unitlist.h"
42
43/* common/aicore */
44#include "caravan.h"
45#include "pf_tools.h"
46
47/* server */
48#include "barbarian.h"
49#include "citytools.h"
50#include "cityturn.h"
51#include "diplomats.h"
52#include "maphand.h"
53#include "srv_log.h"
54#include "unithand.h"
55#include "unittools.h"
56
57/* server/advisors */
58#include "advbuilding.h"
59#include "advgoto.h"
60#include "advtools.h"
61#include "autoexplorer.h"
62#include "autoworkers.h"
63
64/* ai */
65#include "difficulty.h"
66#include "handicaps.h"
67
68/* ai/default */
69#include "daiair.h"
70#include "daicity.h"
71#include "daidata.h"
72#include "daidiplomat.h"
73#include "daieffects.h"
74#include "daiferry.h"
75#include "daiguard.h"
76#include "daihunter.h"
77#include "dailog.h"
78#include "daimilitary.h"
79#include "daiparadrop.h"
80#include "daiplayer.h"
81#include "daitools.h"
82
83#include "daiunit.h"
84
85
86#define LOGLEVEL_RECOVERY LOG_DEBUG
87#define LOG_CARAVAN LOG_DEBUG
88#define LOG_CARAVAN2 LOG_DEBUG
89#define LOG_CARAVAN3 LOG_DEBUG
90
91static bool dai_find_boat_for_unit(struct ai_type *ait, struct unit *punit);
92static bool dai_caravan_can_trade_cities_diff_cont(struct player *pplayer,
93 struct unit *punit);
94static void dai_manage_caravan(struct ai_type *ait, struct player *pplayer,
95 struct unit *punit);
96static void dai_manage_barbarian_leader(struct ai_type *ait,
97 struct player *pplayer,
98 struct unit *leader);
99
100static void dai_military_findjob(struct ai_type *ait, const struct civ_map *nmap,
101 struct player *pplayer, struct unit *punit);
102static void dai_military_defend(struct ai_type *ait, struct player *pplayer,
103 struct unit *punit);
104static void dai_military_attack(struct ai_type *ait, struct player *pplayer,
105 struct unit *punit);
106
107static bool unit_role_defender(const struct unit_type *punittype);
108static int unit_def_rating_squared(const struct unit *punit,
109 const struct unit *pdef);
110
111/*
112 * Cached values. Updated by update_simple_ai_types.
113 *
114 * This a hack to enable emulation of old loops previously hardwired
115 * as
116 * for (i = U_WARRIORS; i <= U_BATTLESHIP; i++)
117 *
118 * (Could probably just adjust the loops themselves fairly simply,
119 * but this is safer for regression testing.)
120 *
121 * Not dealing with planes yet.
122 *
123 * Terminated by nullptr.
124 */
126
127/**********************************************************************/
137static struct city *find_neediest_airlift_city(struct ai_type *ait,
138 const struct player *pplayer)
139{
140 struct city *neediest_city = nullptr;
141 int most_danger = 0;
142 int most_urgent = 0;
143
144 city_list_iterate(pplayer->cities, pcity) {
145 struct ai_city *city_data = def_ai_city_data(pcity, ait);
146
147 if (pcity->airlift) {
148 if (city_data->urgency > most_urgent) {
149 most_urgent = city_data->urgency;
151 } else if (0 == most_urgent /* Urgency trumps danger */
152 && city_data->danger > most_danger) {
153 most_danger = city_data->danger;
155 }
156 }
158
159 return neediest_city;
160}
161
162/**********************************************************************/
168static void dai_airlift(struct ai_type *ait, struct player *pplayer)
169{
170 struct city *most_needed;
171 int comparison;
172 struct unit *transported;
173 const struct civ_map *nmap = &(wld.map);
174
175 do {
177 comparison = 0;
178 transported = nullptr;
179
180 if (!most_needed) {
181 return;
182 }
183
184 unit_list_iterate(pplayer->units, punit) {
185 struct tile *ptile = (unit_tile(punit));
186 struct city *pcity = tile_city(ptile);
187
188 if (pcity) {
189 struct ai_city *city_data = def_ai_city_data(pcity, ait);
190 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
191 const struct unit_type *ptype = unit_type_get(punit);
192
193 if (city_data->urgency == 0
196 && DEFENSE_POWER(ptype) > 2
197 && (unit_data->task == AIUNIT_NONE
198 || unit_data->task == AIUNIT_DEFEND_HOME)
199 && IS_ATTACKER(ptype)) {
200 comparison = city_data->danger;
201 transported = punit;
202 }
203 }
205 if (!transported) {
206 return;
207 }
208 UNIT_LOG(LOG_DEBUG, transported, "airlifted to defend %s",
210 unit_do_action(pplayer, transported->id, most_needed->id,
211 0, "", ACTION_AIRLIFT);
212 } while (TRUE);
213}
214
215/**********************************************************************/
221static bool has_defense(struct city *pcity)
222{
223 struct tile *ptile = city_tile(pcity);
224
225 unit_list_iterate(ptile->units, punit) {
227 && punit->hp != 0) {
229
230 if (pclass->non_native_def_pct > 0
231 || is_native_tile_to_class(pclass, ptile)) {
232 return TRUE;
233 }
234 }
235 }
237
238 return FALSE;
239}
240
241/**********************************************************************/
250{
251 return 2 * utype_build_shield_cost_base(punittype) * punittype->attack_strength /
252 (punittype->attack_strength + punittype->defense_strength);
253}
254
255/**********************************************************************/
258static int unit_att_rating_now(const struct unit *punit)
259{
262}
263
264/**********************************************************************/
267static int unit_att_rating_squared(const struct unit *punit)
268{
269 int v = adv_unit_att_rating(punit);
270
271 return v * v;
272}
273
274/**********************************************************************/
277static int unit_def_rating(const struct unit *attacker,
278 const struct unit *defender)
279{
280 const struct unit_type *def_type = unit_type_get(defender);
281
282 return (get_total_defense_power(attacker, defender)
283 * (attacker->id != 0 ? defender->hp : def_type->hp)
284 * def_type->firepower / POWER_DIVIDER);
285}
286
287/**********************************************************************/
290static int unit_def_rating_squared(const struct unit *attacker,
291 const struct unit *defender)
292{
293 int v = unit_def_rating(attacker, defender);
294
295 return v * v;
296}
297
298/**********************************************************************/
304 const struct unit_type *def_type,
305 struct player *def_player,
306 struct tile *ptile, bool fortified,
307 int veteran)
308{
309 struct civ_map *nmap = &(wld.map);
311 ptile, fortified, veteran)
312 * def_type->hp * def_type->firepower / POWER_DIVIDER;
313
314 return v * v;
315}
316
317/**********************************************************************/
342 int victim_count)
343{
345
346 /* attractiveness danger */
349
350 return desire;
351}
352
353/**********************************************************************/
365static int avg_benefit(int benefit, int loss, double chance)
366{
367 return (int)(((benefit + loss) * chance - loss) * SHIELD_WEIGHTING);
368}
369
370/**********************************************************************/
375 struct tile *ptile0,
376 int *value, int *cost)
377{
378 *cost = 0;
379 *value = 0;
380 square_iterate(&(wld.map), ptile0, 1, ptile) {
381 unit_list_iterate(ptile->units, aunit) {
382 if (aunit != punit
384 int val = adv_unit_att_rating(aunit);
385
386 if (val != 0) {
387 *value += val;
389 }
390 }
393}
394
395/**********************************************************************/
399static bool is_my_turn(struct unit *punit, struct unit *pdef)
400{
401 int val = unit_att_rating_now(punit);
402 int cur, d;
403 const struct unit_type *def_type = unit_type_get(pdef);
404 struct tile *def_tile = unit_tile(pdef);
405 struct civ_map *nmap = &(wld.map);
406
408
409 square_iterate(nmap, def_tile, 1, ptile) {
410 unit_list_iterate(ptile->units, aunit) {
411 if (aunit == punit || unit_owner(aunit) != unit_owner(punit)) {
412 continue;
413 }
415 != ATT_OK)
417 pdef, def_tile)
418 != ATT_OK)) {
419 continue;
420 }
423 FALSE, 0);
424 if (d == 0) {
425 return TRUE; /* Thanks, Markus -- Syela */
426 }
430 FALSE, 0) / d;
431 if (cur > val && ai_fuzzy(unit_owner(punit), TRUE)) {
432 return FALSE;
433 }
436
437 return TRUE;
438}
439
440/**********************************************************************/
445 struct unit *punit,
446 struct tile *ptile,
447 enum action_target_kind *kind)
448{
449 enum gen_action selected;
450 struct city *pcity;
451
453 punit, ptile))
454 != ACTION_NONE
456 punit, ptile))
457 != ACTION_NONE
459 punit, ptile))
460 != ACTION_NONE
462 punit, ptile))
463 != ACTION_NONE) {
464 if (kind != nullptr) {
465 *kind = ATK_STACK;
466 }
467
468 return selected;
469 }
470
472 punit, ptile))
473 != ACTION_NONE) {
474 if (kind != nullptr) {
475 *kind = ATK_TILE;
476 }
477
478 return selected;
479 }
480
481 pcity = tile_city(ptile);
482 if (pcity != nullptr) {
484 punit, pcity))
485 != ACTION_NONE) {
486 if (kind != nullptr) {
487 *kind = ATK_CITY;
488 }
489
490 return selected;
491 }
492 }
493
495 punit, ptile))
496 != ACTION_NONE) {
497 if (kind != nullptr) {
498 *kind = ATK_STACK;
499 }
500
501 return selected;
502 }
503
504 return ACTION_NONE;
505}
506
507/**********************************************************************/
523static int dai_rampage_want(struct unit *punit, struct tile *ptile)
524{
525 struct player *pplayer = unit_owner(punit);
526 struct unit *pdef;
527 struct civ_map *nmap = &(wld.map);
528
530
531 if (can_unit_attack_tile(punit, nullptr, ptile)
532 && (pdef = get_defender(nmap, punit, ptile, nullptr))
533 /* Action enablers might prevent attacking */
534 && dai_select_tile_attack_action(nmap, punit, ptile, nullptr) != ACTION_NONE) {
535 /* See description of kill_desire() about these variables. */
539
540 attack *= attack;
541
542 /* If the victim is in the city/fortress, we correct the benefit
543 * with our health because there could be reprisal attacks.
544 * We shouldn't send already injured units to useless suicide.
545 * Note that we do not specially encourage attacks against
546 * cities: rampage is a hit-n-run operation. */
547 if (!is_stack_vulnerable(ptile)
548 && unit_list_size(ptile->units) > 1) {
550 }
551
552 /* If we have non-zero attack rating... */
553 if (attack > 0 && is_my_turn(punit, pdef)) {
554 double chance = unit_win_chance(nmap, punit, pdef, nullptr);
556
557 /* No need to amortize, our operation takes one turn. */
558 UNIT_LOG(LOG_DEBUG, punit, "Rampage: Desire %d to kill %s(%d,%d)",
559 desire,
562
563 return MAX(0, desire);
564 }
565 } else if (0 == unit_list_size(ptile->units)) {
566 /* No defender. */
567 struct city *pcity = tile_city(ptile);
568
569 /* ...and free foreign city waiting for us. Who would resist! */
570 if (pcity != nullptr
571 && pplayers_at_war(pplayer, city_owner(pcity))
574 }
575
576 /* ...or tiny pleasant hut here! */
577 /* FIXME: unhardcode and variate the desire to enter a hut. */
578 if (unit_can_enter_hut(punit, ptile) && !is_barbarian(pplayer)
579 && is_native_tile(unit_type_get(punit), ptile)) {
580 return -RAMPAGE_HUT_OR_BETTER;
581 }
582 }
583
584 return 0;
585}
586
587/**********************************************************************/
590static struct pf_path *find_rampage_target(struct unit *punit,
591 int thresh_adj, int thresh_move)
592{
593 struct pf_map *tgt_map;
594 struct pf_path *path = nullptr;
595 struct pf_parameter parameter;
596 /* Coordinates of the best target (initialize to silence compiler) */
597 struct tile *ptile = unit_tile(punit);
598 /* Want of the best target */
599 int max_want = 0;
600 struct player *pplayer = unit_owner(punit);
601 const struct civ_map *nmap = &(wld.map);
602
604 parameter.omniscience = !has_handicap(pplayer, H_MAP);
605 /* When trying to find rampage targets we ignore risks such as
606 * enemy units because we are looking for trouble!
607 * Hence no call ai_avoid_risks()
608 */
609
610 tgt_map = pf_map_new(&parameter);
612 int want;
613 bool move_needed;
614 int thresh;
615
616 if (move_cost > punit->moves_left) {
617 /* This is too far */
618 break;
619 }
620
621 if (has_handicap(pplayer, H_TARGETS)
622 && !map_is_known_and_seen(iter_tile, pplayer, V_MAIN)) {
623 /* The target is under fog of war */
624 continue;
625 }
626
628
629 /* Negative want means move needed even though the tiles are adjacent */
631 || want < 0);
632 /* Select the relevant threshold */
634 want = (want < 0 ? -want : want);
635
636 if (want > max_want && want > thresh) {
637 /* The new want exceeds both the previous maximum
638 * and the relevant threshold, so it's worth recording */
639 max_want = want;
640 ptile = iter_tile;
641 }
643
644 if (max_want > 0) {
645 /* We found something */
646 path = pf_map_path(tgt_map, ptile);
647 fc_assert(path != nullptr);
648 }
649
651
652 return path;
653}
654
655/**********************************************************************/
670 int thresh_move)
671{
672 int count = punit->moves_left + 1; /* Break any infinite loops */
673 struct pf_path *path = nullptr;
674
677
679 /* This teaches the AI about the dangers inherent in occupychance. */
681
682 while (count-- > 0 && punit->moves_left > 0
684 if (!adv_unit_execute_path(punit, path)) {
685 /* Died */
686 count = -1;
687 }
688 pf_path_destroy(path);
689 path = nullptr;
690 }
691
692 fc_assert(path == nullptr);
693
695 return (count >= 0);
696}
697
698/**********************************************************************/
702static void dai_military_bodyguard(struct ai_type *ait, struct player *pplayer,
703 struct unit *punit)
704{
705 struct unit *aunit = aiguard_charge_unit(ait, punit);
706 struct city *acity = aiguard_charge_city(ait, punit);
707 struct tile *ptile;
708
710 CHECK_GUARD(ait, punit);
711
712 if (aunit && unit_owner(aunit) == unit_owner(punit)) {
713 /* protect a unit */
714 if (aunit->goto_tile != nullptr) {
715 /* Our charge is going somewhere: maybe we should meet them there */
716 /* FIXME: This probably isn't the best algorithm for this. */
718 int me2goal = real_map_distance(unit_tile(punit), aunit->goto_tile);
719 int them2goal = real_map_distance(unit_tile(aunit), aunit->goto_tile);
720
721 if (me2goal < me2them
725 ptile = aunit->goto_tile;
726 } else {
727 ptile = unit_tile(aunit);
728 }
729 } else {
730 ptile = unit_tile(aunit);
731 }
732 } else if (acity && city_owner(acity) == unit_owner(punit)) {
733 /* protect a city */
734 ptile = acity->tile;
735 } else {
736 /* should be impossible */
737 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "we lost our charge");
738 dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
739 return;
740 }
741
742 if (same_pos(unit_tile(punit), ptile)) {
743 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "at RV");
744 } else {
745 if (goto_is_sane(punit, ptile)) {
746 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "meeting charge");
747 if (!dai_gothere(ait, pplayer, punit, ptile)) {
748 /* We died */
749 return;
750 }
751 } else {
752 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "can not meet charge");
753 dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
754 }
755 }
756
757 /* We might have stopped because of an enemy nearby.
758 * Perhaps we can kill it.*/
761 && same_pos(unit_tile(punit), ptile)) {
762 def_ai_unit_data(punit, ait)->done = TRUE; /* Stay with charge */
763 }
764}
765
766/**********************************************************************/
769static bool unit_role_defender(const struct unit_type *punittype)
770{
772}
773
774/**********************************************************************/
784adv_want look_for_charge(struct ai_type *ait, const struct civ_map *nmap,
785 struct player *pplayer, struct unit *punit,
786 struct unit **aunit, struct city **acity)
787{
788 struct pf_parameter parameter;
789 struct pf_map *pfm;
790 struct city *pcity;
791 struct ai_city *data, *best_data = nullptr;
793 int def, best_def = -1;
794 /* Arbitrary: 3 turns. */
795 const int max_move_cost = 3 * unit_move_rate(punit);
796
797 *aunit = nullptr;
798 *acity = nullptr;
799
800 if (toughness == 0) {
801 /* Useless */
802 return 0;
803 }
804
805 pft_fill_unit_parameter(&parameter, nmap, punit);
806 parameter.omniscience = !has_handicap(pplayer, H_MAP);
807 pfm = pf_map_new(&parameter);
808
809 pf_map_move_costs_iterate(pfm, ptile, move_cost, TRUE) {
810 if (move_cost > max_move_cost) {
811 /* Consider too far. */
812 break;
813 }
814
815 pcity = tile_city(ptile);
816
817 /* Consider unit bodyguard. */
818 unit_list_iterate(ptile->units, buddy) {
819 const struct unit_type *ptype = unit_type_get(punit);
820 const struct unit_type *buddy_type = unit_type_get(buddy);
821
822 /* TODO: allied unit bodyguard? */
824 || unit_owner(buddy) != pplayer
825 || !aiguard_wanted(ait, buddy)
831
832 continue;
833 }
834
836 if (0 >= def) {
837 continue;
838 }
839
841 /* Reduce want based on move cost. We can't do this for
842 * transports since they move around all the time, leading
843 * to hilarious flip-flops. */
844 def >>= move_cost / (2 * unit_move_rate(punit));
845 }
846 if (def > best_def) {
847 *aunit = buddy;
848 *acity = nullptr;
849 best_def = def;
850 }
852
853 /* City bodyguard. TODO: allied city bodyguard? */
854 if (ai_fuzzy(pplayer, TRUE)
855 && pcity != nullptr
856 && city_owner(pcity) == pplayer
857 && (data = def_ai_city_data(pcity, ait))
858 && 0 < data->urgency) {
859 if (best_data != nullptr
860 && (0 < best_data->grave_danger
861 || best_data->urgency > data->urgency
862 || ((best_data->danger > data->danger
863 || AIUNIT_DEFEND_HOME == def_ai_unit_data(punit, ait)->task)
864 && 0 == data->grave_danger))) {
865 /* Chances are we'll be between cities when we are needed the most!
866 * Resuming pf_map_move_costs_iterate()... */
867 continue;
868 }
869 def = (data->danger - assess_defense_quadratic(ait, pcity));
870 if (def <= 0) {
871 continue;
872 }
873 /* Reduce want based on move cost. */
874 def >>= move_cost / (2 * unit_move_rate(punit));
875 if (def > best_def && ai_fuzzy(pplayer, TRUE)) {
876 *acity = pcity;
877 *aunit = nullptr;
878 best_def = def;
879 best_data = data;
880 }
881 }
883
885
886 UNIT_LOG(LOGLEVEL_BODYGUARD, punit, "%s(), best_def=%d, type=%s (%d, %d)",
888 (*acity != nullptr ? city_name_get(*acity)
889 : (*aunit != nullptr ? unit_rule_name(*aunit) : "")),
891 : (*aunit != nullptr ?
894 : (*aunit != nullptr ?
896
897 return ((best_def * 100) / toughness);
898}
899
900/**********************************************************************/
904 const struct unit_type *followee,
905 struct ai_type *ait)
906{
907 struct unit_type_ai *utai = utype_ai_data(follower, ait);
908
909 unit_type_list_iterate(utai->potential_charges, pcharge) {
910 if (pcharge == followee) {
911 return TRUE;
912 }
914
915 return FALSE;
916}
917
918/**********************************************************************/
921static void dai_military_findjob(struct ai_type *ait, const struct civ_map *nmap,
922 struct player *pplayer, struct unit *punit)
923{
924 const struct unit_type *punittype = unit_type_get(punit);
925 struct unit_ai *unit_data;
926
928
929 /* Keep barbarians aggressive and primitive */
930 if (is_barbarian(pplayer)) {
931 if (is_land_barbarian(pplayer)) {
933
935 /* Land barbarians pillage */
937 }
938 }
939 dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
940
941 return;
942 }
943
945
946 /* If I am a bodyguard, check whether I can do my job. */
947 if (unit_data->task == AIUNIT_ESCORT
948 || unit_data->task == AIUNIT_DEFEND_HOME) {
950 }
951
952 if (aiguard_has_charge(ait, punit)
953 && unit_data->task == AIUNIT_ESCORT) {
954 struct unit *aunit = aiguard_charge_unit(ait, punit);
955 struct city *acity = aiguard_charge_city(ait, punit);
956 struct ai_city *city_data = nullptr;
957
958 if (acity != nullptr) {
960 }
961
962 /* Check if the city we are on our way to rescue is still in danger,
963 * or the unit we should protect is still alive... */
964 if ((aunit && (aiguard_has_guard(ait, aunit) || aiguard_wanted(ait, aunit))
967 && city_data->urgency != 0
968 && city_data->danger > assess_defense_quadratic(ait, acity))) {
969 return; /* Yep! */
970 } else {
971 dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr); /* Nope! */
972 }
973 }
974
975 /* Is the unit badly damaged? */
976 if ((unit_data->task == AIUNIT_RECOVER
977 && punit->hp < punittype->hp)
978 || punit->hp < punittype->hp * 0.25) { /* WAG */
979 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "set to hp recovery");
980 dai_unit_new_task(ait, punit, AIUNIT_RECOVER, nullptr);
981 return;
982 }
983
986 /* This is a defending unit that doesn't need to stay put.
987 * It needs to defend something, but not necessarily where it's at.
988 * Therefore, it will consider becoming a bodyguard. -- Syela */
989 struct city *acity;
990 struct unit *aunit;
991
992 look_for_charge(ait, nmap, pplayer, punit, &aunit, &acity);
993 if (acity) {
996 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "going to defend city");
997 } else if (aunit) {
1000 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "going to defend unit");
1001 }
1002 }
1004}
1005
1006/**********************************************************************/
1015static void dai_military_defend(struct ai_type *ait, struct player *pplayer,
1016 struct unit *punit)
1017{
1018 struct city *pcity = aiguard_charge_city(ait, punit);
1019
1021
1022 if (!pcity || city_owner(pcity) != pplayer) {
1024 /* Do not stay defending an allied city forever */
1026 }
1027
1028 if (!pcity) {
1029 /* Try to find a place to rest. Sitting duck out in the wilderness
1030 * is generally a bad idea, since we protect no cities that way, and
1031 * it looks silly. */
1032 pcity = find_closest_city(unit_tile(punit), nullptr, pplayer,
1035 }
1036
1037 if (!pcity) {
1039 }
1040
1043 /* ... We survived */
1044 if (pcity) {
1045 UNIT_LOG(LOG_DEBUG, punit, "go to defend %s", city_name_get(pcity));
1046 if (same_pos(unit_tile(punit), pcity->tile)) {
1047 UNIT_LOG(LOG_DEBUG, punit, "go defend successful");
1049 } else {
1050 (void) dai_gothere(ait, pplayer, punit, pcity->tile);
1051 }
1052 } else {
1053 UNIT_LOG(LOG_VERBOSE, punit, "defending nothing...?");
1054 }
1055 }
1056}
1057
1058/**********************************************************************/
1062 const struct unit_type *utype,
1063 int which)
1064{
1065 int attacks;
1066
1067 if (utype_action_takes_all_mp(utype,
1069 attacks = 1;
1070 } else {
1071 attacks = utype->move_rate;
1072 }
1073 city_data->invasion.attack += attacks;
1074 if (which == INVASION_OCCUPY) {
1075 city_data->invasion.occupy++;
1076 }
1077}
1078
1079/**********************************************************************/
1089static bool invasion_funct(struct ai_type *ait, struct unit *punit,
1090 bool dest, int radius, int which)
1091{
1092 struct tile *ptile;
1093 struct player *pplayer = unit_owner(punit);
1094
1096
1097 if (dest) {
1099
1100 ptile = punit->goto_tile;
1101 } else {
1102 ptile = unit_tile(punit);
1103 }
1104
1105 square_iterate(&(wld.map), ptile, radius, tile1) {
1106 struct city *pcity = tile_city(tile1);
1107
1108 if (pcity
1110 && (dest || !has_defense(pcity))) {
1111 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1112
1113 /* Unit itself */
1115
1116 /* Cargo */
1117 unit_cargo_iterate(punit, cargo) {
1118 const struct unit_type *utype = unit_type_get(cargo);
1119
1120 if (IS_ATTACKER(utype)) {
1124 }
1126 }
1128
1129 return TRUE;
1130}
1131
1132/**********************************************************************/
1135bool find_beachhead(const struct player *pplayer, struct pf_map *ferry_map,
1136 struct tile *dest_tile,
1137 const struct unit_type *cargo_type,
1138 const struct unit_type *ferry_type,
1139 struct tile **ferry_dest, struct tile **beachhead_tile)
1140{
1141 if (tile_city(dest_tile) == nullptr
1143 /* Unit can directly go to 'dest_tile'. */
1144 struct tile *best_tile = nullptr;
1146
1147 if (beachhead_tile != nullptr) {
1148 *beachhead_tile = dest_tile;
1149 }
1150
1151 adjc_iterate(&(wld.map), dest_tile, ptile) {
1153 if (cost != PF_IMPOSSIBLE_MC
1154 && (best_tile == nullptr || cost < best_cost)) {
1155 best_tile = ptile;
1156 best_cost = cost;
1157 }
1159
1160 if (ferry_dest != nullptr) {
1162 }
1163
1164 return (PF_IMPOSSIBLE_MC != best_cost);
1165 } else {
1166 /* We need to find a beach around 'dest_tile'. */
1167 struct tile *best_tile = nullptr, *best_beach = nullptr;
1171
1172 tile_list_append(checked_tiles, dest_tile);
1173 adjc_iterate(&(wld.map), dest_tile, beach) {
1175 /* Can land there. */
1176 adjc_iterate(&(wld.map), beach, ptile) {
1177 if (!tile_list_search(checked_tiles, ptile)
1178 && !is_non_allied_unit_tile(ptile, pplayer,
1179 flagless_ferry)) {
1182 if (cost != PF_IMPOSSIBLE_MC
1183 && (best_tile == nullptr || cost < best_cost)) {
1184 best_beach = beach;
1185 best_tile = ptile;
1186 best_cost = cost;
1187 }
1188 }
1190 }
1192
1194
1195 if (beachhead_tile != nullptr) {
1197 }
1198 if (ferry_dest != nullptr) {
1200 }
1201
1202 return (PF_IMPOSSIBLE_MC != best_cost);
1203 }
1204}
1205
1206/**********************************************************************/
1214adv_want find_something_to_kill(struct ai_type *ait, struct player *pplayer,
1215 struct unit *punit,
1216 struct tile **pdest_tile, struct pf_path **ppath,
1217 struct pf_map **pferrymap,
1218 struct unit **pferryboat,
1219 const struct unit_type **pboattype, int *pmove_time)
1220{
1221 const int attack_value = adv_unit_att_rating(punit); /* Basic attack. */
1222 struct pf_parameter parameter;
1223 struct pf_map *punit_map, *ferry_map;
1224 struct pf_position pos;
1226 const struct unit_type *punit_type = unit_type_get(punit);
1227 struct tile *punit_tile = unit_tile(punit);
1228 /* Type of our boat (a future one if ferryboat == nullptr). */
1229 const struct unit_type *boattype = nullptr;
1230 struct unit *ferryboat = nullptr;
1231 struct city *pcity;
1232 struct ai_city *acity_data;
1233 int bcost, bcost_bal; /* Build cost of the attacker (+adjustments). */
1234 bool handicap = has_handicap(pplayer, H_TARGETS);
1235 bool unhap = FALSE; /* Do we make unhappy citizen. */
1236 bool harbor = FALSE; /* Do we have access to sea? */
1237 bool go_by_boat; /* Whether we need a boat or not. */
1238 int vulnerability; /* Enemy defense rating. */
1239 adv_want benefit; /* Benefit from killing the target. */
1240 struct unit *pdefender; /* Enemy city defender. */
1241 int move_time; /* Turns needed to target. */
1242 int reserves;
1243 int attack; /* Our total attack value with reinforcements. */
1244 int victim_count; /* Number of enemies there. */
1245 int needferry; /* Cost of building a ferry boat. */
1246 /* This is a kluge, because if we don't set x and y with !punit->id,
1247 * p_a_w isn't called, and we end up not wanting ironclads and therefore
1248 * never learning steam engine, even though ironclads would be very
1249 * useful. -- Syela */
1250 adv_want bk = 0;
1251 adv_want want; /* Want (amortized) of the operation. */
1252 adv_want best = 0; /* Best of all wants. */
1253 struct tile *goto_dest_tile = nullptr;
1254 bool can_occupy;
1255 struct civ_map *nmap = &(wld.map);
1256
1257 /* Very preliminary checks. */
1259 if (pferrymap != nullptr) {
1260 *pferrymap = nullptr;
1261 }
1262 if (pferryboat != nullptr) {
1263 *pferryboat = nullptr;
1264 }
1265 if (pboattype != nullptr) {
1266 *pboattype = nullptr;
1267 }
1268 if (pmove_time != nullptr) {
1269 *pmove_time = 0;
1270 }
1271 if (ppath != nullptr) {
1272 *ppath = nullptr;
1273 }
1274
1275 if (attack_value == 0) {
1276 /* A very poor attacker... probably low on HP. */
1277 return 0;
1278 }
1279
1281
1282
1283 /*** Part 1: Calculate targets ***/
1284
1285 /* This horrible piece of code attempts to calculate the attractiveness of
1286 * enemy cities as targets for our units, by checking how many units are
1287 * going towards it or are near it already. */
1288
1289 /* Reset enemy cities data. */
1291 /* See comment below in next usage of POTENTIALLY_HOSTILE_PLAYER. */
1292 if ((punit->id == 0 && !POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer))
1293 || (punit->id != 0 && !pplayers_at_war(pplayer, aplayer))) {
1294 continue;
1295 }
1296 city_list_iterate(aplayer->cities, acity) {
1297 struct ai_city *city_data = def_ai_city_data(acity, ait);
1298
1300 &city_data->attack,
1301 &city_data->bcost);
1302 city_data->invasion.attack = 0;
1303 city_data->invasion.occupy = 0;
1306
1307 /* Second, calculate in units on their way there, and mark targets for
1308 * invasion */
1309 unit_list_iterate(pplayer->units, aunit) {
1310 const struct unit_type *atype;
1311
1312 if (aunit == punit) {
1313 continue;
1314 }
1315
1317
1318 /* Dealing with invasion stuff */
1319 if (IS_ATTACKER(atype)) {
1320 if (aunit->activity == ACTIVITY_GOTO) {
1321 if (invasion_funct(ait, aunit, TRUE, 0,
1324 && (pcity = tile_city(aunit->goto_tile))) {
1325 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1326
1329 }
1330 }
1334 } else if (def_ai_unit_data(aunit, ait)->passenger != 0
1336 /* It's a transport with reinforcements */
1337 if (aunit->activity == ACTIVITY_GOTO) {
1339 }
1341 }
1343 /* End horrible initialization subroutine */
1344
1345
1346 /*** Part 2: Now pick one target ***/
1347
1348 /* We first iterate through all cities, then all units, looking
1349 * for a viable target. We also try to gang up on the target
1350 * to avoid spreading out attacks too widely to be inefficient.
1351 */
1352
1354 if (pcity != nullptr && (punit->id == 0 || pcity->id == punit->homecity)) {
1355 /* I would have thought unhappiness should be taken into account
1356 * irrespectfully the city in which it will surface... -- GB */
1358 }
1359
1362
1364 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1365 punit_map = pf_map_new(&parameter);
1366
1367 if (MOVE_NONE == punit_class->adv.sea_move) {
1368 /* We need boat to move over sea. */
1369 ferryboat = unit_transport_get(punit);
1370
1371 /* First check if we can use the boat we are currently loaded to. */
1372 if (ferryboat == nullptr || !is_boat_free(ait, ferryboat, punit, 0)) {
1373 /* No, we cannot control current boat */
1374 ferryboat = nullptr;
1375 }
1376
1377 if (ferryboat == nullptr) {
1378 /* Try to find new boat */
1379 ferryboat = player_unit_by_number(pplayer,
1380 aiferry_find_boat(ait, punit, 1,
1381 nullptr));
1382 }
1383
1385 TC_OCEAN)) {
1386 harbor = TRUE;
1387 }
1388 }
1389
1390 if (ferryboat != nullptr) {
1391 boattype = unit_type_get(ferryboat);
1392 pft_fill_unit_overlap_param(&parameter, nmap, ferryboat);
1393 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1394 ferry_map = pf_map_new(&parameter);
1395 } else {
1397 if (boattype == nullptr) {
1398 /* We pretend that we can have the simplest boat to stimulate tech. */
1400 }
1401 if (boattype != nullptr && harbor) {
1402 /* Let's simulate a boat at 'punit' position. */
1404 punit_tile, pplayer);
1405 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1406 ferry_map = pf_map_new(&parameter);
1407 } else {
1408 ferry_map = nullptr;
1409 }
1410 }
1411
1413
1415 /* For the virtual unit case, which is when we are called to evaluate
1416 * which units to build, we want to calculate in danger and which
1417 * players we want to make war with in the future. We do _not_ want
1418 * to do this when actually making attacks. */
1419 if ((punit->id == 0 && !POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer))
1420 || (punit->id != 0 && !pplayers_at_war(pplayer, aplayer))) {
1421 continue; /* Not an enemy. */
1422 }
1423
1424 city_list_iterate(aplayer->cities, acity) {
1425 struct tile *atile = city_tile(acity);
1426
1429 /* Can't attack this city. It is on land. */
1430 continue;
1431 }
1432
1433 if (handicap && !map_is_known(atile, pplayer)) {
1434 /* Can't see it */
1435 continue;
1436 }
1437
1439 go_by_boat = FALSE;
1440 move_time = pos.turn;
1441 } else if (ferry_map == nullptr) {
1442 continue; /* Impossible to handle. */
1443 } else {
1444 struct tile *dest, *beach;
1445
1446 if (!find_beachhead(pplayer, ferry_map, atile, punit_type,
1447 boattype, &dest, &beach)) {
1448 continue; /* Impossible to go by boat. */
1449 }
1450 if (!pf_map_position(ferry_map, dest, &pos)) {
1452 continue;
1453 }
1454 move_time = pos.turn; /* Sailing time. */
1455 if (dest != beach) {
1456 move_time++; /* Land time. */
1457 }
1458 if (ferryboat != nullptr && unit_tile(ferryboat) != punit_tile) {
1459 if (pf_map_position(punit_map, unit_tile(ferryboat), &pos)) {
1460 move_time += pos.turn; /* Time to reach the boat. */
1461 } else {
1462 continue; /* Cannot reach the boat. */
1463 }
1464 }
1465 go_by_boat = TRUE;
1466 }
1467
1470 nullptr))) {
1473 } else {
1474 pdefender = nullptr;
1475 vulnerability = 0;
1476 benefit = 0;
1477 }
1478
1479 if (1 < move_time) {
1481
1482 if (def_type) {
1486
1487 if (v > vulnerability) {
1488 /* They can build a better defender! */
1489 vulnerability = v;
1491 }
1492 }
1493 }
1494
1496
1497 reserves = (acity_data->invasion.attack
1498 - unit_list_size(acity->tile->units));
1499
1500 if (punit->id == 0) {
1501 /* Real unit would add to reserves once built. */
1504 reserves++;
1505 } else {
1506 reserves += punit_type->move_rate;
1507 }
1508 }
1509
1510 if (0 < reserves && (can_occupy
1511 || 0 < acity_data->invasion.occupy)) {
1512 /* There are units able to occupy the city after all defenders
1513 * are killed! */
1514 benefit += acity_data->worth * reserves / 5;
1515 }
1516
1517 attack = attack_value + acity_data->attack;
1518 attack *= attack;
1519 /* Avoiding handling upkeep aggregation this way -- Syela */
1520
1521 /* AI was not sending enough reinforcements to totally wipe out a city
1522 * and conquer it in one turn.
1523 * This variable enables total carnage. -- Syela */
1525
1526 if (!can_occupy && pdefender == nullptr) {
1527 /* Nothing there to bash and we can't occupy!
1528 * Not having this check caused warships yoyoing */
1529 want = 0;
1530 } else if (10 < move_time) {
1531 /* Too far! */
1532 want = 0;
1533 } else if (can_occupy && 0 == acity_data->invasion.occupy
1534 && (0 < acity_data->invasion.attack
1535 || victim_count == 0)) {
1536 /* Units able to occupy really needed there! */
1537 want = bcost * SHIELD_WEIGHTING;
1538 } else {
1539 want = kill_desire(benefit, attack, bcost + acity_data->bcost,
1541 }
1544 /* Build_cost of ferry. */
1545 needferry = (go_by_boat && ferryboat == nullptr
1546 ? utype_build_shield_cost(acity, nullptr, boattype) : 0);
1547 /* FIXME: Add time to build the ferry? */
1549 want, MAX(1, move_time),
1551
1552 /* BEGIN STEAM-ENGINES-ARE-OUR-FRIENDS KLUGE. */
1553 if (0 >= want && 0 == punit->id && 0 >= best) {
1557 MAX(1, move_time),
1559
1560 if (bk_e > bk) {
1561 *pdest_tile = atile;
1562 if (pferrymap != nullptr) {
1563 *pferrymap = go_by_boat ? ferry_map : nullptr;
1564 }
1565 if (pferryboat != nullptr) {
1566 *pferryboat = go_by_boat ? ferryboat : nullptr;
1567 }
1568 if (pboattype != nullptr) {
1569 *pboattype = go_by_boat ? boattype : nullptr;
1570 }
1571 if (pmove_time != nullptr) {
1573 }
1574 goto_dest_tile = (go_by_boat && ferryboat != nullptr
1575 ? unit_tile(ferryboat) : atile);
1576 bk = bk_e;
1577 }
1578 }
1579 /* END STEAM-ENGINES KLUGE */
1580
1581 if (punit->id != 0
1582 && ferryboat != nullptr
1583 && punit_class->adv.sea_move == MOVE_NONE) {
1585 "%s(): with boat %s@(%d, %d) -> %s@(%d, %d)"
1586 " (go_by_boat = %d, move_time = %d, want = " ADV_WANT_PRINTF
1587 ", best = " ADV_WANT_PRINTF ")",
1588 __FUNCTION__, unit_rule_name(ferryboat),
1589 TILE_XY(unit_tile(ferryboat)), city_name_get(acity),
1590 TILE_XY(atile), go_by_boat, move_time, want, best);
1591 }
1592
1593 if (want > best && ai_fuzzy(pplayer, TRUE)) {
1594 /* Yes, we like this target */
1595 best = want;
1596 *pdest_tile = atile;
1597 if (pferrymap != nullptr) {
1598 *pferrymap = go_by_boat ? ferry_map : nullptr;
1599 }
1600 if (pferryboat != nullptr) {
1601 *pferryboat = go_by_boat ? ferryboat : nullptr;
1602 }
1603 if (pboattype != nullptr) {
1604 *pboattype = go_by_boat ? boattype : nullptr;
1605 }
1606 if (pmove_time != nullptr) {
1608 }
1609 goto_dest_tile = (go_by_boat && ferryboat != nullptr
1610 ? unit_tile(ferryboat) : atile);
1611 }
1613
1615 /* I'm not sure the following code is good but it seems to be adequate.
1616 * I am deliberately not adding ferryboat code to the unit_list_iterate().
1617 * -- Syela */
1619 struct tile *atile = unit_tile(aunit);
1620
1621 if (tile_city(atile) != nullptr) {
1622 /* Already dealt with it. */
1623 continue;
1624 }
1625
1626 if (handicap && !map_is_known(atile, pplayer)) {
1627 /* Can't see the target. */
1628 continue;
1629 }
1630
1632 && 0 == punit->id) {
1633 /* We will not build units just to chase caravans and
1634 * ambassadors. */
1635 continue;
1636 }
1637
1638 /* We have to assume the attack is diplomatically ok.
1639 * We cannot use can_player_attack_tile(), because we might not
1640 * be at war with aplayer yet */
1641 if (!can_unit_attack_tile(punit, nullptr, atile)
1642 || aunit != get_defender(nmap, punit, atile, nullptr)) {
1643 /* We cannot attack it, or it is not the main defender. */
1644 continue;
1645 }
1646
1648 /* Cannot reach it. */
1649 continue;
1650 }
1651
1654
1655 move_time = pos.turn;
1656 if (10 < move_time) {
1657 /* Too far. */
1658 want = 0;
1659 } else {
1660 want = kill_desire(benefit, attack, bcost, vulnerability, 1);
1661 /* Take into account maintenance of the unit. */
1662 /* FIXME: Depends on the government. */
1663 want -= move_time * SHIELD_WEIGHTING;
1664 /* Take into account unhappiness
1665 * (costs 2 luxuries to compensate). */
1666 want -= (unhap ? 2 * move_time * TRADE_WEIGHTING : 0);
1667 }
1669 want, MAX(1, move_time), bcost_bal);
1670 if (want > best && ai_fuzzy(pplayer, TRUE)) {
1671 best = want;
1672 *pdest_tile = atile;
1673 if (pferrymap != nullptr) {
1674 *pferrymap = nullptr;
1675 }
1676 if (pferryboat != nullptr) {
1677 *pferryboat = nullptr;
1678 }
1679 if (pboattype != nullptr) {
1680 *pboattype = nullptr;
1681 }
1682 if (pmove_time != nullptr) {
1684 }
1686 }
1689
1690 if (ppath != nullptr) {
1691 *ppath = (goto_dest_tile != nullptr && goto_dest_tile != punit_tile
1692 ? pf_map_path(punit_map, goto_dest_tile) : nullptr);
1693 }
1694
1696 if (ferry_map != nullptr
1697 && (pferrymap == nullptr || *pferrymap != ferry_map)) {
1699 }
1700
1702
1703 return best;
1704}
1705
1706/**********************************************************************/
1715{
1716 struct pf_parameter parameter;
1717 struct pf_map *pfm;
1718 struct player *pplayer = unit_owner(punit);
1719 struct city *pcity, *best_city = nullptr;
1720 int best = FC_INFINITY, cur;
1721 const struct civ_map *nmap = &(wld.map);
1722
1723 pft_fill_unit_parameter(&parameter, nmap, punit);
1724 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1725 pfm = pf_map_new(&parameter);
1726
1727 pf_map_move_costs_iterate(pfm, ptile, move_cost, TRUE) {
1728 if (move_cost > best) {
1729 /* We already found a better city. No need to continue. */
1730 break;
1731 }
1732
1733 pcity = tile_city(ptile);
1734 if (pcity == nullptr || !pplayers_allied(pplayer, city_owner(pcity))) {
1735 continue;
1736 }
1737
1738 /* Score based on the move cost. */
1739 cur = move_cost;
1740
1741 /* Note the unit owner may be different from the city owner. */
1742 if (0 == get_unittype_bonus(unit_owner(punit), ptile,
1743 unit_type_get(punit), nullptr,
1744 EFT_HP_REGEN)) {
1745 /* If we cannot regen fast our hit points here, let's make some
1746 * penalty. */
1747 cur *= 3;
1748 }
1749
1750 if (cur < best) {
1751 best_city = pcity;
1752 best = cur;
1753 }
1755
1757 return best_city;
1758}
1759
1760/**********************************************************************/
1766 struct player *pplayer,
1767 struct unit *punit)
1768{
1769 struct city *pc;
1770 bool only_continent = TRUE;
1771
1772 if (unit_transported(punit)) {
1773 /* If we are in transport, we can go to any continent.
1774 * Actually, we are not currently in a continent where to stay. */
1776 }
1777
1778 if ((pc = find_closest_city(unit_tile(punit), nullptr, pplayer, FALSE,
1779 only_continent, FALSE, FALSE, TRUE, nullptr))) {
1781 UNIT_LOG(LOG_DEBUG, punit, "Barbarian heading to conquer %s",
1782 city_name_get(pc));
1783 (void) dai_gothere(ait, pplayer, punit, pc->tile);
1784 } else {
1785 struct unit *ferry = nullptr;
1786
1787 if (unit_transported(punit)) {
1788 ferry = unit_transport_get(punit);
1789
1790 /* We already are in a boat so it needs no
1791 * free capacity */
1792 if (!is_boat_free(ait, ferry, punit, 0)) {
1793 /* We cannot control our ferry. */
1794 ferry = nullptr;
1795 }
1796 } else {
1797 /* We are not in a boat yet. Search for one. */
1799 if (is_boat_free(ait, aunit, punit, 1)
1801 ferry = aunit;
1802 break;
1803 }
1805 }
1806
1807 if (ferry) {
1808 UNIT_LOG(LOG_DEBUG, punit, "Barbarian sailing to conquer %s",
1809 city_name_get(pc));
1810 (void) aiferry_goto_amphibious(ait, ferry, punit, pc->tile);
1811 } else {
1812 /* This is not an error. Somebody else might be in charge
1813 * of the ferry. */
1814 UNIT_LOG(LOG_DEBUG, punit, "unable to find barbarian ferry");
1815 }
1816 }
1817 } else {
1818 UNIT_LOG(LOG_DEBUG, punit, "Barbarian find no target city");
1819 }
1820}
1821
1822/**********************************************************************/
1828static void dai_military_attack(struct ai_type *ait, struct player *pplayer,
1829 struct unit *punit)
1830{
1831 struct tile *dest_tile;
1832 int id = punit->id;
1833 int ct = 10;
1834 struct city *pcity = nullptr;
1835
1837
1838 /* Barbarians pillage, and might keep on doing that so they sometimes
1839 * even finish it. */
1840 if (punit->activity == ACTIVITY_PILLAGE && is_barbarian(pplayer)
1841 && fc_rand(2) == 1) {
1842 return;
1843 }
1844
1845 /* First find easy nearby enemies, anything better than pillage goes.
1846 * NB: We do not need to repeat dai_military_rampage(), it is repeats itself
1847 * until it runs out of targets. */
1848 /* FIXME: 1. dai_military_rampage() never checks if it should defend newly
1849 * conquered cities.
1850 * FIXME: 2. would be more convenient if it returned FALSE if we run out
1851 * of moves too.*/
1853 return; /* We died */
1854 }
1855
1856 if (punit->moves_left <= 0) {
1857 return;
1858 }
1859
1860 /* Main attack loop */
1861 do {
1862 struct tile *start_tile = unit_tile(punit);
1863 struct pf_path *path;
1864 struct unit *ferryboat;
1865
1866 /* Then find enemies the hard way */
1867 find_something_to_kill(ait, pplayer, punit, &dest_tile, &path,
1868 nullptr, &ferryboat, nullptr, nullptr);
1869 if (!same_pos(unit_tile(punit), dest_tile)) {
1870 if (!is_tiles_adjacent(unit_tile(punit), dest_tile)
1871 || !can_unit_attack_tile(punit, nullptr, dest_tile)) {
1872
1873 /* Adjacent and can't attack usually means we are not marines
1874 * and on a ferry. This fixes the problem (usually). */
1875 UNIT_LOG(LOG_DEBUG, punit, "mil att gothere -> (%d, %d)",
1876 TILE_XY(dest_tile));
1877
1878 /* Set ACTIVITY_GOTO more permanently than just inside
1879 * adv_follow_path(). This way other units will know we're
1880 * on our way even if we don't reach target yet. */
1881 punit->goto_tile = dest_tile;
1883 if (path != nullptr && !adv_follow_path(punit, path, dest_tile)) {
1884 /* Died. */
1885 pf_path_destroy(path);
1886 return;
1887 }
1888 if (ferryboat != nullptr) {
1889 /* Need a boat. */
1890 aiferry_gobyboat(ait, pplayer, punit, dest_tile, FALSE);
1891 pf_path_destroy(path);
1892 return;
1893 }
1894 if (punit->moves_left <= 0) {
1895 /* No moves left. */
1896 pf_path_destroy(path);
1897 return;
1898 }
1899
1900 /* Either we're adjacent or we sitting on the tile. We might be
1901 * sitting on the tile if the enemy that _was_ sitting there
1902 * attacked us and died _and_ we had enough movement to get there */
1903 if (same_pos(unit_tile(punit), dest_tile)) {
1904 UNIT_LOG(LOG_DEBUG, punit, "mil att made it -> (%d, %d)",
1905 TILE_XY(dest_tile));
1906 pf_path_destroy(path);
1907 break;
1908 }
1909 }
1910
1911 if (is_tiles_adjacent(unit_tile(punit), dest_tile)) {
1912 /* Close combat. fstk sometimes want us to attack an adjacent
1913 * enemy that rampage wouldn't */
1914 UNIT_LOG(LOG_DEBUG, punit, "mil att bash -> (%d, %d)",
1915 TILE_XY(dest_tile));
1916 if (!dai_unit_attack(ait, punit, dest_tile)) {
1917 /* Died */
1918 pf_path_destroy(path);
1919 return;
1920 }
1921 } else if (!same_pos(start_tile, unit_tile(punit))) {
1922 /* Got stuck. Possibly because of adjacency to an
1923 * enemy unit. Perhaps we are in luck and are now next to a
1924 * tempting target? Let's find out... */
1927 pf_path_destroy(path);
1928 return;
1929 }
1930
1931 } else {
1932 /* FIXME: This happens a bit too often! */
1933 UNIT_LOG(LOG_DEBUG, punit, "fstk didn't find us a worthy target!");
1934 /* No worthy enemies found, so abort loop */
1935 ct = 0;
1936 }
1937 pf_path_destroy(path);
1938
1939 ct--; /* Infinite loops from railroads must be stopped */
1940 } while (punit->moves_left > 0 && ct > 0);
1941
1942 /* Cleanup phase */
1943 if (punit->moves_left == 0) {
1944 return;
1945 }
1947 if (pcity != nullptr
1948 && (dai_is_ferry(punit, ait)
1949 || punit->hp < unit_type_get(punit)->hp * 0.50)) { /* WAG */
1950 /* Go somewhere safe */
1951 UNIT_LOG(LOG_DEBUG, punit, "heading to nearest safe house.");
1952 (void) dai_unit_goto(ait, punit, pcity->tile);
1953 } else if (!is_barbarian(pplayer)) {
1954 /* Nothing else to do, so try exploring. */
1955 switch (manage_auto_explorer(punit)) {
1956 case MR_DEATH:
1957 /* Don't use punit! */
1958 return;
1959 case MR_OK:
1960 UNIT_LOG(LOG_DEBUG, punit, "nothing else to do, so exploring");
1961 break;
1962 default:
1963 UNIT_LOG(LOG_DEBUG, punit, "nothing to do - no more exploring either");
1964 break;
1965 };
1966 } else {
1967 /* You can still have some moves left here, but barbarians should
1968 not sit helplessly, but advance towards nearest known enemy city */
1969 UNIT_LOG(LOG_DEBUG, punit, "attack: barbarian");
1970 dai_military_attack_barbarian(ait, pplayer, punit);
1971 }
1972
1973 if ((punit = game_unit_by_number(id)) && punit->moves_left > 0) {
1974 UNIT_LOG(LOG_DEBUG, punit, "attack: giving up unit to defense");
1975 dai_military_defend(ait, pplayer, punit);
1976 }
1977}
1978
1979/**********************************************************************/
1983static bool dai_find_boat_for_unit(struct ai_type *ait, struct unit *punit)
1984{
1985 bool alive = TRUE;
1986 int ferryboat = 0;
1987 struct pf_path *path_to_ferry = nullptr;
1988
1989 UNIT_LOG(LOG_CARAVAN, punit, "requesting a boat!");
1990 ferryboat = aiferry_find_boat(ait, punit, 1, &path_to_ferry);
1991 /* Going to meet the boat */
1992 if ((ferryboat <= 0)) {
1994 "in find_boat_for_unit cannot find any boats.");
1995 /* If we are undefended on the country side go to a city */
1997
1998 if (current_city == nullptr) {
2000
2001 if (city_near != nullptr) {
2003 }
2004 }
2005 } else {
2006 if (path_to_ferry != nullptr) {
2008 /* Died. */
2010 path_to_ferry = nullptr;
2011 alive = FALSE;
2012 } else {
2014 path_to_ferry = nullptr;
2015 alive = TRUE;
2016 }
2017 }
2018 }
2019
2020 return alive;
2021}
2022
2023/**********************************************************************/
2032 struct tile *ctile, struct tile *ptile)
2033{
2034 /* We usually have Inaccessible terrain, so not testing MOVE_FULL == */
2035 bool lm = MOVE_NONE != pclass->adv.land_move,
2036 sm = MOVE_NONE != pclass->adv.sea_move;
2037 struct civ_map *pmap = &(wld.map);
2038
2039 if (lm && sm) {
2040 return FALSE;
2041 }
2042
2043 /* We could use adjc_iterate() but likely often tiles are on the same
2044 * continent and it will be more time to find where they connect */
2047
2048 if (is_ocean_tile(atile) ? sm : lm) {
2049 iterate_outward(pmap, ptile, 1, btile) {
2050 if (tile_continent(btile) == acont) {
2051 return FALSE;
2052 }
2054 }
2056
2057 if (is_tiles_adjacent(ctile, ptile)) {
2058 return FALSE;
2059 }
2060
2061 return TRUE;
2062}
2063
2064/**********************************************************************/
2070static void dai_caravan_goto(struct ai_type *ait, struct player *pplayer,
2071 struct unit *punit,
2072 const struct city *dest_city,
2073 bool help_wonder,
2074 bool required_boat, bool request_boat)
2075{
2076 bool alive = TRUE;
2077 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2078 const struct civ_map *nmap = &(wld.map);
2079
2080 fc_assert_ret(dest_city != nullptr);
2081
2082 /* if we're not there yet, and we can move, move... */
2083 if (!same_pos(dest_city->tile, unit_tile(punit))
2084 && punit->moves_left != 0) {
2085 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) task %s going to %s in %s %s",
2089 help_wonder ? "help a wonder" : "trade", city_name_get(dest_city),
2090 required_boat ? "with a boat" : "");
2091 if (required_boat) {
2092 /* To trade with boat */
2093 if (request_boat) {
2094 /* Try to find new boat */
2096 } else {
2097 /* If we are not being transported then ask for a boat again */
2098 alive = TRUE;
2101 unit_tile(punit), dest_city->tile)) {
2103 }
2104 }
2105 if (alive) {
2106 /* FIXME: Sometimes we get FALSE here just because
2107 * a trireme that we've boarded can't go over an ocean. */
2108 alive = dai_gothere(ait, pplayer, punit, dest_city->tile);
2109 }
2110 } else {
2111 /* To trade without boat */
2113 }
2114 }
2115
2116 /* If moving didn't kill us, and we got to the destination, handle it. */
2117 if (alive && real_map_distance(dest_city->tile, unit_tile(punit)) <= 1) {
2118 /* Release the boat! */
2119 if (unit_transported(punit)) {
2121 }
2123 punit, dest_city)) {
2124 /*
2125 * We really don't want to just drop all caravans in immediately.
2126 * Instead, we want to aggregate enough caravans to build instantly.
2127 * -AJS, 990704
2128 */
2129 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) helps build wonder in %s",
2132 punit->id,
2135 unit_do_action(pplayer, punit->id, dest_city->id,
2136 0, "", ACTION_HELP_WONDER);
2138 punit, dest_city)) {
2139 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) creates trade route in %s",
2142 punit->id,
2145 unit_do_action(pplayer, punit->id, dest_city->id,
2146 0, "", ACTION_TRADE_ROUTE);
2148 punit, dest_city)) {
2149 /* Get the one time bonus. */
2150 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) enters marketplace of %s",
2153 punit->id,
2156 unit_do_action(pplayer, punit->id, dest_city->id,
2157 0, "", ACTION_MARKETPLACE);
2158 } else {
2159 enum log_level level = LOG_NORMAL;
2160
2161 if (help_wonder) {
2162 /* A Caravan ordered to help build wonder may arrive after
2163 * enough shields to build the wonder is produced. */
2165 }
2166
2168 "%s %s[%d](%d,%d) unable to trade with %s",
2171 punit->id,
2174 }
2175 }
2176}
2177
2178/**********************************************************************/
2182static void caravan_optimize_callback(const struct caravan_result *result,
2183 void *data)
2184{
2185 const struct unit *caravan = data;
2186
2187 log_base(LOG_CARAVAN3, "%s %s[%d](%d,%d) %s: %s %s worth %g",
2189 unit_rule_name(caravan),
2190 caravan->id,
2191 TILE_XY(unit_tile(caravan)),
2192 city_name_get(result->src),
2193 result->help_wonder ? "wonder in" : "trade to",
2194 city_name_get(result->dest),
2195 result->value);
2196}
2197
2198/**********************************************************************/
2202 struct unit *punit)
2203{
2204 struct tile *src = nullptr, *dest = nullptr, *src_home_city = nullptr;
2205 struct city *phome_city = nullptr;
2206 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2207
2208 if ((unit_data->task != AIUNIT_NONE)) {
2209 src = unit_tile(punit);
2211 if (phome_city != nullptr) {
2213 }
2214 dest = punit->goto_tile;
2215
2216 if (src == nullptr || dest == nullptr) {
2217 return FALSE;
2218 }
2219
2220 /* If we have a home continent, and are not there.
2221 * (FIXME: well, why?)
2222 * (I guess because home continent is which we were supposed to leave,
2223 * not the target continent) */
2224 if (src_home_city != nullptr
2226 return FALSE;
2227 }
2228
2229 if (!goto_is_sane(punit, dest)) {
2230 if (unit_transported(punit)) {
2231 /* If we're being transported */
2232 return FALSE;
2233 }
2234 if ((punit->birth_turn + 15 < game.info.turn)) {
2235 /* We are tired of waiting */
2237
2238 if (ferrys <= 0) {
2239 /* There are no ferrys available... give up */
2240 return TRUE;
2241 } else {
2242 if (punit->birth_turn + 20 < game.info.turn) {
2243 /* We are fed up! */
2244 return TRUE;
2245 }
2246 }
2247 }
2248 }
2249 }
2250
2251 return FALSE;
2252}
2253
2254/**********************************************************************/
2261 struct unit *punit)
2262{
2264 Continent_id continent;
2265
2266 fc_assert(pcity != nullptr);
2267
2268 if (unit_class_get(punit)->adv.ferry_types <= 0) {
2269 /* There is just no possible transporters. */
2270 return FALSE;
2271 }
2272 continent = tile_continent(pcity->tile);
2273
2274 /* Look for proper destination city at different continent. */
2275 city_list_iterate(pplayer->cities, acity) {
2277 if (tile_continent(acity->tile) != continent) {
2278 return TRUE;
2279 }
2280 }
2282
2284 if (aplayer == pplayer || !aplayer->is_alive) {
2285 continue;
2286 }
2287 if (pplayers_allied(pplayer, aplayer)) {
2288 city_list_iterate(aplayer->cities, acity) {
2290 if (tile_continent(acity->tile) != continent) {
2291 return TRUE;
2292 }
2293 }
2296 }
2297
2298 return FALSE;
2299}
2300
2301/**********************************************************************/
2305static bool search_homecity_for_caravan(struct ai_type *ait, struct unit *punit)
2306{
2307 struct city *nearest = nullptr;
2308 int min_dist = FC_INFINITY;
2309 struct tile *current_loc = unit_tile(punit);
2311 bool alive = TRUE;
2312
2314 struct tile *ctile = city_tile(pcity);
2315
2316 if (tile_continent(ctile) == continent) {
2318
2319 if (this_dist < min_dist) {
2321 nearest = pcity;
2322 }
2323 }
2325
2326 if (nearest != nullptr) {
2328 if (alive && same_pos(unit_tile(punit), nearest->tile)) {
2330 }
2331 }
2332
2333 return alive;
2334}
2335
2336/**********************************************************************/
2342static void dai_manage_caravan(struct ai_type *ait, struct player *pplayer,
2343 struct unit *punit)
2344{
2345 struct caravan_parameter parameter;
2346 struct caravan_result result;
2347 const struct city *homecity;
2348 const struct city *dest = nullptr;
2349 struct unit_ai *unit_data;
2351 bool expect_boats = pclass->adv.ferry_types > 0;
2352 /* TODO: Will pplayer have a boat for punit in a reasonable time? */
2353 bool help_wonder = FALSE;
2354 bool required_boat = FALSE;
2355 bool request_boat = FALSE;
2357 const struct civ_map *nmap = &(wld.map);
2358
2360
2364 /* We only want units that can establish trade, enter marketplace or
2365 * help build wonders */
2366 return;
2367 }
2368
2370
2371 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d) task %s to (%d,%d)",
2376
2377 homecity = game_city_by_number(punit->homecity);
2378 if (homecity == nullptr && unit_data->task == AIUNIT_TRADE) {
2380 return;
2381 }
2382 homecity = game_city_by_number(punit->homecity);
2383 if (homecity == nullptr) {
2384 return;
2385 }
2386 }
2387
2388 if ((unit_data->task == AIUNIT_TRADE
2389 || unit_data->task == AIUNIT_WONDER)) {
2390 /* We are moving to our destination */
2391 /* We check to see if our current goal is feasible */
2393 struct goods_type *pgood = unit_current_goods(punit, homecity);
2394
2395 if ((city_dest == nullptr)
2397 || (unit_data->task == AIUNIT_TRADE
2398 && !(can_cities_trade(homecity, city_dest)
2400 pgood->replace_priority)))
2401 || (unit_data->task == AIUNIT_WONDER
2402 /* Helping the (new) production is illegal. */
2404 || (unit_data->task == AIUNIT_TRADE
2409 punit, city_dest)))
2410 || (unit_data->task == AIUNIT_WONDER
2413 punit, city_dest))) {
2414 /* Destination invalid! */
2415 dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
2416 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d) destination invalid!",
2419 } else {
2420 /* Destination valid. Are we tired of waiting for a boat? */
2423 dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
2424 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d) unit tired of waiting!",
2428 } else {
2429 dest = city_dest;
2430 help_wonder = (unit_data->task == AIUNIT_WONDER) ? TRUE : FALSE;
2431 required_boat = uclass_need_trans_between(pclass, unit_tile(punit), dest->tile);
2433 }
2434 }
2435 }
2436
2437 if (unit_data->task == AIUNIT_NONE) {
2438 if (homecity == nullptr) {
2439 /* FIXME: We shouldn't bother in getting homecity for
2440 * caravan that will then be used for wonder building. */
2442 return;
2443 }
2444 homecity = game_city_by_number(punit->homecity);
2445 if (homecity == nullptr) {
2446 return;
2447 }
2448 }
2449
2451 /* Make more trade with allies than other peaceful nations
2452 * by considering only allies 50% of the time.
2453 * (the other 50% allies are still considered, but so are other nations) */
2454 if (fc_rand(2)) {
2455 /* Be optimistic about development of relations with no-contact and
2456 * cease-fire nations. */
2457 parameter.allow_foreign_trade = FTL_NONWAR;
2458 } else {
2459 parameter.allow_foreign_trade = FTL_ALLIED;
2460 }
2461
2464 parameter.callback_data = punit;
2465 }
2467 parameter.ignore_transit_time = TRUE;
2468 }
2471 parameter.ignore_transit_time = FALSE;
2472 }
2473 caravan_find_best_destination(nmap, punit, &parameter, &result,
2474 !has_handicap(pplayer, H_MAP));
2475 if (result.dest != nullptr) {
2476 /* We did find a new destination for the unit */
2477 dest = result.dest;
2478 help_wonder = result.help_wonder;
2479 required_boat = uclass_need_trans_between(pclass, unit_tile(punit), dest->tile);
2480 request_boat = required_boat;
2482 (help_wonder) ? AIUNIT_WONDER : AIUNIT_TRADE,
2483 dest->tile);
2484 } else {
2485 dest = nullptr;
2486 }
2487 }
2488
2489 if (required_boat && !expect_boats) {
2490 /* Would require boat, but can't have them. Render destination invalid. */
2491 dest = nullptr;
2492 }
2493
2494 if (dest != nullptr) {
2495 dai_caravan_goto(ait, pplayer, punit, dest, help_wonder,
2496 required_boat, request_boat);
2497 return; /* That may have clobbered the unit */
2498 } else {
2499 /* We have nowhere to go! */
2500 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d), nothing to do!",
2504 /* Should we become a defensive unit? */
2505 }
2506}
2507
2508/**********************************************************************/
2513 struct unit *punit)
2514{
2515 struct player *pplayer = unit_owner(punit);
2516 struct city *pcity = tile_city(unit_tile(punit));
2517 struct city *safe = nullptr;
2518 const struct unit_type *punittype = unit_type_get(punit);
2519 bool no_recovery;
2520
2522
2523 if (pcity != nullptr) {
2524 /* Rest in the city until the hitpoints are recovered, but attempt
2525 * to protect city from attack (and be opportunistic too)*/
2528 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "recovering hit points.");
2529 } else {
2530 return; /* We died heroically defending our city */
2531 }
2532 } else {
2533 /* Goto to nearest city to recover hit points */
2534 /* Just before, check to see if we can occupy an undefended enemy city */
2537 return; /* Oops, we died */
2538 }
2539
2540 /* Find a city to stay and go there */
2542 if (safe) {
2543 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "going to %s to recover",
2545 if (!dai_unit_goto(ait, punit, safe->tile)) {
2546 log_base(LOGLEVEL_RECOVERY, "died trying to hide and recover");
2547 return;
2548 }
2549 } else {
2550 /* Oops */
2551 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "didn't find a city to recover in!");
2552 dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
2553 dai_military_attack(ait, pplayer, punit);
2554 return;
2555 }
2556 }
2557
2558 /* Is the unit still damaged? If true, and could recover hit points, do so.
2559 * Don't wait if would be losing hitpoints that way! */
2561 if (punit->hp == punittype->hp) {
2562 no_recovery = TRUE;
2563 } else {
2565
2566 if (gain < 0) {
2567 no_recovery = TRUE;
2568 } else if (gain == 0 && !punit->moved) {
2569 /* Isn't gaining even though has not moved. */
2570 no_recovery = TRUE;
2571 }
2572 }
2573 if (no_recovery) {
2574 /* We are ready to go out and kick ass again */
2575 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "ready to kick ass again!");
2576 dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
2577 return;
2578 } else {
2579 def_ai_unit_data(punit, ait)->done = TRUE; /* Sit tight */
2580 }
2581}
2582
2583/**********************************************************************/
2587void dai_manage_military(struct ai_type *ait, const struct civ_map *nmap,
2588 struct player *pplayer, struct unit *punit)
2589{
2590 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2591 int id = punit->id;
2592
2594
2595 /* "Escorting" aircraft should not do anything. They are activated
2596 * by their transport or charge. We do _NOT_ set them to 'done'
2597 * since they may need be activated once our charge moves. */
2598 if (unit_data->task == AIUNIT_ESCORT
2600 return;
2601 }
2602
2605 && has_handicap(pplayer, H_AWAY)) {
2606 /* Don't move sentried or fortified units controlled by a player
2607 * in away mode. */
2608 unit_data->done = TRUE;
2609 return;
2610 }
2611
2612 /* Since military units re-evaluate their actions every turn,
2613 we must make sure that previously reserved ferry is freed. */
2615
2617 /* Try hunting with this unit */
2618 if (dai_hunter_qualify(pplayer, punit)) {
2619 int result, sanity = punit->id;
2620
2621 UNIT_LOG(LOGLEVEL_HUNT, punit, "is qualified as hunter");
2622 result = dai_hunter_manage(ait, pplayer, punit);
2623 if (game_unit_by_number(sanity) == nullptr) {
2625 return; /* Died */
2626 }
2627 if (result == -1) {
2628 (void) dai_hunter_manage(ait, pplayer, punit); /* More carnage */
2630 return;
2631 } else if (result >= 1) {
2633 return; /* Done moving */
2634 } else if (unit_data->task == AIUNIT_HUNTER) {
2635 /* This should be very rare */
2636 dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
2637 }
2638 } else if (unit_data->task == AIUNIT_HUNTER) {
2639 dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
2640 }
2642
2643 /* Do we have a specific job for this unit? If not, we default
2644 * to attack. */
2645 dai_military_findjob(ait, nmap, pplayer, punit);
2646
2647 switch (unit_data->task) {
2648 case AIUNIT_AUTO_WORKER:
2649 case AIUNIT_BUILD_CITY:
2650 fc_assert(FALSE); /* This is not the place for this role */
2651 break;
2652 case AIUNIT_DEFEND_HOME:
2654 dai_military_defend(ait, pplayer, punit);
2656 break;
2657 case AIUNIT_ATTACK:
2658 case AIUNIT_NONE:
2660 dai_military_attack(ait, pplayer, punit);
2662 break;
2663 case AIUNIT_ESCORT:
2665 dai_military_bodyguard(ait, pplayer, punit);
2667 break;
2668 case AIUNIT_EXPLORE:
2669 switch (manage_auto_explorer(punit)) {
2670 case MR_DEATH:
2671 /* Don't use punit! */
2672 return;
2673 case MR_OK:
2674 UNIT_LOG(LOG_DEBUG, punit, "more exploring");
2675 break;
2676 default:
2677 UNIT_LOG(LOG_DEBUG, punit, "no more exploring either");
2678 break;
2679 };
2680 def_ai_unit_data(punit, ait)->done = (punit->moves_left <= 0);
2681 break;
2682 case AIUNIT_RECOVER:
2686 break;
2687 case AIUNIT_HUNTER:
2688 fc_assert(FALSE); /* Dealt with above */
2689 break;
2690 default:
2692 }
2693
2694 /* If we are still alive, either sentry or fortify. */
2695 if ((punit = game_unit_by_number(id))) {
2697 struct city *pcity = tile_city(unit_tile(punit));
2698
2699 if (unit_list_find(unit_tile(punit)->units,
2700 unit_data->ferryboat)) {
2702 } else if (pcity || punit->activity == ACTIVITY_IDLE) {
2703 /* We do not need to fortify in cities - we fortify and sentry
2704 * according to home defense setup, for easy debugging. */
2705 if (!pcity || unit_data->task == AIUNIT_DEFEND_HOME) {
2710 }
2711 } else {
2713 }
2714 }
2715 }
2716}
2717
2718/**********************************************************************/
2721static void dai_manage_settler(struct ai_type *ait, struct player *pplayer,
2722 struct unit *punit)
2723{
2724 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2725
2727 unit_data->done = TRUE; /* We will manage this unit later... ugh */
2728 /* If BUILD_CITY must remain BUILD_CITY, otherwise turn into autoworker */
2729 if (unit_data->task == AIUNIT_NONE) {
2731 }
2732}
2733
2734/**********************************************************************/
2742void dai_manage_unit(struct ai_type *ait, struct player *pplayer,
2743 struct unit *punit)
2744{
2745 struct unit_ai *unit_data;
2746 struct unit *bodyguard = aiguard_guard_of(ait, punit);
2747 bool is_ferry = FALSE;
2748 const struct unit_type *ptype;
2749 const struct civ_map *nmap = &(wld.map);
2750
2752
2753 /* Don't manage the unit if it is under human orders. */
2754 if (unit_has_orders(punit)) {
2756
2757 UNIT_LOG(LOG_VERBOSE, punit, "is under human orders, aborting AI control.");
2758 dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
2759 unit_data->done = TRUE;
2760
2761 return;
2762 }
2763
2764 /* Check if we have lost our bodyguard. If we never had one, all
2765 * fine. If we had one and lost it, ask for a new one. */
2766 if (!bodyguard && aiguard_has_guard(ait, punit)) {
2767 UNIT_LOG(LOGLEVEL_BODYGUARD, punit, "lost bodyguard, asking for new");
2769 }
2770
2772
2773 if (punit->moves_left <= 0) {
2774 /* Can do nothing */
2775 unit_data->done = TRUE;
2776
2777 return;
2778 }
2779
2780 is_ferry = dai_is_ferry(punit, ait);
2781
2783
2786 dai_manage_diplomat(ait, pplayer, punit);
2788
2789 return;
2790 } else if (ptype->adv.worker
2792 dai_manage_settler(ait, pplayer, punit);
2793
2794 return;
2799 dai_manage_caravan(ait, pplayer, punit);
2801
2802 return;
2804 dai_manage_barbarian_leader(ait, pplayer, punit);
2805
2806 return;
2809 dai_manage_paratrooper(ait, pplayer, punit);
2810
2811 return;
2812 } else if (is_ferry && unit_data->task != AIUNIT_HUNTER) {
2814 dai_manage_ferryboat(ait, pplayer, punit);
2816
2817 return;
2818 } else if (utype_fuel(ptype)
2819 && unit_data->task != AIUNIT_ESCORT) {
2821 dai_manage_airunit(ait, pplayer, punit);
2823
2824 return;
2825 } else if (is_losing_hp(punit)) {
2826 /* This unit is losing hitpoints over time */
2827
2828 /* TODO: We can try using air-unit code for helicopters, just
2829 * pretend they have fuel = HP / 3 or something. */
2830 unit_data->done = TRUE; /* we did our best, which was ...
2831 nothing */
2832 return;
2833 } else if (!is_special_unit(punit)) {
2835 UNIT_LOG(LOG_DEBUG, punit, "recruit unit for the military");
2836 dai_manage_military(ait, nmap, pplayer, punit);
2838
2839 return;
2840 } else {
2841 /* what else could this be? -- Syela */
2842 switch (manage_auto_explorer(punit)) {
2843 case MR_DEATH:
2844 /* don't use punit! */
2845 break;
2846 case MR_OK:
2847 UNIT_LOG(LOG_DEBUG, punit, "now exploring");
2848 break;
2849 default:
2850 UNIT_LOG(LOG_DEBUG, punit, "fell through all unit tasks, defending");
2852 dai_military_defend(ait, pplayer, punit);
2853 break;
2854 };
2855
2856 return;
2857 }
2858}
2859
2860/**********************************************************************/
2866static void dai_set_defenders(struct ai_type *ait, struct player *pplayer)
2867{
2868 city_list_iterate(pplayer->cities, pcity) {
2869 /* The idea here is that we should never keep more than two
2870 * units in permanent defense. */
2871 int total_defense = 0;
2873 bool emergency = FALSE;
2874 int count = 0;
2879 int entertainers = 0;
2880 bool enough = FALSE;
2881
2884 entertainers += pcity->specialists[sp];
2885 }
2887
2888 martless_unhappy += entertainers; /* We want to use martial law instead
2889 * of entertainers. */
2890
2891 while (!enough
2894 && martless_unhappy > mart_each * count))) {
2895 int best_want = 0;
2896 struct unit *best = nullptr;
2897 bool defense_needed = total_defense <= total_attack; /* Defense or martial */
2898
2900 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2901
2902 if ((unit_data->task == AIUNIT_NONE || emergency)
2903 && unit_data->task != AIUNIT_DEFEND_HOME
2904 && unit_owner(punit) == pplayer) {
2905 int want = assess_defense_unit(ait, pcity, punit, FALSE);
2906
2907 if (want > best_want) {
2908 best_want = want;
2909 best = punit;
2910 }
2911 }
2913
2914 if (best == nullptr) {
2915 if (defense_needed) {
2916 /* Ooops - try to grab any unit as defender! */
2917 if (emergency) {
2918 CITY_LOG(LOG_DEBUG, pcity, "Not defended properly");
2919 break;
2920 }
2921 emergency = TRUE;
2922 } else {
2923 break;
2924 }
2925 } else {
2926 const struct unit_type *btype = unit_type_get(best);
2927
2928 if ((martless_unhappy < mart_each * count
2929 || count >= mart_max || mart_each <= 0)
2930 && ((count >= 2
2931 && btype->attack_strength > btype->defense_strength)
2932 || (count >= 4
2933 && btype->attack_strength == btype->defense_strength))) {
2934 /* In this case attack would be better defense than fortifying
2935 * to city. */
2936 enough = TRUE;
2937 } else {
2938 int loglevel = pcity->server.debug ? LOG_AI_TEST : LOG_DEBUG;
2939
2941 UNIT_LOG(loglevel, best, "Defending city");
2943 count++;
2944 }
2945 }
2946 }
2947 CITY_LOG(LOG_DEBUG, pcity, "Evaluating defense: %d defense, %d incoming"
2948 ", %d defenders (out of %d)", total_defense, total_attack, count,
2951}
2952
2953/**********************************************************************/
2961void dai_manage_units(struct ai_type *ait, struct player *pplayer)
2962{
2964 dai_airlift(ait, pplayer);
2966
2967 /* Clear previous orders, if desirable, here. */
2968 unit_list_iterate(pplayer->units, punit) {
2969 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2970
2971 unit_data->done = FALSE;
2972 if (unit_data->task == AIUNIT_DEFEND_HOME) {
2973 dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
2974 }
2976
2977 /* Find and set city defenders first - figure out which units are
2978 * allowed to leave home. */
2979 dai_set_defenders(ait, pplayer);
2980
2982 if ((!unit_transported(punit)
2983 || unit_owner(unit_transport_get(punit)) != pplayer)
2984 && !def_ai_unit_data(punit, ait)->done) {
2985 /* Though it is usually the passenger who drives the transport,
2986 * the transporter is responsible for managing its passengers. */
2987 dai_manage_unit(ait, pplayer, punit);
2988 }
2990}
2991
2992/**********************************************************************/
2998 const struct city *pcity)
2999{
3000 const struct impr_type *impr_req = nullptr;
3001 const struct req_context context = {
3003 .city = pcity,
3004 .tile = city_tile(pcity),
3005 .unittype = putype,
3006 };
3007
3008 requirement_vector_iterate(&putype->build_reqs, preq) {
3009 if (is_req_active(&context, nullptr, preq, RPT_CERTAIN)) {
3010 /* Already there. */
3011 continue;
3012 }
3014 city_owner(pcity), pcity)) {
3015 /* The unit type can't be built at all. */
3016 return nullptr;
3017 }
3018 if (VUT_IMPROVEMENT == preq->source.kind && preq->present) {
3019 /* This is (one of) the building(s) required. */
3020 impr_req = preq->source.value.building;
3021 }
3023
3024 return impr_req;
3025}
3026
3027/**********************************************************************/
3032 const struct unit_type *base)
3033{
3034 /* This is the real function: */
3035 do {
3036 base = base->obsoleted_by;
3037 if (base == test) {
3038 return TRUE;
3039 }
3040 } while (base);
3041 return FALSE;
3042}
3043
3044/**********************************************************************/
3048static void dai_manage_barbarian_leader(struct ai_type *ait,
3049 struct player *pplayer,
3050 struct unit *leader)
3051{
3053 struct pf_parameter parameter;
3054 struct pf_map *pfm;
3055 struct pf_reverse_map *pfrm;
3056 struct unit *worst_danger;
3057 int move_cost, best_move_cost;
3058 int body_guards;
3059 bool alive = TRUE;
3060 const struct civ_map *nmap = &(wld.map);
3061
3063
3064 if (leader->moves_left == 0
3066 && 1 < unit_list_size(leader_tile->units))) {
3068
3069 return;
3070 }
3071
3072 if (is_boss_of_boat(ait, leader)) {
3073 /* We are in charge. Of course, since we are the leader...
3074 * But maybe somebody more militaristic should lead our ship to battle! */
3075
3076 /* First release boat from leaders lead */
3078
3082 && warrior->moves_left > 0) {
3083 /* This seems like a good warrior to lead us in to conquest! */
3084 dai_manage_unit(ait, pplayer, warrior);
3085
3086 /* If we reached our destination, ferryboat already called
3087 * ai_manage_unit() for leader. So no need to continue here.
3088 * Leader might even be dead.
3089 * If this return is removed, surrounding unit_list_iterate()
3090 * has to be replaced with unit_list_iterate_safe()*/
3091 return;
3092 }
3094 }
3095
3096 /* If we are not in charge of the boat, continue as if we
3097 * were not in a boat - we may want to leave the ship now. */
3098
3099 /* Check the total number of units able to protect our leader. */
3100 body_guards = 0;
3101 unit_list_iterate(pplayer->units, punit) {
3104 body_guards++;
3105 }
3107
3108 if (0 < body_guards) {
3109 pft_fill_unit_parameter(&parameter, nmap, leader);
3110 parameter.omniscience = !has_handicap(pplayer, H_MAP);
3111 pfm = pf_map_new(&parameter);
3112
3113 /* Find the closest body guard.
3114 * FIXME: Maybe choose the strongest too? */
3115 pf_map_tiles_iterate(pfm, ptile, FALSE) {
3116 unit_list_iterate(ptile->units, punit) {
3117 if (unit_owner(punit) == pplayer
3120 struct pf_path *path = pf_map_path(pfm, ptile);
3121
3122 adv_follow_path(leader, path, ptile);
3123 pf_path_destroy(path);
3125
3126 return;
3127 }
3130
3132 }
3133
3134 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader needs to flee");
3135
3136 /* Check for units we could fear. */
3137 pfrm = pf_reverse_map_new(nmap, pplayer, leader_tile, 3,
3138 !has_handicap(pplayer, H_MAP));
3139 worst_danger = nullptr;
3141
3142 players_iterate(other_player) {
3143 if (other_player == pplayer) {
3144 continue;
3145 }
3146
3147 unit_list_iterate(other_player->units, punit) {
3149 if (PF_IMPOSSIBLE_MC != move_cost && move_cost < best_move_cost) {
3150 best_move_cost = move_cost;
3152 }
3155
3157
3158 if (worst_danger == nullptr) {
3160 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader: no close enemy.");
3161 return;
3162 }
3163
3165 parameter.omniscience = !has_handicap(pplayer, H_MAP);
3166 pfm = pf_map_new(&parameter);
3168
3169 /* Try to escape. */
3170 do {
3172
3173 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader: moves left: %d.",
3174 leader->moves_left);
3175
3178 continue;
3179 }
3180
3181 move_cost = pf_map_move_cost(pfm, near_tile);
3182 if (PF_IMPOSSIBLE_MC != move_cost
3183 && move_cost > best_move_cost) {
3185 "Barbarian leader: safest is (%d, %d), safeness %d",
3187 best_move_cost = move_cost;
3189 }
3191
3192 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader: fleeing to (%d, %d).",
3196 "Barbarian leader: reached the safest position.");
3199 return;
3200 }
3201
3203 if (alive) {
3205 /* Didn't move. No point to retry. */
3207 return;
3208 }
3210 }
3211 } while (alive && 0 < leader->moves_left);
3212
3214}
3215
3216/**********************************************************************/
3222void dai_consider_tile_dangerous(struct ai_type *ait, struct tile *ptile,
3223 struct unit *punit,
3224 enum override_bool *result)
3225{
3226 int a = 0, d, db;
3227 struct player *pplayer = unit_owner(punit);
3228 struct city *pcity = tile_city(ptile);
3229 int extras_bonus = 0;
3230
3231 if (is_human(pplayer)) {
3232 /* Use advisors code for humans. */
3233 return;
3234 }
3235
3236 if (pcity != nullptr && pplayers_allied(city_owner(pcity), pplayer)
3237 && !is_non_allied_unit_tile(ptile, pplayer,
3239 /* We will be safe in a friendly city */
3240 *result = OVERRIDE_FALSE;
3241 return;
3242 }
3243
3244 /* Calculate how well we can defend at (x,y) */
3245 db = 10 + tile_terrain(ptile)->defense_bonus / 10;
3247
3248 db += (db * extras_bonus) / 100;
3250
3251 adjc_iterate(&(wld.map), ptile, ptile1) {
3252 if (has_handicap(pplayer, H_FOG)
3253 && !map_is_known_and_seen(ptile1, pplayer, V_MAIN)) {
3254 /* We cannot see danger at (ptile1) => assume there is none */
3255 continue;
3256 }
3257 unit_list_iterate(ptile1->units, enemy) {
3258 if (pplayers_at_war(unit_owner(enemy), pplayer)
3259 && (unit_attack_unit_at_tile_result(enemy, nullptr, punit, ptile)
3260 == ATT_OK)
3261 && (unit_attack_units_at_tile_result(enemy, nullptr, ptile)
3262 == ATT_OK)) {
3264 if ((a * a * 10) >= d) {
3265 /* The enemies combined strength is too big! */
3266 *result = OVERRIDE_TRUE;
3267 return;
3268 }
3269 }
3272
3273 *result = OVERRIDE_FALSE;
3274}
3275
3276/**********************************************************************/
3279static void update_simple_ai_types(void)
3280{
3281 int i = 0;
3282
3285
3288 && !(pclass->adv.land_move == MOVE_NONE
3291 && punittype->transport_capacity < 8) {
3293 i++;
3294 }
3296
3297 simple_ai_types[i] = nullptr;
3298}
3299
3300/**********************************************************************/
3304{
3305 /* TODO: Remove the simple_ai_types cache or merge it with a general ai
3306 * cache; see the comment to struct unit_type *simple_ai_types at
3307 * the beginning of this file. */
3309
3311 struct unit_type_ai *utai = fc_malloc(sizeof(*utai));
3312
3313 utai->low_firepower = FALSE;
3314 utai->ferry = FALSE;
3315 utai->missile_platform = FALSE;
3316 utai->carries_occupiers = FALSE;
3317 utai->potential_charges = unit_type_list_new();
3318
3321
3324
3325 /* Confirm firepower */
3327 if (pbonus->type == CBONUS_LOW_FIREPOWER) {
3329 if (utype_has_flag(penemy, pbonus->flag)) {
3330 struct unit_type_ai *utai = utype_ai_data(penemy, ait);
3331
3332 utai->low_firepower = TRUE;
3333 }
3335 }
3337
3338 /* Consider potential cargo */
3339 if (punittype->transport_capacity > 0) {
3340 struct unit_type_ai *utai = utype_ai_data(punittype, ait);
3341
3344
3347 utai->missile_platform = TRUE;
3348 } else if (pclass->adv.sea_move != MOVE_NONE
3349 && pcargo->adv.land_move != MOVE_NONE) {
3350 if (pcargo->adv.sea_move != MOVE_FULL) {
3351 utai->ferry = TRUE;
3352 } else {
3353 if (0 != utype_fuel(pctype)) {
3354 utai->ferry = TRUE;
3355 }
3356 }
3357 }
3358
3360 utai->carries_occupiers = TRUE;
3361 }
3362 }
3364 }
3365
3366 /* Consider potential charges */
3369
3370 if (0 < utype_fuel(punittype)
3371 && (0 == utype_fuel(pcharge)
3373 continue;
3374 }
3375
3376 unit_class_list_iterate(pclass->cache.subset_movers, chgcls) {
3377 if (chgcls == utype_class(pcharge)) {
3379 }
3381
3383 struct unit_type_ai *utai = utype_ai_data(punittype, ait);
3384 unit_type_list_append(utai->potential_charges, pcharge);
3385 }
3386
3389}
3390
3391/**********************************************************************/
3395{
3397 struct unit_type_ai *utai = utype_ai_data(ptype, ait);
3398
3399 if (utai == nullptr) {
3400 continue;
3401 }
3402 utype_set_ai_data(ptype, ait, nullptr);
3403
3404 unit_type_list_destroy(utai->potential_charges);
3405 free(utai);
3407}
3408
3409/**********************************************************************/
3412void dai_unit_init(struct ai_type *ait, struct unit *punit)
3413{
3414 /* Make sure that contents of unit_ai structure are correctly initialized,
3415 * if you ever allocate it by some other mean than fc_calloc() */
3416 struct unit_ai *unit_data = fc_calloc(1, sizeof(struct unit_ai));
3417
3418 unit_data->done = FALSE;
3419 unit_data->cur_pos = nullptr;
3420 unit_data->prev_pos = nullptr;
3421 unit_data->target = 0;
3422 BV_CLR_ALL(unit_data->hunted);
3423 unit_data->ferryboat = 0;
3424 unit_data->passenger = 0;
3425 unit_data->bodyguard = 0;
3426 unit_data->charge = 0;
3427
3429}
3430
3431/**********************************************************************/
3434void dai_unit_turn_end(struct ai_type *ait, struct unit *punit)
3435{
3436 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3437
3438 fc_assert_ret(unit_data != nullptr);
3439
3440 BV_CLR_ALL(unit_data->hunted);
3441}
3442
3443/**********************************************************************/
3446void dai_unit_close(struct ai_type *ait, struct unit *punit)
3447{
3448 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3449
3450 fc_assert_ret(unit_data != nullptr);
3451
3454
3455 if (unit_data != nullptr) {
3456 unit_set_ai_data(punit, ait, nullptr);
3458 }
3459}
3460
3461/**********************************************************************/
3464void dai_unit_save(struct ai_type *ait, const char *aitstr,
3465 struct section_file *file,
3466 const struct unit *punit, const char *unitstr)
3467{
3468 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3469
3470 secfile_insert_int(file, unit_data->passenger, "%s.%spassenger",
3471 unitstr, aitstr);
3472 secfile_insert_int(file, unit_data->ferryboat, "%s.%sferryboat",
3473 unitstr, aitstr);
3474 secfile_insert_int(file, unit_data->charge, "%s.%scharge",
3475 unitstr, aitstr);
3476 secfile_insert_int(file, unit_data->bodyguard, "%s.%sbodyguard",
3477 unitstr, aitstr);
3478}
3479
3480/**********************************************************************/
3483void dai_unit_load(struct ai_type *ait, const char *aitstr,
3484 const struct section_file *file,
3485 struct unit *punit, const char *unitstr)
3486{
3487 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3488
3489 unit_data->passenger
3490 = secfile_lookup_int_default(file, 0, "%s.%spassenger",
3491 unitstr, aitstr);
3492 unit_data->ferryboat
3493 = secfile_lookup_int_default(file, 0, "%s.%sferryboat",
3494 unitstr, aitstr);
3495 unit_data->charge
3496 = secfile_lookup_int_default(file, 0, "%s.%scharge",
3497 unitstr, aitstr);
3498 unit_data->bodyguard
3499 = secfile_lookup_int_default(file, 0, "%s.%sbodyguard",
3500 unitstr, aitstr);
3501}
3502
3508
3509/**********************************************************************/
3512static bool role_unit_cb(struct unit_type *ptype, void *data)
3513{
3514 struct role_unit_cb_data *cb_data = (struct role_unit_cb_data *)data;
3516 const struct civ_map *nmap = &(wld.map);
3517
3518 if ((cb_data->tc == TC_LAND && pclass->adv.land_move == MOVE_NONE)
3519 || (cb_data->tc == TC_OCEAN && pclass->adv.sea_move == MOVE_NONE)) {
3520 return FALSE;
3521 }
3522
3523 if (cb_data->build_city == nullptr
3524 || can_city_build_unit_now(nmap, cb_data->build_city, ptype,
3525 RPT_CERTAIN)) {
3526 return TRUE;
3527 }
3528
3529 return FALSE;
3530}
3531
3532/**********************************************************************/
3536 enum terrain_class tc)
3537{
3538 struct role_unit_cb_data cb_data = { .build_city = pcity, .tc = tc };
3539
3541}
3542
3543/**********************************************************************/
3546bool dai_unit_can_strike_my_unit(const struct unit *attacker,
3547 const struct unit *defender)
3548{
3549 struct pf_parameter parameter;
3550 struct pf_map *pfm;
3551 const struct tile *ptarget = unit_tile(defender);
3552 int max_move_cost = attacker->moves_left;
3553 bool able_to_strike = FALSE;
3554 const struct civ_map *nmap = &(wld.map);
3555
3556 pft_fill_unit_parameter(&parameter, nmap, attacker);
3557 parameter.omniscience = !has_handicap(unit_owner(defender), H_MAP);
3558 pfm = pf_map_new(&parameter);
3559
3560 pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
3561 if (move_cost > max_move_cost) {
3562 break;
3563 }
3564
3565 if (ptile == ptarget) {
3567 break;
3568 }
3570
3572
3573 return able_to_strike;
3574}
3575
3576/**********************************************************************/
3579void dai_switch_to_explore(struct ai_type *ait, struct unit *punit,
3580 struct tile *target, enum override_bool *allow)
3581{
3582 struct unit_ai *udata = def_ai_unit_data(punit, ait);
3583
3584 if (udata->task != AIUNIT_NONE && udata->task != AIUNIT_EXPLORE) {
3586
3587 return;
3588 }
3589}
enum gen_action select_actres_action_unit_on_stack(struct civ_map *nmap, enum action_result actres, struct unit *punit, struct tile *ptile)
Definition actions.c:7561
bool is_action_enabled_unit_on_city(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct city *target_city)
Definition actions.c:3103
enum gen_action select_actres_action_unit_on_tile(struct civ_map *nmap, enum action_result actres, struct unit *punit, struct tile *ptile)
Definition actions.c:7585
enum gen_action select_actres_action_unit_on_city(struct civ_map *nmap, enum action_result actres, struct unit *punit, struct city *pcity)
Definition actions.c:7610
static struct action * action_by_number(action_id act_id)
Definition actions.h:400
#define ACTION_NONE
Definition actions.h:59
#define TRADE_WEIGHTING
Definition advbuilding.h:21
#define SHIELD_WEIGHTING
Definition advbuilding.h:20
bool adv_follow_path(struct unit *punit, struct pf_path *path, struct tile *ptile)
Definition advgoto.c:49
int adv_unit_def_rating_basic_squared(const struct unit *punit)
Definition advgoto.c:417
int adv_unit_def_rating_basic(const struct unit *punit)
Definition advgoto.c:408
int adv_unittype_att_rating(const struct unit_type *punittype, int veteran, int moves_left, int hp)
Definition advgoto.c:387
int adv_unit_att_rating(const struct unit *punit)
Definition advgoto.c:398
int adv_could_unit_move_to_tile(struct unit *punit, struct tile *dest_tile)
Definition advgoto.c:361
bool adv_unit_execute_path(struct unit *punit, struct pf_path *path)
Definition advgoto.c:88
#define POWER_DIVIDER
Definition advtools.h:32
enum unit_move_result manage_auto_explorer(struct unit *punit)
void adv_unit_new_task(struct unit *punit, enum adv_unit_task task, struct tile *ptile)
bool is_land_barbarian(struct player *pplayer)
Definition barbarian.c:75
#define BV_CLR_ALL(bv)
Definition bitvector.h:103
void caravan_find_best_destination(const struct civ_map *nmap, const struct unit *caravan, const struct caravan_parameter *parameter, struct caravan_result *result, bool omniscient)
Definition caravan.c:682
void caravan_parameter_init_from_unit(struct caravan_parameter *parameter, const struct unit *caravan)
Definition caravan.c:53
@ FTL_ALLIED
Definition caravan.h:31
@ FTL_NATIONAL_ONLY
Definition caravan.h:30
@ FTL_NONWAR
Definition caravan.h:33
bool city_production_gets_caravan_shields(const struct universal *tgt)
Definition city.c:1917
const char * city_name_get(const struct city *pcity)
Definition city.c:1157
int city_production_unit_veteran_level(struct city *pcity, const struct unit_type *punittype)
Definition city.c:808
bool can_city_build_unit_now(const struct civ_map *nmap, const struct city *pcity, const struct unit_type *punittype, const enum req_problem_type prob_type)
Definition city.c:957
#define city_list_iterate(citylist, pcity)
Definition city.h:508
#define city_tile(_pcity_)
Definition city.h:565
@ CITIZEN_ANGRY
Definition city.h:269
@ CITIZEN_UNHAPPY
Definition city.h:268
#define city_owner(_pcity_)
Definition city.h:564
#define city_list_iterate_end
Definition city.h:510
@ FEELING_NATIONALITY
Definition city.h:280
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)
Definition citytools.c:856
double unit_win_chance(const struct civ_map *nmap, const struct unit *attacker, const struct unit *defender, const struct action *paction)
Definition combat.c:480
bool is_stack_vulnerable(const struct tile *ptile)
Definition combat.c:994
int get_virtual_defense_power(const struct civ_map *nmap, const struct unit_type *att_type, const struct unit_type *def_type, struct player *def_player, struct tile *ptile, bool fortified, int veteran)
Definition combat.c:717
enum unit_attack_result unit_attack_units_at_tile_result(const struct unit *punit, const struct action *paction, const struct tile *ptile)
Definition combat.c:257
int get_total_defense_power(const struct unit *attacker, const struct unit *defender)
Definition combat.c:772
enum unit_attack_result unit_attack_unit_at_tile_result(const struct unit *punit, const struct action *paction, const struct unit *pdefender, const struct tile *dest_tile)
Definition combat.c:123
struct unit * get_defender(const struct civ_map *nmap, const struct unit *attacker, const struct tile *ptile, const struct action *paction)
Definition combat.c:841
bool can_unit_attack_tile(const struct unit *punit, const struct action *paction, const struct tile *dest_tile)
Definition combat.c:312
int base_get_defense_power(const struct unit *punit)
Definition combat.c:574
@ ATT_OK
Definition combat.h:35
char * incite_cost
Definition comments.c:77
void dai_manage_airunit(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiair.c:492
void dai_manage_diplomat(struct ai_type *ait, struct player *pplayer, struct unit *punit)
bool dai_can_requirement_be_met_in_city(const struct requirement *preq, const struct player *pplayer, const struct city *pcity)
Definition daieffects.c:821
bool aiferry_gobyboat(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct tile *dest_tile, bool with_bodyguard)
Definition daiferry.c:764
int aiferry_find_boat(struct ai_type *ait, struct unit *punit, int cap, struct pf_path **path)
Definition daiferry.c:495
void dai_manage_ferryboat(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiferry.c:1119
bool is_boat_free(struct ai_type *ait, struct unit *boat, struct unit *punit, int cap)
Definition daiferry.c:438
bool aiferry_goto_amphibious(struct ai_type *ait, struct unit *ferry, struct unit *passenger, struct tile *ptile)
Definition daiferry.c:730
bool is_boss_of_boat(struct ai_type *ait, struct unit *punit)
Definition daiferry.c:471
int aiferry_avail_boats(struct ai_type *ait, struct player *pplayer)
Definition daiferry.c:353
bool dai_is_ferry(struct unit *pferry, struct ai_type *ait)
Definition daiferry.c:159
void aiferry_clear_boat(struct ai_type *ait, struct unit *punit)
Definition daiferry.c:251
struct city * aiguard_charge_city(struct ai_type *ait, struct unit *guard)
Definition daiguard.c:289
void aiguard_clear_charge(struct ai_type *ait, struct unit *guard)
Definition daiguard.c:117
void aiguard_request_guard(struct ai_type *ait, struct unit *punit)
Definition daiguard.c:227
bool aiguard_has_guard(struct ai_type *ait, struct unit *charge)
Definition daiguard.c:259
void aiguard_assign_guard_unit(struct ai_type *ait, struct unit *charge, struct unit *guard)
Definition daiguard.c:173
bool aiguard_wanted(struct ai_type *ait, struct unit *charge)
Definition daiguard.c:241
void aiguard_assign_guard_city(struct ai_type *ait, struct city *charge, struct unit *guard)
Definition daiguard.c:196
struct unit * aiguard_charge_unit(struct ai_type *ait, struct unit *guard)
Definition daiguard.c:279
void aiguard_clear_guard(struct ai_type *ait, struct unit *charge)
Definition daiguard.c:146
struct unit * aiguard_guard_of(struct ai_type *ait, struct unit *charge)
Definition daiguard.c:269
bool aiguard_has_charge(struct ai_type *ait, struct unit *guard)
Definition daiguard.c:250
void aiguard_update_charge(struct ai_type *ait, struct unit *guard)
Definition daiguard.c:299
#define CHECK_GUARD(ait, guard)
Definition daiguard.h:21
bool dai_hunter_qualify(struct player *pplayer, struct unit *punit)
Definition daihunter.c:288
int dai_hunter_manage(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daihunter.c:436
#define BODYGUARD_LOG(ait, loglevel, punit, msg,...)
Definition dailog.h:69
struct unit_type * dai_choose_defender_versus(struct city *pcity, struct unit *attacker)
Definition daimilitary.c:89
int assess_defense_quadratic(struct ai_type *ait, struct city *pcity)
int assess_defense_unit(struct ai_type *ait, struct city *pcity, struct unit *punit, bool igwall)
void dai_manage_paratrooper(struct ai_type *ait, struct player *pplayer, struct unit *punit)
static struct ai_city * def_ai_city_data(const struct city *pcity, struct ai_type *deftype)
Definition daiplayer.h:42
static struct unit_ai * def_ai_unit_data(const struct unit *punit, struct ai_type *deftype)
Definition daiplayer.h:48
int stack_cost(struct unit *pattacker, struct unit *pdefender)
Definition daitools.c:1308
bool goto_is_sane(struct unit *punit, struct tile *ptile)
Definition daitools.c:429
bool dai_unit_attack(struct ai_type *ait, struct unit *punit, struct tile *ptile)
Definition daitools.c:817
bool dai_unit_goto(struct ai_type *ait, struct unit *punit, struct tile *ptile)
Definition daitools.c:605
void dai_unit_new_task(struct ai_type *ait, struct unit *punit, enum ai_unit_task task, struct tile *ptile)
Definition daitools.c:643
bool dai_assess_military_unhappiness(const struct civ_map *nmap, struct city *pcity)
Definition daitools.c:1444
bool dai_unit_make_homecity(struct unit *punit, struct city *pcity)
Definition daitools.c:755
const char * dai_unit_task_rule_name(const enum ai_unit_task task)
Definition daitools.c:76
adv_want military_amortize(struct player *pplayer, struct city *pcity, adv_want value, int delay, int build_cost)
Definition daitools.c:117
bool dai_gothere(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct tile *dest_tile)
Definition daitools.c:244
void dai_unit_save(struct ai_type *ait, const char *aitstr, struct section_file *file, const struct unit *punit, const char *unitstr)
Definition daiunit.c:3464
static bool invasion_funct(struct ai_type *ait, struct unit *punit, bool dest, int radius, int which)
Definition daiunit.c:1089
static void dai_military_findjob(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct unit *punit)
Definition daiunit.c:921
static bool has_defense(struct city *pcity)
Definition daiunit.c:221
adv_want kill_desire(adv_want benefit, int attack, int loss, int vuln, int victim_count)
Definition daiunit.c:341
static bool search_homecity_for_caravan(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:2305
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)
Definition daiunit.c:2070
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)
Definition daiunit.c:303
static bool unit_role_defender(const struct unit_type *punittype)
Definition daiunit.c:769
void dai_units_ruleset_init(struct ai_type *ait)
Definition daiunit.c:3303
#define LOG_CARAVAN
Definition daiunit.c:87
static int unit_att_rating_now(const struct unit *punit)
Definition daiunit.c:258
static void dai_military_attack_barbarian(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:1765
bool find_beachhead(const struct player *pplayer, struct pf_map *ferry_map, struct tile *dest_tile, const struct unit_type *cargo_type, const struct unit_type *ferry_type, struct tile **ferry_dest, struct tile **beachhead_tile)
Definition daiunit.c:1135
enum gen_action dai_select_tile_attack_action(struct civ_map *nmap, struct unit *punit, struct tile *ptile, enum action_target_kind *kind)
Definition daiunit.c:444
static void update_simple_ai_types(void)
Definition daiunit.c:3279
const struct impr_type * utype_needs_improvement(const struct unit_type *putype, const struct city *pcity)
Definition daiunit.c:2997
void dai_switch_to_explore(struct ai_type *ait, struct unit *punit, struct tile *target, enum override_bool *allow)
Definition daiunit.c:3579
void dai_manage_military(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct unit *punit)
Definition daiunit.c:2587
static bool dai_find_boat_for_unit(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:1983
static void reinforcements_cost_and_value(struct unit *punit, struct tile *ptile0, int *value, int *cost)
Definition daiunit.c:374
struct unit_type * simple_ai_types[U_LAST]
Definition daiunit.c:125
static void dai_airlift(struct ai_type *ait, struct player *pplayer)
Definition daiunit.c:168
int build_cost_balanced(const struct unit_type *punittype)
Definition daiunit.c:249
bool dai_unit_can_strike_my_unit(const struct unit *attacker, const struct unit *defender)
Definition daiunit.c:3546
bool is_on_unit_upgrade_path(const struct unit_type *test, const struct unit_type *base)
Definition daiunit.c:3031
static void dai_military_bodyguard(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:702
static void single_invader(struct ai_city *city_data, const struct unit_type *utype, int which)
Definition daiunit.c:1061
#define LOG_CARAVAN3
Definition daiunit.c:89
void dai_manage_units(struct ai_type *ait, struct player *pplayer)
Definition daiunit.c:2961
static void dai_manage_caravan(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:2342
adv_want find_something_to_kill(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct tile **pdest_tile, struct pf_path **ppath, struct pf_map **pferrymap, struct unit **pferryboat, const struct unit_type **pboattype, int *pmove_time)
Definition daiunit.c:1214
static void dai_set_defenders(struct ai_type *ait, struct player *pplayer)
Definition daiunit.c:2866
void dai_manage_unit(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:2742
adv_want look_for_charge(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct unit *punit, struct unit **aunit, struct city **acity)
Definition daiunit.c:784
static bool role_unit_cb(struct unit_type *ptype, void *data)
Definition daiunit.c:3512
static void dai_military_attack(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:1828
void dai_unit_turn_end(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:3434
static void dai_manage_settler(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:2721
static int avg_benefit(int benefit, int loss, double chance)
Definition daiunit.c:365
#define LOG_CARAVAN2
Definition daiunit.c:88
static struct city * find_neediest_airlift_city(struct ai_type *ait, const struct player *pplayer)
Definition daiunit.c:137
static int unit_def_rating(const struct unit *attacker, const struct unit *defender)
Definition daiunit.c:277
static bool dai_is_unit_tired_waiting_boat(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:2201
static int dai_rampage_want(struct unit *punit, struct tile *ptile)
Definition daiunit.c:523
bool dai_can_unit_type_follow_unit_type(const struct unit_type *follower, const struct unit_type *followee, struct ai_type *ait)
Definition daiunit.c:903
struct city * find_nearest_safe_city(struct unit *punit)
Definition daiunit.c:1714
static void dai_manage_barbarian_leader(struct ai_type *ait, struct player *pplayer, struct unit *leader)
Definition daiunit.c:3048
static void dai_manage_hitpoint_recovery(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:2512
static int unit_att_rating_squared(const struct unit *punit)
Definition daiunit.c:267
static struct pf_path * find_rampage_target(struct unit *punit, int thresh_adj, int thresh_move)
Definition daiunit.c:590
static bool is_my_turn(struct unit *punit, struct unit *pdef)
Definition daiunit.c:399
static int unit_def_rating_squared(const struct unit *punit, const struct unit *pdef)
Definition daiunit.c:290
void dai_unit_init(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:3412
void dai_consider_tile_dangerous(struct ai_type *ait, struct tile *ptile, struct unit *punit, enum override_bool *result)
Definition daiunit.c:3222
bool uclass_need_trans_between(struct unit_class *pclass, struct tile *ctile, struct tile *ptile)
Definition daiunit.c:2031
void dai_unit_load(struct ai_type *ait, const char *aitstr, const struct section_file *file, struct unit *punit, const char *unitstr)
Definition daiunit.c:3483
static void caravan_optimize_callback(const struct caravan_result *result, void *data)
Definition daiunit.c:2182
#define LOGLEVEL_RECOVERY
Definition daiunit.c:86
void dai_unit_close(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:3446
void dai_units_ruleset_close(struct ai_type *ait)
Definition daiunit.c:3394
struct unit_type * dai_role_utype_for_terrain_class(struct city *pcity, int role, enum terrain_class tc)
Definition daiunit.c:3535
static void dai_military_defend(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:1015
bool dai_military_rampage(struct unit *punit, int thresh_adj, int thresh_move)
Definition daiunit.c:669
static bool dai_caravan_can_trade_cities_diff_cont(struct player *pplayer, struct unit *punit)
Definition daiunit.c:2260
#define POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer)
Definition daiunit.h:72
@ AIUNIT_BUILD_CITY
Definition daiunit.h:27
@ AIUNIT_NONE
Definition daiunit.h:27
@ AIUNIT_ATTACK
Definition daiunit.h:28
@ AIUNIT_EXPLORE
Definition daiunit.h:29
@ AIUNIT_HUNTER
Definition daiunit.h:29
@ AIUNIT_AUTO_WORKER
Definition daiunit.h:27
@ AIUNIT_RECOVER
Definition daiunit.h:29
@ AIUNIT_TRADE
Definition daiunit.h:30
@ AIUNIT_DEFEND_HOME
Definition daiunit.h:28
@ AIUNIT_ESCORT
Definition daiunit.h:28
@ AIUNIT_WONDER
Definition daiunit.h:30
#define RAMPAGE_ANYTHING
Definition daiunit.h:85
#define RAMPAGE_FREE_CITY_OR_BETTER
Definition daiunit.h:87
#define INVASION_ATTACK
Definition daiunit.h:81
#define INVASION_OCCUPY
Definition daiunit.h:80
#define RAMPAGE_HUT_OR_BETTER
Definition daiunit.h:86
#define DEFENSE_POWER(ptype)
Definition daiunit.h:66
#define IS_ATTACKER(ptype)
Definition daiunit.h:70
#define BODYGUARD_RAMPAGE_THRESHOLD
Definition daiunit.h:88
#define ATTACK_POWER(ptype)
Definition daiunit.h:68
static void attack(QVariant data1, QVariant data2)
Definition dialogs.cpp:3055
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2977
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit * punit
Definition dialogs_g.h:74
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:78
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int cost
Definition dialogs_g.h:74
bool ai_fuzzy(const struct player *pplayer, bool normal_decision)
Definition difficulty.c:339
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:842
int get_unittype_bonus(const struct player *pplayer, const struct tile *ptile, const struct unit_type *punittype, const struct action *paction, enum effect_type effect_type)
Definition effects.c:1036
bool unit_can_enter_hut(const struct unit *punit, const struct tile *ptile)
Definition extras.c:720
float adv_want
Definition fc_types.h:1050
@ RPT_CERTAIN
Definition fc_types.h:516
@ AUT_AUTO_WORKER
Definition fc_types.h:231
#define ADV_WANT_PRINTF
Definition fc_types.h:1051
@ O_LUXURY
Definition fc_types.h:103
signed short Continent_id
Definition fc_types.h:233
override_bool
Definition fc_types.h:96
@ OVERRIDE_TRUE
Definition fc_types.h:96
@ OVERRIDE_FALSE
Definition fc_types.h:96
struct civ_game game
Definition game.c:62
struct world wld
Definition game.c:63
struct unit * game_unit_by_number(int id)
Definition game.c:115
struct city * game_city_by_number(int id)
Definition game.c:106
static struct tile * pos
Definition finddlg.c:53
bool has_handicap(const struct player *pplayer, enum handicap_type htype)
Definition handicaps.c:66
@ H_MAP
Definition handicaps.h:28
@ H_TARGETS
Definition handicaps.h:24
@ H_AWAY
Definition handicaps.h:19
@ H_FOG
Definition handicaps.h:26
#define fc_assert_ret(condition)
Definition log.h:192
#define fc_assert(condition)
Definition log.h:177
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define log_do_output_for_level(level)
Definition log.h:90
#define log_base(level, message,...)
Definition log.h:95
log_level
Definition log.h:29
@ LOG_DEBUG
Definition log.h:35
@ LOG_NORMAL
Definition log.h:33
@ LOG_VERBOSE
Definition log.h:34
bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
Definition map.c:1076
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:1085
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:675
int map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:699
#define iterate_outward(nmap, start_tile, max_dist, itr_tile)
Definition map.h:373
#define iterate_outward_end
Definition map.h:377
#define adjc_iterate_end
Definition map.h:439
static int index_to_map_pos_y(int mindex)
Definition map.h:772
#define square_iterate(nmap, center_tile, radius, tile_itr)
Definition map.h:397
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:434
#define square_iterate_end
Definition map.h:400
static int index_to_map_pos_x(int mindex)
Definition map.h:759
#define pmap(_tile)
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:899
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:925
#define fc_calloc(n, esz)
Definition mem.h:38
#define FC_FREE(ptr)
Definition mem.h:41
#define fc_malloc(sz)
Definition mem.h:34
bool can_unit_exist_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:350
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:362
int unit_move_rate(const struct unit *punit)
Definition movement.c:89
bool can_attack_from_non_native(const struct unit_type *utype)
Definition movement.c:226
bool can_unit_survive_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:522
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Definition movement.c:919
bool can_attack_non_native(const struct unit_type *utype)
Definition movement.c:213
#define SINGLE_MOVE
Definition movement.h:26
static bool is_native_tile_to_class(const struct unit_class *punitclass, const struct tile *ptile)
Definition movement.h:88
@ MR_OK
Definition movement.h:35
@ MR_DEATH
Definition movement.h:36
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:138
struct nation_type * nation_of_unit(const struct unit *punit)
Definition nation.c:461
void pf_path_destroy(struct pf_path *path)
struct pf_map * pf_map_new(const struct pf_parameter *parameter)
struct pf_path * pf_map_path(struct pf_map *pfm, struct tile *ptile)
bool pf_map_position(struct pf_map *pfm, struct tile *ptile, struct pf_position *pos)
void pf_reverse_map_destroy(struct pf_reverse_map *pfrm)
int pf_reverse_map_unit_move_cost(struct pf_reverse_map *pfrm, const struct unit *punit)
void pf_map_destroy(struct pf_map *pfm)
struct pf_reverse_map * pf_reverse_map_new(const struct civ_map *nmap, const struct player *pplayer, struct tile *target_tile, int max_turns, bool omniscient)
int pf_map_move_cost(struct pf_map *pfm, struct tile *ptile)
#define PF_IMPOSSIBLE_MC
#define pf_map_move_costs_iterate_end
#define pf_map_move_costs_iterate(ARG_pfm, NAME_tile, NAME_cost, COND_from_start)
#define pf_map_tiles_iterate(ARG_pfm, NAME_tile, COND_from_start)
#define pf_map_tiles_iterate_end
void pft_fill_unit_parameter(struct pf_parameter *parameter, const struct civ_map *nmap, const struct unit *punit)
Definition pf_tools.c:843
void pft_fill_unit_attack_param(struct pf_parameter *parameter, const struct civ_map *nmap, const struct unit *punit)
Definition pf_tools.c:952
void pft_fill_unit_overlap_param(struct pf_parameter *parameter, const struct civ_map *nmap, const struct unit *punit)
Definition pf_tools.c:894
void pft_fill_utype_overlap_param(struct pf_parameter *parameter, const struct civ_map *nmap, const struct unit_type *punittype, struct tile *pstart_tile, struct player *pplayer)
Definition pf_tools.c:879
struct unit * player_unit_by_number(const struct player *pplayer, int unit_id)
Definition player.c:1217
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1376
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1397
#define players_iterate_end
Definition player.h:552
#define players_iterate(_pplayer)
Definition player.h:547
static bool is_barbarian(const struct player *pplayer)
Definition player.h:499
#define is_human(plr)
Definition player.h:231
#define fc_rand(_size)
Definition rand.h:56
int secfile_lookup_int_default(const struct section_file *secfile, int def, const char *path,...)
#define secfile_insert_int(secfile, value, path,...)
bool is_req_active(const struct req_context *context, const struct req_context *other_context, const struct requirement *req, const enum req_problem_type prob_type)
#define requirement_vector_iterate_end
#define requirement_vector_iterate(req_vec, preq)
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:190
#define FC_INFINITY
Definition shared.h:36
#define MAX(x, y)
Definition shared.h:54
int get_specialist_output(const struct city *pcity, Specialist_type_id sp, Output_type_id otype)
Definition specialist.c:270
#define normal_specialist_type_iterate(sp)
Definition specialist.h:89
#define normal_specialist_type_iterate_end
Definition specialist.h:95
#define CITY_LOG(loglevel, pcity, msg,...)
Definition srv_log.h:83
#define LOGLEVEL_HUNT
Definition srv_log.h:35
#define UNIT_LOG(loglevel, punit, msg,...)
Definition srv_log.h:98
#define LOG_AI_TEST
Definition srv_log.h:38
@ AIT_RECOVER
Definition srv_log.h:68
@ AIT_FSTK
Definition srv_log.h:54
@ AIT_CARAVAN
Definition srv_log.h:56
@ AIT_RAMPAGE
Definition srv_log.h:71
@ AIT_ATTACK
Definition srv_log.h:66
@ AIT_HUNTER
Definition srv_log.h:57
@ AIT_BODYGUARD
Definition srv_log.h:69
@ AIT_DEFENDERS
Definition srv_log.h:55
@ AIT_AIRUNIT
Definition srv_log.h:60
@ AIT_FERRY
Definition srv_log.h:70
@ AIT_MILITARY
Definition srv_log.h:67
@ AIT_DIPLOMAT
Definition srv_log.h:59
@ AIT_AIRLIFT
Definition srv_log.h:58
@ TIMER_STOP
Definition srv_log.h:76
@ TIMER_START
Definition srv_log.h:76
#define TIMING_LOG(timer, activity)
Definition srv_log.h:125
#define LOGLEVEL_BODYGUARD
Definition srv_log.h:30
unsigned int danger
Definition daicity.h:47
int bcost
Definition daicity.h:44
Definition ai.h:50
void(* callback)(const struct caravan_result *result, void *data)
Definition caravan.h:124
enum foreign_trade_limit allow_foreign_trade
Definition caravan.h:99
bool ignore_transit_time
Definition caravan.h:108
void * callback_data
Definition caravan.h:125
const struct city * src
Definition caravan.h:52
const struct city * dest
Definition caravan.h:53
bool help_wonder
Definition caravan.h:57
double value
Definition caravan.h:56
Definition city.h:318
struct adv_city * adv
Definition city.h:452
struct tile * tile
Definition city.h:320
struct packet_game_info info
Definition game.h:89
int occupychance
Definition game.h:177
struct civ_game::@32::@36 server
struct city_list * cities
Definition player.h:281
struct unit_list * units
Definition player.h:282
bool is_alive
Definition player.h:268
const struct player * player
enum terrain_class tc
Definition daiunit.c:3505
struct city * build_city
Definition daiunit.c:3506
Definition tile.h:50
struct unit_list * units
Definition tile.h:58
Continent_id continent
Definition tile.h:54
bool done
Definition daiunit.h:44
bv_unit_classes cargo
Definition unittype.h:565
struct veteran_system * veteran
Definition unittype.h:551
int move_rate
Definition unittype.h:524
Definition unit.h:140
enum unit_activity activity
Definition unit.h:159
int moves_left
Definition unit.h:152
int id
Definition unit.h:147
bool moved
Definition unit.h:176
bool debug
Definition unit.h:237
int hp
Definition unit.h:153
struct unit::@84::@87 server
struct tile * tile
Definition unit.h:142
int homecity
Definition unit.h:148
int birth_turn
Definition unit.h:210
struct tile * goto_tile
Definition unit.h:157
int veteran
Definition unit.h:154
struct player * owner
Definition unit.h:145
struct civ_map map
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
bool is_terrain_class_near_tile(const struct civ_map *nmap, const struct tile *ptile, enum terrain_class tclass)
Definition terrain.c:615
#define is_ocean_tile(ptile)
Definition terrain.h:197
int tile_extras_defense_bonus(const struct tile *ptile, const struct unit_type *punittype)
Definition tile.c:234
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_index(_pt_)
Definition tile.h:89
#define tile_terrain(_tile)
Definition tile.h:115
#define TILE_XY(ptile)
Definition tile.h:43
#define tile_continent(_tile)
Definition tile.h:93
bool can_cities_trade(const struct city *pc1, const struct city *pc2)
struct goods_type * unit_current_goods(const struct unit *punit, const struct city *homecity)
bool can_establish_trade_route(const struct city *pc1, const struct city *pc2, int priority)
void unit_set_ai_data(struct unit *punit, const struct ai_type *ai, void *data)
Definition unit.c:2343
bool unit_transport_load(struct unit *pcargo, struct unit *ptrans, bool force)
Definition unit.c:2461
bool is_losing_hp(const struct unit *punit)
Definition unit.c:2281
bool unit_can_airlift_to(const struct civ_map *nmap, const struct unit *punit, const struct city *pdest_city)
Definition unit.c:205
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2525
int unit_gain_hitpoints(const struct unit *punit)
Definition unit.c:2236
bool unit_is_cityfounder(const struct unit *punit)
Definition unit.c:2722
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:402
bool unit_can_do_action_result(const struct unit *punit, enum action_result result)
Definition unit.c:412
enum gen_action activity_default_action(enum unit_activity act)
Definition unit.c:2942
bool can_unit_do_activity(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity, enum gen_action action)
Definition unit.c:912
int get_transporter_capacity(const struct unit *punit)
Definition unit.c:316
bool is_special_unit(const struct unit *punit)
Definition unit.c:369
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2511
bool is_guard_unit(const struct unit *punit)
Definition unit.c:359
bool unit_has_orders(const struct unit *punit)
Definition unit.c:221
#define unit_tile(_pu)
Definition unit.h:408
#define unit_cargo_iterate_end
Definition unit.h:602
#define unit_cargo_iterate(_ptrans, _pcargo)
Definition unit.h:599
#define CHECK_UNIT(punit)
Definition unit.h:273
#define unit_owner(_pu)
Definition unit.h:407
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer, bool everyone_non_allied)
Definition unit.h:446
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity, enum gen_action trigger_action)
Definition unithand.c:6708
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)
Definition unithand.c:3350
bool unit_server_side_agent_set(struct player *pplayer, struct unit *punit, enum server_side_agent agent)
Definition unithand.c:6606
struct unit * unit_list_find(const struct unit_list *punitlist, int unit_id)
Definition unitlist.c:30
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_safe(unitlist, _unit)
Definition unitlist.h:39
#define unit_list_iterate_end
Definition unitlist.h:33
#define unit_list_iterate_safe_end
Definition unitlist.h:61
bool utype_action_takes_all_mp(const struct unit_type *putype, struct action *paction)
Definition unittype.c:1216
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:126
struct unit_type * role_units_iterate_backwards(int role, role_unit_callback cb, void *data)
Definition unittype.c:2267
struct unit_type * get_role_unit(int role, int role_index)
Definition unittype.c:2284
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1613
bool utype_has_role(const struct unit_type *punittype, int role)
Definition unittype.c:224
int utype_build_shield_cost_base(const struct unit_type *punittype)
Definition unittype.c:1493
int unit_build_shield_cost_base(const struct unit *punit)
Definition unittype.c:1509
struct unit_type * best_role_unit_for_player(const struct player *pplayer, int role)
Definition unittype.c:2330
struct unit_class * unit_class_get(const struct unit *punit)
Definition unittype.c:2535
bool utype_can_do_action_result(const struct unit_type *putype, enum action_result result)
Definition unittype.c:412
bool unit_has_type_role(const struct unit *punit, enum unit_role_id role)
Definition unittype.c:233
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:215
bool unit_can_take_over(const struct unit *punit)
Definition unittype.c:289
void * utype_ai_data(const struct unit_type *ptype, const struct ai_type *ai)
Definition unittype.c:2776
bool utype_can_take_over(const struct unit_type *punittype)
Definition unittype.c:301
void utype_set_ai_data(struct unit_type *ptype, const struct ai_type *ai, void *data)
Definition unittype.c:2784
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1463
bool utype_acts_hostile(const struct unit_type *putype)
Definition unittype.c:468
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:396
#define utype_class(_t_)
Definition unittype.h:756
#define utype_fuel(ptype)
Definition unittype.h:849
#define combat_bonus_list_iterate_end
Definition unittype.h:487
#define combat_bonus_list_iterate(bonuslist, pbonus)
Definition unittype.h:485
@ MOVE_FULL
Definition unittype.h:144
@ MOVE_NONE
Definition unittype.h:144
#define unit_type_list_iterate(utype_list, ptype)
Definition unittype.h:950
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:624
#define unit_class_list_iterate(uclass_list, pclass)
Definition unittype.h:942
#define unit_type_iterate(_p)
Definition unittype.h:865
#define unit_type_list_iterate_end
Definition unittype.h:952
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:872
#define unit_class_list_iterate_end
Definition unittype.h:944