Freeciv-3.3
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 "aidiplomat.h"
70#include "aiferry.h"
71#include "aiguard.h"
72#include "aihand.h"
73#include "aiparatrooper.h"
74#include "daiair.h"
75#include "daicity.h"
76#include "daidata.h"
77#include "daieffects.h"
78#include "daihunter.h"
79#include "dailog.h"
80#include "daimilitary.h"
81#include "daiplayer.h"
82#include "daitools.h"
83
84#include "daiunit.h"
85
86
87#define LOGLEVEL_RECOVERY LOG_DEBUG
88#define LOG_CARAVAN LOG_DEBUG
89#define LOG_CARAVAN2 LOG_DEBUG
90#define LOG_CARAVAN3 LOG_DEBUG
91
92static bool dai_find_boat_for_unit(struct ai_type *ait, struct unit *punit);
93static bool dai_caravan_can_trade_cities_diff_cont(struct player *pplayer,
94 struct unit *punit);
95static void dai_manage_caravan(struct ai_type *ait, struct player *pplayer,
96 struct unit *punit);
97static void dai_manage_barbarian_leader(struct ai_type *ait,
98 struct player *pplayer,
99 struct unit *leader);
100
101static void dai_military_findjob(struct ai_type *ait,
102 struct player *pplayer, struct unit *punit);
103static void dai_military_defend(struct ai_type *ait, struct player *pplayer,
104 struct unit *punit);
105static void dai_military_attack(struct ai_type *ait, struct player *pplayer,
106 struct unit *punit);
107
108static bool unit_role_defender(const struct unit_type *punittype);
109static int unit_def_rating_squared(const struct unit *punit,
110 const struct unit *pdef);
111
112/*
113 * Cached values. Updated by update_simple_ai_types.
114 *
115 * This a hack to enable emulation of old loops previously hardwired
116 * as
117 * for (i = U_WARRIORS; i <= U_BATTLESHIP; i++)
118 *
119 * (Could probably just adjust the loops themselves fairly simply,
120 * but this is safer for regression testing.)
121 *
122 * Not dealing with planes yet.
123 *
124 * Terminated by NULL.
125 */
127
128/**********************************************************************/
138static struct city *find_neediest_airlift_city(struct ai_type *ait,
139 const struct player *pplayer)
140{
141 struct city *neediest_city = NULL;
142 int most_danger = 0;
143 int most_urgent = 0;
144
145 city_list_iterate(pplayer->cities, pcity) {
146 struct ai_city *city_data = def_ai_city_data(pcity, ait);
147
148 if (pcity->airlift) {
149 if (city_data->urgency > most_urgent) {
150 most_urgent = city_data->urgency;
151 neediest_city = pcity;
152 } else if (0 == most_urgent /* urgency trumps danger */
153 && city_data->danger > most_danger) {
154 most_danger = city_data->danger;
155 neediest_city = pcity;
156 }
157 }
159
160 return neediest_city;
161}
162
163/**********************************************************************/
169static void dai_airlift(struct ai_type *ait, struct player *pplayer)
170{
171 struct city *most_needed;
172 int comparison;
173 struct unit *transported;
174
175 do {
177 comparison = 0;
178 transported = NULL;
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/**********************************************************************/
456static int dai_rampage_want(struct unit *punit, struct tile *ptile)
457{
458 struct player *pplayer = unit_owner(punit);
459 struct unit *pdef;
460 struct civ_map *nmap = &(wld.map);
461
463
464 if (can_unit_attack_tile(punit, NULL, ptile)
465 && (pdef = get_defender(nmap, punit, ptile, NULL))) {
466 /* See description of kill_desire() about these variables. */
470
471 attack *= attack;
472
473 /* If the victim is in the city/fortress, we correct the benefit
474 * with our health because there could be reprisal attacks. We
475 * shouldn't send already injured units to useless suicide.
476 * Note that we do not specially encourage attacks against
477 * cities: rampage is a hit-n-run operation. */
478 if (!is_stack_vulnerable(ptile)
479 && unit_list_size(ptile->units) > 1) {
481 }
482
483 /* If we have non-zero attack rating... */
484 if (attack > 0 && is_my_turn(punit, pdef)) {
487
488 /* No need to amortize, our operation takes one turn. */
489 UNIT_LOG(LOG_DEBUG, punit, "Rampage: Desire %d to kill %s(%d,%d)",
490 desire,
493
494 return MAX(0, desire);
495 }
496 } else if (0 == unit_list_size(ptile->units)) {
497 /* No defender. */
498 struct city *pcity = tile_city(ptile);
499
500 /* ...and free foreign city waiting for us. Who would resist! */
501 if (NULL != pcity
502 && pplayers_at_war(pplayer, city_owner(pcity))
505 }
506
507 /* ...or tiny pleasant hut here! */
508 /* FIXME: unhardcode and variate the desire to enter a hut. */
509 if (unit_can_enter_hut(punit, ptile) && !is_barbarian(pplayer)
510 && is_native_tile(unit_type_get(punit), ptile)) {
511 return -RAMPAGE_HUT_OR_BETTER;
512 }
513 }
514
515 return 0;
516}
517
518/**********************************************************************/
521static struct pf_path *find_rampage_target(struct unit *punit,
522 int thresh_adj, int thresh_move)
523{
524 struct pf_map *tgt_map;
525 struct pf_path *path = NULL;
526 struct pf_parameter parameter;
527 /* Coordinates of the best target (initialize to silence compiler) */
528 struct tile *ptile = unit_tile(punit);
529 /* Want of the best target */
530 int max_want = 0;
531 struct player *pplayer = unit_owner(punit);
532 const struct civ_map *nmap = &(wld.map);
533
535 parameter.omniscience = !has_handicap(pplayer, H_MAP);
536 /* When trying to find rampage targets we ignore risks such as
537 * enemy units because we are looking for trouble!
538 * Hence no call ai_avoid_risks()
539 */
540
541 tgt_map = pf_map_new(&parameter);
543 int want;
544 bool move_needed;
545 int thresh;
546
547 if (move_cost > punit->moves_left) {
548 /* This is too far */
549 break;
550 }
551
552 if (has_handicap(pplayer, H_TARGETS)
553 && !map_is_known_and_seen(iter_tile, pplayer, V_MAIN)) {
554 /* The target is under fog of war */
555 continue;
556 }
557
559
560 /* Negative want means move needed even though the tiles are adjacent */
562 || want < 0);
563 /* Select the relevant threshold */
565 want = (want < 0 ? -want : want);
566
567 if (want > max_want && want > thresh) {
568 /* The new want exceeds both the previous maximum
569 * and the relevant threshold, so it's worth recording */
570 max_want = want;
571 ptile = iter_tile;
572 }
574
575 if (max_want > 0) {
576 /* We found something */
577 path = pf_map_path(tgt_map, ptile);
578 fc_assert(path != NULL);
579 }
580
582
583 return path;
584}
585
586/**********************************************************************/
601 int thresh_move)
602{
603 int count = punit->moves_left + 1; /* break any infinite loops */
604 struct pf_path *path = NULL;
605
608
610 /* This teaches the AI about the dangers inherent in occupychance. */
612
613 while (count-- > 0 && punit->moves_left > 0
615 if (!adv_unit_execute_path(punit, path)) {
616 /* Died */
617 count = -1;
618 }
619 pf_path_destroy(path);
620 path = NULL;
621 }
622
623 fc_assert(NULL == path);
624
626 return (count >= 0);
627}
628
629/**********************************************************************/
633static void dai_military_bodyguard(struct ai_type *ait, struct player *pplayer,
634 struct unit *punit)
635{
636 struct unit *aunit = aiguard_charge_unit(ait, punit);
637 struct city *acity = aiguard_charge_city(ait, punit);
638 struct tile *ptile;
639
641 CHECK_GUARD(ait, punit);
642
643 if (aunit && unit_owner(aunit) == unit_owner(punit)) {
644 /* protect a unit */
645 if (aunit->goto_tile != NULL) {
646 /* Our charge is going somewhere: maybe we should meet them there */
647 /* FIXME: This probably isn't the best algorithm for this. */
649 int me2goal = real_map_distance(unit_tile(punit), aunit->goto_tile);
650 int them2goal = real_map_distance(unit_tile(aunit), aunit->goto_tile);
651
652 if (me2goal < me2them
656 ptile = aunit->goto_tile;
657 } else {
658 ptile = unit_tile(aunit);
659 }
660 } else {
661 ptile = unit_tile(aunit);
662 }
663 } else if (acity && city_owner(acity) == unit_owner(punit)) {
664 /* protect a city */
665 ptile = acity->tile;
666 } else {
667 /* should be impossible */
668 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "we lost our charge");
670 return;
671 }
672
673 if (same_pos(unit_tile(punit), ptile)) {
674 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "at RV");
675 } else {
676 if (goto_is_sane(punit, ptile)) {
677 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "meeting charge");
678 if (!dai_gothere(ait, pplayer, punit, ptile)) {
679 /* We died */
680 return;
681 }
682 } else {
683 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "can not meet charge");
685 }
686 }
687 /* We might have stopped because of an enemy nearby.
688 * Perhaps we can kill it.*/
691 && same_pos(unit_tile(punit), ptile)) {
692 def_ai_unit_data(punit, ait)->done = TRUE; /* Stay with charge */
693 }
694}
695
696/**********************************************************************/
699static bool unit_role_defender(const struct unit_type *punittype)
700{
702}
703
704/**********************************************************************/
714adv_want look_for_charge(struct ai_type *ait, struct player *pplayer,
715 struct unit *punit,
716 struct unit **aunit, struct city **acity)
717{
718 struct pf_parameter parameter;
719 struct pf_map *pfm;
720 struct city *pcity;
721 struct ai_city *data, *best_data = NULL;
723 int def, best_def = -1;
724 /* Arbitrary: 3 turns. */
725 const int max_move_cost = 3 * unit_move_rate(punit);
726 const struct civ_map *nmap = &(wld.map);
727
728 *aunit = NULL;
729 *acity = NULL;
730
731 if (0 == toughness) {
732 /* useless */
733 return 0;
734 }
735
736 pft_fill_unit_parameter(&parameter, nmap, punit);
737 parameter.omniscience = !has_handicap(pplayer, H_MAP);
738 pfm = pf_map_new(&parameter);
739
740 pf_map_move_costs_iterate(pfm, ptile, move_cost, TRUE) {
741 if (move_cost > max_move_cost) {
742 /* Consider too far. */
743 break;
744 }
745
746 pcity = tile_city(ptile);
747
748 /* Consider unit bodyguard. */
749 unit_list_iterate(ptile->units, buddy) {
750 const struct unit_type *ptype = unit_type_get(punit);
751 const struct unit_type *buddy_type = unit_type_get(buddy);
752
753 /* TODO: allied unit bodyguard? */
755 || unit_owner(buddy) != pplayer
756 || !aiguard_wanted(ait, buddy)
762
763 continue;
764 }
765
767 if (0 >= def) {
768 continue;
769 }
770
772 /* Reduce want based on move cost. We can't do this for
773 * transports since they move around all the time, leading
774 * to hillarious flip-flops. */
775 def >>= move_cost / (2 * unit_move_rate(punit));
776 }
777 if (def > best_def) {
778 *aunit = buddy;
779 *acity = NULL;
780 best_def = def;
781 }
783
784 /* City bodyguard. TODO: allied city bodyguard? */
785 if (ai_fuzzy(pplayer, TRUE)
786 && NULL != pcity
787 && city_owner(pcity) == pplayer
788 && (data = def_ai_city_data(pcity, ait))
789 && 0 < data->urgency) {
790 if (NULL != best_data
791 && (0 < best_data->grave_danger
792 || best_data->urgency > data->urgency
793 || ((best_data->danger > data->danger
794 || AIUNIT_DEFEND_HOME == def_ai_unit_data(punit, ait)->task)
795 && 0 == data->grave_danger))) {
796 /* Chances are we'll be between cities when we are needed the most!
797 * Resuming pf_map_move_costs_iterate()... */
798 continue;
799 }
800 def = (data->danger - assess_defense_quadratic(ait, pcity));
801 if (def <= 0) {
802 continue;
803 }
804 /* Reduce want based on move cost. */
805 def >>= move_cost / (2 * unit_move_rate(punit));
806 if (def > best_def && ai_fuzzy(pplayer, TRUE)) {
807 *acity = pcity;
808 *aunit = NULL;
809 best_def = def;
810 best_data = data;
811 }
812 }
814
816
817 UNIT_LOG(LOGLEVEL_BODYGUARD, punit, "%s(), best_def=%d, type=%s (%d, %d)",
820 : (NULL != *aunit ? unit_rule_name(*aunit) : "")),
822 : (NULL != *aunit ?
825 : (NULL != *aunit ?
827
828 return ((best_def * 100) / toughness);
829}
830
831/**********************************************************************/
835 const struct unit_type *followee,
836 struct ai_type *ait)
837{
838 struct unit_type_ai *utai = utype_ai_data(follower, ait);
839
840 unit_type_list_iterate(utai->potential_charges, pcharge) {
841 if (pcharge == followee) {
842 return TRUE;
843 }
845
846 return FALSE;
847}
848
849/**********************************************************************/
852static void dai_military_findjob(struct ai_type *ait,
853 struct player *pplayer, struct unit *punit)
854{
855 const struct unit_type *punittype = unit_type_get(punit);
856 struct unit_ai *unit_data;
857 const struct civ_map *nmap = &(wld.map);
858
860
861 /* Keep barbarians aggressive and primitive */
862 if (is_barbarian(pplayer)) {
864 && is_land_barbarian(pplayer)) {
865 /* Land barbarians pillage */
868 }
870
871 return;
872 }
873
875
876 /* If I am a bodyguard, check whether I can do my job. */
877 if (unit_data->task == AIUNIT_ESCORT
878 || unit_data->task == AIUNIT_DEFEND_HOME) {
880 }
881
882 if (aiguard_has_charge(ait, punit)
883 && unit_data->task == AIUNIT_ESCORT) {
884 struct unit *aunit = aiguard_charge_unit(ait, punit);
885 struct city *acity = aiguard_charge_city(ait, punit);
886 struct ai_city *city_data = NULL;
887
888 if (acity != NULL) {
890 }
891
892 /* Check if the city we are on our way to rescue is still in danger,
893 * or the unit we should protect is still alive... */
894 if ((aunit && (aiguard_has_guard(ait, aunit) || aiguard_wanted(ait, aunit))
897 && city_data->urgency != 0
898 && city_data->danger > assess_defense_quadratic(ait, acity))) {
899 return; /* Yep! */
900 } else {
901 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL); /* Nope! */
902 }
903 }
904
905 /* Is the unit badly damaged? */
906 if ((unit_data->task == AIUNIT_RECOVER
907 && punit->hp < punittype->hp)
908 || punit->hp < punittype->hp * 0.25) { /* WAG */
909 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "set to hp recovery");
911 return;
912 }
913
916 /* This is a defending unit that doesn't need to stay put.
917 * It needs to defend something, but not necessarily where it's at.
918 * Therefore, it will consider becoming a bodyguard. -- Syela */
919 struct city *acity;
920 struct unit *aunit;
921
922 look_for_charge(ait, pplayer, punit, &aunit, &acity);
923 if (acity) {
926 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "going to defend city");
927 } else if (aunit) {
930 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "going to defend unit");
931 }
932 }
934}
935
936/**********************************************************************/
945static void dai_military_defend(struct ai_type *ait, struct player *pplayer,
946 struct unit *punit)
947{
948 struct city *pcity = aiguard_charge_city(ait, punit);
949
951
952 if (!pcity || city_owner(pcity) != pplayer) {
953 pcity = tile_city(unit_tile(punit));
954 /* Do not stay defending an allied city forever */
956 }
957
958 if (!pcity) {
959 /* Try to find a place to rest. Sitting duck out in the wilderness
960 * is generally a bad idea, since we protect no cities that way, and
961 * it looks silly. */
962 pcity = find_closest_city(unit_tile(punit), NULL, pplayer,
965 }
966
967 if (!pcity) {
969 }
970
973 /* ... we survived */
974 if (pcity) {
975 UNIT_LOG(LOG_DEBUG, punit, "go to defend %s", city_name_get(pcity));
976 if (same_pos(unit_tile(punit), pcity->tile)) {
977 UNIT_LOG(LOG_DEBUG, punit, "go defend successful");
979 } else {
980 (void) dai_gothere(ait, pplayer, punit, pcity->tile);
981 }
982 } else {
983 UNIT_LOG(LOG_VERBOSE, punit, "defending nothing...?");
984 }
985 }
986}
987
988/**********************************************************************/
991static void single_invader(struct ai_city *city_data,
992 const struct unit_type *utype,
993 int which)
994{
995 int attacks;
996
999 attacks = 1;
1000 } else {
1001 attacks = utype->move_rate;
1002 }
1003 city_data->invasion.attack += attacks;
1004 if (which == INVASION_OCCUPY) {
1005 city_data->invasion.occupy++;
1006 }
1007}
1008
1009/**********************************************************************/
1019static void invasion_funct(struct ai_type *ait, struct unit *punit,
1020 bool dest, int radius, int which)
1021{
1022 struct tile *ptile;
1023 struct player *pplayer = unit_owner(punit);
1024
1026
1027 if (dest) {
1028 ptile = punit->goto_tile;
1029 } else {
1030 ptile = unit_tile(punit);
1031 }
1032
1033 square_iterate(&(wld.map), ptile, radius, tile1) {
1034 struct city *pcity = tile_city(tile1);
1035
1036 if (pcity
1037 && POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, city_owner(pcity))
1038 && (dest || !has_defense(pcity))) {
1039 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1040
1041 /* Unit itself */
1043
1044 /* Cargo */
1045 unit_cargo_iterate(punit, cargo) {
1046 const struct unit_type *utype = unit_type_get(cargo);
1047
1048 if (IS_ATTACKER(utype)) {
1052 }
1054 }
1056}
1057
1058/**********************************************************************/
1061bool find_beachhead(const struct player *pplayer, struct pf_map *ferry_map,
1062 struct tile *dest_tile,
1063 const struct unit_type *cargo_type,
1064 const struct unit_type *ferry_type,
1065 struct tile **ferry_dest, struct tile **beachhead_tile)
1066{
1067 if (NULL == tile_city(dest_tile)
1069 /* Unit can directly go to 'dest_tile'. */
1070 struct tile *best_tile = NULL;
1072
1073 if (NULL != beachhead_tile) {
1074 *beachhead_tile = dest_tile;
1075 }
1076
1077 adjc_iterate(&(wld.map), dest_tile, ptile) {
1079 if (cost != PF_IMPOSSIBLE_MC
1080 && (NULL == best_tile || cost < best_cost)) {
1081 best_tile = ptile;
1082 best_cost = cost;
1083 }
1085
1086 if (NULL != ferry_dest) {
1088 }
1089
1090 return (PF_IMPOSSIBLE_MC != best_cost);
1091 } else {
1092 /* We need to find a beach around 'dest_tile'. */
1093 struct tile *best_tile = NULL, *best_beach = NULL;
1097
1098 tile_list_append(checked_tiles, dest_tile);
1099 adjc_iterate(&(wld.map), dest_tile, beach) {
1101 /* Can land there. */
1102 adjc_iterate(&(wld.map), beach, ptile) {
1103 if (!tile_list_search(checked_tiles, ptile)
1104 && !is_non_allied_unit_tile(ptile, pplayer,
1105 flagless_ferry)) {
1108 if (cost != PF_IMPOSSIBLE_MC
1109 && (NULL == best_tile || cost < best_cost)) {
1110 best_beach = beach;
1111 best_tile = ptile;
1112 best_cost = cost;
1113 }
1114 }
1116 }
1118
1120
1121 if (NULL != beachhead_tile) {
1123 }
1124 if (NULL != ferry_dest) {
1126 }
1127 return (PF_IMPOSSIBLE_MC != best_cost);
1128 }
1129}
1130
1131/**********************************************************************/
1139adv_want find_something_to_kill(struct ai_type *ait, struct player *pplayer,
1140 struct unit *punit,
1141 struct tile **pdest_tile, struct pf_path **ppath,
1142 struct pf_map **pferrymap,
1143 struct unit **pferryboat,
1144 const struct unit_type **pboattype, int *pmove_time)
1145{
1146 const int attack_value = adv_unit_att_rating(punit); /* basic attack. */
1147 struct pf_parameter parameter;
1148 struct pf_map *punit_map, *ferry_map;
1149 struct pf_position pos;
1151 const struct unit_type *punit_type = unit_type_get(punit);
1152 struct tile *punit_tile = unit_tile(punit);
1153 /* Type of our boat (a future one if ferryboat == NULL). */
1154 const struct unit_type *boattype = NULL;
1155 struct unit *ferryboat = NULL;
1156 struct city *pcity;
1157 struct ai_city *acity_data;
1158 int bcost, bcost_bal; /* Build cost of the attacker (+adjustments). */
1159 bool handicap = has_handicap(pplayer, H_TARGETS);
1160 bool unhap = FALSE; /* Do we make unhappy citizen. */
1161 bool harbor = FALSE; /* Do we have access to sea? */
1162 bool go_by_boat; /* Whether we need a boat or not. */
1163 int vulnerability; /* Enemy defense rating. */
1164 adv_want benefit; /* Benefit from killing the target. */
1165 struct unit *pdefender; /* Enemy city defender. */
1166 int move_time; /* Turns needed to target. */
1167 int reserves;
1168 int attack; /* Our total attack value with reinforcements. */
1169 int victim_count; /* Number of enemies there. */
1170 int needferry; /* Cost of building a ferry boat. */
1171 /* This is a kluge, because if we don't set x and y with !punit->id,
1172 * p_a_w isn't called, and we end up not wanting ironclads and therefore
1173 * never learning steam engine, even though ironclads would be very
1174 * useful. -- Syela */
1175 adv_want bk = 0;
1176 adv_want want; /* Want (amortized) of the operaton. */
1177 adv_want best = 0; /* Best of all wants. */
1178 struct tile *goto_dest_tile = NULL;
1179 bool can_occupy;
1180 struct civ_map *nmap = &(wld.map);
1181
1182 /* Very preliminary checks. */
1184 if (NULL != pferrymap) {
1185 *pferrymap = NULL;
1186 }
1187 if (NULL != pferryboat) {
1188 *pferryboat = NULL;
1189 }
1190 if (NULL != pboattype) {
1191 *pboattype = NULL;
1192 }
1193 if (NULL != pmove_time) {
1194 *pmove_time = 0;
1195 }
1196 if (NULL != ppath) {
1197 *ppath = NULL;
1198 }
1199
1200 if (0 == attack_value) {
1201 /* A very poor attacker... probably low on HP. */
1202 return 0;
1203 }
1204
1206
1207
1208 /*** Part 1: Calculate targets ***/
1209
1210 /* This horrible piece of code attempts to calculate the attractiveness of
1211 * enemy cities as targets for our units, by checking how many units are
1212 * going towards it or are near it already. */
1213
1214 /* Reset enemy cities data. */
1216 /* See comment below in next usage of POTENTIALLY_HOSTILE_PLAYER. */
1217 if ((punit->id == 0 && !POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer))
1218 || (punit->id != 0 && !pplayers_at_war(pplayer, aplayer))) {
1219 continue;
1220 }
1221 city_list_iterate(aplayer->cities, acity) {
1222 struct ai_city *city_data = def_ai_city_data(acity, ait);
1223
1225 &city_data->attack,
1226 &city_data->bcost);
1227 city_data->invasion.attack = 0;
1228 city_data->invasion.occupy = 0;
1231
1232 /* Second, calculate in units on their way there, and mark targets for
1233 * invasion */
1234 unit_list_iterate(pplayer->units, aunit) {
1235 const struct unit_type *atype;
1236
1237 if (aunit == punit) {
1238 continue;
1239 }
1240
1242
1243 /* Dealing with invasion stuff */
1244 if (IS_ATTACKER(atype)) {
1245 if (aunit->activity == ACTIVITY_GOTO) {
1246 invasion_funct(ait, aunit, TRUE, 0,
1249 if ((pcity = tile_city(aunit->goto_tile))) {
1250 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1251
1254 }
1255 }
1259 } else if (def_ai_unit_data(aunit, ait)->passenger != 0
1261 /* It's a transport with reinforcements */
1262 if (aunit->activity == ACTIVITY_GOTO) {
1264 }
1266 }
1268 /* end horrible initialization subroutine */
1269
1270
1271 /*** Part 2: Now pick one target ***/
1272
1273 /* We first iterate through all cities, then all units, looking
1274 * for a viable target. We also try to gang up on the target
1275 * to avoid spreading out attacks too widely to be inefficient.
1276 */
1277
1278 pcity = tile_city(punit_tile);
1279 if (NULL != pcity && (0 == punit->id || pcity->id == punit->homecity)) {
1280 /* I would have thought unhappiness should be taken into account
1281 * irrespectfully the city in which it will surface... -- GB */
1283 }
1284
1287
1289 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1290 punit_map = pf_map_new(&parameter);
1291
1292 if (MOVE_NONE == punit_class->adv.sea_move) {
1293 /* We need boat to move over sea. */
1294 ferryboat = unit_transport_get(punit);
1295
1296 /* First check if we can use the boat we are currently loaded to. */
1297 if (ferryboat == NULL || !is_boat_free(ait, ferryboat, punit, 0)) {
1298 /* No, we cannot control current boat */
1299 ferryboat = NULL;
1300 }
1301
1302 if (NULL == ferryboat) {
1303 /* Try to find new boat */
1304 ferryboat = player_unit_by_number(pplayer,
1305 aiferry_find_boat(ait, punit, 1, NULL));
1306 }
1307
1309 harbor = TRUE;
1310 }
1311 }
1312
1313 if (NULL != ferryboat) {
1314 boattype = unit_type_get(ferryboat);
1315 pft_fill_unit_overlap_param(&parameter, nmap, ferryboat);
1316 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1317 ferry_map = pf_map_new(&parameter);
1318 } else {
1320 if (NULL == boattype) {
1321 /* We pretend that we can have the simplest boat to stimulate tech. */
1323 }
1324 if (NULL != boattype && harbor) {
1325 /* Let's simulate a boat at 'punit' position. */
1327 punit_tile, pplayer);
1328 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1329 ferry_map = pf_map_new(&parameter);
1330 } else {
1331 ferry_map = NULL;
1332 }
1333 }
1334
1336
1338 /* For the virtual unit case, which is when we are called to evaluate
1339 * which units to build, we want to calculate in danger and which
1340 * players we want to make war with in the future. We do _not_ want
1341 * to do this when actually making attacks. */
1342 if ((punit->id == 0 && !POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer))
1343 || (punit->id != 0 && !pplayers_at_war(pplayer, aplayer))) {
1344 continue; /* Not an enemy. */
1345 }
1346
1347 city_list_iterate(aplayer->cities, acity) {
1348 struct tile *atile = city_tile(acity);
1349
1352 /* Can't attack this city. It is on land. */
1353 continue;
1354 }
1355
1356 if (handicap && !map_is_known(atile, pplayer)) {
1357 /* Can't see it */
1358 continue;
1359 }
1360
1362 go_by_boat = FALSE;
1363 move_time = pos.turn;
1364 } else if (NULL == ferry_map) {
1365 continue; /* Impossible to handle. */
1366 } else {
1367 struct tile *dest, *beach;
1368
1369 if (!find_beachhead(pplayer, ferry_map, atile, punit_type,
1370 boattype, &dest, &beach)) {
1371 continue; /* Impossible to go by boat. */
1372 }
1373 if (!pf_map_position(ferry_map, dest, &pos)) {
1375 continue;
1376 }
1377 move_time = pos.turn; /* Sailing time. */
1378 if (dest != beach) {
1379 move_time++; /* Land time. */
1380 }
1381 if (NULL != ferryboat && unit_tile(ferryboat) != punit_tile) {
1382 if (pf_map_position(punit_map, unit_tile(ferryboat), &pos)) {
1383 move_time += pos.turn; /* Time to reach the boat. */
1384 } else {
1385 continue; /* Cannot reach the boat. */
1386 }
1387 }
1388 go_by_boat = TRUE;
1389 }
1390
1395 } else {
1396 pdefender = NULL;
1397 vulnerability = 0;
1398 benefit = 0;
1399 }
1400
1401 if (1 < move_time) {
1403
1404 if (def_type) {
1408 if (v > vulnerability) {
1409 /* They can build a better defender! */
1410 vulnerability = v;
1412 }
1413 }
1414 }
1415
1417
1418 reserves = (acity_data->invasion.attack
1419 - unit_list_size(acity->tile->units));
1420
1421 if (punit->id == 0) {
1422 /* Real unit would add to reserves once built. */
1425 reserves++;
1426 } else {
1427 reserves += punit_type->move_rate;
1428 }
1429 }
1430
1431 if (0 < reserves && (can_occupy
1432 || 0 < acity_data->invasion.occupy)) {
1433 /* There are units able to occupy the city after all defenders
1434 * are killed! */
1435 benefit += acity_data->worth * reserves / 5;
1436 }
1437
1438 attack = attack_value + acity_data->attack;
1439 attack *= attack;
1440 /* Avoiding handling upkeep aggregation this way -- Syela */
1441
1442 /* AI was not sending enough reinforcements to totally wipe out a city
1443 * and conquer it in one turn.
1444 * This variable enables total carnage. -- Syela */
1446
1447 if (!can_occupy && NULL == pdefender) {
1448 /* Nothing there to bash and we can't occupy!
1449 * Not having this check caused warships yoyoing */
1450 want = 0;
1451 } else if (10 < move_time) {
1452 /* Too far! */
1453 want = 0;
1454 } else if (can_occupy && 0 == acity_data->invasion.occupy
1455 && (0 < acity_data->invasion.attack
1456 || victim_count == 0)) {
1457 /* Units able to occupy really needed there! */
1458 want = bcost * SHIELD_WEIGHTING;
1459 } else {
1460 want = kill_desire(benefit, attack, bcost + acity_data->bcost,
1462 }
1465 /* Build_cost of ferry. */
1466 needferry = (go_by_boat && NULL == ferryboat
1468 /* FIXME: add time to build the ferry? */
1470 want, MAX(1, move_time),
1472
1473 /* BEGIN STEAM-ENGINES-ARE-OUR-FRIENDS KLUGE. */
1474 if (0 >= want && 0 == punit->id && 0 >= best) {
1478 MAX(1, move_time),
1480
1481 if (bk_e > bk) {
1482 *pdest_tile = atile;
1483 if (NULL != pferrymap) {
1485 }
1486 if (NULL != pferryboat) {
1487 *pferryboat = go_by_boat ? ferryboat : NULL;
1488 }
1489 if (NULL != pboattype) {
1491 }
1492 if (NULL != pmove_time) {
1494 }
1495 goto_dest_tile = (go_by_boat && NULL != ferryboat
1496 ? unit_tile(ferryboat) : atile);
1497 bk = bk_e;
1498 }
1499 }
1500 /* END STEAM-ENGINES KLUGE */
1501
1502 if (0 != punit->id
1503 && NULL != ferryboat
1504 && punit_class->adv.sea_move == MOVE_NONE) {
1506 "%s(): with boat %s@(%d, %d) -> %s@(%d, %d)"
1507 " (go_by_boat = %d, move_time = %d, want = " ADV_WANT_PRINTF
1508 ", best = " ADV_WANT_PRINTF ")",
1509 __FUNCTION__, unit_rule_name(ferryboat),
1510 TILE_XY(unit_tile(ferryboat)), city_name_get(acity),
1511 TILE_XY(atile), go_by_boat, move_time, want, best);
1512 }
1513
1514 if (want > best && ai_fuzzy(pplayer, TRUE)) {
1515 /* Yes, we like this target */
1516 best = want;
1517 *pdest_tile = atile;
1518 if (NULL != pferrymap) {
1520 }
1521 if (NULL != pferryboat) {
1522 *pferryboat = go_by_boat ? ferryboat : NULL;
1523 }
1524 if (NULL != pboattype) {
1526 }
1527 if (NULL != pmove_time) {
1529 }
1530 goto_dest_tile = (go_by_boat && NULL != ferryboat
1531 ? unit_tile(ferryboat) : atile);
1532 }
1534
1536 /* I'm not sure the following code is good but it seems to be adequate.
1537 * I am deliberately not adding ferryboat code to the unit_list_iterate.
1538 * -- Syela */
1540 struct tile *atile = unit_tile(aunit);
1541
1542 if (NULL != tile_city(atile)) {
1543 /* already dealt with it. */
1544 continue;
1545 }
1546
1547 if (handicap && !map_is_known(atile, pplayer)) {
1548 /* Can't see the target. */
1549 continue;
1550 }
1551
1553 && 0 == punit->id) {
1554 /* We will not build units just to chase caravans and
1555 * ambassadors. */
1556 continue;
1557 }
1558
1559 /* We have to assume the attack is diplomatically ok.
1560 * We cannot use can_player_attack_tile, because we might not
1561 * be at war with aplayer yet */
1563 || aunit != get_defender(nmap, punit, atile, NULL)) {
1564 /* We cannot attack it, or it is not the main defender. */
1565 continue;
1566 }
1567
1569 /* Cannot reach it. */
1570 continue;
1571 }
1572
1575
1576 move_time = pos.turn;
1577 if (10 < move_time) {
1578 /* Too far. */
1579 want = 0;
1580 } else {
1581 want = kill_desire(benefit, attack, bcost, vulnerability, 1);
1582 /* Take into account maintainance of the unit. */
1583 /* FIXME: Depends on the government. */
1584 want -= move_time * SHIELD_WEIGHTING;
1585 /* Take into account unhappiness
1586 * (costs 2 luxuries to compensate). */
1587 want -= (unhap ? 2 * move_time * TRADE_WEIGHTING : 0);
1588 }
1590 want, MAX(1, move_time), bcost_bal);
1591 if (want > best && ai_fuzzy(pplayer, TRUE)) {
1592 best = want;
1593 *pdest_tile = atile;
1594 if (NULL != pferrymap) {
1595 *pferrymap = NULL;
1596 }
1597 if (NULL != pferryboat) {
1598 *pferryboat = NULL;
1599 }
1600 if (NULL != pboattype) {
1601 *pboattype = NULL;
1602 }
1603 if (NULL != pmove_time) {
1605 }
1607 }
1610
1611 if (NULL != ppath) {
1614 }
1615
1617 if (NULL != ferry_map
1618 && (NULL == pferrymap || *pferrymap != ferry_map)) {
1620 }
1621
1623
1624 return best;
1625}
1626
1627/**********************************************************************/
1636{
1637 struct pf_parameter parameter;
1638 struct pf_map *pfm;
1639 struct player *pplayer = unit_owner(punit);
1640 struct city *pcity, *best_city = NULL;
1641 int best = FC_INFINITY, cur;
1642 const struct civ_map *nmap = &(wld.map);
1643
1644 pft_fill_unit_parameter(&parameter, nmap, punit);
1645 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1646 pfm = pf_map_new(&parameter);
1647
1648 pf_map_move_costs_iterate(pfm, ptile, move_cost, TRUE) {
1649 if (move_cost > best) {
1650 /* We already found a better city. No need to continue. */
1651 break;
1652 }
1653
1654 pcity = tile_city(ptile);
1655 if (NULL == pcity || !pplayers_allied(pplayer, city_owner(pcity))) {
1656 continue;
1657 }
1658
1659 /* Score based on the move cost. */
1660 cur = move_cost;
1661
1662 /* Note the unit owner may be different from the city owner. */
1663 if (0 == get_unittype_bonus(unit_owner(punit), ptile,
1665 EFT_HP_REGEN)) {
1666 /* If we cannot regen fast our hit points here, let's make some
1667 * penalty. */
1668 cur *= 3;
1669 }
1670
1671 if (cur < best) {
1672 best_city = pcity;
1673 best = cur;
1674 }
1676
1678 return best_city;
1679}
1680
1681/**********************************************************************/
1687 struct player *pplayer,
1688 struct unit *punit)
1689{
1690 struct city *pc;
1691 bool only_continent = TRUE;
1692
1693 if (unit_transported(punit)) {
1694 /* If we are in transport, we can go to any continent.
1695 * Actually, we are not currently in a continent where to stay. */
1697 }
1698
1699 if ((pc = find_closest_city(unit_tile(punit), NULL, pplayer, FALSE,
1702 UNIT_LOG(LOG_DEBUG, punit, "Barbarian heading to conquer %s",
1703 city_name_get(pc));
1704 (void) dai_gothere(ait, pplayer, punit, pc->tile);
1705 } else {
1706 struct unit *ferry = NULL;
1707
1708 if (unit_transported(punit)) {
1709 ferry = unit_transport_get(punit);
1710
1711 /* We already are in a boat so it needs no
1712 * free capacity */
1713 if (!is_boat_free(ait, ferry, punit, 0)) {
1714 /* We cannot control our ferry. */
1715 ferry = NULL;
1716 }
1717 } else {
1718 /* We are not in a boat yet. Search for one. */
1720 if (is_boat_free(ait, aunit, punit, 1)
1722 ferry = aunit;
1723 break;
1724 }
1726 }
1727
1728 if (ferry) {
1729 UNIT_LOG(LOG_DEBUG, punit, "Barbarian sailing to conquer %s",
1730 city_name_get(pc));
1731 (void) aiferry_goto_amphibious(ait, ferry, punit, pc->tile);
1732 } else {
1733 /* This is not an error. Somebody else might be in charge
1734 * of the ferry. */
1735 UNIT_LOG(LOG_DEBUG, punit, "unable to find barbarian ferry");
1736 }
1737 }
1738 } else {
1739 UNIT_LOG(LOG_DEBUG, punit, "Barbarian find no target city");
1740 }
1741}
1742
1743/**********************************************************************/
1749static void dai_military_attack(struct ai_type *ait, struct player *pplayer,
1750 struct unit *punit)
1751{
1752 struct tile *dest_tile;
1753 int id = punit->id;
1754 int ct = 10;
1755 struct city *pcity = NULL;
1756
1758
1759 /* Barbarians pillage, and might keep on doing that so they sometimes
1760 * even finish it. */
1761 if (punit->activity == ACTIVITY_PILLAGE && is_barbarian(pplayer)
1762 && fc_rand(2) == 1) {
1763 return;
1764 }
1765
1766 /* First find easy nearby enemies, anything better than pillage goes.
1767 * NB: We do not need to repeat dai_military_rampage, it is repeats itself
1768 * until it runs out of targets. */
1769 /* FIXME: 1. dai_military_rampage never checks if it should defend newly
1770 * conquered cities.
1771 * FIXME: 2. would be more convenient if it returned FALSE if we run out
1772 * of moves too.*/
1774 return; /* we died */
1775 }
1776
1777 if (punit->moves_left <= 0) {
1778 return;
1779 }
1780
1781 /* Main attack loop */
1782 do {
1783 struct tile *start_tile = unit_tile(punit);
1784 struct pf_path *path;
1785 struct unit *ferryboat;
1786
1787 /* Then find enemies the hard way */
1788 find_something_to_kill(ait, pplayer, punit, &dest_tile, &path,
1789 NULL, &ferryboat, NULL, NULL);
1790 if (!same_pos(unit_tile(punit), dest_tile)) {
1791 if (!is_tiles_adjacent(unit_tile(punit), dest_tile)
1792 || !can_unit_attack_tile(punit, NULL, dest_tile)) {
1793
1794 /* Adjacent and can't attack usually means we are not marines
1795 * and on a ferry. This fixes the problem (usually). */
1796 UNIT_LOG(LOG_DEBUG, punit, "mil att gothere -> (%d, %d)",
1797 TILE_XY(dest_tile));
1798
1799 /* Set ACTIVITY_GOTO more permanently than just inside
1800 * adv_follow_path(). This way other units will know we're
1801 * on our way even if we don't reach target yet. */
1802 punit->goto_tile = dest_tile;
1804 if (NULL != path && !adv_follow_path(punit, path, dest_tile)) {
1805 /* Died. */
1806 pf_path_destroy(path);
1807 return;
1808 }
1809 if (NULL != ferryboat) {
1810 /* Need a boat. */
1811 aiferry_gobyboat(ait, pplayer, punit, dest_tile, FALSE);
1812 pf_path_destroy(path);
1813 return;
1814 }
1815 if (0 >= punit->moves_left) {
1816 /* No moves left. */
1817 pf_path_destroy(path);
1818 return;
1819 }
1820
1821 /* Either we're adjacent or we sitting on the tile. We might be
1822 * sitting on the tile if the enemy that _was_ sitting there
1823 * attacked us and died _and_ we had enough movement to get there */
1824 if (same_pos(unit_tile(punit), dest_tile)) {
1825 UNIT_LOG(LOG_DEBUG, punit, "mil att made it -> (%d, %d)",
1826 TILE_XY(dest_tile));
1827 pf_path_destroy(path);
1828 break;
1829 }
1830 }
1831
1832 if (is_tiles_adjacent(unit_tile(punit), dest_tile)) {
1833 /* Close combat. fstk sometimes want us to attack an adjacent
1834 * enemy that rampage wouldn't */
1835 UNIT_LOG(LOG_DEBUG, punit, "mil att bash -> (%d, %d)",
1836 TILE_XY(dest_tile));
1837 if (!dai_unit_attack(ait, punit, dest_tile)) {
1838 /* Died */
1839 pf_path_destroy(path);
1840 return;
1841 }
1842 } else if (!same_pos(start_tile, unit_tile(punit))) {
1843 /* Got stuck. Possibly because of adjacency to an
1844 * enemy unit. Perhaps we are in luck and are now next to a
1845 * tempting target? Let's find out... */
1848 pf_path_destroy(path);
1849 return;
1850 }
1851
1852 } else {
1853 /* FIXME: This happens a bit too often! */
1854 UNIT_LOG(LOG_DEBUG, punit, "fstk didn't find us a worthy target!");
1855 /* No worthy enemies found, so abort loop */
1856 ct = 0;
1857 }
1858 pf_path_destroy(path);
1859
1860 ct--; /* infinite loops from railroads must be stopped */
1861 } while (punit->moves_left > 0 && ct > 0);
1862
1863 /* Cleanup phase */
1864 if (punit->moves_left == 0) {
1865 return;
1866 }
1868 if (pcity != NULL
1869 && (dai_is_ferry(punit, ait)
1870 || punit->hp < unit_type_get(punit)->hp * 0.50)) { /* WAG */
1871 /* Go somewhere safe */
1872 UNIT_LOG(LOG_DEBUG, punit, "heading to nearest safe house.");
1873 (void) dai_unit_goto(ait, punit, pcity->tile);
1874 } else if (!is_barbarian(pplayer)) {
1875 /* Nothing else to do, so try exploring. */
1876 switch (manage_auto_explorer(punit)) {
1877 case MR_DEATH:
1878 /* don't use punit! */
1879 return;
1880 case MR_OK:
1881 UNIT_LOG(LOG_DEBUG, punit, "nothing else to do, so exploring");
1882 break;
1883 default:
1884 UNIT_LOG(LOG_DEBUG, punit, "nothing to do - no more exploring either");
1885 break;
1886 };
1887 } else {
1888 /* You can still have some moves left here, but barbarians should
1889 not sit helplessly, but advance towards nearest known enemy city */
1890 UNIT_LOG(LOG_DEBUG, punit, "attack: barbarian");
1891 dai_military_attack_barbarian(ait, pplayer, punit);
1892 }
1893 if ((punit = game_unit_by_number(id)) && punit->moves_left > 0) {
1894 UNIT_LOG(LOG_DEBUG, punit, "attack: giving up unit to defense");
1895 dai_military_defend(ait, pplayer, punit);
1896 }
1897}
1898
1899/**********************************************************************/
1903static bool dai_find_boat_for_unit(struct ai_type *ait, struct unit *punit)
1904{
1905 bool alive = TRUE;
1906 int ferryboat = 0;
1907 struct pf_path *path_to_ferry = NULL;
1908
1909 UNIT_LOG(LOG_CARAVAN, punit, "requesting a boat!");
1910 ferryboat = aiferry_find_boat(ait, punit, 1, &path_to_ferry);
1911 /* going to meet the boat */
1912 if ((ferryboat <= 0)) {
1914 "in find_boat_for_unit cannot find any boats.");
1915 /* if we are undefended on the country side go to a city */
1917 if (current_city == NULL) {
1919 if (city_near != NULL) {
1921 }
1922 }
1923 } else {
1924 if (path_to_ferry != NULL) {
1926 /* Died. */
1929 alive = FALSE;
1930 } else {
1933 alive = TRUE;
1934 }
1935 }
1936 }
1937 return alive;
1938}
1939
1940/**********************************************************************/
1949 struct tile *ctile, struct tile *ptile)
1950{
1951 /* We usually have Inaccessible terrain, so not testing MOVE_FULL == */
1952 bool lm = MOVE_NONE != pclass->adv.land_move,
1953 sm = MOVE_NONE != pclass->adv.sea_move;
1954 struct civ_map *pmap = &(wld.map);
1955
1956 if (lm && sm) {
1957 return FALSE;
1958 }
1959
1960 /* We could use adjc_iterate() but likely often tiles are on the same
1961 * continent and it will be more time to find where they connect */
1964
1965 if (is_ocean_tile(atile) ? sm : lm) {
1966 iterate_outward(pmap, ptile, 1, btile) {
1967 if (tile_continent(btile) == acont) {
1968 return FALSE;
1969 }
1971 }
1973
1974 if (is_tiles_adjacent(ctile, ptile)) {
1975 return FALSE;
1976 }
1977
1978 return TRUE;
1979}
1980
1981/**********************************************************************/
1987static void dai_caravan_goto(struct ai_type *ait, struct player *pplayer,
1988 struct unit *punit,
1989 const struct city *dest_city,
1990 bool help_wonder,
1991 bool required_boat, bool request_boat)
1992{
1993 bool alive = TRUE;
1994 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
1995 const struct civ_map *nmap = &(wld.map);
1996
1998
1999 /* if we're not there yet, and we can move, move... */
2000 if (!same_pos(dest_city->tile, unit_tile(punit))
2001 && punit->moves_left != 0) {
2002 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) task %s going to %s in %s %s",
2006 help_wonder ? "help a wonder" : "trade", city_name_get(dest_city),
2007 required_boat ? "with a boat" : "");
2008 if (required_boat) {
2009 /* to trade with boat */
2010 if (request_boat) {
2011 /* Try to find new boat */
2013 } else {
2014 /* if we are not being transported then ask for a boat again */
2015 alive = TRUE;
2018 unit_tile(punit), dest_city->tile)) {
2020 }
2021 }
2022 if (alive) {
2023 /* FIXME: sometimes we get FALSE here just because
2024 * a trireme that we've boarded can't go over an ocean. */
2025 alive = dai_gothere(ait, pplayer, punit, dest_city->tile);
2026 }
2027 } else {
2028 /* to trade without boat */
2030 }
2031 }
2032
2033 /* if moving didn't kill us, and we got to the destination, handle it. */
2034 if (alive && real_map_distance(dest_city->tile, unit_tile(punit)) <= 1) {
2035 /* release the boat! */
2036 if (unit_transported(punit)) {
2038 }
2040 punit, dest_city)) {
2041 /*
2042 * We really don't want to just drop all caravans in immediately.
2043 * Instead, we want to aggregate enough caravans to build instantly.
2044 * -AJS, 990704
2045 */
2046 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) helps build wonder in %s",
2049 punit->id,
2052 unit_do_action(pplayer, punit->id, dest_city->id,
2053 0, "", ACTION_HELP_WONDER);
2055 punit, dest_city)) {
2056 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) creates trade route in %s",
2059 punit->id,
2062 unit_do_action(pplayer, punit->id, dest_city->id,
2063 0, "", ACTION_TRADE_ROUTE);
2065 punit, dest_city)) {
2066 /* Get the one time bonus. */
2067 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) enters marketplace of %s",
2070 punit->id,
2073 unit_do_action(pplayer, punit->id, dest_city->id,
2074 0, "", ACTION_MARKETPLACE);
2075 } else {
2076 enum log_level level = LOG_NORMAL;
2077
2078 if (help_wonder) {
2079 /* A Caravan ordered to help build wonder may arrive after
2080 * enough shields to build the wonder is produced. */
2082 }
2083
2085 "%s %s[%d](%d,%d) unable to trade with %s",
2088 punit->id,
2091 }
2092 }
2093}
2094
2095/**********************************************************************/
2099static void caravan_optimize_callback(const struct caravan_result *result,
2100 void *data)
2101{
2102 const struct unit *caravan = data;
2103
2104 log_base(LOG_CARAVAN3, "%s %s[%d](%d,%d) %s: %s %s worth %g",
2106 unit_rule_name(caravan),
2107 caravan->id,
2108 TILE_XY(unit_tile(caravan)),
2109 city_name_get(result->src),
2110 result->help_wonder ? "wonder in" : "trade to",
2111 city_name_get(result->dest),
2112 result->value);
2113}
2114
2115/**********************************************************************/
2119 struct unit *punit)
2120{
2121 struct tile *src = NULL, *dest = NULL, *src_home_city = NULL;
2122 struct city *phome_city = NULL;
2123 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2124
2125 if ((unit_data->task != AIUNIT_NONE)) {
2126 src = unit_tile(punit);
2128 if (phome_city != NULL) {
2130 }
2131 dest = punit->goto_tile;
2132
2133 if (src == NULL || dest == NULL) {
2134 return FALSE;
2135 }
2136
2137 /* If we have a home continent, and are not there.
2138 * (FIXME: well, why?)
2139 * (I guess because home continent is which we were supposed to leave,
2140 * not the target continent) */
2141 if (src_home_city != NULL
2143 return FALSE;
2144 }
2145
2146 if (!goto_is_sane(punit, dest)) {
2147 if (unit_transported(punit)) {
2148 /* If we're being transported */
2149 return FALSE;
2150 }
2151 if ((punit->birth_turn + 15 < game.info.turn)) {
2152 /* We are tired of waiting */
2154
2155 if (ferrys <= 0) {
2156 /* There are no ferrys available... give up */
2157 return TRUE;
2158 } else {
2159 if (punit->birth_turn + 20 < game.info.turn) {
2160 /* We are fed up! */
2161 return TRUE;
2162 }
2163 }
2164 }
2165 }
2166 }
2167
2168 return FALSE;
2169}
2170
2171/**********************************************************************/
2178 struct unit *punit)
2179{
2180 struct city *pcity = game_city_by_number(punit->homecity);
2181 Continent_id continent;
2182
2183 fc_assert(pcity != NULL);
2184
2185 if (unit_class_get(punit)->adv.ferry_types <= 0) {
2186 /* There is just no possible transporters. */
2187 return FALSE;
2188 }
2189 continent = tile_continent(pcity->tile);
2190
2191 /* Look for proper destination city at different continent. */
2192 city_list_iterate(pplayer->cities, acity) {
2193 if (can_cities_trade(pcity, acity)) {
2194 if (tile_continent(acity->tile) != continent) {
2195 return TRUE;
2196 }
2197 }
2199
2201 if (aplayer == pplayer || !aplayer->is_alive) {
2202 continue;
2203 }
2204 if (pplayers_allied(pplayer, aplayer)) {
2205 city_list_iterate(aplayer->cities, acity) {
2206 if (can_cities_trade(pcity, acity)) {
2207 if (tile_continent(acity->tile) != continent) {
2208 return TRUE;
2209 }
2210 }
2213 }
2214
2215 return FALSE;
2216}
2217
2218/**********************************************************************/
2222static bool search_homecity_for_caravan(struct ai_type *ait, struct unit *punit)
2223{
2224 struct city *nearest = NULL;
2225 int min_dist = FC_INFINITY;
2226 struct tile *current_loc = unit_tile(punit);
2228 bool alive = TRUE;
2229
2231 struct tile *ctile = city_tile(pcity);
2232
2233 if (tile_continent(ctile) == continent) {
2235
2236 if (this_dist < min_dist) {
2238 nearest = pcity;
2239 }
2240 }
2242
2243 if (nearest != NULL) {
2245 if (alive && same_pos(unit_tile(punit), nearest->tile)) {
2247 }
2248 }
2249
2250 return alive;
2251}
2252
2253/**********************************************************************/
2259static void dai_manage_caravan(struct ai_type *ait, struct player *pplayer,
2260 struct unit *punit)
2261{
2262 struct caravan_parameter parameter;
2263 struct caravan_result result;
2264 const struct city *homecity;
2265 const struct city *dest = NULL;
2266 struct unit_ai *unit_data;
2268 bool expect_boats = pclass->adv.ferry_types > 0;
2269 /* TODO: will pplayer have a boat for punit in a reasonable time? */
2270 bool help_wonder = FALSE;
2271 bool required_boat = FALSE;
2272 bool request_boat = FALSE;
2274 const struct civ_map *nmap = &(wld.map);
2275
2277
2281 /* we only want units that can establish trade, enter marketplace or
2282 * help build wonders */
2283 return;
2284 }
2285
2287
2288 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d) task %s to (%d,%d)",
2293
2294 homecity = game_city_by_number(punit->homecity);
2295 if (homecity == NULL && unit_data->task == AIUNIT_TRADE) {
2297 return;
2298 }
2299 homecity = game_city_by_number(punit->homecity);
2300 if (homecity == NULL) {
2301 return;
2302 }
2303 }
2304
2305 if ((unit_data->task == AIUNIT_TRADE
2306 || unit_data->task == AIUNIT_WONDER)) {
2307 /* We are moving to our destination */
2308 /* We check to see if our current goal is feasible */
2310 struct goods_type *pgood = unit_current_goods(punit, homecity);
2311
2312 if ((city_dest == NULL)
2314 || (unit_data->task == AIUNIT_TRADE
2315 && !(can_cities_trade(homecity, city_dest)
2317 pgood->priority)))
2318 || (unit_data->task == AIUNIT_WONDER
2319 /* Helping the (new) production is illegal. */
2321 || (unit_data->task == AIUNIT_TRADE
2326 punit, city_dest)))
2327 || (unit_data->task == AIUNIT_WONDER
2330 punit, city_dest))) {
2331 /* destination invalid! */
2333 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d) destination invalid!",
2336 } else {
2337 /* destination valid, are we tired of waiting for a boat? */
2341 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d) unit tired of waiting!",
2345 } else {
2346 dest = city_dest;
2347 help_wonder = (unit_data->task == AIUNIT_WONDER) ? TRUE : FALSE;
2348 required_boat = uclass_need_trans_between(pclass, unit_tile(punit), dest->tile);
2350 }
2351 }
2352 }
2353
2354 if (unit_data->task == AIUNIT_NONE) {
2355 if (homecity == NULL) {
2356 /* FIXME: We shouldn't bother in getting homecity for
2357 * caravan that will then be used for wonder building. */
2359 return;
2360 }
2361 homecity = game_city_by_number(punit->homecity);
2362 if (homecity == NULL) {
2363 return;
2364 }
2365 }
2366
2368 /* Make more trade with allies than other peaceful nations
2369 * by considering only allies 50% of the time.
2370 * (the other 50% allies are still considered, but so are other nations) */
2371 if (fc_rand(2)) {
2372 /* Be optimistic about development of relations with no-contact and
2373 * cease-fire nations. */
2374 parameter.allow_foreign_trade = FTL_NONWAR;
2375 } else {
2376 parameter.allow_foreign_trade = FTL_ALLIED;
2377 }
2378
2381 parameter.callback_data = punit;
2382 }
2384 parameter.ignore_transit_time = TRUE;
2385 }
2388 parameter.ignore_transit_time = FALSE;
2389 }
2390 caravan_find_best_destination(nmap, punit, &parameter, &result,
2391 !has_handicap(pplayer, H_MAP));
2392 if (result.dest != NULL) {
2393 /* We did find a new destination for the unit */
2394 dest = result.dest;
2395 help_wonder = result.help_wonder;
2396 required_boat = uclass_need_trans_between(pclass, unit_tile(punit), dest->tile);
2397 request_boat = required_boat;
2399 (help_wonder) ? AIUNIT_WONDER : AIUNIT_TRADE,
2400 dest->tile);
2401 } else {
2402 dest = NULL;
2403 }
2404 }
2405
2406 if (required_boat && !expect_boats) {
2407 /* Would require boat, but can't have them. Render destination invalid. */
2408 dest = NULL;
2409 }
2410
2411 if (dest != NULL) {
2412 dai_caravan_goto(ait, pplayer, punit, dest, help_wonder,
2413 required_boat, request_boat);
2414 return; /* that may have clobbered the unit */
2415 } else {
2416 /* We have nowhere to go! */
2417 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d), nothing to do!",
2421 /* Should we become a defensive unit? */
2422 }
2423}
2424
2425/**********************************************************************/
2430 struct unit *punit)
2431{
2432 struct player *pplayer = unit_owner(punit);
2433 struct city *pcity = tile_city(unit_tile(punit));
2434 struct city *safe = NULL;
2435 const struct unit_type *punittype = unit_type_get(punit);
2436 bool no_recovery;
2437
2439
2440 if (pcity != NULL) {
2441 /* Rest in the city until the hitpoints are recovered, but attempt
2442 * to protect city from attack (and be opportunistic too)*/
2445 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "recovering hit points.");
2446 } else {
2447 return; /* We died heroically defending our city */
2448 }
2449 } else {
2450 /* Goto to nearest city to recover hit points */
2451 /* Just before, check to see if we can occupy an undefended enemy city */
2454 return; /* Oops, we died */
2455 }
2456
2457 /* Find a city to stay and go there */
2459 if (safe) {
2460 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "going to %s to recover",
2462 if (!dai_unit_goto(ait, punit, safe->tile)) {
2463 log_base(LOGLEVEL_RECOVERY, "died trying to hide and recover");
2464 return;
2465 }
2466 } else {
2467 /* Oops */
2468 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "didn't find a city to recover in!");
2470 dai_military_attack(ait, pplayer, punit);
2471 return;
2472 }
2473 }
2474
2475 /* Is the unit still damaged? If true, and could recover hit points, do so.
2476 * Don't wait if would be losing hitpoints that way! */
2478 if (punit->hp == punittype->hp) {
2479 no_recovery = TRUE;
2480 } else {
2482
2483 if (gain < 0) {
2484 no_recovery = TRUE;
2485 } else if (gain == 0 && !punit->moved) {
2486 /* Isn't gaining even though has not moved. */
2487 no_recovery = TRUE;
2488 }
2489 }
2490 if (no_recovery) {
2491 /* We are ready to go out and kick ass again */
2492 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "ready to kick ass again!");
2494 return;
2495 } else {
2496 def_ai_unit_data(punit, ait)->done = TRUE; /* Sit tight */
2497 }
2498}
2499
2500/**********************************************************************/
2504void dai_manage_military(struct ai_type *ait, struct player *pplayer,
2505 struct unit *punit)
2506{
2507 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2508 int id = punit->id;
2509
2511
2512 /* "Escorting" aircraft should not do anything. They are activated
2513 * by their transport or charge. We do _NOT_ set them to 'done'
2514 * since they may need be activated once our charge moves. */
2515 if (unit_data->task == AIUNIT_ESCORT
2517 return;
2518 }
2519
2522 && has_handicap(pplayer, H_AWAY)) {
2523 /* Don't move sentried or fortified units controlled by a player
2524 * in away mode. */
2525 unit_data->done = TRUE;
2526 return;
2527 }
2528
2529 /* Since military units re-evaluate their actions every turn,
2530 we must make sure that previously reserved ferry is freed. */
2532
2534 /* Try hunting with this unit */
2535 if (dai_hunter_qualify(pplayer, punit)) {
2536 int result, sanity = punit->id;
2537
2538 UNIT_LOG(LOGLEVEL_HUNT, punit, "is qualified as hunter");
2539 result = dai_hunter_manage(ait, pplayer, punit);
2542 return; /* Died */
2543 }
2544 if (result == -1) {
2545 (void) dai_hunter_manage(ait, pplayer, punit); /* More carnage */
2547 return;
2548 } else if (result >= 1) {
2550 return; /* Done moving */
2551 } else if (unit_data->task == AIUNIT_HUNTER) {
2552 /* This should be very rare */
2554 }
2555 } else if (unit_data->task == AIUNIT_HUNTER) {
2557 }
2559
2560 /* Do we have a specific job for this unit? If not, we default
2561 * to attack. */
2562 dai_military_findjob(ait, pplayer, punit);
2563
2564 switch (unit_data->task) {
2565 case AIUNIT_AUTO_WORKER:
2566 case AIUNIT_BUILD_CITY:
2567 fc_assert(FALSE); /* This is not the place for this role */
2568 break;
2569 case AIUNIT_DEFEND_HOME:
2571 dai_military_defend(ait, pplayer, punit);
2573 break;
2574 case AIUNIT_ATTACK:
2575 case AIUNIT_NONE:
2577 dai_military_attack(ait, pplayer, punit);
2579 break;
2580 case AIUNIT_ESCORT:
2582 dai_military_bodyguard(ait, pplayer, punit);
2584 break;
2585 case AIUNIT_EXPLORE:
2586 switch (manage_auto_explorer(punit)) {
2587 case MR_DEATH:
2588 /* Don't use punit! */
2589 return;
2590 case MR_OK:
2591 UNIT_LOG(LOG_DEBUG, punit, "more exploring");
2592 break;
2593 default:
2594 UNIT_LOG(LOG_DEBUG, punit, "no more exploring either");
2595 break;
2596 };
2597 def_ai_unit_data(punit, ait)->done = (punit->moves_left <= 0);
2598 break;
2599 case AIUNIT_RECOVER:
2603 break;
2604 case AIUNIT_HUNTER:
2605 fc_assert(FALSE); /* Dealt with above */
2606 break;
2607 default:
2609 }
2610
2611 /* If we are still alive, either sentry or fortify. */
2612 if ((punit = game_unit_by_number(id))) {
2614 struct city *pcity = tile_city(unit_tile(punit));
2615
2616 if (unit_list_find(unit_tile(punit)->units,
2617 unit_data->ferryboat)) {
2619 } else if (pcity || punit->activity == ACTIVITY_IDLE) {
2620 /* We do not need to fortify in cities - we fortify and sentry
2621 * according to home defense setup, for easy debugging. */
2622 if (!pcity || unit_data->task == AIUNIT_DEFEND_HOME) {
2627 }
2628 } else {
2630 }
2631 }
2632 }
2633}
2634
2635/**********************************************************************/
2638static void dai_manage_settler(struct ai_type *ait, struct player *pplayer,
2639 struct unit *punit)
2640{
2641 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2642
2644 unit_data->done = TRUE; /* We will manage this unit later... ugh */
2645 /* If BUILD_CITY must remain BUILD_CITY, otherwise turn into autoworker */
2646 if (unit_data->task == AIUNIT_NONE) {
2648 }
2649}
2650
2651/**********************************************************************/
2659void dai_manage_unit(struct ai_type *ait, struct player *pplayer,
2660 struct unit *punit)
2661{
2662 struct unit_ai *unit_data;
2663 struct unit *bodyguard = aiguard_guard_of(ait, punit);
2664 bool is_ferry = FALSE;
2665 const struct unit_type *ptype;
2666
2668
2669 /* Don't manage the unit if it is under human orders. */
2670 if (unit_has_orders(punit)) {
2672
2673 UNIT_LOG(LOG_VERBOSE, punit, "is under human orders, aborting AI control.");
2675 unit_data->done = TRUE;
2676 return;
2677 }
2678
2679 /* Check if we have lost our bodyguard. If we never had one, all
2680 * fine. If we had one and lost it, ask for a new one. */
2681 if (!bodyguard && aiguard_has_guard(ait, punit)) {
2682 UNIT_LOG(LOGLEVEL_BODYGUARD, punit, "lost bodyguard, asking for new");
2684 }
2685
2687
2688 if (punit->moves_left <= 0) {
2689 /* Can do nothing */
2690 unit_data->done = TRUE;
2691 return;
2692 }
2693
2694 is_ferry = dai_is_ferry(punit, ait);
2695
2697
2700 dai_manage_diplomat(ait, pplayer, punit);
2702 return;
2703 } else if (ptype->adv.worker
2705 dai_manage_settler(ait, pplayer, punit);
2706 return;
2711 dai_manage_caravan(ait, pplayer, punit);
2713 return;
2715 dai_manage_barbarian_leader(ait, pplayer, punit);
2716 return;
2719 dai_manage_paratrooper(ait, pplayer, punit);
2720 return;
2721 } else if (is_ferry && unit_data->task != AIUNIT_HUNTER) {
2723 dai_manage_ferryboat(ait, pplayer, punit);
2725 return;
2726 } else if (utype_fuel(ptype)
2727 && unit_data->task != AIUNIT_ESCORT) {
2729 dai_manage_airunit(ait, pplayer, punit);
2731 return;
2732 } else if (is_losing_hp(punit)) {
2733 /* This unit is losing hitpoints over time */
2734
2735 /* TODO: We can try using air-unit code for helicopters, just
2736 * pretend they have fuel = HP / 3 or something. */
2737 unit_data->done = TRUE; /* we did our best, which was ...
2738 nothing */
2739 return;
2740 } else if (!is_special_unit(punit)) {
2742 UNIT_LOG(LOG_DEBUG, punit, "recruit unit for the military");
2743 dai_manage_military(ait, pplayer, punit);
2745 return;
2746 } else {
2747 /* what else could this be? -- Syela */
2748 switch (manage_auto_explorer(punit)) {
2749 case MR_DEATH:
2750 /* don't use punit! */
2751 break;
2752 case MR_OK:
2753 UNIT_LOG(LOG_DEBUG, punit, "now exploring");
2754 break;
2755 default:
2756 UNIT_LOG(LOG_DEBUG, punit, "fell through all unit tasks, defending");
2758 dai_military_defend(ait, pplayer, punit);
2759 break;
2760 };
2761 return;
2762 }
2763}
2764
2765/**********************************************************************/
2771static void dai_set_defenders(struct ai_type *ait, struct player *pplayer)
2772{
2773 city_list_iterate(pplayer->cities, pcity) {
2774 /* The idea here is that we should never keep more than two
2775 * units in permanent defense. */
2776 int total_defense = 0;
2777 int total_attack = def_ai_city_data(pcity, ait)->danger;
2778 bool emergency = FALSE;
2779 int count = 0;
2783 + pcity->feel[CITIZEN_ANGRY][FEELING_NATIONALITY];
2784 int entertainers = 0;
2785 bool enough = FALSE;
2786
2788 if (get_specialist_output(pcity, sp, O_LUXURY) > 0) {
2789 entertainers += pcity->specialists[sp];
2790 }
2792
2793 martless_unhappy += entertainers; /* We want to use martial law instead
2794 * of entertainers. */
2795
2796 while (!enough
2799 && martless_unhappy > mart_each * count))) {
2800 int best_want = 0;
2801 struct unit *best = NULL;
2802 bool defense_needed = total_defense <= total_attack; /* Defense or martial */
2803
2804 unit_list_iterate(pcity->tile->units, punit) {
2805 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2806
2807 if ((unit_data->task == AIUNIT_NONE || emergency)
2808 && unit_data->task != AIUNIT_DEFEND_HOME
2809 && unit_owner(punit) == pplayer) {
2810 int want = assess_defense_unit(ait, pcity, punit, FALSE);
2811
2812 if (want > best_want) {
2813 best_want = want;
2814 best = punit;
2815 }
2816 }
2818
2819 if (best == NULL) {
2820 if (defense_needed) {
2821 /* Ooops - try to grab any unit as defender! */
2822 if (emergency) {
2823 CITY_LOG(LOG_DEBUG, pcity, "Not defended properly");
2824 break;
2825 }
2826 emergency = TRUE;
2827 } else {
2828 break;
2829 }
2830 } else {
2831 const struct unit_type *btype = unit_type_get(best);
2832
2833 if ((martless_unhappy < mart_each * count
2834 || count >= mart_max || mart_each <= 0)
2835 && ((count >= 2
2836 && btype->attack_strength > btype->defense_strength)
2837 || (count >= 4
2838 && btype->attack_strength == btype->defense_strength))) {
2839 /* In this case attack would be better defense than fortifying
2840 * to city. */
2841 enough = TRUE;
2842 } else {
2843 int loglevel = pcity->server.debug ? LOG_AI_TEST : LOG_DEBUG;
2844
2846 UNIT_LOG(loglevel, best, "Defending city");
2847 dai_unit_new_task(ait, best, AIUNIT_DEFEND_HOME, pcity->tile);
2848 count++;
2849 }
2850 }
2851 }
2852 CITY_LOG(LOG_DEBUG, pcity, "Evaluating defense: %d defense, %d incoming"
2853 ", %d defenders (out of %d)", total_defense, total_attack, count,
2854 unit_list_size(pcity->tile->units));
2856}
2857
2858/**********************************************************************/
2866void dai_manage_units(struct ai_type *ait, struct player *pplayer)
2867{
2869 dai_airlift(ait, pplayer);
2871
2872 /* Clear previous orders, if desirable, here. */
2873 unit_list_iterate(pplayer->units, punit) {
2874 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2875
2876 unit_data->done = FALSE;
2877 if (unit_data->task == AIUNIT_DEFEND_HOME) {
2879 }
2881
2882 /* Find and set city defenders first - figure out which units are
2883 * allowed to leave home. */
2884 dai_set_defenders(ait, pplayer);
2885
2888 && !def_ai_unit_data(punit, ait)->done) {
2889 /* Though it is usually the passenger who drives the transport,
2890 * the transporter is responsible for managing its passengers. */
2891 dai_manage_unit(ait, pplayer, punit);
2892 }
2894}
2895
2896/**********************************************************************/
2902 const struct city *pcity)
2903{
2904 const struct impr_type *impr_req = NULL;
2905 const struct req_context context = {
2906 .player = city_owner(pcity),
2907 .city = pcity,
2908 .tile = city_tile(pcity),
2909 .unittype = putype,
2910 };
2911
2912 requirement_vector_iterate(&putype->build_reqs, preq) {
2914 /* Already there. */
2915 continue;
2916 }
2918 city_owner(pcity), pcity)) {
2919 /* The unit type can't be built at all. */
2920 return NULL;
2921 }
2922 if (VUT_IMPROVEMENT == preq->source.kind && preq->present) {
2923 /* This is (one of) the building(s) required. */
2924 impr_req = preq->source.value.building;
2925 }
2927
2928 return impr_req;
2929}
2930
2931/**********************************************************************/
2936 const struct unit_type *base)
2937{
2938 /* This is the real function: */
2939 do {
2940 base = base->obsoleted_by;
2941 if (base == test) {
2942 return TRUE;
2943 }
2944 } while (base);
2945 return FALSE;
2946}
2947
2948/**********************************************************************/
2953static void dai_manage_barbarian_leader(struct ai_type *ait,
2954 struct player *pplayer,
2955 struct unit *leader)
2956{
2958 struct pf_parameter parameter;
2959 struct pf_map *pfm;
2960 struct pf_reverse_map *pfrm;
2961 struct unit *worst_danger;
2962 int move_cost, best_move_cost;
2963 int body_guards;
2964 bool alive = TRUE;
2965 const struct civ_map *nmap = &(wld.map);
2966
2968
2969 if (leader->moves_left == 0
2971 && 1 < unit_list_size(leader_tile->units))) {
2973
2974 return;
2975 }
2976
2977 if (is_boss_of_boat(ait, leader)) {
2978 /* We are in charge. Of course, since we are the leader...
2979 * But maybe somebody more militaristic should lead our ship to battle! */
2980
2981 /* First release boat from leaders lead */
2983
2987 && warrior->moves_left > 0) {
2988 /* This seems like a good warrior to lead us in to conquest! */
2989 dai_manage_unit(ait, pplayer, warrior);
2990
2991 /* If we reached our destination, ferryboat already called
2992 * ai_manage_unit() for leader. So no need to continue here.
2993 * Leader might even be dead.
2994 * If this return is removed, surronding unit_list_iterate()
2995 * has to be replaced with unit_list_iterate_safe()*/
2996 return;
2997 }
2999 }
3000
3001 /* If we are not in charge of the boat, continue as if we
3002 * were not in a boat - we may want to leave the ship now. */
3003
3004 /* Check the total number of units able to protect our leader. */
3005 body_guards = 0;
3006 unit_list_iterate(pplayer->units, punit) {
3009 body_guards++;
3010 }
3012
3013 if (0 < body_guards) {
3014 pft_fill_unit_parameter(&parameter, nmap, leader);
3015 parameter.omniscience = !has_handicap(pplayer, H_MAP);
3016 pfm = pf_map_new(&parameter);
3017
3018 /* Find the closest body guard.
3019 * FIXME: maybe choose the strongest too? */
3020 pf_map_tiles_iterate(pfm, ptile, FALSE) {
3021 unit_list_iterate(ptile->units, punit) {
3022 if (unit_owner(punit) == pplayer
3025 struct pf_path *path = pf_map_path(pfm, ptile);
3026
3027 adv_follow_path(leader, path, ptile);
3028 pf_path_destroy(path);
3030 return;
3031 }
3034
3036 }
3037
3038 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader needs to flee");
3039
3040 /* Check for units we could fear. */
3041 pfrm = pf_reverse_map_new(pplayer, leader_tile, 3,
3042 !has_handicap(pplayer, H_MAP), &(wld.map));
3045
3046 players_iterate(other_player) {
3047 if (other_player == pplayer) {
3048 continue;
3049 }
3050
3051 unit_list_iterate(other_player->units, punit) {
3053 if (PF_IMPOSSIBLE_MC != move_cost && move_cost < best_move_cost) {
3054 best_move_cost = move_cost;
3056 }
3059
3061
3062 if (NULL == worst_danger) {
3064 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader: no close enemy.");
3065 return;
3066 }
3067
3069 parameter.omniscience = !has_handicap(pplayer, H_MAP);
3070 pfm = pf_map_new(&parameter);
3072
3073 /* Try to escape. */
3074 do {
3076
3077 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader: moves left: %d.",
3078 leader->moves_left);
3079
3082 continue;
3083 }
3084
3085 move_cost = pf_map_move_cost(pfm, near_tile);
3086 if (PF_IMPOSSIBLE_MC != move_cost
3087 && move_cost > best_move_cost) {
3089 "Barbarian leader: safest is (%d, %d), safeness %d",
3091 best_move_cost = move_cost;
3093 }
3095
3096 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader: fleeing to (%d, %d).",
3100 "Barbarian leader: reached the safest position.");
3103 return;
3104 }
3105
3107 if (alive) {
3109 /* Didn't move. No point to retry. */
3111 return;
3112 }
3114 }
3115 } while (alive && 0 < leader->moves_left);
3116
3118}
3119
3120/**********************************************************************/
3126void dai_consider_tile_dangerous(struct ai_type *ait, struct tile *ptile,
3127 struct unit *punit,
3128 enum override_bool *result)
3129{
3130 int a = 0, d, db;
3131 struct player *pplayer = unit_owner(punit);
3132 struct city *pcity = tile_city(ptile);
3133 int extras_bonus = 0;
3134
3135 if (is_human(pplayer)) {
3136 /* Use advisors code for humans. */
3137 return;
3138 }
3139
3140 if (pcity != NULL && pplayers_allied(city_owner(pcity), pplayer)
3141 && !is_non_allied_unit_tile(ptile, pplayer,
3143 /* We will be safe in a friendly city */
3144 *result = OVERRIDE_FALSE;
3145 return;
3146 }
3147
3148 /* Calculate how well we can defend at (x,y) */
3149 db = 10 + tile_terrain(ptile)->defense_bonus / 10;
3151
3152 db += (db * extras_bonus) / 100;
3154
3155 adjc_iterate(&(wld.map), ptile, ptile1) {
3156 if (has_handicap(pplayer, H_FOG)
3157 && !map_is_known_and_seen(ptile1, pplayer, V_MAIN)) {
3158 /* We cannot see danger at (ptile1) => assume there is none */
3159 continue;
3160 }
3161 unit_list_iterate(ptile1->units, enemy) {
3162 if (pplayers_at_war(unit_owner(enemy), pplayer)
3164 == ATT_OK)
3166 == ATT_OK)) {
3168 if ((a * a * 10) >= d) {
3169 /* The enemies combined strength is too big! */
3170 *result = OVERRIDE_TRUE;
3171 return;
3172 }
3173 }
3176
3177 *result = OVERRIDE_FALSE;
3178}
3179
3180/**********************************************************************/
3183static void update_simple_ai_types(void)
3184{
3185 int i = 0;
3186
3189
3192 && !(pclass->adv.land_move == MOVE_NONE
3195 && punittype->transport_capacity < 8) {
3197 i++;
3198 }
3200
3202}
3203
3204/**********************************************************************/
3208{
3209 /* TODO: remove the simple_ai_types cache or merge it with a general ai
3210 * cache; see the comment to struct unit_type *simple_ai_types at
3211 * the beginning of this file. */
3213
3215 struct unit_type_ai *utai = fc_malloc(sizeof(*utai));
3216
3217 utai->low_firepower = FALSE;
3218 utai->ferry = FALSE;
3219 utai->missile_platform = FALSE;
3220 utai->carries_occupiers = FALSE;
3221 utai->potential_charges = unit_type_list_new();
3222
3225
3228
3229 /* Confirm firepower */
3231 if (pbonus->type == CBONUS_LOW_FIREPOWER) {
3233 if (utype_has_flag(penemy, pbonus->flag)) {
3234 struct unit_type_ai *utai = utype_ai_data(penemy, ait);
3235
3236 utai->low_firepower = TRUE;
3237 }
3239 }
3241
3242 /* Consider potential cargo */
3243 if (punittype->transport_capacity > 0) {
3244 struct unit_type_ai *utai = utype_ai_data(punittype, ait);
3245
3248
3251 utai->missile_platform = TRUE;
3252 } else if (pclass->adv.sea_move != MOVE_NONE
3253 && pcargo->adv.land_move != MOVE_NONE) {
3254 if (pcargo->adv.sea_move != MOVE_FULL) {
3255 utai->ferry = TRUE;
3256 } else {
3257 if (0 != utype_fuel(pctype)) {
3258 utai->ferry = TRUE;
3259 }
3260 }
3261 }
3262
3264 utai->carries_occupiers = TRUE;
3265 }
3266 }
3268 }
3269
3270 /* Consider potential charges */
3273
3274 if (0 < utype_fuel(punittype)
3275 && (0 == utype_fuel(pcharge)
3277 continue;
3278 }
3279
3280 unit_class_list_iterate(pclass->cache.subset_movers, chgcls) {
3281 if (chgcls == utype_class(pcharge)) {
3283 }
3285
3287 struct unit_type_ai *utai = utype_ai_data(punittype, ait);
3288 unit_type_list_append(utai->potential_charges, pcharge);
3289 }
3290
3293}
3294
3295/**********************************************************************/
3299{
3301 struct unit_type_ai *utai = utype_ai_data(ptype, ait);
3302
3303 if (utai == NULL) {
3304 continue;
3305 }
3307
3308 unit_type_list_destroy(utai->potential_charges);
3309 free(utai);
3311}
3312
3313/**********************************************************************/
3316void dai_unit_init(struct ai_type *ait, struct unit *punit)
3317{
3318 /* Make sure that contents of unit_ai structure are correctly initialized,
3319 * if you ever allocate it by some other mean than fc_calloc() */
3320 struct unit_ai *unit_data = fc_calloc(1, sizeof(struct unit_ai));
3321
3322 unit_data->done = FALSE;
3323 unit_data->cur_pos = NULL;
3324 unit_data->prev_pos = NULL;
3325 unit_data->target = 0;
3326 BV_CLR_ALL(unit_data->hunted);
3327 unit_data->ferryboat = 0;
3328 unit_data->passenger = 0;
3329 unit_data->bodyguard = 0;
3330 unit_data->charge = 0;
3331
3333}
3334
3335/**********************************************************************/
3338void dai_unit_turn_end(struct ai_type *ait, struct unit *punit)
3339{
3340 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3341
3343
3344 BV_CLR_ALL(unit_data->hunted);
3345}
3346
3347/**********************************************************************/
3350void dai_unit_close(struct ai_type *ait, struct unit *punit)
3351{
3352 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3353
3355
3358
3359 if (unit_data != NULL) {
3362 }
3363}
3364
3365/**********************************************************************/
3368void dai_unit_save(struct ai_type *ait, const char *aitstr,
3369 struct section_file *file,
3370 const struct unit *punit, const char *unitstr)
3371{
3372 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3373
3374 secfile_insert_int(file, unit_data->passenger, "%s.%spassenger",
3375 unitstr, aitstr);
3376 secfile_insert_int(file, unit_data->ferryboat, "%s.%sferryboat",
3377 unitstr, aitstr);
3378 secfile_insert_int(file, unit_data->charge, "%s.%scharge",
3379 unitstr, aitstr);
3380 secfile_insert_int(file, unit_data->bodyguard, "%s.%sbodyguard",
3381 unitstr, aitstr);
3382}
3383
3384/**********************************************************************/
3387void dai_unit_load(struct ai_type *ait, const char *aitstr,
3388 const struct section_file *file,
3389 struct unit *punit, const char *unitstr)
3390{
3391 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3392
3393 unit_data->passenger
3394 = secfile_lookup_int_default(file, 0, "%s.%spassenger",
3395 unitstr, aitstr);
3396 unit_data->ferryboat
3397 = secfile_lookup_int_default(file, 0, "%s.%sferryboat",
3398 unitstr, aitstr);
3399 unit_data->charge
3400 = secfile_lookup_int_default(file, 0, "%s.%scharge",
3401 unitstr, aitstr);
3402 unit_data->bodyguard
3403 = secfile_lookup_int_default(file, 0, "%s.%sbodyguard",
3404 unitstr, aitstr);
3405}
3406
3412
3413/**********************************************************************/
3416static bool role_unit_cb(struct unit_type *ptype, void *data)
3417{
3418 struct role_unit_cb_data *cb_data = (struct role_unit_cb_data *)data;
3420
3421 if ((cb_data->tc == TC_LAND && pclass->adv.land_move == MOVE_NONE)
3422 || (cb_data->tc == TC_OCEAN && pclass->adv.sea_move == MOVE_NONE)) {
3423 return FALSE;
3424 }
3425
3426 if (cb_data->build_city == NULL
3427 || can_city_build_unit_now(cb_data->build_city, ptype)) {
3428 return TRUE;
3429 }
3430
3431 return FALSE;
3432}
3433
3434/**********************************************************************/
3438 enum terrain_class tc)
3439{
3440 struct role_unit_cb_data cb_data = { .build_city = pcity, .tc = tc };
3441
3443}
3444
3445/**********************************************************************/
3448bool dai_unit_can_strike_my_unit(const struct unit *attacker,
3449 const struct unit *defender)
3450{
3451 struct pf_parameter parameter;
3452 struct pf_map *pfm;
3453 const struct tile *ptarget = unit_tile(defender);
3454 int max_move_cost = attacker->moves_left;
3455 bool able_to_strike = FALSE;
3456 const struct civ_map *nmap = &(wld.map);
3457
3458 pft_fill_unit_parameter(&parameter, nmap, attacker);
3459 parameter.omniscience = !has_handicap(unit_owner(defender), H_MAP);
3460 pfm = pf_map_new(&parameter);
3461
3462 pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
3463 if (move_cost > max_move_cost) {
3464 break;
3465 }
3466
3467 if (ptile == ptarget) {
3469 break;
3470 }
3472
3474
3475 return able_to_strike;
3476}
3477
3478/**********************************************************************/
3481void dai_switch_to_explore(struct ai_type *ait, struct unit *punit,
3482 struct tile *target, enum override_bool *allow)
3483{
3484 struct unit_ai *udata = def_ai_unit_data(punit, ait);
3485
3486 if (udata->task != AIUNIT_NONE && udata->task != AIUNIT_EXPLORE) {
3488
3489 return;
3490 }
3491}
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:3052
static struct action * action_by_number(action_id act_id)
Definition actions.h:390
#define ACTION_NONE
Definition actions.h:55
#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:47
int adv_unit_def_rating_basic_squared(const struct unit *punit)
Definition advgoto.c:415
int adv_unit_def_rating_basic(const struct unit *punit)
Definition advgoto.c:406
int adv_unittype_att_rating(const struct unit_type *punittype, int veteran, int moves_left, int hp)
Definition advgoto.c:385
int adv_unit_att_rating(const struct unit *punit)
Definition advgoto.c:396
int adv_could_unit_move_to_tile(struct unit *punit, struct tile *dest_tile)
Definition advgoto.c:359
bool adv_unit_execute_path(struct unit *punit, struct pf_path *path)
Definition advgoto.c:86
#define POWER_DIVIDER
Definition advtools.h:32
void dai_manage_diplomat(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aidiplomat.c:723
bool aiferry_gobyboat(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct tile *dest_tile, bool with_bodyguard)
Definition aiferry.c:764
int aiferry_find_boat(struct ai_type *ait, struct unit *punit, int cap, struct pf_path **path)
Definition aiferry.c:495
void dai_manage_ferryboat(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aiferry.c:1113
bool is_boat_free(struct ai_type *ait, struct unit *boat, struct unit *punit, int cap)
Definition aiferry.c:438
bool aiferry_goto_amphibious(struct ai_type *ait, struct unit *ferry, struct unit *passenger, struct tile *ptile)
Definition aiferry.c:730
bool is_boss_of_boat(struct ai_type *ait, struct unit *punit)
Definition aiferry.c:471
int aiferry_avail_boats(struct ai_type *ait, struct player *pplayer)
Definition aiferry.c:353
bool dai_is_ferry(struct unit *pferry, struct ai_type *ait)
Definition aiferry.c:159
void aiferry_clear_boat(struct ai_type *ait, struct unit *punit)
Definition aiferry.c:251
struct city * aiguard_charge_city(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:289
void aiguard_clear_charge(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:117
void aiguard_request_guard(struct ai_type *ait, struct unit *punit)
Definition aiguard.c:227
bool aiguard_has_guard(struct ai_type *ait, struct unit *charge)
Definition aiguard.c:259
void aiguard_assign_guard_unit(struct ai_type *ait, struct unit *charge, struct unit *guard)
Definition aiguard.c:173
bool aiguard_wanted(struct ai_type *ait, struct unit *charge)
Definition aiguard.c:241
void aiguard_assign_guard_city(struct ai_type *ait, struct city *charge, struct unit *guard)
Definition aiguard.c:196
struct unit * aiguard_charge_unit(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:279
void aiguard_clear_guard(struct ai_type *ait, struct unit *charge)
Definition aiguard.c:146
struct unit * aiguard_guard_of(struct ai_type *ait, struct unit *charge)
Definition aiguard.c:269
bool aiguard_has_charge(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:250
void aiguard_update_charge(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:299
#define CHECK_GUARD(ait, guard)
Definition aiguard.h:21
void dai_manage_paratrooper(struct ai_type *ait, struct player *pplayer, struct unit *punit)
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:95
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:679
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:1856
const char * city_name_get(const struct city *pcity)
Definition city.c:1133
int city_production_unit_veteran_level(struct city *pcity, const struct unit_type *punittype)
Definition city.c:804
bool can_city_build_unit_now(const struct city *pcity, const struct unit_type *punittype)
Definition city.c:948
#define city_list_iterate(citylist, pcity)
Definition city.h:508
#define city_tile(_pcity_)
Definition city.h:564
@ CITIZEN_ANGRY
Definition city.h:271
@ CITIZEN_UNHAPPY
Definition city.h:270
#define city_owner(_pcity_)
Definition city.h:563
#define city_list_iterate_end
Definition city.h:510
@ FEELING_NATIONALITY
Definition city.h:282
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:851
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:992
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:715
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:770
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:839
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:74
void dai_manage_airunit(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiair.c:487
bool dai_can_requirement_be_met_in_city(const struct requirement *preq, const struct player *pplayer, const struct city *pcity)
Definition daieffects.c:811
bool dai_hunter_qualify(struct player *pplayer, struct unit *punit)
Definition daihunter.c:285
int dai_hunter_manage(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daihunter.c:433
#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)
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:1279
bool goto_is_sane(struct unit *punit, struct tile *ptile)
Definition daitools.c:427
bool dai_assess_military_unhappiness(struct city *pcity)
Definition daitools.c:1414
bool dai_unit_attack(struct ai_type *ait, struct unit *punit, struct tile *ptile)
Definition daitools.c:815
bool dai_unit_goto(struct ai_type *ait, struct unit *punit, struct tile *ptile)
Definition daitools.c:603
void dai_unit_new_task(struct ai_type *ait, struct unit *punit, enum ai_unit_task task, struct tile *ptile)
Definition daitools.c:641
bool dai_unit_make_homecity(struct unit *punit, struct city *pcity)
Definition daitools.c:753
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:242
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:3368
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
void dai_manage_military(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:2504
static bool search_homecity_for_caravan(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:2222
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:1987
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:699
void dai_units_ruleset_init(struct ai_type *ait)
Definition daiunit.c:3207
#define LOG_CARAVAN
Definition daiunit.c:88
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:1686
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:1061
static void invasion_funct(struct ai_type *ait, struct unit *punit, bool dest, int radius, int which)
Definition daiunit.c:1019
static void update_simple_ai_types(void)
Definition daiunit.c:3183
const struct impr_type * utype_needs_improvement(const struct unit_type *putype, const struct city *pcity)
Definition daiunit.c:2901
void dai_switch_to_explore(struct ai_type *ait, struct unit *punit, struct tile *target, enum override_bool *allow)
Definition daiunit.c:3481
static bool dai_find_boat_for_unit(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:1903
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:126
static void dai_airlift(struct ai_type *ait, struct player *pplayer)
Definition daiunit.c:169
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:3448
bool is_on_unit_upgrade_path(const struct unit_type *test, const struct unit_type *base)
Definition daiunit.c:2935
static void dai_military_bodyguard(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:633
static void single_invader(struct ai_city *city_data, const struct unit_type *utype, int which)
Definition daiunit.c:991
#define LOG_CARAVAN3
Definition daiunit.c:90
void dai_manage_units(struct ai_type *ait, struct player *pplayer)
Definition daiunit.c:2866
adv_want look_for_charge(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct unit **aunit, struct city **acity)
Definition daiunit.c:714
static void dai_manage_caravan(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:2259
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:1139
static void dai_set_defenders(struct ai_type *ait, struct player *pplayer)
Definition daiunit.c:2771
void dai_manage_unit(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:2659
static bool role_unit_cb(struct unit_type *ptype, void *data)
Definition daiunit.c:3416
static void dai_military_attack(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:1749
void dai_unit_turn_end(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:3338
static void dai_manage_settler(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:2638
static int avg_benefit(int benefit, int loss, double chance)
Definition daiunit.c:365
#define LOG_CARAVAN2
Definition daiunit.c:89
static struct city * find_neediest_airlift_city(struct ai_type *ait, const struct player *pplayer)
Definition daiunit.c:138
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:2118
static int dai_rampage_want(struct unit *punit, struct tile *ptile)
Definition daiunit.c:456
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:834
struct city * find_nearest_safe_city(struct unit *punit)
Definition daiunit.c:1635
static void dai_manage_barbarian_leader(struct ai_type *ait, struct player *pplayer, struct unit *leader)
Definition daiunit.c:2953
static void dai_manage_hitpoint_recovery(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:2429
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:521
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:3316
void dai_consider_tile_dangerous(struct ai_type *ait, struct tile *ptile, struct unit *punit, enum override_bool *result)
Definition daiunit.c:3126
static void dai_military_findjob(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:852
bool uclass_need_trans_between(struct unit_class *pclass, struct tile *ctile, struct tile *ptile)
Definition daiunit.c:1948
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:3387
static void caravan_optimize_callback(const struct caravan_result *result, void *data)
Definition daiunit.c:2099
#define LOGLEVEL_RECOVERY
Definition daiunit.c:87
void dai_unit_close(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:3350
void dai_units_ruleset_close(struct ai_type *ait)
Definition daiunit.c:3298
struct unit_type * dai_role_utype_for_terrain_class(struct city *pcity, int role, enum terrain_class tc)
Definition daiunit.c:3437
static void dai_military_defend(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:945
bool dai_military_rampage(struct unit *punit, int thresh_adj, int thresh_move)
Definition daiunit.c:600
static bool dai_caravan_can_trade_cities_diff_cont(struct player *pplayer, struct unit *punit)
Definition daiunit.c:2177
#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:3016
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2938
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 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:1031
bool unit_can_enter_hut(const struct unit *punit, const struct tile *ptile)
Definition extras.c:720
float adv_want
Definition fc_types.h:1335
@ RPT_CERTAIN
Definition fc_types.h:678
@ AUT_AUTO_WORKER
Definition fc_types.h:374
#define ADV_WANT_PRINTF
Definition fc_types.h:1336
@ O_LUXURY
Definition fc_types.h:101
signed short Continent_id
Definition fc_types.h:376
override_bool
Definition fc_types.h:94
@ OVERRIDE_TRUE
Definition fc_types.h:94
@ OVERRIDE_FALSE
Definition fc_types.h:94
struct civ_game game
Definition game.c:61
struct world wld
Definition game.c:62
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:191
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define log_do_output_for_level(level)
Definition log.h:89
#define log_base(level, message,...)
Definition log.h:94
log_level
Definition log.h:28
@ LOG_DEBUG
Definition log.h:34
@ LOG_NORMAL
Definition log.h:32
@ LOG_VERBOSE
Definition log.h:33
bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
Definition map.c:941
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:950
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:636
int map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:660
#define iterate_outward(nmap, start_tile, max_dist, itr_tile)
Definition map.h:353
#define iterate_outward_end
Definition map.h:357
#define adjc_iterate_end
Definition map.h:419
static int index_to_map_pos_y(int mindex)
Definition map.h:710
#define square_iterate(nmap, center_tile, radius, tile_itr)
Definition map.h:377
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:414
#define square_iterate_end
Definition map.h:380
static int index_to_map_pos_x(int mindex)
Definition map.h:701
#define pmap(_tile)
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:901
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:927
#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:318
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:330
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:490
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Definition movement.c:869
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:84
@ 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:463
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)
struct pf_reverse_map * pf_reverse_map_new(const struct player *pplayer, struct tile *target_tile, int max_turns, bool omniscient, const struct civ_map *nmap)
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)
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:1229
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1388
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1409
#define players_iterate_end
Definition player.h:539
#define players_iterate(_pplayer)
Definition player.h:534
static bool is_barbarian(const struct player *pplayer)
Definition player.h:491
#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:217
#define specialist_type_iterate_end
Definition specialist.h:79
#define specialist_type_iterate(sp)
Definition specialist.h:73
#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:320
int id
Definition city.h:326
struct adv_city * adv
Definition city.h:452
struct tile * tile
Definition city.h:322
struct packet_game_info info
Definition game.h:89
int occupychance
Definition game.h:170
struct civ_game::@31::@35 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:3409
struct city * build_city
Definition daiunit.c:3410
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
int hp
Definition unit.h:153
struct tile * tile
Definition unit.h:142
struct unit_adv * adv
Definition unit.h:239
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:612
#define is_ocean_tile(ptile)
Definition terrain.h:196
int tile_extras_defense_bonus(const struct tile *ptile, const struct unit_type *punittype)
Definition tile.c:233
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:111
#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:2328
bool unit_transport_load(struct unit *pcargo, struct unit *ptrans, bool force)
Definition unit.c:2428
bool is_losing_hp(const struct unit *punit)
Definition unit.c:2266
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2499
int unit_gain_hitpoints(const struct unit *punit)
Definition unit.c:2221
bool unit_is_cityfounder(const struct unit *punit)
Definition unit.c:2699
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:386
bool unit_can_do_action_result(const struct unit *punit, enum action_result result)
Definition unit.c:396
enum gen_action activity_default_action(enum unit_activity act)
Definition unit.c:2911
int get_transporter_capacity(const struct unit *punit)
Definition unit.c:300
bool unit_can_airlift_to(const struct unit *punit, const struct city *pdest_city)
Definition unit.c:186
bool can_unit_do_activity(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity)
Definition unit.c:893
bool is_special_unit(const struct unit *punit)
Definition unit.c:353
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2483
bool is_guard_unit(const struct unit *punit)
Definition unit.c:343
bool unit_has_orders(const struct unit *punit)
Definition unit.c:205
#define unit_tile(_pu)
Definition unit.h:397
#define unit_cargo_iterate_end
Definition unit.h:575
#define unit_cargo_iterate(_ptrans, _pcargo)
Definition unit.h:572
#define CHECK_UNIT(punit)
Definition unit.h:273
#define unit_owner(_pu)
Definition unit.h:396
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer, bool everyone_non_allied)
Definition unit.h:433
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity, enum gen_action trigger_action)
Definition unithand.c:6613
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:3317
bool unit_server_side_agent_set(struct player *pplayer, struct unit *punit, enum server_side_agent agent)
Definition unithand.c:6513
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:1191
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
struct unit_type * role_units_iterate_backwards(int role, role_unit_callback cb, void *data)
Definition unittype.c:2236
struct unit_type * get_role_unit(int role, int role_index)
Definition unittype.c:2253
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1587
bool utype_has_role(const struct unit_type *punittype, int role)
Definition unittype.c:199
int utype_build_shield_cost_base(const struct unit_type *punittype)
Definition unittype.c:1468
int unit_build_shield_cost_base(const struct unit *punit)
Definition unittype.c:1484
struct unit_type * best_role_unit_for_player(const struct player *pplayer, int role)
Definition unittype.c:2297
struct unit_class * unit_class_get(const struct unit *punit)
Definition unittype.c:2498
bool utype_can_do_action_result(const struct unit_type *putype, enum action_result result)
Definition unittype.c:387
bool unit_has_type_role(const struct unit *punit, enum unit_role_id role)
Definition unittype.c:208
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:190
bool unit_can_take_over(const struct unit *punit)
Definition unittype.c:264
void * utype_ai_data(const struct unit_type *ptype, const struct ai_type *ai)
Definition unittype.c:2725
bool utype_can_take_over(const struct unit_type *punittype)
Definition unittype.c:276
void utype_set_ai_data(struct unit_type *ptype, const struct ai_type *ai, void *data)
Definition unittype.c:2733
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1438
bool utype_acts_hostile(const struct unit_type *putype)
Definition unittype.c:443
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:371
#define utype_class(_t_)
Definition unittype.h:756
#define utype_fuel(ptype)
Definition unittype.h:843
#define combat_bonus_list_iterate_end
Definition unittype.h:489
#define combat_bonus_list_iterate(bonuslist, pbonus)
Definition unittype.h:487
@ MOVE_FULL
Definition unittype.h:144
@ MOVE_NONE
Definition unittype.h:144
#define unit_type_list_iterate(utype_list, ptype)
Definition unittype.h:944
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:936
#define unit_type_iterate(_p)
Definition unittype.h:859
#define unit_type_list_iterate_end
Definition unittype.h:946
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:866
#define unit_class_list_iterate_end
Definition unittype.h:938