Freeciv-3.2
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 "autosettlers.h"
63
64/* ai */
65#include "difficulty.h"
66#include "handicaps.h"
67
68/* ai/default */
69#include "aiair.h"
70#include "aidiplomat.h"
71#include "aiferry.h"
72#include "aiguard.h"
73#include "aihand.h"
74#include "aihunt.h"
75#include "aiparatrooper.h"
76#include "aitools.h"
77#include "daicity.h"
78#include "daidata.h"
79#include "daieffects.h"
80#include "dailog.h"
81#include "daimilitary.h"
82#include "daiplayer.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, const struct civ_map *nmap,
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 const struct civ_map *nmap = &(wld.map);
175
176 do {
178 comparison = 0;
179 transported = NULL;
180
181 if (!most_needed) {
182 return;
183 }
184
185 unit_list_iterate(pplayer->units, punit) {
186 struct tile *ptile = (unit_tile(punit));
187 struct city *pcity = tile_city(ptile);
188
189 if (pcity) {
190 struct ai_city *city_data = def_ai_city_data(pcity, ait);
191 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
192 const struct unit_type *ptype = unit_type_get(punit);
193
194 if (city_data->urgency == 0
197 && DEFENSE_POWER(ptype) > 2
198 && (unit_data->task == AIUNIT_NONE
199 || unit_data->task == AIUNIT_DEFEND_HOME)
200 && IS_ATTACKER(ptype)) {
201 comparison = city_data->danger;
202 transported = punit;
203 }
204 }
206 if (!transported) {
207 return;
208 }
209 UNIT_LOG(LOG_DEBUG, transported, "airlifted to defend %s",
211 unit_do_action(pplayer, transported->id, most_needed->id,
212 0, "", ACTION_AIRLIFT);
213 } while (TRUE);
214}
215
216/**********************************************************************/
222static bool has_defense(struct city *pcity)
223{
224 struct tile *ptile = city_tile(pcity);
225
226 unit_list_iterate(ptile->units, punit) {
228 && punit->hp != 0) {
230
231 if (pclass->non_native_def_pct > 0
232 || is_native_tile_to_class(pclass, ptile)) {
233 return TRUE;
234 }
235 }
236 }
238
239 return FALSE;
240}
241
242/**********************************************************************/
251{
252 return 2 * utype_build_shield_cost_base(punittype) * punittype->attack_strength /
253 (punittype->attack_strength + punittype->defense_strength);
254}
255
256/**********************************************************************/
259static int unit_att_rating_now(const struct unit *punit)
260{
263}
264
265/**********************************************************************/
268static int unit_att_rating_squared(const struct unit *punit)
269{
270 int v = adv_unit_att_rating(punit);
271
272 return v * v;
273}
274
275/**********************************************************************/
278static int unit_def_rating(const struct unit *attacker,
279 const struct unit *defender)
280{
281 const struct unit_type *def_type = unit_type_get(defender);
282
283 return (get_total_defense_power(attacker, defender)
284 * (attacker->id != 0 ? defender->hp : def_type->hp)
285 * def_type->firepower / POWER_DIVIDER);
286}
287
288/**********************************************************************/
291static int unit_def_rating_squared(const struct unit *attacker,
292 const struct unit *defender)
293{
294 int v = unit_def_rating(attacker, defender);
295
296 return v * v;
297}
298
299/**********************************************************************/
305 const struct unit_type *def_type,
306 struct player *def_player,
307 struct tile *ptile, bool fortified,
308 int veteran)
309{
310 struct civ_map *nmap = &(wld.map);
312 ptile, fortified, veteran)
313 * def_type->hp * def_type->firepower / POWER_DIVIDER;
314
315 return v * v;
316}
317
318/**********************************************************************/
343 int victim_count)
344{
346
347 /* attractiveness danger */
350
351 return desire;
352}
353
354/**********************************************************************/
366static int avg_benefit(int benefit, int loss, double chance)
367{
368 return (int)(((benefit + loss) * chance - loss) * SHIELD_WEIGHTING);
369}
370
371/**********************************************************************/
376 struct tile *ptile0,
377 int *value, int *cost)
378{
379 *cost = 0;
380 *value = 0;
381 square_iterate(&(wld.map), ptile0, 1, ptile) {
382 unit_list_iterate(ptile->units, aunit) {
383 if (aunit != punit
385 int val = adv_unit_att_rating(aunit);
386
387 if (val != 0) {
388 *value += val;
390 }
391 }
394}
395
396/**********************************************************************/
400static bool is_my_turn(struct unit *punit, struct unit *pdef)
401{
402 int val = unit_att_rating_now(punit);
403 int cur, d;
404 const struct unit_type *def_type = unit_type_get(pdef);
405 struct tile *def_tile = unit_tile(pdef);
406 struct civ_map *nmap = &(wld.map);
407
409
410 square_iterate(nmap, def_tile, 1, ptile) {
411 unit_list_iterate(ptile->units, aunit) {
412 if (aunit == punit || unit_owner(aunit) != unit_owner(punit)) {
413 continue;
414 }
416 != ATT_OK)
418 pdef, def_tile)
419 != ATT_OK)) {
420 continue;
421 }
424 FALSE, 0);
425 if (d == 0) {
426 return TRUE; /* Thanks, Markus -- Syela */
427 }
431 FALSE, 0) / d;
432 if (cur > val && ai_fuzzy(unit_owner(punit), TRUE)) {
433 return FALSE;
434 }
437
438 return TRUE;
439}
440
441/**********************************************************************/
446 struct unit *punit,
447 struct tile *ptile,
448 enum action_target_kind *kind)
449{
450 enum gen_action selected;
451 struct city *pcity;
452
454 punit, ptile))
455 != ACTION_NONE
457 punit, ptile))
458 != ACTION_NONE
460 punit, ptile))
461 != ACTION_NONE
463 punit, ptile))
464 != ACTION_NONE) {
465 if (kind != nullptr) {
466 *kind = ATK_UNITS;
467 }
468
469 return selected;
470 }
471
473 punit, ptile))
474 != ACTION_NONE) {
475 if (kind != nullptr) {
476 *kind = ATK_TILE;
477 }
478
479 return selected;
480 }
481
482 pcity = tile_city(ptile);
483 if (pcity != nullptr) {
485 punit, pcity))
486 != ACTION_NONE) {
487 if (kind != nullptr) {
488 *kind = ATK_CITY;
489 }
490
491 return selected;
492 }
493 }
494
496 punit, ptile))
497 != ACTION_NONE) {
498 if (kind != nullptr) {
499 *kind = ATK_UNITS;
500 }
501
502 return selected;
503 }
504
505 return ACTION_NONE;
506}
507
508/**********************************************************************/
524static int dai_rampage_want(struct unit *punit, struct tile *ptile)
525{
526 struct player *pplayer = unit_owner(punit);
527 struct unit *pdef;
528 struct civ_map *nmap = &(wld.map);
529
531
532 if (can_unit_attack_tile(punit, NULL, ptile)
533 && (pdef = get_defender(nmap, punit, ptile, NULL))
534 /* Action enablers might prevent attacking */
535 && dai_select_tile_attack_action(nmap, punit, ptile, nullptr) != ACTION_NONE) {
536 /* See description of kill_desire() about these variables. */
540
541 attack *= attack;
542
543 /* If the victim is in the city/fortress, we correct the benefit
544 * with our health because there could be reprisal attacks. We
545 * shouldn't send already injured units to useless suicide.
546 * Note that we do not specially encourage attacks against
547 * cities: rampage is a hit-n-run operation. */
548 if (!is_stack_vulnerable(ptile)
549 && unit_list_size(ptile->units) > 1) {
551 }
552
553 /* If we have non-zero attack rating... */
554 if (attack > 0 && is_my_turn(punit, pdef)) {
557
558 /* No need to amortize, our operation takes one turn. */
559 UNIT_LOG(LOG_DEBUG, punit, "Rampage: Desire %d to kill %s(%d,%d)",
560 desire,
563
564 return MAX(0, desire);
565 }
566 } else if (0 == unit_list_size(ptile->units)) {
567 /* No defender. */
568 struct city *pcity = tile_city(ptile);
569
570 /* ...and free foreign city waiting for us. Who would resist! */
571 if (NULL != pcity
572 && pplayers_at_war(pplayer, city_owner(pcity))
575 }
576
577 /* ...or tiny pleasant hut here! */
578 /* FIXME: unhardcode and variate the desire to enter a hut. */
579 if (unit_can_enter_hut(punit, ptile) && !is_barbarian(pplayer)
580 && is_native_tile(unit_type_get(punit), ptile)) {
581 return -RAMPAGE_HUT_OR_BETTER;
582 }
583 }
584
585 return 0;
586}
587
588/**********************************************************************/
591static struct pf_path *find_rampage_target(struct unit *punit,
592 int thresh_adj, int thresh_move)
593{
594 struct pf_map *tgt_map;
595 struct pf_path *path = NULL;
596 struct pf_parameter parameter;
597 /* Coordinates of the best target (initialize to silence compiler) */
598 struct tile *ptile = unit_tile(punit);
599 /* Want of the best target */
600 int max_want = 0;
601 struct player *pplayer = unit_owner(punit);
602 const struct civ_map *nmap = &(wld.map);
603
605 parameter.omniscience = !has_handicap(pplayer, H_MAP);
606 /* When trying to find rampage targets we ignore risks such as
607 * enemy units because we are looking for trouble!
608 * Hence no call ai_avoid_risks()
609 */
610
611 tgt_map = pf_map_new(&parameter);
613 int want;
614 bool move_needed;
615 int thresh;
616
617 if (move_cost > punit->moves_left) {
618 /* This is too far */
619 break;
620 }
621
622 if (has_handicap(pplayer, H_TARGETS)
623 && !map_is_known_and_seen(iter_tile, pplayer, V_MAIN)) {
624 /* The target is under fog of war */
625 continue;
626 }
627
629
630 /* Negative want means move needed even though the tiles are adjacent */
632 || want < 0);
633 /* Select the relevant threshold */
635 want = (want < 0 ? -want : want);
636
637 if (want > max_want && want > thresh) {
638 /* The new want exceeds both the previous maximum
639 * and the relevant threshold, so it's worth recording */
640 max_want = want;
641 ptile = iter_tile;
642 }
644
645 if (max_want > 0) {
646 /* We found something */
647 path = pf_map_path(tgt_map, ptile);
648 fc_assert(path != NULL);
649 }
650
652
653 return path;
654}
655
656/**********************************************************************/
671 int thresh_move)
672{
673 int count = punit->moves_left + 1; /* break any infinite loops */
674 struct pf_path *path = NULL;
675
678
680 /* This teaches the AI about the dangers inherent in occupychance. */
682
683 while (count-- > 0 && punit->moves_left > 0
685 if (!adv_unit_execute_path(punit, path)) {
686 /* Died */
687 count = -1;
688 }
689 pf_path_destroy(path);
690 path = NULL;
691 }
692
693 fc_assert(NULL == path);
694
696 return (count >= 0);
697}
698
699/**********************************************************************/
703static void dai_military_bodyguard(struct ai_type *ait, struct player *pplayer,
704 struct unit *punit)
705{
706 struct unit *aunit = aiguard_charge_unit(ait, punit);
707 struct city *acity = aiguard_charge_city(ait, punit);
708 struct tile *ptile;
709
711 CHECK_GUARD(ait, punit);
712
713 if (aunit && unit_owner(aunit) == unit_owner(punit)) {
714 /* protect a unit */
715 if (aunit->goto_tile != NULL) {
716 /* Our charge is going somewhere: maybe we should meet them there */
717 /* FIXME: This probably isn't the best algorithm for this. */
719 int me2goal = real_map_distance(unit_tile(punit), aunit->goto_tile);
720 int them2goal = real_map_distance(unit_tile(aunit), aunit->goto_tile);
721
722 if (me2goal < me2them
726 ptile = aunit->goto_tile;
727 } else {
728 ptile = unit_tile(aunit);
729 }
730 } else {
731 ptile = unit_tile(aunit);
732 }
733 } else if (acity && city_owner(acity) == unit_owner(punit)) {
734 /* protect a city */
735 ptile = acity->tile;
736 } else {
737 /* should be impossible */
738 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "we lost our charge");
740 return;
741 }
742
743 if (same_pos(unit_tile(punit), ptile)) {
744 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "at RV");
745 } else {
746 if (goto_is_sane(punit, ptile)) {
747 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "meeting charge");
748 if (!dai_gothere(ait, pplayer, punit, ptile)) {
749 /* We died */
750 return;
751 }
752 } else {
753 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "can not meet charge");
755 }
756 }
757 /* We might have stopped because of an enemy nearby.
758 * Perhaps we can kill it.*/
761 && same_pos(unit_tile(punit), ptile)) {
762 def_ai_unit_data(punit, ait)->done = TRUE; /* Stay with charge */
763 }
764}
765
766/**********************************************************************/
769static bool unit_role_defender(const struct unit_type *punittype)
770{
772}
773
774/**********************************************************************/
784adv_want look_for_charge(struct ai_type *ait, const struct civ_map *nmap,
785 struct player *pplayer, struct unit *punit,
786 struct unit **aunit, struct city **acity)
787{
788 struct pf_parameter parameter;
789 struct pf_map *pfm;
790 struct city *pcity;
791 struct ai_city *data, *best_data = NULL;
793 int def, best_def = -1;
794 /* Arbitrary: 3 turns. */
795 const int max_move_cost = 3 * unit_move_rate(punit);
796
797 *aunit = NULL;
798 *acity = NULL;
799
800 if (0 == toughness) {
801 /* useless */
802 return 0;
803 }
804
805 pft_fill_unit_parameter(&parameter, nmap, punit);
806 parameter.omniscience = !has_handicap(pplayer, H_MAP);
807 pfm = pf_map_new(&parameter);
808
809 pf_map_move_costs_iterate(pfm, ptile, move_cost, TRUE) {
810 if (move_cost > max_move_cost) {
811 /* Consider too far. */
812 break;
813 }
814
815 pcity = tile_city(ptile);
816
817 /* Consider unit bodyguard. */
818 unit_list_iterate(ptile->units, buddy) {
819 const struct unit_type *ptype = unit_type_get(punit);
820 const struct unit_type *buddy_type = unit_type_get(buddy);
821
822 /* TODO: allied unit bodyguard? */
824 || unit_owner(buddy) != pplayer
825 || !aiguard_wanted(ait, buddy)
831
832 continue;
833 }
834
836 if (0 >= def) {
837 continue;
838 }
839
841 /* Reduce want based on move cost. We can't do this for
842 * transports since they move around all the time, leading
843 * to hilarious flip-flops. */
844 def >>= move_cost / (2 * unit_move_rate(punit));
845 }
846 if (def > best_def) {
847 *aunit = buddy;
848 *acity = NULL;
849 best_def = def;
850 }
852
853 /* City bodyguard. TODO: allied city bodyguard? */
854 if (ai_fuzzy(pplayer, TRUE)
855 && NULL != pcity
856 && city_owner(pcity) == pplayer
857 && (data = def_ai_city_data(pcity, ait))
858 && 0 < data->urgency) {
859 if (NULL != best_data
860 && (0 < best_data->grave_danger
861 || best_data->urgency > data->urgency
862 || ((best_data->danger > data->danger
863 || AIUNIT_DEFEND_HOME == def_ai_unit_data(punit, ait)->task)
864 && 0 == data->grave_danger))) {
865 /* Chances are we'll be between cities when we are needed the most!
866 * Resuming pf_map_move_costs_iterate()... */
867 continue;
868 }
869 def = (data->danger - assess_defense_quadratic(ait, pcity));
870 if (def <= 0) {
871 continue;
872 }
873 /* Reduce want based on move cost. */
874 def >>= move_cost / (2 * unit_move_rate(punit));
875 if (def > best_def && ai_fuzzy(pplayer, TRUE)) {
876 *acity = pcity;
877 *aunit = NULL;
878 best_def = def;
879 best_data = data;
880 }
881 }
883
885
886 UNIT_LOG(LOGLEVEL_BODYGUARD, punit, "%s(), best_def=%d, type=%s (%d, %d)",
889 : (NULL != *aunit ? unit_rule_name(*aunit) : "")),
891 : (NULL != *aunit ?
894 : (NULL != *aunit ?
896
897 return ((best_def * 100) / toughness);
898}
899
900/**********************************************************************/
904 const struct unit_type *followee,
905 struct ai_type *ait)
906{
907 struct unit_type_ai *utai = utype_ai_data(follower, ait);
908
909 unit_type_list_iterate(utai->potential_charges, pcharge) {
910 if (pcharge == followee) {
911 return TRUE;
912 }
914
915 return FALSE;
916}
917
918/**********************************************************************/
921static void dai_military_findjob(struct ai_type *ait, const struct civ_map *nmap,
922 struct player *pplayer, struct unit *punit)
923{
924 const struct unit_type *punittype = unit_type_get(punit);
925 struct unit_ai *unit_data;
926
928
929 /* Keep barbarians aggressive and primitive */
930 if (is_barbarian(pplayer)) {
932 && is_land_barbarian(pplayer)) {
933 /* Land barbarians pillage */
935 }
937
938 return;
939 }
940
942
943 /* If I am a bodyguard, check whether I can do my job. */
944 if (unit_data->task == AIUNIT_ESCORT
945 || unit_data->task == AIUNIT_DEFEND_HOME) {
947 }
948
949 if (aiguard_has_charge(ait, punit)
950 && unit_data->task == AIUNIT_ESCORT) {
951 struct unit *aunit = aiguard_charge_unit(ait, punit);
952 struct city *acity = aiguard_charge_city(ait, punit);
953 struct ai_city *city_data = NULL;
954
955 if (acity != NULL) {
957 }
958
959 /* Check if the city we are on our way to rescue is still in danger,
960 * or the unit we should protect is still alive... */
961 if ((aunit && (aiguard_has_guard(ait, aunit) || aiguard_wanted(ait, aunit))
964 && city_data->urgency != 0
965 && city_data->danger > assess_defense_quadratic(ait, acity))) {
966 return; /* Yep! */
967 } else {
968 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL); /* Nope! */
969 }
970 }
971
972 /* Is the unit badly damaged? */
973 if ((unit_data->task == AIUNIT_RECOVER
974 && punit->hp < punittype->hp)
975 || punit->hp < punittype->hp * 0.25) { /* WAG */
976 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "set to hp recovery");
978 return;
979 }
980
983 /* This is a defending unit that doesn't need to stay put.
984 * It needs to defend something, but not necessarily where it's at.
985 * Therefore, it will consider becoming a bodyguard. -- Syela */
986 struct city *acity;
987 struct unit *aunit;
988
989 look_for_charge(ait, nmap, pplayer, punit, &aunit, &acity);
990 if (acity) {
993 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "going to defend city");
994 } else if (aunit) {
997 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "going to defend unit");
998 }
999 }
1001}
1002
1003/**********************************************************************/
1012static void dai_military_defend(struct ai_type *ait, struct player *pplayer,
1013 struct unit *punit)
1014{
1015 struct city *pcity = aiguard_charge_city(ait, punit);
1016
1018
1019 if (!pcity || city_owner(pcity) != pplayer) {
1020 pcity = tile_city(unit_tile(punit));
1021 /* Do not stay defending an allied city forever */
1023 }
1024
1025 if (!pcity) {
1026 /* Try to find a place to rest. Sitting duck out in the wilderness
1027 * is generally a bad idea, since we protect no cities that way, and
1028 * it looks silly. */
1029 pcity = find_closest_city(unit_tile(punit), NULL, pplayer,
1032 }
1033
1034 if (!pcity) {
1036 }
1037
1040 /* ... we survived */
1041 if (pcity) {
1042 UNIT_LOG(LOG_DEBUG, punit, "go to defend %s", city_name_get(pcity));
1043 if (same_pos(unit_tile(punit), pcity->tile)) {
1044 UNIT_LOG(LOG_DEBUG, punit, "go defend successful");
1046 } else {
1047 (void) dai_gothere(ait, pplayer, punit, pcity->tile);
1048 }
1049 } else {
1050 UNIT_LOG(LOG_VERBOSE, punit, "defending nothing...?");
1051 }
1052 }
1053}
1054
1055/**********************************************************************/
1059 const struct unit_type *utype,
1060 int which)
1061{
1062 int attacks;
1063
1064 if (utype_action_takes_all_mp(utype,
1066 attacks = 1;
1067 } else {
1068 attacks = utype->move_rate;
1069 }
1070 city_data->invasion.attack += attacks;
1071 if (which == INVASION_OCCUPY) {
1072 city_data->invasion.occupy++;
1073 }
1074}
1075
1076/**********************************************************************/
1086static bool invasion_funct(struct ai_type *ait, struct unit *punit,
1087 bool dest, int radius, int which)
1088{
1089 struct tile *ptile;
1090 struct player *pplayer = unit_owner(punit);
1091
1093
1094 if (dest) {
1096
1097 ptile = punit->goto_tile;
1098 } else {
1099 ptile = unit_tile(punit);
1100 }
1101
1102 square_iterate(&(wld.map), ptile, radius, tile1) {
1103 struct city *pcity = tile_city(tile1);
1104
1105 if (pcity
1106 && POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, city_owner(pcity))
1107 && (dest || !has_defense(pcity))) {
1108 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1109
1110 /* Unit itself */
1112
1113 /* Cargo */
1114 unit_cargo_iterate(punit, cargo) {
1115 const struct unit_type *utype = unit_type_get(cargo);
1116
1117 if (IS_ATTACKER(utype)) {
1121 }
1123 }
1125
1126 return TRUE;
1127}
1128
1129/**********************************************************************/
1132bool find_beachhead(const struct player *pplayer, struct pf_map *ferry_map,
1133 struct tile *dest_tile,
1134 const struct unit_type *cargo_type,
1135 struct tile **ferry_dest, struct tile **beachhead_tile)
1136{
1137 if (NULL == tile_city(dest_tile)
1139 /* Unit can directly go to 'dest_tile'. */
1140 struct tile *best_tile = NULL;
1142
1143 if (NULL != beachhead_tile) {
1144 *beachhead_tile = dest_tile;
1145 }
1146
1147 adjc_iterate(&(wld.map), dest_tile, ptile) {
1149 if (cost != PF_IMPOSSIBLE_MC
1150 && (NULL == best_tile || cost < best_cost)) {
1151 best_tile = ptile;
1152 best_cost = cost;
1153 }
1155
1156 if (NULL != ferry_dest) {
1158 }
1159
1160 return (PF_IMPOSSIBLE_MC != best_cost);
1161 } else {
1162 /* We need to find a beach around 'dest_tile'. */
1163 struct tile *best_tile = NULL, *best_beach = NULL;
1166
1167 tile_list_append(checked_tiles, dest_tile);
1168 adjc_iterate(&(wld.map), dest_tile, beach) {
1170 /* Can land there. */
1171 adjc_iterate(&(wld.map), beach, ptile) {
1172 if (!tile_list_search(checked_tiles, ptile)
1173 && !is_non_allied_unit_tile(ptile, pplayer)) {
1176 if (cost != PF_IMPOSSIBLE_MC
1177 && (NULL == best_tile || cost < best_cost)) {
1178 best_beach = beach;
1179 best_tile = ptile;
1180 best_cost = cost;
1181 }
1182 }
1184 }
1186
1188
1189 if (NULL != beachhead_tile) {
1191 }
1192 if (NULL != ferry_dest) {
1194 }
1195 return (PF_IMPOSSIBLE_MC != best_cost);
1196 }
1197}
1198
1199/**********************************************************************/
1207adv_want find_something_to_kill(struct ai_type *ait, struct player *pplayer,
1208 struct unit *punit,
1209 struct tile **pdest_tile, struct pf_path **ppath,
1210 struct pf_map **pferrymap,
1211 struct unit **pferryboat,
1212 const struct unit_type **pboattype, int *pmove_time)
1213{
1214 const int attack_value = adv_unit_att_rating(punit); /* basic attack. */
1215 struct pf_parameter parameter;
1216 struct pf_map *punit_map, *ferry_map;
1217 struct pf_position pos;
1219 const struct unit_type *punit_type = unit_type_get(punit);
1220 struct tile *punit_tile = unit_tile(punit);
1221 /* Type of our boat (a future one if ferryboat == NULL). */
1222 const struct unit_type *boattype = NULL;
1223 struct unit *ferryboat = NULL;
1224 struct city *pcity;
1225 struct ai_city *acity_data;
1226 int bcost, bcost_bal; /* Build cost of the attacker (+adjustments). */
1227 bool handicap = has_handicap(pplayer, H_TARGETS);
1228 bool unhap = FALSE; /* Do we make unhappy citizen. */
1229 bool harbor = FALSE; /* Do we have access to sea? */
1230 bool go_by_boat; /* Whether we need a boat or not. */
1231 int vulnerability; /* Enemy defense rating. */
1232 adv_want benefit; /* Benefit from killing the target. */
1233 struct unit *pdefender; /* Enemy city defender. */
1234 int move_time; /* Turns needed to target. */
1235 int reserves;
1236 int attack; /* Our total attack value with reinforcements. */
1237 int victim_count; /* Number of enemies there. */
1238 int needferry; /* Cost of building a ferry boat. */
1239 /* This is a kluge, because if we don't set x and y with !punit->id,
1240 * p_a_w isn't called, and we end up not wanting ironclads and therefore
1241 * never learning steam engine, even though ironclads would be very
1242 * useful. -- Syela */
1243 adv_want bk = 0;
1244 adv_want want; /* Want (amortized) of the operation. */
1245 adv_want best = 0; /* Best of all wants. */
1246 struct tile *goto_dest_tile = NULL;
1247 bool can_occupy;
1248 struct civ_map *nmap = &(wld.map);
1249
1250 /* Very preliminary checks. */
1252 if (NULL != pferrymap) {
1253 *pferrymap = NULL;
1254 }
1255 if (NULL != pferryboat) {
1256 *pferryboat = NULL;
1257 }
1258 if (NULL != pboattype) {
1259 *pboattype = NULL;
1260 }
1261 if (NULL != pmove_time) {
1262 *pmove_time = 0;
1263 }
1264 if (NULL != ppath) {
1265 *ppath = NULL;
1266 }
1267
1268 if (0 == attack_value) {
1269 /* A very poor attacker... probably low on HP. */
1270 return 0;
1271 }
1272
1274
1275
1276 /*** Part 1: Calculate targets ***/
1277
1278 /* This horrible piece of code attempts to calculate the attractiveness of
1279 * enemy cities as targets for our units, by checking how many units are
1280 * going towards it or are near it already. */
1281
1282 /* Reset enemy cities data. */
1284 /* See comment below in next usage of POTENTIALLY_HOSTILE_PLAYER. */
1285 if ((punit->id == 0 && !POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer))
1286 || (punit->id != 0 && !pplayers_at_war(pplayer, aplayer))) {
1287 continue;
1288 }
1289 city_list_iterate(aplayer->cities, acity) {
1290 struct ai_city *city_data = def_ai_city_data(acity, ait);
1291
1293 &city_data->attack,
1294 &city_data->bcost);
1295 city_data->invasion.attack = 0;
1296 city_data->invasion.occupy = 0;
1299
1300 /* Second, calculate in units on their way there, and mark targets for
1301 * invasion */
1302 unit_list_iterate(pplayer->units, aunit) {
1303 const struct unit_type *atype;
1304
1305 if (aunit == punit) {
1306 continue;
1307 }
1308
1310
1311 /* Dealing with invasion stuff */
1312 if (IS_ATTACKER(atype)) {
1313 if (aunit->activity == ACTIVITY_GOTO) {
1314 if (invasion_funct(ait, aunit, TRUE, 0,
1317 && (pcity = tile_city(aunit->goto_tile))) {
1318 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1319
1322 }
1323 }
1327 } else if (def_ai_unit_data(aunit, ait)->passenger != 0
1329 /* It's a transport with reinforcements */
1330 if (aunit->activity == ACTIVITY_GOTO) {
1332 }
1334 }
1336 /* end horrible initialization subroutine */
1337
1338
1339 /*** Part 2: Now pick one target ***/
1340
1341 /* We first iterate through all cities, then all units, looking
1342 * for a viable target. We also try to gang up on the target
1343 * to avoid spreading out attacks too widely to be inefficient.
1344 */
1345
1346 pcity = tile_city(punit_tile);
1347 if (NULL != pcity && (0 == punit->id || pcity->id == punit->homecity)) {
1348 /* I would have thought unhappiness should be taken into account
1349 * irrespectfully the city in which it will surface... -- GB */
1351 }
1352
1355
1357 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1358 punit_map = pf_map_new(&parameter);
1359
1360 if (MOVE_NONE == punit_class->adv.sea_move) {
1361 /* We need boat to move over sea. */
1362 ferryboat = unit_transport_get(punit);
1363
1364 /* First check if we can use the boat we are currently loaded to. */
1365 if (ferryboat == NULL || !is_boat_free(ait, ferryboat, punit, 0)) {
1366 /* No, we cannot control current boat */
1367 ferryboat = NULL;
1368 }
1369
1370 if (NULL == ferryboat) {
1371 /* Try to find new boat */
1372 ferryboat = player_unit_by_number(pplayer,
1373 aiferry_find_boat(ait, punit, 1, NULL));
1374 }
1375
1377 harbor = TRUE;
1378 }
1379 }
1380
1381 if (NULL != ferryboat) {
1382 boattype = unit_type_get(ferryboat);
1383 pft_fill_unit_overlap_param(&parameter, nmap, ferryboat);
1384 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1385 ferry_map = pf_map_new(&parameter);
1386 } else {
1388 if (NULL == boattype) {
1389 /* We pretend that we can have the simplest boat to stimulate tech. */
1391 }
1392 if (NULL != boattype && harbor) {
1393 /* Let's simulate a boat at 'punit' position. */
1395 punit_tile, pplayer);
1396 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1397 ferry_map = pf_map_new(&parameter);
1398 } else {
1399 ferry_map = NULL;
1400 }
1401 }
1402
1404
1406 /* For the virtual unit case, which is when we are called to evaluate
1407 * which units to build, we want to calculate in danger and which
1408 * players we want to make war with in the future. We do _not_ want
1409 * to do this when actually making attacks. */
1410 if ((punit->id == 0 && !POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer))
1411 || (punit->id != 0 && !pplayers_at_war(pplayer, aplayer))) {
1412 continue; /* Not an enemy. */
1413 }
1414
1415 city_list_iterate(aplayer->cities, acity) {
1416 struct tile *atile = city_tile(acity);
1417
1420 /* Can't attack this city. It is on land. */
1421 continue;
1422 }
1423
1424 if (handicap && !map_is_known(atile, pplayer)) {
1425 /* Can't see it */
1426 continue;
1427 }
1428
1430 go_by_boat = FALSE;
1431 move_time = pos.turn;
1432 } else if (NULL == ferry_map) {
1433 continue; /* Impossible to handle. */
1434 } else {
1435 struct tile *dest, *beach;
1436
1437 if (!find_beachhead(pplayer, ferry_map, atile, punit_type,
1438 &dest, &beach)) {
1439 continue; /* Impossible to go by boat. */
1440 }
1441 if (!pf_map_position(ferry_map, dest, &pos)) {
1443 continue;
1444 }
1445 move_time = pos.turn; /* Sailing time. */
1446 if (dest != beach) {
1447 move_time++; /* Land time. */
1448 }
1449 if (NULL != ferryboat && unit_tile(ferryboat) != punit_tile) {
1450 if (pf_map_position(punit_map, unit_tile(ferryboat), &pos)) {
1451 move_time += pos.turn; /* Time to reach the boat. */
1452 } else {
1453 continue; /* Cannot reach the boat. */
1454 }
1455 }
1456 go_by_boat = TRUE;
1457 }
1458
1463 } else {
1464 pdefender = NULL;
1465 vulnerability = 0;
1466 benefit = 0;
1467 }
1468
1469 if (1 < move_time) {
1471
1472 if (def_type) {
1476 if (v > vulnerability) {
1477 /* They can build a better defender! */
1478 vulnerability = v;
1480 }
1481 }
1482 }
1483
1485
1486 reserves = (acity_data->invasion.attack
1487 - unit_list_size(acity->tile->units));
1488
1489 if (punit->id == 0) {
1490 /* Real unit would add to reserves once built. */
1493 reserves++;
1494 } else {
1495 reserves += punit_type->move_rate;
1496 }
1497 }
1498
1499 if (0 < reserves && (can_occupy
1500 || 0 < acity_data->invasion.occupy)) {
1501 /* There are units able to occupy the city after all defenders
1502 * are killed! */
1503 benefit += acity_data->worth * reserves / 5;
1504 }
1505
1506 attack = attack_value + acity_data->attack;
1507 attack *= attack;
1508 /* Avoiding handling upkeep aggregation this way -- Syela */
1509
1510 /* AI was not sending enough reinforcements to totally wipe out a city
1511 * and conquer it in one turn.
1512 * This variable enables total carnage. -- Syela */
1514
1515 if (!can_occupy && NULL == pdefender) {
1516 /* Nothing there to bash and we can't occupy!
1517 * Not having this check caused warships yoyoing */
1518 want = 0;
1519 } else if (10 < move_time) {
1520 /* Too far! */
1521 want = 0;
1522 } else if (can_occupy && 0 == acity_data->invasion.occupy
1523 && (0 < acity_data->invasion.attack
1524 || victim_count == 0)) {
1525 /* Units able to occupy really needed there! */
1526 want = bcost * SHIELD_WEIGHTING;
1527 } else {
1528 want = kill_desire(benefit, attack, bcost + acity_data->bcost,
1530 }
1533 /* Build_cost of ferry. */
1534 needferry = (go_by_boat && NULL == ferryboat
1536 /* FIXME: add time to build the ferry? */
1538 want, MAX(1, move_time),
1540
1541 /* BEGIN STEAM-ENGINES-ARE-OUR-FRIENDS KLUGE. */
1542 if (0 >= want && 0 == punit->id && 0 >= best) {
1546 MAX(1, move_time),
1548
1549 if (bk_e > bk) {
1550 *pdest_tile = atile;
1551 if (NULL != pferrymap) {
1553 }
1554 if (NULL != pferryboat) {
1555 *pferryboat = go_by_boat ? ferryboat : NULL;
1556 }
1557 if (NULL != pboattype) {
1559 }
1560 if (NULL != pmove_time) {
1562 }
1563 goto_dest_tile = (go_by_boat && NULL != ferryboat
1564 ? unit_tile(ferryboat) : atile);
1565 bk = bk_e;
1566 }
1567 }
1568 /* END STEAM-ENGINES KLUGE */
1569
1570 if (0 != punit->id
1571 && NULL != ferryboat
1572 && punit_class->adv.sea_move == MOVE_NONE) {
1574 "%s(): with boat %s@(%d, %d) -> %s@(%d, %d)"
1575 " (go_by_boat = %d, move_time = %d, want = " ADV_WANT_PRINTF
1576 ", best = " ADV_WANT_PRINTF ")",
1577 __FUNCTION__, unit_rule_name(ferryboat),
1578 TILE_XY(unit_tile(ferryboat)), city_name_get(acity),
1579 TILE_XY(atile), go_by_boat, move_time, want, best);
1580 }
1581
1582 if (want > best && ai_fuzzy(pplayer, TRUE)) {
1583 /* Yes, we like this target */
1584 best = want;
1585 *pdest_tile = atile;
1586 if (NULL != pferrymap) {
1588 }
1589 if (NULL != pferryboat) {
1590 *pferryboat = go_by_boat ? ferryboat : NULL;
1591 }
1592 if (NULL != pboattype) {
1594 }
1595 if (NULL != pmove_time) {
1597 }
1598 goto_dest_tile = (go_by_boat && NULL != ferryboat
1599 ? unit_tile(ferryboat) : atile);
1600 }
1602
1604 /* I'm not sure the following code is good but it seems to be adequate.
1605 * I am deliberately not adding ferryboat code to the unit_list_iterate.
1606 * -- Syela */
1608 struct tile *atile = unit_tile(aunit);
1609
1610 if (NULL != tile_city(atile)) {
1611 /* already dealt with it. */
1612 continue;
1613 }
1614
1615 if (handicap && !map_is_known(atile, pplayer)) {
1616 /* Can't see the target. */
1617 continue;
1618 }
1619
1621 && 0 == punit->id) {
1622 /* We will not build units just to chase caravans and
1623 * ambassadors. */
1624 continue;
1625 }
1626
1627 /* We have to assume the attack is diplomatically ok.
1628 * We cannot use can_player_attack_tile, because we might not
1629 * be at war with aplayer yet */
1631 || aunit != get_defender(nmap, punit, atile, NULL)) {
1632 /* We cannot attack it, or it is not the main defender. */
1633 continue;
1634 }
1635
1637 /* Cannot reach it. */
1638 continue;
1639 }
1640
1643
1644 move_time = pos.turn;
1645 if (10 < move_time) {
1646 /* Too far. */
1647 want = 0;
1648 } else {
1649 want = kill_desire(benefit, attack, bcost, vulnerability, 1);
1650 /* Take into account maintenance of the unit. */
1651 /* FIXME: Depends on the government. */
1652 want -= move_time * SHIELD_WEIGHTING;
1653 /* Take into account unhappiness
1654 * (costs 2 luxuries to compensate). */
1655 want -= (unhap ? 2 * move_time * TRADE_WEIGHTING : 0);
1656 }
1658 want, MAX(1, move_time), bcost_bal);
1659 if (want > best && ai_fuzzy(pplayer, TRUE)) {
1660 best = want;
1661 *pdest_tile = atile;
1662 if (NULL != pferrymap) {
1663 *pferrymap = NULL;
1664 }
1665 if (NULL != pferryboat) {
1666 *pferryboat = NULL;
1667 }
1668 if (NULL != pboattype) {
1669 *pboattype = NULL;
1670 }
1671 if (NULL != pmove_time) {
1673 }
1675 }
1678
1679 if (NULL != ppath) {
1682 }
1683
1685 if (NULL != ferry_map
1686 && (NULL == pferrymap || *pferrymap != ferry_map)) {
1688 }
1689
1691
1692 return best;
1693}
1694
1695/**********************************************************************/
1704{
1705 struct pf_parameter parameter;
1706 struct pf_map *pfm;
1707 struct player *pplayer = unit_owner(punit);
1708 struct city *pcity, *best_city = NULL;
1709 int best = FC_INFINITY, cur;
1710 const struct civ_map *nmap = &(wld.map);
1711
1712 pft_fill_unit_parameter(&parameter, nmap, punit);
1713 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1714 pfm = pf_map_new(&parameter);
1715
1716 pf_map_move_costs_iterate(pfm, ptile, move_cost, TRUE) {
1717 if (move_cost > best) {
1718 /* We already found a better city. No need to continue. */
1719 break;
1720 }
1721
1722 pcity = tile_city(ptile);
1723 if (NULL == pcity || !pplayers_allied(pplayer, city_owner(pcity))) {
1724 continue;
1725 }
1726
1727 /* Score based on the move cost. */
1728 cur = move_cost;
1729
1730 /* Note the unit owner may be different from the city owner. */
1731 if (0 == get_unittype_bonus(unit_owner(punit), ptile,
1733 EFT_HP_REGEN)) {
1734 /* If we cannot regen fast our hit points here, let's make some
1735 * penalty. */
1736 cur *= 3;
1737 }
1738
1739 if (cur < best) {
1740 best_city = pcity;
1741 best = cur;
1742 }
1744
1746 return best_city;
1747}
1748
1749/**********************************************************************/
1755 struct player *pplayer,
1756 struct unit *punit)
1757{
1758 struct city *pc;
1759 bool only_continent = TRUE;
1760
1761 if (unit_transported(punit)) {
1762 /* If we are in transport, we can go to any continent.
1763 * Actually, we are not currently in a continent where to stay. */
1765 }
1766
1767 if ((pc = find_closest_city(unit_tile(punit), NULL, pplayer, FALSE,
1770 UNIT_LOG(LOG_DEBUG, punit, "Barbarian heading to conquer %s",
1771 city_name_get(pc));
1772 (void) dai_gothere(ait, pplayer, punit, pc->tile);
1773 } else {
1774 struct unit *ferry = NULL;
1775
1776 if (unit_transported(punit)) {
1777 ferry = unit_transport_get(punit);
1778
1779 /* We already are in a boat so it needs no
1780 * free capacity */
1781 if (!is_boat_free(ait, ferry, punit, 0)) {
1782 /* We cannot control our ferry. */
1783 ferry = NULL;
1784 }
1785 } else {
1786 /* We are not in a boat yet. Search for one. */
1788 if (is_boat_free(ait, aunit, punit, 1)
1790 ferry = aunit;
1791 break;
1792 }
1794 }
1795
1796 if (ferry) {
1797 UNIT_LOG(LOG_DEBUG, punit, "Barbarian sailing to conquer %s",
1798 city_name_get(pc));
1799 (void) aiferry_goto_amphibious(ait, ferry, punit, pc->tile);
1800 } else {
1801 /* This is not an error. Somebody else might be in charge
1802 * of the ferry. */
1803 UNIT_LOG(LOG_DEBUG, punit, "unable to find barbarian ferry");
1804 }
1805 }
1806 } else {
1807 UNIT_LOG(LOG_DEBUG, punit, "Barbarian find no target city");
1808 }
1809}
1810
1811/**********************************************************************/
1817static void dai_military_attack(struct ai_type *ait, struct player *pplayer,
1818 struct unit *punit)
1819{
1820 struct tile *dest_tile;
1821 int id = punit->id;
1822 int ct = 10;
1823 struct city *pcity = NULL;
1824
1826
1827 /* Barbarians pillage, and might keep on doing that so they sometimes
1828 * even finish it. */
1829 if (punit->activity == ACTIVITY_PILLAGE && is_barbarian(pplayer)
1830 && fc_rand(2) == 1) {
1831 return;
1832 }
1833
1834 /* First find easy nearby enemies, anything better than pillage goes.
1835 * NB: We do not need to repeat dai_military_rampage, it is repeats itself
1836 * until it runs out of targets. */
1837 /* FIXME: 1. dai_military_rampage never checks if it should defend newly
1838 * conquered cities.
1839 * FIXME: 2. would be more convenient if it returned FALSE if we run out
1840 * of moves too.*/
1842 return; /* we died */
1843 }
1844
1845 if (punit->moves_left <= 0) {
1846 return;
1847 }
1848
1849 /* Main attack loop */
1850 do {
1851 struct tile *start_tile = unit_tile(punit);
1852 struct pf_path *path;
1853 struct unit *ferryboat;
1854
1855 /* Then find enemies the hard way */
1856 find_something_to_kill(ait, pplayer, punit, &dest_tile, &path,
1857 NULL, &ferryboat, NULL, NULL);
1858 if (!same_pos(unit_tile(punit), dest_tile)) {
1859 if (!is_tiles_adjacent(unit_tile(punit), dest_tile)
1860 || !can_unit_attack_tile(punit, NULL, dest_tile)) {
1861
1862 /* Adjacent and can't attack usually means we are not marines
1863 * and on a ferry. This fixes the problem (usually). */
1864 UNIT_LOG(LOG_DEBUG, punit, "mil att gothere -> (%d, %d)",
1865 TILE_XY(dest_tile));
1866
1867 /* Set ACTIVITY_GOTO more permanently than just inside
1868 * adv_follow_path(). This way other units will know we're
1869 * on our way even if we don't reach target yet. */
1870 punit->goto_tile = dest_tile;
1872 if (NULL != path && !adv_follow_path(punit, path, dest_tile)) {
1873 /* Died. */
1874 pf_path_destroy(path);
1875 return;
1876 }
1877 if (NULL != ferryboat) {
1878 /* Need a boat. */
1879 aiferry_gobyboat(ait, pplayer, punit, dest_tile, FALSE);
1880 pf_path_destroy(path);
1881 return;
1882 }
1883 if (0 >= punit->moves_left) {
1884 /* No moves left. */
1885 pf_path_destroy(path);
1886 return;
1887 }
1888
1889 /* Either we're adjacent or we sitting on the tile. We might be
1890 * sitting on the tile if the enemy that _was_ sitting there
1891 * attacked us and died _and_ we had enough movement to get there */
1892 if (same_pos(unit_tile(punit), dest_tile)) {
1893 UNIT_LOG(LOG_DEBUG, punit, "mil att made it -> (%d, %d)",
1894 TILE_XY(dest_tile));
1895 pf_path_destroy(path);
1896 break;
1897 }
1898 }
1899
1900 if (is_tiles_adjacent(unit_tile(punit), dest_tile)) {
1901 /* Close combat. fstk sometimes want us to attack an adjacent
1902 * enemy that rampage wouldn't */
1903 UNIT_LOG(LOG_DEBUG, punit, "mil att bash -> (%d, %d)",
1904 TILE_XY(dest_tile));
1905 if (!dai_unit_attack(ait, punit, dest_tile)) {
1906 /* Died */
1907 pf_path_destroy(path);
1908 return;
1909 }
1910 } else if (!same_pos(start_tile, unit_tile(punit))) {
1911 /* Got stuck. Possibly because of adjacency to an
1912 * enemy unit. Perhaps we are in luck and are now next to a
1913 * tempting target? Let's find out... */
1916 pf_path_destroy(path);
1917 return;
1918 }
1919
1920 } else {
1921 /* FIXME: This happens a bit too often! */
1922 UNIT_LOG(LOG_DEBUG, punit, "fstk didn't find us a worthy target!");
1923 /* No worthy enemies found, so abort loop */
1924 ct = 0;
1925 }
1926 pf_path_destroy(path);
1927
1928 ct--; /* infinite loops from railroads must be stopped */
1929 } while (punit->moves_left > 0 && ct > 0);
1930
1931 /* Cleanup phase */
1932 if (punit->moves_left == 0) {
1933 return;
1934 }
1936 if (pcity != NULL
1937 && (dai_is_ferry(punit, ait)
1938 || punit->hp < unit_type_get(punit)->hp * 0.50)) { /* WAG */
1939 /* Go somewhere safe */
1940 UNIT_LOG(LOG_DEBUG, punit, "heading to nearest safe house.");
1941 (void) dai_unit_goto(ait, punit, pcity->tile);
1942 } else if (!is_barbarian(pplayer)) {
1943 /* Nothing else to do, so try exploring. */
1944 switch (manage_auto_explorer(punit)) {
1945 case MR_DEATH:
1946 /* don't use punit! */
1947 return;
1948 case MR_OK:
1949 UNIT_LOG(LOG_DEBUG, punit, "nothing else to do, so exploring");
1950 break;
1951 default:
1952 UNIT_LOG(LOG_DEBUG, punit, "nothing to do - no more exploring either");
1953 break;
1954 };
1955 } else {
1956 /* You can still have some moves left here, but barbarians should
1957 not sit helplessly, but advance towards nearest known enemy city */
1958 UNIT_LOG(LOG_DEBUG, punit, "attack: barbarian");
1959 dai_military_attack_barbarian(ait, pplayer, punit);
1960 }
1961 if ((punit = game_unit_by_number(id)) && punit->moves_left > 0) {
1962 UNIT_LOG(LOG_DEBUG, punit, "attack: giving up unit to defense");
1963 dai_military_defend(ait, pplayer, punit);
1964 }
1965}
1966
1967/**********************************************************************/
1971static bool dai_find_boat_for_unit(struct ai_type *ait, struct unit *punit)
1972{
1973 bool alive = TRUE;
1974 int ferryboat = 0;
1975 struct pf_path *path_to_ferry = NULL;
1976
1977 UNIT_LOG(LOG_CARAVAN, punit, "requesting a boat!");
1978 ferryboat = aiferry_find_boat(ait, punit, 1, &path_to_ferry);
1979 /* going to meet the boat */
1980 if ((ferryboat <= 0)) {
1982 "in find_boat_for_unit cannot find any boats.");
1983 /* if we are undefended on the country side go to a city */
1985 if (current_city == NULL) {
1987 if (city_near != NULL) {
1989 }
1990 }
1991 } else {
1992 if (path_to_ferry != NULL) {
1994 /* Died. */
1997 alive = FALSE;
1998 } else {
2001 alive = TRUE;
2002 }
2003 }
2004 }
2005 return alive;
2006}
2007
2008/**********************************************************************/
2017 struct tile *ctile, struct tile *ptile)
2018{
2019 /* We usually have Inaccessible terrain, so not testing MOVE_FULL == */
2020 bool lm = MOVE_NONE != pclass->adv.land_move,
2021 sm = MOVE_NONE != pclass->adv.sea_move;
2022 struct civ_map *pmap = &(wld.map);
2023
2024 if (lm && sm) {
2025 return FALSE;
2026 }
2027
2028 /* We could use adjc_iterate() but likely often tiles are on the same
2029 * continent and it will be more time to find where they connect */
2032
2033 if (is_ocean_tile(atile) ? sm : lm) {
2034 iterate_outward(pmap, ptile, 1, btile) {
2035 if (tile_continent(btile) == acont) {
2036 return FALSE;
2037 }
2039 }
2041
2042 if (is_tiles_adjacent(ctile, ptile)) {
2043 return FALSE;
2044 }
2045
2046 return TRUE;
2047}
2048
2049/**********************************************************************/
2055static void dai_caravan_goto(struct ai_type *ait, struct player *pplayer,
2056 struct unit *punit,
2057 const struct city *dest_city,
2058 bool help_wonder,
2059 bool required_boat, bool request_boat)
2060{
2061 bool alive = TRUE;
2062 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2063 const struct civ_map *nmap = &(wld.map);
2064
2066
2067 /* if we're not there yet, and we can move, move... */
2068 if (!same_pos(dest_city->tile, unit_tile(punit))
2069 && punit->moves_left != 0) {
2070 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) task %s going to %s in %s %s",
2074 help_wonder ? "help a wonder" : "trade", city_name_get(dest_city),
2075 required_boat ? "with a boat" : "");
2076 if (required_boat) {
2077 /* to trade with boat */
2078 if (request_boat) {
2079 /* Try to find new boat */
2081 } else {
2082 /* if we are not being transported then ask for a boat again */
2083 alive = TRUE;
2086 unit_tile(punit), dest_city->tile)) {
2088 }
2089 }
2090 if (alive) {
2091 /* FIXME: sometimes we get FALSE here just because
2092 * a trireme that we've boarded can't go over an ocean. */
2093 alive = dai_gothere(ait, pplayer, punit, dest_city->tile);
2094 }
2095 } else {
2096 /* to trade without boat */
2098 }
2099 }
2100
2101 /* if moving didn't kill us, and we got to the destination, handle it. */
2102 if (alive && real_map_distance(dest_city->tile, unit_tile(punit)) <= 1) {
2103 /* release the boat! */
2104 if (unit_transported(punit)) {
2106 }
2108 punit, dest_city)) {
2109 /*
2110 * We really don't want to just drop all caravans in immediately.
2111 * Instead, we want to aggregate enough caravans to build instantly.
2112 * -AJS, 990704
2113 */
2114 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) helps build wonder in %s",
2117 punit->id,
2120 unit_do_action(pplayer, punit->id, dest_city->id,
2121 0, "", ACTION_HELP_WONDER);
2123 punit, dest_city)) {
2124 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) creates trade route in %s",
2127 punit->id,
2130 unit_do_action(pplayer, punit->id, dest_city->id,
2131 0, "", ACTION_TRADE_ROUTE);
2133 punit, dest_city)) {
2134 /* Get the one time bonus. */
2135 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) enters marketplace of %s",
2138 punit->id,
2141 unit_do_action(pplayer, punit->id, dest_city->id,
2142 0, "", ACTION_MARKETPLACE);
2143 } else {
2144 enum log_level level = LOG_NORMAL;
2145
2146 if (help_wonder) {
2147 /* A Caravan ordered to help build wonder may arrive after
2148 * enough shields to build the wonder is produced. */
2150 }
2151
2153 "%s %s[%d](%d,%d) unable to trade with %s",
2156 punit->id,
2159 }
2160 }
2161}
2162
2163/**********************************************************************/
2167static void caravan_optimize_callback(const struct caravan_result *result,
2168 void *data)
2169{
2170 const struct unit *caravan = data;
2171
2172 log_base(LOG_CARAVAN3, "%s %s[%d](%d,%d) %s: %s %s worth %g",
2174 unit_rule_name(caravan),
2175 caravan->id,
2176 TILE_XY(unit_tile(caravan)),
2177 city_name_get(result->src),
2178 result->help_wonder ? "wonder in" : "trade to",
2179 city_name_get(result->dest),
2180 result->value);
2181}
2182
2183/**********************************************************************/
2187 struct unit *punit)
2188{
2189 struct tile *src = NULL, *dest = NULL, *src_home_city = NULL;
2190 struct city *phome_city = NULL;
2191 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2192
2193 if ((unit_data->task != AIUNIT_NONE)) {
2194 src = unit_tile(punit);
2196 if (phome_city != NULL) {
2198 }
2199 dest = punit->goto_tile;
2200
2201 if (src == NULL || dest == NULL) {
2202 return FALSE;
2203 }
2204
2205 /* If we have a home continent, and are not there.
2206 * (FIXME: well, why?)
2207 * (I guess because home continent is which we were supposed to leave,
2208 * not the target continent) */
2209 if (src_home_city != NULL
2211 return FALSE;
2212 }
2213
2214 if (!goto_is_sane(punit, dest)) {
2215 if (unit_transported(punit)) {
2216 /* If we're being transported */
2217 return FALSE;
2218 }
2219 if ((punit->birth_turn + 15 < game.info.turn)) {
2220 /* We are tired of waiting */
2222
2223 if (ferrys <= 0) {
2224 /* There are no ferrys available... give up */
2225 return TRUE;
2226 } else {
2227 if (punit->birth_turn + 20 < game.info.turn) {
2228 /* We are fed up! */
2229 return TRUE;
2230 }
2231 }
2232 }
2233 }
2234 }
2235
2236 return FALSE;
2237}
2238
2239/**********************************************************************/
2246 struct unit *punit)
2247{
2248 struct city *pcity = game_city_by_number(punit->homecity);
2249 Continent_id continent;
2250
2251 fc_assert(pcity != NULL);
2252
2253 if (unit_class_get(punit)->adv.ferry_types <= 0) {
2254 /* There is just no possible transporters. */
2255 return FALSE;
2256 }
2257 continent = tile_continent(pcity->tile);
2258
2259 /* Look for proper destination city at different continent. */
2260 city_list_iterate(pplayer->cities, acity) {
2261 if (can_cities_trade(pcity, acity)) {
2262 if (tile_continent(acity->tile) != continent) {
2263 return TRUE;
2264 }
2265 }
2267
2269 if (aplayer == pplayer || !aplayer->is_alive) {
2270 continue;
2271 }
2272 if (pplayers_allied(pplayer, aplayer)) {
2273 city_list_iterate(aplayer->cities, acity) {
2274 if (can_cities_trade(pcity, acity)) {
2275 if (tile_continent(acity->tile) != continent) {
2276 return TRUE;
2277 }
2278 }
2281 }
2282
2283 return FALSE;
2284}
2285
2286/**********************************************************************/
2290static bool search_homecity_for_caravan(struct ai_type *ait, struct unit *punit)
2291{
2292 struct city *nearest = NULL;
2293 int min_dist = FC_INFINITY;
2294 struct tile *current_loc = unit_tile(punit);
2296 bool alive = TRUE;
2297
2299 struct tile *ctile = city_tile(pcity);
2300
2301 if (tile_continent(ctile) == continent) {
2303
2304 if (this_dist < min_dist) {
2306 nearest = pcity;
2307 }
2308 }
2310
2311 if (nearest != NULL) {
2313 if (alive && same_pos(unit_tile(punit), nearest->tile)) {
2315 }
2316 }
2317
2318 return alive;
2319}
2320
2321/**********************************************************************/
2327static void dai_manage_caravan(struct ai_type *ait, struct player *pplayer,
2328 struct unit *punit)
2329{
2330 struct caravan_parameter parameter;
2331 struct caravan_result result;
2332 const struct city *homecity;
2333 const struct city *dest = NULL;
2334 struct unit_ai *unit_data;
2336 bool expect_boats = pclass->adv.ferry_types > 0;
2337 /* TODO: will pplayer have a boat for punit in a reasonable time? */
2338 bool help_wonder = FALSE;
2339 bool required_boat = FALSE;
2340 bool request_boat = FALSE;
2342 const struct civ_map *nmap = &(wld.map);
2343
2345
2349 /* we only want units that can establish trade, enter marketplace or
2350 * help build wonders */
2351 return;
2352 }
2353
2355
2356 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d) task %s to (%d,%d)",
2361
2362 homecity = game_city_by_number(punit->homecity);
2363 if (homecity == NULL && unit_data->task == AIUNIT_TRADE) {
2365 return;
2366 }
2367 homecity = game_city_by_number(punit->homecity);
2368 if (homecity == NULL) {
2369 return;
2370 }
2371 }
2372
2373 if ((unit_data->task == AIUNIT_TRADE
2374 || unit_data->task == AIUNIT_WONDER)) {
2375 /* we are moving to our destination */
2376 /* we check to see if our current goal is feasible */
2378
2379 if ((city_dest == NULL)
2381 || (unit_data->task == AIUNIT_TRADE
2382 && !(can_cities_trade(homecity, city_dest)
2383 && can_establish_trade_route(homecity, city_dest)))
2384 || (unit_data->task == AIUNIT_WONDER
2385 /* Helping the (new) production is illegal. */
2387 || (unit_data->task == AIUNIT_TRADE
2392 punit, city_dest)))
2393 || (unit_data->task == AIUNIT_WONDER
2396 punit, city_dest))) {
2397 /* destination invalid! */
2399 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d) destination invalid!",
2402 } else {
2403 /* destination valid, are we tired of waiting for a boat? */
2407 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d) unit tired of waiting!",
2411 } else {
2412 dest = city_dest;
2413 help_wonder = (unit_data->task == AIUNIT_WONDER) ? TRUE : FALSE;
2414 required_boat = uclass_need_trans_between(pclass, unit_tile(punit), dest->tile);
2416 }
2417 }
2418 }
2419
2420 if (unit_data->task == AIUNIT_NONE) {
2421 if (homecity == NULL) {
2422 /* FIXME: We shouldn't bother in getting homecity for
2423 * caravan that will then be used for wonder building. */
2425 return;
2426 }
2427 homecity = game_city_by_number(punit->homecity);
2428 if (homecity == NULL) {
2429 return;
2430 }
2431 }
2432
2434 /* Make more trade with allies than other peaceful nations
2435 * by considering only allies 50% of the time.
2436 * (the other 50% allies are still considered, but so are other nations) */
2437 if (fc_rand(2)) {
2438 /* Be optimistic about development of relations with no-contact and
2439 * cease-fire nations. */
2440 parameter.allow_foreign_trade = FTL_NONWAR;
2441 } else {
2442 parameter.allow_foreign_trade = FTL_ALLIED;
2443 }
2444
2447 parameter.callback_data = punit;
2448 }
2450 parameter.ignore_transit_time = TRUE;
2451 }
2454 parameter.ignore_transit_time = FALSE;
2455 }
2456 caravan_find_best_destination(nmap, punit, &parameter, &result,
2457 !has_handicap(pplayer, H_MAP));
2458 if (result.dest != NULL) {
2459 /* We did find a new destination for the unit */
2460 dest = result.dest;
2461 help_wonder = result.help_wonder;
2462 required_boat = uclass_need_trans_between(pclass, unit_tile(punit), dest->tile);
2463 request_boat = required_boat;
2465 (help_wonder) ? AIUNIT_WONDER : AIUNIT_TRADE,
2466 dest->tile);
2467 } else {
2468 dest = NULL;
2469 }
2470 }
2471
2472 if (required_boat && !expect_boats) {
2473 /* Would require boat, but can't have them. Render destination invalid. */
2474 dest = NULL;
2475 }
2476
2477 if (dest != NULL) {
2478 dai_caravan_goto(ait, pplayer, punit, dest, help_wonder,
2479 required_boat, request_boat);
2480 return; /* that may have clobbered the unit */
2481 } else {
2482 /* We have nowhere to go! */
2483 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d), nothing to do!",
2487 /* Should we become a defensive unit? */
2488 }
2489}
2490
2491/**********************************************************************/
2496 struct unit *punit)
2497{
2498 struct player *pplayer = unit_owner(punit);
2499 struct city *pcity = tile_city(unit_tile(punit));
2500 struct city *safe = NULL;
2501 const struct unit_type *punittype = unit_type_get(punit);
2502 bool no_recovery;
2503
2505
2506 if (pcity != NULL) {
2507 /* Rest in the city until the hitpoints are recovered, but attempt
2508 * to protect city from attack (and be opportunistic too)*/
2511 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "recovering hit points.");
2512 } else {
2513 return; /* We died heroically defending our city */
2514 }
2515 } else {
2516 /* Goto to nearest city to recover hit points */
2517 /* Just before, check to see if we can occupy an undefended enemy city */
2520 return; /* Oops, we died */
2521 }
2522
2523 /* Find a city to stay and go there */
2525 if (safe) {
2526 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "going to %s to recover",
2528 if (!dai_unit_goto(ait, punit, safe->tile)) {
2529 log_base(LOGLEVEL_RECOVERY, "died trying to hide and recover");
2530 return;
2531 }
2532 } else {
2533 /* Oops */
2534 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "didn't find a city to recover in!");
2536 dai_military_attack(ait, pplayer, punit);
2537 return;
2538 }
2539 }
2540
2541 /* Is the unit still damaged? If true, and could recover hit points, do so.
2542 * Don't wait if would be losing hitpoints that way! */
2544 if (punit->hp == punittype->hp) {
2545 no_recovery = TRUE;
2546 } else {
2548
2549 if (gain < 0) {
2550 no_recovery = TRUE;
2551 } else if (gain == 0 && !punit->moved) {
2552 /* Isn't gaining even though has not moved. */
2553 no_recovery = TRUE;
2554 }
2555 }
2556 if (no_recovery) {
2557 /* We are ready to go out and kick ass again */
2558 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "ready to kick ass again!");
2560 return;
2561 } else {
2562 def_ai_unit_data(punit, ait)->done = TRUE; /* Sit tight */
2563 }
2564}
2565
2566/**********************************************************************/
2570void dai_manage_military(struct ai_type *ait, const struct civ_map *nmap,
2571 struct player *pplayer, struct unit *punit)
2572{
2573 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2574 int id = punit->id;
2575
2577
2578 /* "Escorting" aircraft should not do anything. They are activated
2579 * by their transport or charge. We do _NOT_ set them to 'done'
2580 * since they may need be activated once our charge moves. */
2581 if (unit_data->task == AIUNIT_ESCORT
2583 return;
2584 }
2585
2588 && has_handicap(pplayer, H_AWAY)) {
2589 /* Don't move sentried or fortified units controlled by a player
2590 * in away mode. */
2591 unit_data->done = TRUE;
2592 return;
2593 }
2594
2595 /* Since military units re-evaluate their actions every turn,
2596 we must make sure that previously reserved ferry is freed. */
2598
2600 /* Try hunting with this unit */
2601 if (dai_hunter_qualify(pplayer, punit)) {
2602 int result, sanity = punit->id;
2603
2604 UNIT_LOG(LOGLEVEL_HUNT, punit, "is qualified as hunter");
2605 result = dai_hunter_manage(ait, pplayer, punit);
2608 return; /* died */
2609 }
2610 if (result == -1) {
2611 (void) dai_hunter_manage(ait, pplayer, punit); /* More carnage */
2613 return;
2614 } else if (result >= 1) {
2616 return; /* Done moving */
2617 } else if (unit_data->task == AIUNIT_HUNTER) {
2618 /* This should be very rare */
2620 }
2621 } else if (unit_data->task == AIUNIT_HUNTER) {
2623 }
2625
2626 /* Do we have a specific job for this unit? If not, we default
2627 * to attack. */
2628 dai_military_findjob(ait, nmap, pplayer, punit);
2629
2630 switch (unit_data->task) {
2632 case AIUNIT_BUILD_CITY:
2633 fc_assert(FALSE); /* This is not the place for this role */
2634 break;
2635 case AIUNIT_DEFEND_HOME:
2637 dai_military_defend(ait, pplayer, punit);
2639 break;
2640 case AIUNIT_ATTACK:
2641 case AIUNIT_NONE:
2643 dai_military_attack(ait, pplayer, punit);
2645 break;
2646 case AIUNIT_ESCORT:
2648 dai_military_bodyguard(ait, pplayer, punit);
2650 break;
2651 case AIUNIT_EXPLORE:
2652 switch (manage_auto_explorer(punit)) {
2653 case MR_DEATH:
2654 /* don't use punit! */
2655 return;
2656 case MR_OK:
2657 UNIT_LOG(LOG_DEBUG, punit, "more exploring");
2658 break;
2659 default:
2660 UNIT_LOG(LOG_DEBUG, punit, "no more exploring either");
2661 break;
2662 };
2663 def_ai_unit_data(punit, ait)->done = (punit->moves_left <= 0);
2664 break;
2665 case AIUNIT_RECOVER:
2669 break;
2670 case AIUNIT_HUNTER:
2671 fc_assert(FALSE); /* dealt with above */
2672 break;
2673 default:
2675 }
2676
2677 /* If we are still alive, either sentry or fortify. */
2678 if ((punit = game_unit_by_number(id))) {
2680 struct city *pcity = tile_city(unit_tile(punit));
2681
2682 if (unit_list_find(unit_tile(punit)->units,
2683 unit_data->ferryboat)) {
2685 } else if (pcity || punit->activity == ACTIVITY_IDLE) {
2686 /* We do not need to fortify in cities - we fortify and sentry
2687 * according to home defense setup, for easy debugging. */
2688 if (!pcity || unit_data->task == AIUNIT_DEFEND_HOME) {
2692 }
2693 } else {
2695 }
2696 }
2697 }
2698}
2699
2700/**********************************************************************/
2703static void dai_manage_settler(struct ai_type *ait, struct player *pplayer,
2704 struct unit *punit)
2705{
2706 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2707
2709 unit_data->done = TRUE; /* we will manage this unit later... ugh */
2710 /* if BUILD_CITY must remain BUILD_CITY, otherwise turn into autosettler */
2711 if (unit_data->task == AIUNIT_NONE) {
2713 }
2714 return;
2715}
2716
2717/**********************************************************************/
2725void dai_manage_unit(struct ai_type *ait, struct player *pplayer,
2726 struct unit *punit)
2727{
2728 struct unit_ai *unit_data;
2729 struct unit *bodyguard = aiguard_guard_of(ait, punit);
2730 bool is_ferry = FALSE;
2731 const struct unit_type *ptype;
2732 const struct civ_map *nmap = &(wld.map);
2733
2735
2736 /* Don't manage the unit if it is under human orders. */
2737 if (unit_has_orders(punit)) {
2739
2740 UNIT_LOG(LOG_VERBOSE, punit, "is under human orders, aborting AI control.");
2742 unit_data->done = TRUE;
2743 return;
2744 }
2745
2746 /* Check if we have lost our bodyguard. If we never had one, all
2747 * fine. If we had one and lost it, ask for a new one. */
2748 if (!bodyguard && aiguard_has_guard(ait, punit)) {
2749 UNIT_LOG(LOGLEVEL_BODYGUARD, punit, "lost bodyguard, asking for new");
2751 }
2752
2754
2755 if (punit->moves_left <= 0) {
2756 /* Can do nothing */
2757 unit_data->done = TRUE;
2758 return;
2759 }
2760
2761 is_ferry = dai_is_ferry(punit, ait);
2762
2764
2767 dai_manage_diplomat(ait, pplayer, punit);
2769 return;
2770 } else if (ptype->adv.worker
2772 dai_manage_settler(ait, pplayer, punit);
2773 return;
2778 dai_manage_caravan(ait, pplayer, punit);
2780 return;
2782 dai_manage_barbarian_leader(ait, pplayer, punit);
2783 return;
2786 dai_manage_paratrooper(ait, pplayer, punit);
2787 return;
2788 } else if (is_ferry && unit_data->task != AIUNIT_HUNTER) {
2790 dai_manage_ferryboat(ait, pplayer, punit);
2792 return;
2793 } else if (utype_fuel(ptype)
2794 && unit_data->task != AIUNIT_ESCORT) {
2796 dai_manage_airunit(ait, pplayer, punit);
2798 return;
2799 } else if (is_losing_hp(punit)) {
2800 /* This unit is losing hitpoints over time */
2801
2802 /* TODO: We can try using air-unit code for helicopters, just
2803 * pretend they have fuel = HP / 3 or something. */
2804 unit_data->done = TRUE; /* we did our best, which was ...
2805 nothing */
2806 return;
2807 } else if (!is_special_unit(punit)) {
2809 UNIT_LOG(LOG_DEBUG, punit, "recruit unit for the military");
2810 dai_manage_military(ait, nmap, pplayer, punit);
2812 return;
2813 } else {
2814 /* what else could this be? -- Syela */
2815 switch (manage_auto_explorer(punit)) {
2816 case MR_DEATH:
2817 /* don't use punit! */
2818 break;
2819 case MR_OK:
2820 UNIT_LOG(LOG_DEBUG, punit, "now exploring");
2821 break;
2822 default:
2823 UNIT_LOG(LOG_DEBUG, punit, "fell through all unit tasks, defending");
2825 dai_military_defend(ait, pplayer, punit);
2826 break;
2827 };
2828 return;
2829 }
2830}
2831
2832/**********************************************************************/
2838static void dai_set_defenders(struct ai_type *ait, struct player *pplayer)
2839{
2840 city_list_iterate(pplayer->cities, pcity) {
2841 /* The idea here is that we should never keep more than two
2842 * units in permanent defense. */
2843 int total_defense = 0;
2844 int total_attack = def_ai_city_data(pcity, ait)->danger;
2845 bool emergency = FALSE;
2846 int count = 0;
2850 + pcity->feel[CITIZEN_ANGRY][FEELING_NATIONALITY];
2851 int entertainers = 0;
2852 bool enough = FALSE;
2853
2855 if (get_specialist_output(pcity, sp, O_LUXURY) > 0) {
2856 entertainers += pcity->specialists[sp];
2857 }
2859
2860 martless_unhappy += entertainers; /* We want to use martial law instead
2861 * of entertainers. */
2862
2863 while (!enough
2866 && martless_unhappy > mart_each * count))) {
2867 int best_want = 0;
2868 struct unit *best = NULL;
2869 bool defense_needed = total_defense <= total_attack; /* Defense or martial */
2870
2871 unit_list_iterate(pcity->tile->units, punit) {
2872 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2873
2874 if ((unit_data->task == AIUNIT_NONE || emergency)
2875 && unit_data->task != AIUNIT_DEFEND_HOME
2876 && unit_owner(punit) == pplayer) {
2877 int want = assess_defense_unit(ait, pcity, punit, FALSE);
2878
2879 if (want > best_want) {
2880 best_want = want;
2881 best = punit;
2882 }
2883 }
2885
2886 if (best == NULL) {
2887 if (defense_needed) {
2888 /* Ooops - try to grab any unit as defender! */
2889 if (emergency) {
2890 CITY_LOG(LOG_DEBUG, pcity, "Not defended properly");
2891 break;
2892 }
2893 emergency = TRUE;
2894 } else {
2895 break;
2896 }
2897 } else {
2898 const struct unit_type *btype = unit_type_get(best);
2899
2900 if ((martless_unhappy < mart_each * count
2901 || count >= mart_max || mart_each <= 0)
2902 && ((count >= 2
2903 && btype->attack_strength > btype->defense_strength)
2904 || (count >= 4
2905 && btype->attack_strength == btype->defense_strength))) {
2906 /* In this case attack would be better defense than fortifying
2907 * to city. */
2908 enough = TRUE;
2909 } else {
2910 int loglevel = pcity->server.debug ? LOG_AI_TEST : LOG_DEBUG;
2911
2913 UNIT_LOG(loglevel, best, "Defending city");
2914 dai_unit_new_task(ait, best, AIUNIT_DEFEND_HOME, pcity->tile);
2915 count++;
2916 }
2917 }
2918 }
2919 CITY_LOG(LOG_DEBUG, pcity, "Evaluating defense: %d defense, %d incoming"
2920 ", %d defenders (out of %d)", total_defense, total_attack, count,
2921 unit_list_size(pcity->tile->units));
2923}
2924
2925/**********************************************************************/
2933void dai_manage_units(struct ai_type *ait, struct player *pplayer)
2934{
2936 dai_airlift(ait, pplayer);
2938
2939 /* Clear previous orders, if desirable, here. */
2940 unit_list_iterate(pplayer->units, punit) {
2941 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2942
2943 unit_data->done = FALSE;
2944 if (unit_data->task == AIUNIT_DEFEND_HOME) {
2946 }
2948
2949 /* Find and set city defenders first - figure out which units are
2950 * allowed to leave home. */
2951 dai_set_defenders(ait, pplayer);
2952
2955 && !def_ai_unit_data(punit, ait)->done) {
2956 /* Though it is usually the passenger who drives the transport,
2957 * the transporter is responsible for managing its passengers. */
2958 dai_manage_unit(ait, pplayer, punit);
2959 }
2961}
2962
2963/**********************************************************************/
2969 const struct city *pcity)
2970{
2971 const struct impr_type *impr_req = NULL;
2972 const struct req_context context = {
2973 .player = city_owner(pcity),
2974 .city = pcity,
2975 .tile = city_tile(pcity),
2976 .unittype = putype,
2977 };
2978
2979 requirement_vector_iterate(&putype->build_reqs, preq) {
2981 /* Already there. */
2982 continue;
2983 }
2985 city_owner(pcity), pcity)) {
2986 /* The unit type can't be built at all. */
2987 return NULL;
2988 }
2989 if (VUT_IMPROVEMENT == preq->source.kind && preq->present) {
2990 /* This is (one of) the building(s) required. */
2991 impr_req = preq->source.value.building;
2992 }
2994
2995 return impr_req;
2996}
2997
2998/**********************************************************************/
3003 const struct unit_type *base)
3004{
3005 /* This is the real function: */
3006 do {
3007 base = base->obsoleted_by;
3008 if (base == test) {
3009 return TRUE;
3010 }
3011 } while (base);
3012 return FALSE;
3013}
3014
3015/**********************************************************************/
3020static void dai_manage_barbarian_leader(struct ai_type *ait,
3021 struct player *pplayer,
3022 struct unit *leader)
3023{
3025 struct pf_parameter parameter;
3026 struct pf_map *pfm;
3027 struct pf_reverse_map *pfrm;
3028 struct unit *worst_danger;
3029 int move_cost, best_move_cost;
3030 int body_guards;
3031 bool alive = TRUE;
3032 const struct civ_map *nmap = &(wld.map);
3033
3035
3036 if (leader->moves_left == 0
3038 && 1 < unit_list_size(leader_tile->units))) {
3040
3041 return;
3042 }
3043
3044 if (is_boss_of_boat(ait, leader)) {
3045 /* We are in charge. Of course, since we are the leader...
3046 * But maybe somebody more militaristic should lead our ship to battle! */
3047
3048 /* First release boat from leaders lead */
3050
3054 && warrior->moves_left > 0) {
3055 /* This seems like a good warrior to lead us in to conquest! */
3056 dai_manage_unit(ait, pplayer, warrior);
3057
3058 /* If we reached our destination, ferryboat already called
3059 * ai_manage_unit() for leader. So no need to continue here.
3060 * Leader might even be dead.
3061 * If this return is removed, surrounding unit_list_iterate()
3062 * has to be replaced with unit_list_iterate_safe()*/
3063 return;
3064 }
3066 }
3067
3068 /* If we are not in charge of the boat, continue as if we
3069 * were not in a boat - we may want to leave the ship now. */
3070
3071 /* Check the total number of units able to protect our leader. */
3072 body_guards = 0;
3073 unit_list_iterate(pplayer->units, punit) {
3076 body_guards++;
3077 }
3079
3080 if (0 < body_guards) {
3081 pft_fill_unit_parameter(&parameter, nmap, leader);
3082 parameter.omniscience = !has_handicap(pplayer, H_MAP);
3083 pfm = pf_map_new(&parameter);
3084
3085 /* Find the closest body guard.
3086 * FIXME: maybe choose the strongest too? */
3087 pf_map_tiles_iterate(pfm, ptile, FALSE) {
3088 unit_list_iterate(ptile->units, punit) {
3089 if (unit_owner(punit) == pplayer
3092 struct pf_path *path = pf_map_path(pfm, ptile);
3093
3094 adv_follow_path(leader, path, ptile);
3095 pf_path_destroy(path);
3097 return;
3098 }
3101
3103 }
3104
3105 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader needs to flee");
3106
3107 /* Check for units we could fear. */
3108 pfrm = pf_reverse_map_new(nmap, pplayer, leader_tile, 3,
3109 !has_handicap(pplayer, H_MAP));
3112
3113 players_iterate(other_player) {
3114 if (other_player == pplayer) {
3115 continue;
3116 }
3117
3118 unit_list_iterate(other_player->units, punit) {
3120 if (PF_IMPOSSIBLE_MC != move_cost && move_cost < best_move_cost) {
3121 best_move_cost = move_cost;
3123 }
3126
3128
3129 if (NULL == worst_danger) {
3131 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader: no close enemy.");
3132 return;
3133 }
3134
3136 parameter.omniscience = !has_handicap(pplayer, H_MAP);
3137 pfm = pf_map_new(&parameter);
3139
3140 /* Try to escape. */
3141 do {
3143
3144 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader: moves left: %d.",
3145 leader->moves_left);
3146
3149 continue;
3150 }
3151
3152 move_cost = pf_map_move_cost(pfm, near_tile);
3153 if (PF_IMPOSSIBLE_MC != move_cost
3154 && move_cost > best_move_cost) {
3156 "Barbarian leader: safest is (%d, %d), safeness %d",
3158 best_move_cost = move_cost;
3160 }
3162
3163 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader: fleeing to (%d, %d).",
3167 "Barbarian leader: reached the safest position.");
3170 return;
3171 }
3172
3174 if (alive) {
3176 /* Didn't move. No point to retry. */
3178 return;
3179 }
3181 }
3182 } while (alive && 0 < leader->moves_left);
3183
3185}
3186
3187/**********************************************************************/
3193void dai_consider_tile_dangerous(struct ai_type *ait, struct tile *ptile,
3194 struct unit *punit,
3195 enum override_bool *result)
3196{
3197 int a = 0, d, db;
3198 struct player *pplayer = unit_owner(punit);
3199 struct city *pcity = tile_city(ptile);
3200 int extras_bonus = 0;
3201
3202 if (is_human(pplayer)) {
3203 /* Use advisors code for humans. */
3204 return;
3205 }
3206
3207 if (pcity && pplayers_allied(city_owner(pcity), unit_owner(punit))
3208 && !is_non_allied_unit_tile(ptile, pplayer)) {
3209 /* We will be safe in a friendly city */
3210 *result = OVERRIDE_FALSE;
3211 return;
3212 }
3213
3214 /* Calculate how well we can defend at (x,y) */
3215 db = 10 + tile_terrain(ptile)->defense_bonus / 10;
3217
3218 db += (db * extras_bonus) / 100;
3220
3221 adjc_iterate(&(wld.map), ptile, ptile1) {
3222 if (has_handicap(pplayer, H_FOG)
3224 /* We cannot see danger at (ptile1) => assume there is none */
3225 continue;
3226 }
3227 unit_list_iterate(ptile1->units, enemy) {
3230 == ATT_OK)
3232 == ATT_OK)) {
3234 if ((a * a * 10) >= d) {
3235 /* The enemies combined strength is too big! */
3236 *result = OVERRIDE_TRUE;
3237 return;
3238 }
3239 }
3242
3243 *result = OVERRIDE_FALSE;
3244}
3245
3246/**********************************************************************/
3249static void update_simple_ai_types(void)
3250{
3251 int i = 0;
3252
3255
3258 && !(pclass->adv.land_move == MOVE_NONE
3261 && punittype->transport_capacity < 8) {
3263 i++;
3264 }
3266
3268}
3269
3270/**********************************************************************/
3274{
3275 /* TODO: remove the simple_ai_types cache or merge it with a general ai
3276 * cache; see the comment to struct unit_type *simple_ai_types at
3277 * the beginning of this file. */
3279
3281 struct unit_type_ai *utai = fc_malloc(sizeof(*utai));
3282
3283 utai->low_firepower = FALSE;
3284 utai->ferry = FALSE;
3285 utai->missile_platform = FALSE;
3286 utai->carries_occupiers = FALSE;
3287 utai->potential_charges = unit_type_list_new();
3288
3291
3294
3295 /* Confirm firepower */
3297 if (pbonus->type == CBONUS_LOW_FIREPOWER) {
3299 if (utype_has_flag(penemy, pbonus->flag)) {
3300 struct unit_type_ai *utai = utype_ai_data(penemy, ait);
3301
3302 utai->low_firepower = TRUE;
3303 }
3305 }
3307
3308 /* Consider potential cargo */
3309 if (punittype->transport_capacity > 0) {
3310 struct unit_type_ai *utai = utype_ai_data(punittype, ait);
3311
3314
3317 utai->missile_platform = TRUE;
3318 } else if (pclass->adv.sea_move != MOVE_NONE
3319 && pcargo->adv.land_move != MOVE_NONE) {
3320 if (pcargo->adv.sea_move != MOVE_FULL) {
3321 utai->ferry = TRUE;
3322 } else {
3323 if (0 != utype_fuel(pctype)) {
3324 utai->ferry = TRUE;
3325 }
3326 }
3327 }
3328
3330 utai->carries_occupiers = TRUE;
3331 }
3332 }
3334 }
3335
3336 /* Consider potential charges */
3339
3340 if (0 < utype_fuel(punittype)
3341 && (0 == utype_fuel(pcharge)
3343 continue;
3344 }
3345
3346 unit_class_list_iterate(pclass->cache.subset_movers, chgcls) {
3347 if (chgcls == utype_class(pcharge)) {
3349 }
3351
3353 struct unit_type_ai *utai = utype_ai_data(punittype, ait);
3354 unit_type_list_append(utai->potential_charges, pcharge);
3355 }
3356
3359}
3360
3361/**********************************************************************/
3365{
3367 struct unit_type_ai *utai = utype_ai_data(ptype, ait);
3368
3369 if (utai == NULL) {
3370 continue;
3371 }
3373
3374 unit_type_list_destroy(utai->potential_charges);
3375 free(utai);
3377}
3378
3379/**********************************************************************/
3382void dai_unit_init(struct ai_type *ait, struct unit *punit)
3383{
3384 /* Make sure that contents of unit_ai structure are correctly initialized,
3385 * if you ever allocate it by some other mean than fc_calloc() */
3386 struct unit_ai *unit_data = fc_calloc(1, sizeof(struct unit_ai));
3387
3388 unit_data->done = FALSE;
3389 unit_data->cur_pos = NULL;
3390 unit_data->prev_pos = NULL;
3391 unit_data->target = 0;
3392 BV_CLR_ALL(unit_data->hunted);
3393 unit_data->ferryboat = 0;
3394 unit_data->passenger = 0;
3395 unit_data->bodyguard = 0;
3396 unit_data->charge = 0;
3397
3399}
3400
3401/**********************************************************************/
3404void dai_unit_turn_end(struct ai_type *ait, struct unit *punit)
3405{
3406 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3407
3409
3410 BV_CLR_ALL(unit_data->hunted);
3411}
3412
3413/**********************************************************************/
3416void dai_unit_close(struct ai_type *ait, struct unit *punit)
3417{
3418 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3419
3421
3424
3425 if (unit_data != NULL) {
3428 }
3429}
3430
3431/**********************************************************************/
3434void dai_unit_save(struct ai_type *ait, const char *aitstr,
3435 struct section_file *file,
3436 const struct unit *punit, const char *unitstr)
3437{
3438 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3439
3440 secfile_insert_int(file, unit_data->passenger, "%s.%spassenger",
3441 unitstr, aitstr);
3442 secfile_insert_int(file, unit_data->ferryboat, "%s.%sferryboat",
3443 unitstr, aitstr);
3444 secfile_insert_int(file, unit_data->charge, "%s.%scharge",
3445 unitstr, aitstr);
3446 secfile_insert_int(file, unit_data->bodyguard, "%s.%sbodyguard",
3447 unitstr, aitstr);
3448}
3449
3450/**********************************************************************/
3453void dai_unit_load(struct ai_type *ait, const char *aitstr,
3454 const struct section_file *file,
3455 struct unit *punit, const char *unitstr)
3456{
3457 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3458
3459 unit_data->passenger
3460 = secfile_lookup_int_default(file, 0, "%s.%spassenger",
3461 unitstr, aitstr);
3462 unit_data->ferryboat
3463 = secfile_lookup_int_default(file, 0, "%s.%sferryboat",
3464 unitstr, aitstr);
3465 unit_data->charge
3466 = secfile_lookup_int_default(file, 0, "%s.%scharge",
3467 unitstr, aitstr);
3468 unit_data->bodyguard
3469 = secfile_lookup_int_default(file, 0, "%s.%sbodyguard",
3470 unitstr, aitstr);
3471}
3472
3478
3479/**********************************************************************/
3482static bool role_unit_cb(struct unit_type *ptype, void *data)
3483{
3484 struct role_unit_cb_data *cb_data = (struct role_unit_cb_data *)data;
3486 const struct civ_map *nmap = &(wld.map);
3487
3488 if ((cb_data->tc == TC_LAND && pclass->adv.land_move == MOVE_NONE)
3489 || (cb_data->tc == TC_OCEAN && pclass->adv.sea_move == MOVE_NONE)) {
3490 return FALSE;
3491 }
3492
3493 if (cb_data->build_city == NULL
3494 || can_city_build_unit_now(nmap, cb_data->build_city, ptype)) {
3495 return TRUE;
3496 }
3497
3498 return FALSE;
3499}
3500
3501/**********************************************************************/
3505 enum terrain_class tc)
3506{
3507 struct role_unit_cb_data cb_data = { .build_city = pcity, .tc = tc };
3508
3510}
3511
3512/**********************************************************************/
3515bool dai_unit_can_strike_my_unit(const struct unit *attacker,
3516 const struct unit *defender)
3517{
3518 struct pf_parameter parameter;
3519 struct pf_map *pfm;
3520 const struct tile *ptarget = unit_tile(defender);
3521 int max_move_cost = attacker->moves_left;
3522 bool able_to_strike = FALSE;
3523 const struct civ_map *nmap = &(wld.map);
3524
3525 pft_fill_unit_parameter(&parameter, nmap, attacker);
3526 parameter.omniscience = !has_handicap(unit_owner(defender), H_MAP);
3527 pfm = pf_map_new(&parameter);
3528
3529 pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
3530 if (move_cost > max_move_cost) {
3531 break;
3532 }
3533
3534 if (ptile == ptarget) {
3536 break;
3537 }
3539
3541
3542 return able_to_strike;
3543}
3544
3545/**********************************************************************/
3548void dai_switch_to_explore(struct ai_type *ait, struct unit *punit,
3549 struct tile *target, enum override_bool *allow)
3550{
3551 struct unit_ai *udata = def_ai_unit_data(punit, ait);
3552
3553 if (udata->task != AIUNIT_NONE && udata->task != AIUNIT_EXPLORE) {
3555
3556 return;
3557 }
3558}
enum gen_action select_actres_action_unit_on_stack(struct civ_map *nmap, enum action_result actres, struct unit *punit, struct tile *ptile)
Definition actions.c:8156
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:3841
enum gen_action select_actres_action_unit_on_tile(struct civ_map *nmap, enum action_result actres, struct unit *punit, struct tile *ptile)
Definition actions.c:8180
enum gen_action select_actres_action_unit_on_city(struct civ_map *nmap, enum action_result actres, struct unit *punit, struct city *pcity)
Definition actions.c:8205
static struct action * action_by_number(action_id act_id)
Definition actions.h:635
#define ACTION_NONE
Definition actions.h:311
#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:410
int adv_unit_def_rating_basic(const struct unit *punit)
Definition advgoto.c:401
int adv_unittype_att_rating(const struct unit_type *punittype, int veteran, int moves_left, int hp)
Definition advgoto.c:380
int adv_unit_att_rating(const struct unit *punit)
Definition advgoto.c:391
int adv_could_unit_move_to_tile(struct unit *punit, struct tile *dest_tile)
Definition advgoto.c:354
bool adv_unit_execute_path(struct unit *punit, struct pf_path *path)
Definition advgoto.c:82
#define POWER_DIVIDER
Definition advtools.h:32
void dai_manage_airunit(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aiair.c:491
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
bool dai_hunter_qualify(struct player *pplayer, struct unit *punit)
Definition aihunt.c:290
int dai_hunter_manage(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aihunt.c:438
void dai_manage_paratrooper(struct ai_type *ait, struct player *pplayer, struct unit *punit)
int stack_cost(struct unit *pattacker, struct unit *pdefender)
Definition aitools.c:1307
bool goto_is_sane(struct unit *punit, struct tile *ptile)
Definition aitools.c:430
bool dai_unit_attack(struct ai_type *ait, struct unit *punit, struct tile *ptile)
Definition aitools.c:818
bool dai_unit_goto(struct ai_type *ait, struct unit *punit, struct tile *ptile)
Definition aitools.c:606
void dai_unit_new_task(struct ai_type *ait, struct unit *punit, enum ai_unit_task task, struct tile *ptile)
Definition aitools.c:644
bool dai_assess_military_unhappiness(const struct civ_map *nmap, struct city *pcity)
Definition aitools.c:1442
bool dai_unit_make_homecity(struct unit *punit, struct city *pcity)
Definition aitools.c:756
const char * dai_unit_task_rule_name(const enum ai_unit_task task)
Definition aitools.c:77
adv_want military_amortize(struct player *pplayer, struct city *pcity, adv_want value, int delay, int build_cost)
Definition aitools.c:118
bool dai_gothere(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct tile *dest_tile)
Definition aitools.c:245
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:752
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:1860
const char * city_name_get(const struct city *pcity)
Definition city.c:1137
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 civ_map *nmap, const struct city *pcity, const struct unit_type *punittype)
Definition city.c:947
#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:856
double unit_win_chance(const struct civ_map *nmap, const struct unit *attacker, const struct unit *defender, const struct action *paction)
Definition combat.c:478
bool is_stack_vulnerable(const struct tile *ptile)
Definition combat.c:989
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:712
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:256
int get_total_defense_power(const struct unit *attacker, const struct unit *defender)
Definition combat.c:767
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:122
struct unit * get_defender(const struct civ_map *nmap, const struct unit *attacker, const struct tile *ptile, const struct action *paction)
Definition combat.c:836
bool can_unit_attack_tile(const struct unit *punit, const struct action *paction, const struct tile *dest_tile)
Definition combat.c:311
int base_get_defense_power(const struct unit *punit)
Definition combat.c:569
@ ATT_OK
Definition combat.h:35
char * incite_cost
Definition comments.c:75
bool dai_can_requirement_be_met_in_city(const struct requirement *preq, const struct player *pplayer, const struct city *pcity)
Definition daieffects.c:782
#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:91
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
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:3434
static bool invasion_funct(struct ai_type *ait, struct unit *punit, bool dest, int radius, int which)
Definition daiunit.c:1086
static void dai_military_findjob(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct unit *punit)
Definition daiunit.c:921
static bool has_defense(struct city *pcity)
Definition daiunit.c:222
adv_want kill_desire(adv_want benefit, int attack, int loss, int vuln, int victim_count)
Definition daiunit.c:342
static bool search_homecity_for_caravan(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:2290
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:2055
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:304
static bool unit_role_defender(const struct unit_type *punittype)
Definition daiunit.c:769
void dai_units_ruleset_init(struct ai_type *ait)
Definition daiunit.c:3273
#define LOG_CARAVAN
Definition daiunit.c:88
static int unit_att_rating_now(const struct unit *punit)
Definition daiunit.c:259
static void dai_military_attack_barbarian(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:1754
enum gen_action dai_select_tile_attack_action(struct civ_map *nmap, struct unit *punit, struct tile *ptile, enum action_target_kind *kind)
Definition daiunit.c:445
static void update_simple_ai_types(void)
Definition daiunit.c:3249
const struct impr_type * utype_needs_improvement(const struct unit_type *putype, const struct city *pcity)
Definition daiunit.c:2968
void dai_switch_to_explore(struct ai_type *ait, struct unit *punit, struct tile *target, enum override_bool *allow)
Definition daiunit.c:3548
void dai_manage_military(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct unit *punit)
Definition daiunit.c:2570
static bool dai_find_boat_for_unit(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:1971
static void reinforcements_cost_and_value(struct unit *punit, struct tile *ptile0, int *value, int *cost)
Definition daiunit.c:375
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:250
bool dai_unit_can_strike_my_unit(const struct unit *attacker, const struct unit *defender)
Definition daiunit.c:3515
bool is_on_unit_upgrade_path(const struct unit_type *test, const struct unit_type *base)
Definition daiunit.c:3002
static void dai_military_bodyguard(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:703
static void single_invader(struct ai_city *city_data, const struct unit_type *utype, int which)
Definition daiunit.c:1058
#define LOG_CARAVAN3
Definition daiunit.c:90
void dai_manage_units(struct ai_type *ait, struct player *pplayer)
Definition daiunit.c:2933
static void dai_manage_caravan(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:2327
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:1207
static void dai_set_defenders(struct ai_type *ait, struct player *pplayer)
Definition daiunit.c:2838
void dai_manage_unit(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:2725
adv_want look_for_charge(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct unit *punit, struct unit **aunit, struct city **acity)
Definition daiunit.c:784
static bool role_unit_cb(struct unit_type *ptype, void *data)
Definition daiunit.c:3482
static void dai_military_attack(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:1817
void dai_unit_turn_end(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:3404
static void dai_manage_settler(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:2703
static int avg_benefit(int benefit, int loss, double chance)
Definition daiunit.c:366
#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:278
static bool dai_is_unit_tired_waiting_boat(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:2186
static int dai_rampage_want(struct unit *punit, struct tile *ptile)
Definition daiunit.c:524
bool dai_can_unit_type_follow_unit_type(const struct unit_type *follower, const struct unit_type *followee, struct ai_type *ait)
Definition daiunit.c:903
struct city * find_nearest_safe_city(struct unit *punit)
Definition daiunit.c:1703
static void dai_manage_barbarian_leader(struct ai_type *ait, struct player *pplayer, struct unit *leader)
Definition daiunit.c:3020
static void dai_manage_hitpoint_recovery(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:2495
static int unit_att_rating_squared(const struct unit *punit)
Definition daiunit.c:268
static struct pf_path * find_rampage_target(struct unit *punit, int thresh_adj, int thresh_move)
Definition daiunit.c:591
static bool is_my_turn(struct unit *punit, struct unit *pdef)
Definition daiunit.c:400
static int unit_def_rating_squared(const struct unit *punit, const struct unit *pdef)
Definition daiunit.c:291
void dai_unit_init(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:3382
void dai_consider_tile_dangerous(struct ai_type *ait, struct tile *ptile, struct unit *punit, enum override_bool *result)
Definition daiunit.c:3193
bool uclass_need_trans_between(struct unit_class *pclass, struct tile *ctile, struct tile *ptile)
Definition daiunit.c:2016
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:3453
static void caravan_optimize_callback(const struct caravan_result *result, void *data)
Definition daiunit.c:2167
#define LOGLEVEL_RECOVERY
Definition daiunit.c:87
void dai_unit_close(struct ai_type *ait, struct unit *punit)
Definition daiunit.c:3416
void dai_units_ruleset_close(struct ai_type *ait)
Definition daiunit.c:3364
struct unit_type * dai_role_utype_for_terrain_class(struct city *pcity, int role, enum terrain_class tc)
Definition daiunit.c:3504
bool find_beachhead(const struct player *pplayer, struct pf_map *ferry_map, struct tile *dest_tile, const struct unit_type *cargo_type, struct tile **ferry_dest, struct tile **beachhead_tile)
Definition daiunit.c:1132
static void dai_military_defend(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daiunit.c:1012
bool dai_military_rampage(struct unit *punit, int thresh_adj, int thresh_move)
Definition daiunit.c:670
static bool dai_caravan_can_trade_cities_diff_cont(struct player *pplayer, struct unit *punit)
Definition daiunit.c:2245
#define POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer)
Definition daiunit.h:73
@ AIUNIT_BUILD_CITY
Definition daiunit.h:28
@ AIUNIT_NONE
Definition daiunit.h:28
@ AIUNIT_ATTACK
Definition daiunit.h:29
@ AIUNIT_EXPLORE
Definition daiunit.h:30
@ AIUNIT_HUNTER
Definition daiunit.h:30
@ AIUNIT_RECOVER
Definition daiunit.h:30
@ AIUNIT_TRADE
Definition daiunit.h:31
@ AIUNIT_DEFEND_HOME
Definition daiunit.h:29
@ AIUNIT_ESCORT
Definition daiunit.h:29
@ AIUNIT_AUTO_SETTLER
Definition daiunit.h:28
@ AIUNIT_WONDER
Definition daiunit.h:31
#define RAMPAGE_ANYTHING
Definition daiunit.h:86
#define RAMPAGE_FREE_CITY_OR_BETTER
Definition daiunit.h:88
#define INVASION_ATTACK
Definition daiunit.h:82
#define INVASION_OCCUPY
Definition daiunit.h:81
#define RAMPAGE_HUT_OR_BETTER
Definition daiunit.h:87
#define DEFENSE_POWER(ptype)
Definition daiunit.h:67
#define IS_ATTACKER(ptype)
Definition daiunit.h:71
#define BODYGUARD_RAMPAGE_THRESHOLD
Definition daiunit.h:89
#define ATTACK_POWER(ptype)
Definition daiunit.h:69
static void attack(QVariant data1, QVariant data2)
Definition dialogs.cpp:3018
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2940
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:846
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:1035
bool unit_can_enter_hut(const struct unit *punit, const struct tile *ptile)
Definition extras.c:712
float adv_want
Definition fc_types.h:1354
@ RPT_CERTAIN
Definition fc_types.h:701
@ AUT_AUTO_SETTLER
Definition fc_types.h:370
#define ADV_WANT_PRINTF
Definition fc_types.h:1355
@ O_LUXURY
Definition fc_types.h:101
signed short Continent_id
Definition fc_types.h:372
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:62
struct world wld
Definition game.c:63
struct unit * game_unit_by_number(int id)
Definition game.c:116
struct city * game_city_by_number(int id)
Definition game.c:107
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:940
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:949
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:630
int map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:654
#define iterate_outward(nmap, start_tile, max_dist, itr_tile)
Definition map.h:367
#define iterate_outward_end
Definition map.h:371
#define adjc_iterate_end
Definition map.h:433
static int index_to_map_pos_y(int mindex)
Definition map.h:735
#define square_iterate(nmap, center_tile, radius, tile_itr)
Definition map.h:391
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:428
#define square_iterate_end
Definition map.h:394
static int index_to_map_pos_x(int mindex)
Definition map.h:722
#define pmap(_tile)
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:894
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:920
#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:351
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:363
int unit_move_rate(const struct unit *punit)
Definition movement.c:90
bool can_attack_from_non_native(const struct unit_type *utype)
Definition movement.c:227
bool can_unit_survive_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:523
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Definition movement.c:900
bool can_attack_non_native(const struct unit_type *utype)
Definition movement.c:214
#define SINGLE_MOVE
Definition movement.h:26
static bool is_native_tile_to_class(const struct unit_class *punitclass, const struct tile *ptile)
Definition movement.h:88
@ MR_OK
Definition movement.h:35
@ MR_DEATH
Definition movement.h:36
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:138
struct nation_type * nation_of_unit(const struct unit *punit)
Definition nation.c: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)
bool pf_map_position(struct pf_map *pfm, struct tile *ptile, struct pf_position *pos)
void pf_reverse_map_destroy(struct pf_reverse_map *pfrm)
int pf_reverse_map_unit_move_cost(struct pf_reverse_map *pfrm, const struct unit *punit)
void pf_map_destroy(struct pf_map *pfm)
struct pf_reverse_map * pf_reverse_map_new(const struct civ_map *nmap, const struct player *pplayer, struct tile *target_tile, int max_turns, bool omniscient)
int pf_map_move_cost(struct pf_map *pfm, struct tile *ptile)
#define PF_IMPOSSIBLE_MC
#define pf_map_move_costs_iterate_end
#define pf_map_move_costs_iterate(ARG_pfm, NAME_tile, NAME_cost, COND_from_start)
#define pf_map_tiles_iterate(ARG_pfm, NAME_tile, COND_from_start)
#define pf_map_tiles_iterate_end
void pft_fill_unit_parameter(struct pf_parameter *parameter, const struct civ_map *nmap, const struct unit *punit)
Definition pf_tools.c:840
void pft_fill_unit_attack_param(struct pf_parameter *parameter, const struct civ_map *nmap, const struct unit *punit)
Definition pf_tools.c:949
void pft_fill_unit_overlap_param(struct pf_parameter *parameter, const struct civ_map *nmap, const struct unit *punit)
Definition pf_tools.c:891
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:876
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:1405
#define players_iterate_end
Definition player.h:537
#define players_iterate(_pplayer)
Definition player.h:532
static bool is_barbarian(const struct player *pplayer)
Definition player.h:489
#define is_human(plr)
Definition player.h:229
#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 player *other_player, 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:174
struct civ_game::@31::@35 server
struct city_list * cities
Definition player.h:279
struct unit_list * units
Definition player.h:280
bool is_alive
Definition player.h:266
const struct player * player
enum terrain_class tc
Definition daiunit.c:3475
struct city * build_city
Definition daiunit.c:3476
Definition tile.h:50
struct unit_list * units
Definition tile.h:58
Continent_id continent
Definition tile.h:54
bool done
Definition daiunit.h:45
bv_unit_classes cargo
Definition unittype.h:558
struct veteran_system * veteran
Definition unittype.h:544
int move_rate
Definition unittype.h:517
Definition unit.h:138
enum unit_activity activity
Definition unit.h:157
int moves_left
Definition unit.h:150
int id
Definition unit.h:145
bool moved
Definition unit.h:173
int hp
Definition unit.h:151
struct tile * tile
Definition unit.h:140
struct unit_adv * adv
Definition unit.h:236
int homecity
Definition unit.h:146
int birth_turn
Definition unit.h:207
struct tile * goto_tile
Definition unit.h:155
int veteran
Definition unit.h:152
struct player * owner
Definition unit.h:143
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:303
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:88
#define tile_terrain(_tile)
Definition tile.h:114
#define TILE_XY(ptile)
Definition tile.h:43
#define tile_continent(_tile)
Definition tile.h:92
bool can_cities_trade(const struct city *pc1, const struct city *pc2)
bool can_establish_trade_route(const struct city *pc1, const struct city *pc2)
void unit_set_ai_data(struct unit *punit, const struct ai_type *ai, void *data)
Definition unit.c:2298
bool unit_transport_load(struct unit *pcargo, struct unit *ptrans, bool force)
Definition unit.c:2378
bool is_losing_hp(const struct unit *punit)
Definition unit.c:2236
bool unit_can_airlift_to(const struct civ_map *nmap, const struct unit *punit, const struct city *pdest_city)
Definition unit.c:194
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2449
int unit_gain_hitpoints(const struct unit *punit)
Definition unit.c:2191
bool unit_is_cityfounder(const struct unit *punit)
Definition unit.c:2649
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:367
bool unit_can_do_action_result(const struct unit *punit, enum action_result result)
Definition unit.c:377
int get_transporter_capacity(const struct unit *punit)
Definition unit.c:305
bool can_unit_do_activity(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity)
Definition unit.c:876
bool is_special_unit(const struct unit *punit)
Definition unit.c:358
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2433
bool is_guard_unit(const struct unit *punit)
Definition unit.c:348
bool unit_has_orders(const struct unit *punit)
Definition unit.c:210
#define unit_tile(_pu)
Definition unit.h:397
#define unit_cargo_iterate_end
Definition unit.h:573
#define unit_cargo_iterate(_ptrans, _pcargo)
Definition unit.h:570
#define CHECK_UNIT(punit)
Definition unit.h:270
#define unit_owner(_pu)
Definition unit.h:396
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.h:432
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity)
Definition unithand.c:6471
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:3293
bool unit_server_side_agent_set(struct player *pplayer, struct unit *punit, enum server_side_agent agent)
Definition unithand.c:6370
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:2298
struct unit_class * unit_class_get(const struct unit *punit)
Definition unittype.c:2499
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_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:2739
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:2747
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:749
#define utype_fuel(ptype)
Definition unittype.h:839
#define combat_bonus_list_iterate_end
Definition unittype.h:482
#define combat_bonus_list_iterate(bonuslist, pbonus)
Definition unittype.h:480
@ MOVE_FULL
Definition unittype.h:144
@ MOVE_NONE
Definition unittype.h:144
#define unit_type_list_iterate(utype_list, ptype)
Definition unittype.h:940
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:617
#define unit_class_list_iterate(uclass_list, pclass)
Definition unittype.h:932
#define unit_type_iterate(_p)
Definition unittype.h:855
#define unit_type_list_iterate_end
Definition unittype.h:942
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:862
#define unit_class_list_iterate_end
Definition unittype.h:934