Freeciv-3.1
Loading...
Searching...
No Matches
aiunit.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 "rand.h"
25#include "registry.h"
26#include "shared.h"
27#include "timing.h"
28
29/* common */
30#include "city.h"
31#include "combat.h"
32#include "game.h"
33#include "government.h"
34#include "map.h"
35#include "movement.h"
36#include "packets.h"
37#include "specialist.h"
38#include "traderoutes.h"
39#include "unit.h"
40#include "unitlist.h"
41
42/* common/aicore */
43#include "caravan.h"
44#include "pf_tools.h"
45
46/* server */
47#include "barbarian.h"
48#include "citytools.h"
49#include "cityturn.h"
50#include "diplomats.h"
51#include "maphand.h"
52#include "srv_log.h"
53#include "unithand.h"
54#include "unittools.h"
55
56/* server/advisors */
57#include "advbuilding.h"
58#include "advgoto.h"
59#include "advtools.h"
60#include "autoexplorer.h"
61#include "autosettlers.h"
62
63/* ai */
64#include "difficulty.h"
65#include "handicaps.h"
66
67/* ai/default */
68#include "aiair.h"
69#include "aidata.h"
70#include "aidiplomat.h"
71#include "aiferry.h"
72#include "aiguard.h"
73#include "aihand.h"
74#include "aihunt.h"
75#include "ailog.h"
76#include "aiparatrooper.h"
77#include "aiplayer.h"
78#include "aitools.h"
79#include "daicity.h"
80#include "daieffects.h"
81#include "daimilitary.h"
82
83#include "aiunit.h"
84
85
86#define LOGLEVEL_RECOVERY LOG_DEBUG
87#define LOG_CARAVAN LOG_DEBUG
88#define LOG_CARAVAN2 LOG_DEBUG
89#define LOG_CARAVAN3 LOG_DEBUG
90
91static bool dai_find_boat_for_unit(struct ai_type *ait, struct unit *punit);
92static bool dai_caravan_can_trade_cities_diff_cont(struct player *pplayer,
93 struct unit *punit);
94static void dai_manage_caravan(struct ai_type *ait, struct player *pplayer,
95 struct unit *punit);
96static void dai_manage_barbarian_leader(struct ai_type *ait,
97 struct player *pplayer,
98 struct unit *leader);
99
100static void dai_military_findjob(struct ai_type *ait, const struct civ_map *nmap,
101 struct player *pplayer, struct unit *punit);
102static void dai_military_defend(struct ai_type *ait, struct player *pplayer,
103 struct unit *punit);
104static void dai_military_attack(struct ai_type *ait, struct player *pplayer,
105 struct unit *punit);
106
107static bool unit_role_defender(const struct unit_type *punittype);
108static int unit_def_rating_squared(const struct unit *punit,
109 const struct unit *pdef);
110
111/*
112 * Cached values. Updated by update_simple_ai_types.
113 *
114 * This a hack to enable emulation of old loops previously hardwired
115 * as
116 * for (i = U_WARRIORS; i <= U_BATTLESHIP; i++)
117 *
118 * (Could probably just adjust the loops themselves fairly simply,
119 * but this is safer for regression testing.)
120 *
121 * Not dealing with planes yet.
122 *
123 * Terminated by NULL.
124 */
126
127/**********************************************************************/
137static struct city *find_neediest_airlift_city(struct ai_type *ait,
138 const struct player *pplayer)
139{
140 struct city *neediest_city = NULL;
141 int most_danger = 0;
142 int most_urgent = 0;
143
144 city_list_iterate(pplayer->cities, pcity) {
145 struct ai_city *city_data = def_ai_city_data(pcity, ait);
146
147 if (pcity->airlift) {
148 if (city_data->urgency > most_urgent) {
149 most_urgent = city_data->urgency;
150 neediest_city = pcity;
151 } else if (0 == most_urgent /* urgency trumps danger */
152 && city_data->danger > most_danger) {
153 most_danger = city_data->danger;
154 neediest_city = pcity;
155 }
156 }
158
159 return neediest_city;
160}
161
162/**********************************************************************/
168static void dai_airlift(struct ai_type *ait, struct player *pplayer)
169{
170 struct city *most_needed;
171 int comparison;
172 struct unit *transported;
173 const struct civ_map *nmap = &(wld.map);
174
175 do {
176 most_needed = find_neediest_airlift_city(ait, pplayer);
177 comparison = 0;
178 transported = NULL;
179
180 if (!most_needed) {
181 return;
182 }
183
184 unit_list_iterate(pplayer->units, punit) {
185 struct tile *ptile = (unit_tile(punit));
186 struct city *pcity = tile_city(ptile);
187
188 if (pcity) {
189 struct ai_city *city_data = def_ai_city_data(pcity, ait);
190 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
191 const struct unit_type *ptype = unit_type_get(punit);
192
193 if (city_data->urgency == 0
194 && city_data->danger - DEFENSE_POWER(ptype) < comparison
195 && unit_can_airlift_to(nmap, punit, most_needed)
196 && DEFENSE_POWER(ptype) > 2
197 && (unit_data->task == AIUNIT_NONE
198 || unit_data->task == AIUNIT_DEFEND_HOME)
199 && IS_ATTACKER(ptype)) {
200 comparison = city_data->danger;
201 transported = punit;
202 }
203 }
205 if (!transported) {
206 return;
207 }
208 UNIT_LOG(LOG_DEBUG, transported, "airlifted to defend %s",
209 city_name_get(most_needed));
210 unit_do_action(pplayer, transported->id, most_needed->id,
211 0, "", ACTION_AIRLIFT);
212 } while (TRUE);
213}
214
215/**********************************************************************/
221static bool has_defense(struct city *pcity)
222{
223 struct tile *ptile = city_tile(pcity);
224
225 unit_list_iterate(ptile->units, punit) {
227 && punit->hp != 0) {
228 struct unit_class *pclass = unit_class_get(punit);
229
230 if (pclass->non_native_def_pct > 0
231 || is_native_tile_to_class(pclass, ptile)) {
232 return TRUE;
233 }
234 }
235 }
237
238 return FALSE;
239}
240
241/**********************************************************************/
249int build_cost_balanced(const struct unit_type *punittype)
250{
251 return 2 * utype_build_shield_cost_base(punittype) * punittype->attack_strength /
252 (punittype->attack_strength + punittype->defense_strength);
253}
254
255/**********************************************************************/
258static int unit_att_rating_now(const struct unit *punit)
259{
262}
263
264/**********************************************************************/
267static int unit_att_rating_squared(const struct unit *punit)
268{
269 int v = adv_unit_att_rating(punit);
270
271 return v * v;
272}
273
274/**********************************************************************/
277static int unit_def_rating(const struct unit *attacker,
278 const struct unit *defender)
279{
280 const struct unit_type *def_type = unit_type_get(defender);
281
282 return (get_total_defense_power(attacker, defender)
283 * (attacker->id != 0 ? defender->hp : def_type->hp)
284 * def_type->firepower / POWER_DIVIDER);
285}
286
287/**********************************************************************/
290static int unit_def_rating_squared(const struct unit *attacker,
291 const struct unit *defender)
292{
293 int v = unit_def_rating(attacker, defender);
294
295 return v * v;
296}
297
298/**********************************************************************/
303int unittype_def_rating_squared(const struct unit_type *att_type,
304 const struct unit_type *def_type,
305 struct player *def_player,
306 struct tile *ptile, bool fortified,
307 int veteran)
308{
309 struct civ_map *nmap = &(wld.map);
310 int v = get_virtual_defense_power(nmap, att_type, def_type, def_player,
311 ptile, fortified, veteran)
312 * def_type->hp * def_type->firepower / POWER_DIVIDER;
313
314 return v * v;
315}
316
317/**********************************************************************/
341adv_want kill_desire(adv_want benefit, int attack, int loss, int vuln,
342 int victim_count)
343{
344 adv_want desire;
345
346 /* attractiveness danger */
347 desire = (benefit * attack - loss * vuln) * victim_count
348 * SHIELD_WEIGHTING / (attack + vuln * victim_count);
349
350 return desire;
351}
352
353/**********************************************************************/
365static int avg_benefit(int benefit, int loss, double chance)
366{
367 return (int)(((benefit + loss) * chance - loss) * SHIELD_WEIGHTING);
368}
369
370/**********************************************************************/
375 struct tile *ptile0,
376 int *value, int *cost)
377{
378 *cost = 0;
379 *value = 0;
380 square_iterate(&(wld.map), ptile0, 1, ptile) {
381 unit_list_iterate(ptile->units, aunit) {
382 if (aunit != punit
384 int val = adv_unit_att_rating(aunit);
385
386 if (val != 0) {
387 *value += val;
389 }
390 }
393}
394
395/**********************************************************************/
399static bool is_my_turn(struct unit *punit, struct unit *pdef)
400{
401 int val = unit_att_rating_now(punit);
402 int cur, d;
403 const struct unit_type *def_type = unit_type_get(pdef);
404 struct tile *def_tile = unit_tile(pdef);
405 struct civ_map *nmap = &(wld.map);
406
408
409 square_iterate(nmap, def_tile, 1, ptile) {
410 unit_list_iterate(ptile->units, aunit) {
411 if (aunit == punit || unit_owner(aunit) != unit_owner(punit)) {
412 continue;
413 }
414 if ((unit_attack_units_at_tile_result(aunit, NULL, def_tile)
415 != ATT_OK)
416 || (unit_attack_unit_at_tile_result(aunit, NULL,
417 pdef, def_tile)
418 != ATT_OK)) {
419 continue;
420 }
421 d = get_virtual_defense_power(nmap, unit_type_get(aunit), def_type,
422 unit_owner(pdef), def_tile,
423 FALSE, 0);
424 if (d == 0) {
425 return TRUE; /* Thanks, Markus -- Syela */
426 }
427 cur = unit_att_rating_now(aunit) *
429 unit_owner(pdef), def_tile,
430 FALSE, 0) / d;
431 if (cur > val && ai_fuzzy(unit_owner(punit), TRUE)) {
432 return FALSE;
433 }
436
437 return TRUE;
438}
439
440/**********************************************************************/
456static int dai_rampage_want(struct unit *punit, struct tile *ptile)
457{
458 struct player *pplayer = unit_owner(punit);
459 struct unit *pdef;
460 struct civ_map *nmap = &(wld.map);
461
463
464 if (can_unit_attack_tile(punit, NULL, ptile)
465 && (pdef = get_defender(nmap, punit, ptile))) {
466 /* See description of kill_desire() about these variables. */
468 int benefit = stack_cost(punit, pdef);
470
471 attack *= attack;
472
473 /* If the victim is in the city/fortress, we correct the benefit
474 * with our health because there could be reprisal attacks. We
475 * shouldn't send already injured units to useless suicide.
476 * Note that we do not specially encourage attacks against
477 * cities: rampage is a hit-n-run operation. */
478 if (!is_stack_vulnerable(ptile)
479 && unit_list_size(ptile->units) > 1) {
480 benefit = (benefit * punit->hp) / unit_type_get(punit)->hp;
481 }
482
483 /* If we have non-zero attack rating... */
484 if (attack > 0 && is_my_turn(punit, pdef)) {
485 double chance = unit_win_chance(nmap, punit, pdef);
486 int desire = avg_benefit(benefit, loss, chance);
487
488 /* No need to amortize, our operation takes one turn. */
489 UNIT_LOG(LOG_DEBUG, punit, "Rampage: Desire %d to kill %s(%d,%d)",
490 desire,
491 unit_rule_name(pdef),
492 TILE_XY(unit_tile(pdef)));
493
494 return MAX(0, desire);
495 }
496 } else if (0 == unit_list_size(ptile->units)) {
497 /* No defender. */
498 struct city *pcity = tile_city(ptile);
499
500 /* ...and free foreign city waiting for us. Who would resist! */
501 if (NULL != pcity
502 && pplayers_at_war(pplayer, city_owner(pcity))
505 }
506
507 /* ...or tiny pleasant hut here! */
508 /* FIXME: unhardcode and variate the desire to enter a hut. */
509 if (unit_can_enter_hut(punit, ptile) && !is_barbarian(pplayer)
510 && is_native_tile(unit_type_get(punit), ptile)) {
511 return -RAMPAGE_HUT_OR_BETTER;
512 }
513 }
514
515 return 0;
516}
517
518/**********************************************************************/
521static struct pf_path *find_rampage_target(struct unit *punit,
522 int thresh_adj, int thresh_move)
523{
524 struct pf_map *tgt_map;
525 struct pf_path *path = NULL;
526 struct pf_parameter parameter;
527 /* Coordinates of the best target (initialize to silence compiler) */
528 struct tile *ptile = unit_tile(punit);
529 /* Want of the best target */
530 int max_want = 0;
531 struct player *pplayer = unit_owner(punit);
532 const struct civ_map *nmap = &(wld.map);
533
534 pft_fill_unit_attack_param(&parameter, nmap, punit);
535 parameter.omniscience = !has_handicap(pplayer, H_MAP);
536 /* When trying to find rampage targets we ignore risks such as
537 * enemy units because we are looking for trouble!
538 * Hence no call ai_avoid_risks()
539 */
540
541 tgt_map = pf_map_new(&parameter);
542 pf_map_move_costs_iterate(tgt_map, iter_tile, move_cost, FALSE) {
543 int want;
544 bool move_needed;
545 int thresh;
546
547 if (move_cost > punit->moves_left) {
548 /* This is too far */
549 break;
550 }
551
552 if (has_handicap(pplayer, H_TARGETS)
553 && !map_is_known_and_seen(iter_tile, pplayer, V_MAIN)) {
554 /* The target is under fog of war */
555 continue;
556 }
557
558 want = dai_rampage_want(punit, iter_tile);
559
560 /* Negative want means move needed even though the tiles are adjacent */
561 move_needed = (!is_tiles_adjacent(unit_tile(punit), iter_tile)
562 || want < 0);
563 /* Select the relevant threshold */
564 thresh = (move_needed ? thresh_move : thresh_adj);
565 want = (want < 0 ? -want : want);
566
567 if (want > max_want && want > thresh) {
568 /* The new want exceeds both the previous maximum
569 * and the relevant threshold, so it's worth recording */
570 max_want = want;
571 ptile = iter_tile;
572 }
574
575 if (max_want > 0) {
576 /* We found something */
577 path = pf_map_path(tgt_map, ptile);
578 fc_assert(path != NULL);
579 }
580
581 pf_map_destroy(tgt_map);
582
583 return path;
584}
585
586/**********************************************************************/
600bool dai_military_rampage(struct unit *punit, int thresh_adj,
601 int thresh_move)
602{
603 int count = punit->moves_left + 1; /* break any infinite loops */
604 struct pf_path *path = NULL;
605
608
609 fc_assert_ret_val(thresh_adj <= thresh_move, TRUE);
610 /* This teaches the AI about the dangers inherent in occupychance. */
611 thresh_adj += ((thresh_move - thresh_adj) * game.server.occupychance / 100);
612
613 while (count-- > 0 && punit->moves_left > 0
614 && (path = find_rampage_target(punit, thresh_adj, thresh_move))) {
615 if (!adv_unit_execute_path(punit, path)) {
616 /* Died */
617 count = -1;
618 }
619 pf_path_destroy(path);
620 path = NULL;
621 }
622
623 fc_assert(NULL == path);
624
626 return (count >= 0);
627}
628
629/**********************************************************************/
633static void dai_military_bodyguard(struct ai_type *ait, struct player *pplayer,
634 struct unit *punit)
635{
636 struct unit *aunit = aiguard_charge_unit(ait, punit);
637 struct city *acity = aiguard_charge_city(ait, punit);
638 struct tile *ptile;
639
641 CHECK_GUARD(ait, punit);
642
643 if (aunit && unit_owner(aunit) == unit_owner(punit)) {
644 /* protect a unit */
645 if (aunit->goto_tile != NULL) {
646 /* Our charge is going somewhere: maybe we should meet them there */
647 /* FIXME: This probably isn't the best algorithm for this. */
648 int me2them = real_map_distance(unit_tile(punit), unit_tile(aunit));
649 int me2goal = real_map_distance(unit_tile(punit), aunit->goto_tile);
650 int them2goal = real_map_distance(unit_tile(aunit), aunit->goto_tile);
651
652 if (me2goal < me2them
653 || (me2goal/unit_move_rate(punit) < them2goal/unit_move_rate(aunit)
654 && me2goal/unit_move_rate(punit) < me2them/unit_move_rate(punit)
655 && unit_move_rate(punit) > unit_move_rate(aunit))) {
656 ptile = aunit->goto_tile;
657 } else {
658 ptile = unit_tile(aunit);
659 }
660 } else {
661 ptile = unit_tile(aunit);
662 }
663 } else if (acity && city_owner(acity) == unit_owner(punit)) {
664 /* protect a city */
665 ptile = acity->tile;
666 } else {
667 /* should be impossible */
668 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "we lost our charge");
670 return;
671 }
672
673 if (same_pos(unit_tile(punit), ptile)) {
674 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "at RV");
675 } else {
676 if (goto_is_sane(punit, ptile)) {
677 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "meeting charge");
678 if (!dai_gothere(ait, pplayer, punit, ptile)) {
679 /* We died */
680 return;
681 }
682 } else {
683 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "can not meet charge");
685 }
686 }
687 /* We might have stopped because of an enemy nearby.
688 * Perhaps we can kill it.*/
691 && same_pos(unit_tile(punit), ptile)) {
692 def_ai_unit_data(punit, ait)->done = TRUE; /* Stay with charge */
693 }
694}
695
696/**********************************************************************/
699static bool unit_role_defender(const struct unit_type *punittype)
700{
701 return (utype_has_role(punittype, L_DEFEND_GOOD));
702}
703
704/**********************************************************************/
714adv_want look_for_charge(struct ai_type *ait, const struct civ_map *nmap,
715 struct player *pplayer, struct unit *punit,
716 struct unit **aunit, struct city **acity)
717{
718 struct pf_parameter parameter;
719 struct pf_map *pfm;
720 struct city *pcity;
721 struct ai_city *data, *best_data = NULL;
722 const int toughness = adv_unit_def_rating_basic_squared(punit);
723 int def, best_def = -1;
724 /* Arbitrary: 3 turns. */
725 const int max_move_cost = 3 * unit_move_rate(punit);
726
727 *aunit = NULL;
728 *acity = NULL;
729
730 if (0 == toughness) {
731 /* useless */
732 return 0;
733 }
734
735 pft_fill_unit_parameter(&parameter, nmap, punit);
736 parameter.omniscience = !has_handicap(pplayer, H_MAP);
737 pfm = pf_map_new(&parameter);
738
739 pf_map_move_costs_iterate(pfm, ptile, move_cost, TRUE) {
740 if (move_cost > max_move_cost) {
741 /* Consider too far. */
742 break;
743 }
744
745 pcity = tile_city(ptile);
746
747 /* Consider unit bodyguard. */
748 unit_list_iterate(ptile->units, buddy) {
749 const struct unit_type *ptype = unit_type_get(punit);
750 const struct unit_type *buddy_type = unit_type_get(buddy);
751
752 /* TODO: allied unit bodyguard? */
753 if (!dai_can_unit_type_follow_unit_type(ptype, buddy_type, ait)
754 || unit_owner(buddy) != pplayer
755 || !aiguard_wanted(ait, buddy)
757 || DEFENSE_POWER(buddy_type) >= DEFENSE_POWER(ptype)
758 || (utype_can_do_action_result(buddy_type, ACTRES_ATTACK)
759 && 0 == get_transporter_capacity(buddy)
760 && ATTACK_POWER(buddy_type) <= ATTACK_POWER(ptype))) {
761
762 continue;
763 }
764
765 def = (toughness - adv_unit_def_rating_basic_squared(buddy));
766 if (0 >= def) {
767 continue;
768 }
769
770 if (0 == get_transporter_capacity(buddy)) {
771 /* Reduce want based on move cost. We can't do this for
772 * transports since they move around all the time, leading
773 * to hillarious flip-flops. */
774 def >>= move_cost / (2 * unit_move_rate(punit));
775 }
776 if (def > best_def) {
777 *aunit = buddy;
778 *acity = NULL;
779 best_def = def;
780 }
782
783 /* City bodyguard. TODO: allied city bodyguard? */
784 if (ai_fuzzy(pplayer, TRUE)
785 && NULL != pcity
786 && city_owner(pcity) == pplayer
787 && (data = def_ai_city_data(pcity, ait))
788 && 0 < data->urgency) {
789 if (NULL != best_data
790 && (0 < best_data->grave_danger
791 || best_data->urgency > data->urgency
792 || ((best_data->danger > data->danger
793 || AIUNIT_DEFEND_HOME == def_ai_unit_data(punit, ait)->task)
794 && 0 == data->grave_danger))) {
795 /* Chances are we'll be between cities when we are needed the most!
796 * Resuming pf_map_move_costs_iterate()... */
797 continue;
798 }
799 def = (data->danger - assess_defense_quadratic(ait, pcity));
800 if (def <= 0) {
801 continue;
802 }
803 /* Reduce want based on move cost. */
804 def >>= move_cost / (2 * unit_move_rate(punit));
805 if (def > best_def && ai_fuzzy(pplayer, TRUE)) {
806 *acity = pcity;
807 *aunit = NULL;
808 best_def = def;
809 best_data = data;
810 }
811 }
813
814 pf_map_destroy(pfm);
815
816 UNIT_LOG(LOGLEVEL_BODYGUARD, punit, "%s(), best_def=%d, type=%s (%d, %d)",
817 __FUNCTION__, best_def * 100 / toughness,
818 (NULL != *acity ? city_name_get(*acity)
819 : (NULL != *aunit ? unit_rule_name(*aunit) : "")),
820 (NULL != *acity ? index_to_map_pos_x(tile_index(city_tile(*acity)))
821 : (NULL != *aunit ?
822 index_to_map_pos_x(tile_index(unit_tile(*aunit))) : -1)),
823 (NULL != *acity ? index_to_map_pos_y(tile_index(city_tile(*acity)))
824 : (NULL != *aunit ?
825 index_to_map_pos_y(tile_index(unit_tile(*aunit))) : -1)));
826
827 return ((best_def * 100) / toughness);
828}
829
830/**********************************************************************/
834 const struct unit_type *followee,
835 struct ai_type *ait)
836{
837 struct unit_type_ai *utai = utype_ai_data(follower, ait);
838
840 if (pcharge == followee) {
841 return TRUE;
842 }
844
845 return FALSE;
846}
847
848/**********************************************************************/
851static void dai_military_findjob(struct ai_type *ait, const struct civ_map *nmap,
852 struct player *pplayer, struct unit *punit)
853{
854 const struct unit_type *punittype = unit_type_get(punit);
855 struct unit_ai *unit_data;
856
858
859 /* Keep barbarians aggressive and primitive */
860 if (is_barbarian(pplayer)) {
861 if (can_unit_do_activity(nmap, punit, ACTIVITY_PILLAGE)
862 && is_land_barbarian(pplayer)) {
863 /* Land barbarians pillage */
864 unit_activity_handling(punit, ACTIVITY_PILLAGE);
865 }
867
868 return;
869 }
870
871 unit_data = def_ai_unit_data(punit, ait);
872
873 /* If I am a bodyguard, check whether I can do my job. */
874 if (unit_data->task == AIUNIT_ESCORT
875 || unit_data->task == AIUNIT_DEFEND_HOME) {
877 }
878
879 if (aiguard_has_charge(ait, punit)
880 && unit_data->task == AIUNIT_ESCORT) {
881 struct unit *aunit = aiguard_charge_unit(ait, punit);
882 struct city *acity = aiguard_charge_city(ait, punit);
883 struct ai_city *city_data = NULL;
884
885 if (acity != NULL) {
886 city_data = def_ai_city_data(acity, ait);
887 }
888
889 /* Check if the city we are on our way to rescue is still in danger,
890 * or the unit we should protect is still alive... */
891 if ((aunit && (aiguard_has_guard(ait, aunit) || aiguard_wanted(ait, aunit))
893 || (acity && city_owner(acity) == unit_owner(punit)
894 && city_data->urgency != 0
895 && city_data->danger > assess_defense_quadratic(ait, acity))) {
896 return; /* Yep! */
897 } else {
898 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL); /* Nope! */
899 }
900 }
901
902 /* Is the unit badly damaged? */
903 if ((unit_data->task == AIUNIT_RECOVER
904 && punit->hp < punittype->hp)
905 || punit->hp < punittype->hp * 0.25) { /* WAG */
906 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "set to hp recovery");
908 return;
909 }
910
913 /* This is a defending unit that doesn't need to stay put.
914 * It needs to defend something, but not necessarily where it's at.
915 * Therefore, it will consider becoming a bodyguard. -- Syela */
916 struct city *acity;
917 struct unit *aunit;
918
919 look_for_charge(ait, nmap, pplayer, punit, &aunit, &acity);
920 if (acity) {
922 aiguard_assign_guard_city(ait, acity, punit);
923 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "going to defend city");
924 } else if (aunit) {
926 aiguard_assign_guard_unit(ait, aunit, punit);
927 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "going to defend unit");
928 }
929 }
931}
932
933/**********************************************************************/
942static void dai_military_defend(struct ai_type *ait, struct player *pplayer,
943 struct unit *punit)
944{
945 struct city *pcity = aiguard_charge_city(ait, punit);
946
948
949 if (!pcity || city_owner(pcity) != pplayer) {
950 pcity = tile_city(unit_tile(punit));
951 /* Do not stay defending an allied city forever */
953 }
954
955 if (!pcity) {
956 /* Try to find a place to rest. Sitting duck out in the wilderness
957 * is generally a bad idea, since we protect no cities that way, and
958 * it looks silly. */
959 pcity = find_closest_city(unit_tile(punit), NULL, pplayer,
962 }
963
964 if (!pcity) {
966 }
967
970 /* ... we survived */
971 if (pcity) {
972 UNIT_LOG(LOG_DEBUG, punit, "go to defend %s", city_name_get(pcity));
973 if (same_pos(unit_tile(punit), pcity->tile)) {
974 UNIT_LOG(LOG_DEBUG, punit, "go defend successful");
976 } else {
977 (void) dai_gothere(ait, pplayer, punit, pcity->tile);
978 }
979 } else {
980 UNIT_LOG(LOG_VERBOSE, punit, "defending nothing...?");
981 }
982 }
983}
984
985/**********************************************************************/
988static void single_invader(struct ai_city *city_data,
989 const struct unit_type *utype,
990 int which)
991{
992 int attacks;
993
995 action_by_number(ACTION_ATTACK))) {
996 attacks = 1;
997 } else {
998 attacks = utype->move_rate;
999 }
1000 city_data->invasion.attack += attacks;
1001 if (which == INVASION_OCCUPY) {
1002 city_data->invasion.occupy++;
1003 }
1004}
1005
1006/**********************************************************************/
1016static void invasion_funct(struct ai_type *ait, struct unit *punit,
1017 bool dest, int radius, int which)
1018{
1019 struct tile *ptile;
1020 struct player *pplayer = unit_owner(punit);
1021
1023
1024 if (dest) {
1025 ptile = punit->goto_tile;
1026 } else {
1027 ptile = unit_tile(punit);
1028 }
1029
1030 square_iterate(&(wld.map), ptile, radius, tile1) {
1031 struct city *pcity = tile_city(tile1);
1032
1033 if (pcity
1034 && POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, city_owner(pcity))
1035 && (dest || !has_defense(pcity))) {
1036 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1037
1038 /* Unit itself */
1039 single_invader(city_data, unit_type_get(punit), which);
1040
1041 /* Cargo */
1042 unit_cargo_iterate(punit, cargo) {
1043 const struct unit_type *utype = unit_type_get(cargo);
1044
1045 if (IS_ATTACKER(utype)) {
1046 single_invader(city_data, utype,
1049 }
1051 }
1053}
1054
1055/**********************************************************************/
1058bool find_beachhead(const struct player *pplayer, struct pf_map *ferry_map,
1059 struct tile *dest_tile,
1060 const struct unit_type *cargo_type,
1061 struct tile **ferry_dest, struct tile **beachhead_tile)
1062{
1063 if (NULL == tile_city(dest_tile)
1064 || can_attack_from_non_native(cargo_type)) {
1065 /* Unit can directly go to 'dest_tile'. */
1066 struct tile *best_tile = NULL;
1067 int best_cost = PF_IMPOSSIBLE_MC, cost;
1068
1069 if (NULL != beachhead_tile) {
1070 *beachhead_tile = dest_tile;
1071 }
1072
1073 adjc_iterate(&(wld.map), dest_tile, ptile) {
1074 cost = pf_map_move_cost(ferry_map, ptile);
1075 if (cost != PF_IMPOSSIBLE_MC
1076 && (NULL == best_tile || cost < best_cost)) {
1077 best_tile = ptile;
1078 best_cost = cost;
1079 }
1081
1082 if (NULL != ferry_dest) {
1083 *ferry_dest = best_tile;
1084 }
1085
1086 return (PF_IMPOSSIBLE_MC != best_cost);
1087 } else {
1088 /* We need to find a beach around 'dest_tile'. */
1089 struct tile *best_tile = NULL, *best_beach = NULL;
1090 struct tile_list *checked_tiles = tile_list_new();
1091 int best_cost = PF_IMPOSSIBLE_MC, cost;
1092
1093 tile_list_append(checked_tiles, dest_tile);
1094 adjc_iterate(&(wld.map), dest_tile, beach) {
1095 if (is_native_tile(cargo_type, beach)) {
1096 /* Can land there. */
1097 adjc_iterate(&(wld.map), beach, ptile) {
1098 if (!tile_list_search(checked_tiles, ptile)
1099 && !is_non_allied_unit_tile(ptile, pplayer)) {
1100 tile_list_append(checked_tiles, ptile);
1101 cost = pf_map_move_cost(ferry_map, ptile);
1102 if (cost != PF_IMPOSSIBLE_MC
1103 && (NULL == best_tile || cost < best_cost)) {
1104 best_beach = beach;
1105 best_tile = ptile;
1106 best_cost = cost;
1107 }
1108 }
1110 }
1112
1113 tile_list_destroy(checked_tiles);
1114
1115 if (NULL != beachhead_tile) {
1116 *beachhead_tile = best_beach;
1117 }
1118 if (NULL != ferry_dest) {
1119 *ferry_dest = best_tile;
1120 }
1121 return (PF_IMPOSSIBLE_MC != best_cost);
1122 }
1123}
1124
1125/**********************************************************************/
1133adv_want find_something_to_kill(struct ai_type *ait, struct player *pplayer,
1134 struct unit *punit,
1135 struct tile **pdest_tile, struct pf_path **ppath,
1136 struct pf_map **pferrymap,
1137 struct unit **pferryboat,
1138 const struct unit_type **pboattype, int *pmove_time)
1139{
1140 const int attack_value = adv_unit_att_rating(punit); /* basic attack. */
1141 struct pf_parameter parameter;
1142 struct pf_map *punit_map, *ferry_map;
1143 struct pf_position pos;
1144 struct unit_class *punit_class = unit_class_get(punit);
1145 const struct unit_type *punit_type = unit_type_get(punit);
1146 struct tile *punit_tile = unit_tile(punit);
1147 /* Type of our boat (a future one if ferryboat == NULL). */
1148 const struct unit_type *boattype = NULL;
1149 struct unit *ferryboat = NULL;
1150 struct city *pcity;
1151 struct ai_city *acity_data;
1152 int bcost, bcost_bal; /* Build cost of the attacker (+adjustments). */
1153 bool handicap = has_handicap(pplayer, H_TARGETS);
1154 bool unhap = FALSE; /* Do we make unhappy citizen. */
1155 bool harbor = FALSE; /* Do we have access to sea? */
1156 bool go_by_boat; /* Whether we need a boat or not. */
1157 int vulnerability; /* Enemy defense rating. */
1158 adv_want benefit; /* Benefit from killing the target. */
1159 struct unit *pdefender; /* Enemy city defender. */
1160 int move_time; /* Turns needed to target. */
1161 int reserves;
1162 int attack; /* Our total attack value with reinforcements. */
1163 int victim_count; /* Number of enemies there. */
1164 int needferry; /* Cost of building a ferry boat. */
1165 /* This is a kluge, because if we don't set x and y with !punit->id,
1166 * p_a_w isn't called, and we end up not wanting ironclads and therefore
1167 * never learning steam engine, even though ironclads would be very
1168 * useful. -- Syela */
1169 adv_want bk = 0;
1170 adv_want want; /* Want (amortized) of the operaton. */
1171 adv_want best = 0; /* Best of all wants. */
1172 struct tile *goto_dest_tile = NULL;
1173 bool can_occupy;
1174 struct civ_map *nmap = &(wld.map);
1175
1176 /* Very preliminary checks. */
1177 *pdest_tile = punit_tile;
1178 if (NULL != pferrymap) {
1179 *pferrymap = NULL;
1180 }
1181 if (NULL != pferryboat) {
1182 *pferryboat = NULL;
1183 }
1184 if (NULL != pboattype) {
1185 *pboattype = NULL;
1186 }
1187 if (NULL != pmove_time) {
1188 *pmove_time = 0;
1189 }
1190 if (NULL != ppath) {
1191 *ppath = NULL;
1192 }
1193
1194 if (0 == attack_value) {
1195 /* A very poor attacker... probably low on HP. */
1196 return 0;
1197 }
1198
1200
1201
1202 /*** Part 1: Calculate targets ***/
1203
1204 /* This horrible piece of code attempts to calculate the attractiveness of
1205 * enemy cities as targets for our units, by checking how many units are
1206 * going towards it or are near it already. */
1207
1208 /* Reset enemy cities data. */
1209 players_iterate(aplayer) {
1210 /* See comment below in next usage of POTENTIALLY_HOSTILE_PLAYER. */
1211 if ((punit->id == 0 && !POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer))
1212 || (punit->id != 0 && !pplayers_at_war(pplayer, aplayer))) {
1213 continue;
1214 }
1215 city_list_iterate(aplayer->cities, acity) {
1216 struct ai_city *city_data = def_ai_city_data(acity, ait);
1217
1219 &city_data->attack,
1220 &city_data->bcost);
1221 city_data->invasion.attack = 0;
1222 city_data->invasion.occupy = 0;
1225
1226 /* Second, calculate in units on their way there, and mark targets for
1227 * invasion */
1228 unit_list_iterate(pplayer->units, aunit) {
1229 const struct unit_type *atype;
1230
1231 if (aunit == punit) {
1232 continue;
1233 }
1234
1235 atype = unit_type_get(aunit);
1236
1237 /* Dealing with invasion stuff */
1238 if (IS_ATTACKER(atype)) {
1239 if (aunit->activity == ACTIVITY_GOTO) {
1240 invasion_funct(ait, aunit, TRUE, 0,
1241 (unit_can_take_over(aunit)
1243 if ((pcity = tile_city(aunit->goto_tile))) {
1244 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1245
1246 city_data->attack += adv_unit_att_rating(aunit);
1247 city_data->bcost += unit_build_shield_cost_base(aunit);
1248 }
1249 }
1250 invasion_funct(ait, aunit, FALSE, unit_move_rate(aunit) / SINGLE_MOVE,
1251 (unit_can_take_over(aunit)
1253 } else if (def_ai_unit_data(aunit, ait)->passenger != 0
1254 && !same_pos(unit_tile(aunit), unit_tile(punit))) {
1255 /* It's a transport with reinforcements */
1256 if (aunit->activity == ACTIVITY_GOTO) {
1257 invasion_funct(ait, aunit, TRUE, 1, INVASION_OCCUPY);
1258 }
1259 invasion_funct(ait, aunit, FALSE, 2, INVASION_OCCUPY);
1260 }
1262 /* end horrible initialization subroutine */
1263
1264
1265 /*** Part 2: Now pick one target ***/
1266
1267 /* We first iterate through all cities, then all units, looking
1268 * for a viable target. We also try to gang up on the target
1269 * to avoid spreading out attacks too widely to be inefficient.
1270 */
1271
1272 pcity = tile_city(punit_tile);
1273 if (NULL != pcity && (0 == punit->id || pcity->id == punit->homecity)) {
1274 /* I would have thought unhappiness should be taken into account
1275 * irrespectfully the city in which it will surface... -- GB */
1276 unhap = dai_assess_military_unhappiness(nmap, pcity);
1277 }
1278
1280 bcost_bal = build_cost_balanced(punit_type);
1281
1282 pft_fill_unit_attack_param(&parameter, nmap, punit);
1283 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1284 punit_map = pf_map_new(&parameter);
1285
1286 if (MOVE_NONE == punit_class->adv.sea_move) {
1287 /* We need boat to move over sea. */
1288 ferryboat = unit_transport_get(punit);
1289
1290 /* First check if we can use the boat we are currently loaded to. */
1291 if (ferryboat == NULL || !is_boat_free(ait, ferryboat, punit, 0)) {
1292 /* No, we cannot control current boat */
1293 ferryboat = NULL;
1294 }
1295
1296 if (NULL == ferryboat) {
1297 /* Try to find new boat */
1298 ferryboat = player_unit_by_number(pplayer,
1299 aiferry_find_boat(ait, punit, 1, NULL));
1300 }
1301
1302 if (punit->id == 0 && is_terrain_class_near_tile(nmap, punit_tile, TC_OCEAN)) {
1303 harbor = TRUE;
1304 }
1305 }
1306
1307 if (NULL != ferryboat) {
1308 boattype = unit_type_get(ferryboat);
1309 pft_fill_unit_overlap_param(&parameter, nmap, ferryboat);
1310 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1311 ferry_map = pf_map_new(&parameter);
1312 } else {
1313 boattype = best_role_unit_for_player(pplayer, L_FERRYBOAT);
1314 if (NULL == boattype) {
1315 /* We pretend that we can have the simplest boat to stimulate tech. */
1316 boattype = get_role_unit(L_FERRYBOAT, 0);
1317 }
1318 if (NULL != boattype && harbor) {
1319 /* Let's simulate a boat at 'punit' position. */
1320 pft_fill_utype_overlap_param(&parameter, nmap, boattype,
1321 punit_tile, pplayer);
1322 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1323 ferry_map = pf_map_new(&parameter);
1324 } else {
1325 ferry_map = NULL;
1326 }
1327 }
1328
1329 can_occupy = unit_can_take_over(punit);
1330
1331 players_iterate(aplayer) {
1332 /* For the virtual unit case, which is when we are called to evaluate
1333 * which units to build, we want to calculate in danger and which
1334 * players we want to make war with in the future. We do _not_ want
1335 * to do this when actually making attacks. */
1336 if ((punit->id == 0 && !POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer))
1337 || (punit->id != 0 && !pplayers_at_war(pplayer, aplayer))) {
1338 continue; /* Not an enemy. */
1339 }
1340
1341 city_list_iterate(aplayer->cities, acity) {
1342 struct tile *atile = city_tile(acity);
1343
1344 if (!is_native_tile(punit_type, atile)
1345 && !can_attack_non_native(punit_type)) {
1346 /* Can't attack this city. It is on land. */
1347 continue;
1348 }
1349
1350 if (handicap && !map_is_known(atile, pplayer)) {
1351 /* Can't see it */
1352 continue;
1353 }
1354
1355 if (pf_map_position(punit_map, atile, &pos)) {
1356 go_by_boat = FALSE;
1357 move_time = pos.turn;
1358 } else if (NULL == ferry_map) {
1359 continue; /* Impossible to handle. */
1360 } else {
1361 struct tile *dest, *beach;
1362
1363 if (!find_beachhead(pplayer, ferry_map, atile, punit_type,
1364 &dest, &beach)) {
1365 continue; /* Impossible to go by boat. */
1366 }
1367 if (!pf_map_position(ferry_map, dest, &pos)) {
1368 fc_assert(pf_map_position(ferry_map, dest, &pos));
1369 continue;
1370 }
1371 move_time = pos.turn; /* Sailing time. */
1372 if (dest != beach) {
1373 move_time++; /* Land time. */
1374 }
1375 if (NULL != ferryboat && unit_tile(ferryboat) != punit_tile) {
1376 if (pf_map_position(punit_map, unit_tile(ferryboat), &pos)) {
1377 move_time += pos.turn; /* Time to reach the boat. */
1378 } else {
1379 continue; /* Cannot reach the boat. */
1380 }
1381 }
1382 go_by_boat = TRUE;
1383 }
1384
1385 if (can_unit_attack_tile(punit, NULL, city_tile(acity))
1386 && (pdefender = get_defender(nmap, punit, city_tile(acity)))) {
1387 vulnerability = unit_def_rating_squared(punit, pdefender);
1388 benefit = unit_build_shield_cost_base(pdefender);
1389 } else {
1390 pdefender = NULL;
1391 vulnerability = 0;
1392 benefit = 0;
1393 }
1394
1395 if (1 < move_time) {
1396 struct unit_type *def_type = dai_choose_defender_versus(acity, punit);
1397
1398 if (def_type) {
1400 punit_type, def_type, aplayer, atile, FALSE,
1401 city_production_unit_veteran_level(acity, def_type));
1402 if (v > vulnerability) {
1403 /* They can build a better defender! */
1404 vulnerability = v;
1405 benefit = utype_build_shield_cost(acity, NULL, def_type);
1406 }
1407 }
1408 }
1409
1410 acity_data = def_ai_city_data(acity, ait);
1411
1412 reserves = (acity_data->invasion.attack
1413 - unit_list_size(acity->tile->units));
1414
1415 if (punit->id == 0) {
1416 /* Real unit would add to reserves once built. */
1418 action_by_number(ACTION_ATTACK))) {
1419 reserves++;
1420 } else {
1421 reserves += punit_type->move_rate;
1422 }
1423 }
1424
1425 if (0 < reserves && (can_occupy
1426 || 0 < acity_data->invasion.occupy)) {
1427 /* There are units able to occupy the city after all defenders
1428 * are killed! */
1429 benefit += acity_data->worth * reserves / 5;
1430 }
1431
1432 attack = attack_value + acity_data->attack;
1433 attack *= attack;
1434 /* Avoiding handling upkeep aggregation this way -- Syela */
1435
1436 /* AI was not sending enough reinforcements to totally wipe out a city
1437 * and conquer it in one turn.
1438 * This variable enables total carnage. -- Syela */
1439 victim_count = unit_list_size(atile->units);
1440
1441 if (!can_occupy && NULL == pdefender) {
1442 /* Nothing there to bash and we can't occupy!
1443 * Not having this check caused warships yoyoing */
1444 want = 0;
1445 } else if (10 < move_time) {
1446 /* Too far! */
1447 want = 0;
1448 } else if (can_occupy && 0 == acity_data->invasion.occupy
1449 && (0 < acity_data->invasion.attack
1450 || victim_count == 0)) {
1451 /* Units able to occupy really needed there! */
1452 want = bcost * SHIELD_WEIGHTING;
1453 } else {
1454 want = kill_desire(benefit, attack, bcost + acity_data->bcost,
1455 vulnerability, victim_count + 1);
1456 }
1457 want -= move_time * (unhap ? SHIELD_WEIGHTING + 2 * TRADE_WEIGHTING
1459 /* Build_cost of ferry. */
1460 needferry = (go_by_boat && NULL == ferryboat
1461 ? utype_build_shield_cost(acity, NULL, boattype) : 0);
1462 /* FIXME: add time to build the ferry? */
1464 want, MAX(1, move_time),
1465 bcost_bal + needferry);
1466
1467 /* BEGIN STEAM-ENGINES-ARE-OUR-FRIENDS KLUGE. */
1468 if (0 >= want && 0 == punit->id && 0 >= best) {
1469 adv_want bk_e = military_amortize(pplayer,
1471 benefit * SHIELD_WEIGHTING,
1472 MAX(1, move_time),
1473 bcost_bal + needferry);
1474
1475 if (bk_e > bk) {
1476 *pdest_tile = atile;
1477 if (NULL != pferrymap) {
1478 *pferrymap = go_by_boat ? ferry_map : NULL;
1479 }
1480 if (NULL != pferryboat) {
1481 *pferryboat = go_by_boat ? ferryboat : NULL;
1482 }
1483 if (NULL != pboattype) {
1484 *pboattype = go_by_boat ? boattype : NULL;
1485 }
1486 if (NULL != pmove_time) {
1487 *pmove_time = move_time;
1488 }
1489 goto_dest_tile = (go_by_boat && NULL != ferryboat
1490 ? unit_tile(ferryboat) : atile);
1491 bk = bk_e;
1492 }
1493 }
1494 /* END STEAM-ENGINES KLUGE */
1495
1496 if (0 != punit->id
1497 && NULL != ferryboat
1498 && punit_class->adv.sea_move == MOVE_NONE) {
1500 "%s(): with boat %s@(%d, %d) -> %s@(%d, %d)"
1501 " (go_by_boat = %d, move_time = %d, want = " ADV_WANT_PRINTF
1502 ", best = " ADV_WANT_PRINTF ")",
1503 __FUNCTION__, unit_rule_name(ferryboat),
1504 TILE_XY(unit_tile(ferryboat)), city_name_get(acity),
1505 TILE_XY(atile), go_by_boat, move_time, want, best);
1506 }
1507
1508 if (want > best && ai_fuzzy(pplayer, TRUE)) {
1509 /* Yes, we like this target */
1510 best = want;
1511 *pdest_tile = atile;
1512 if (NULL != pferrymap) {
1513 *pferrymap = go_by_boat ? ferry_map : NULL;
1514 }
1515 if (NULL != pferryboat) {
1516 *pferryboat = go_by_boat ? ferryboat : NULL;
1517 }
1518 if (NULL != pboattype) {
1519 *pboattype = go_by_boat ? boattype : NULL;
1520 }
1521 if (NULL != pmove_time) {
1522 *pmove_time = move_time;
1523 }
1524 goto_dest_tile = (go_by_boat && NULL != ferryboat
1525 ? unit_tile(ferryboat) : atile);
1526 }
1528
1530 /* I'm not sure the following code is good but it seems to be adequate.
1531 * I am deliberately not adding ferryboat code to the unit_list_iterate.
1532 * -- Syela */
1533 unit_list_iterate(aplayer->units, aunit) {
1534 struct tile *atile = unit_tile(aunit);
1535
1536 if (NULL != tile_city(atile)) {
1537 /* already dealt with it. */
1538 continue;
1539 }
1540
1541 if (handicap && !map_is_known(atile, pplayer)) {
1542 /* Can't see the target. */
1543 continue;
1544 }
1545
1547 && 0 == punit->id) {
1548 /* We will not build units just to chase caravans and
1549 * ambassadors. */
1550 continue;
1551 }
1552
1553 /* We have to assume the attack is diplomatically ok.
1554 * We cannot use can_player_attack_tile, because we might not
1555 * be at war with aplayer yet */
1556 if (!can_unit_attack_tile(punit, NULL, atile)
1557 || aunit != get_defender(nmap, punit, atile)) {
1558 /* We cannot attack it, or it is not the main defender. */
1559 continue;
1560 }
1561
1562 if (!pf_map_position(punit_map, atile, &pos)) {
1563 /* Cannot reach it. */
1564 continue;
1565 }
1566
1567 vulnerability = unit_def_rating_squared(punit, aunit);
1568 benefit = unit_build_shield_cost_base(aunit);
1569
1570 move_time = pos.turn;
1571 if (10 < move_time) {
1572 /* Too far. */
1573 want = 0;
1574 } else {
1575 want = kill_desire(benefit, attack, bcost, vulnerability, 1);
1576 /* Take into account maintainance of the unit. */
1577 /* FIXME: Depends on the government. */
1578 want -= move_time * SHIELD_WEIGHTING;
1579 /* Take into account unhappiness
1580 * (costs 2 luxuries to compensate). */
1581 want -= (unhap ? 2 * move_time * TRADE_WEIGHTING : 0);
1582 }
1584 want, MAX(1, move_time), bcost_bal);
1585 if (want > best && ai_fuzzy(pplayer, TRUE)) {
1586 best = want;
1587 *pdest_tile = atile;
1588 if (NULL != pferrymap) {
1589 *pferrymap = NULL;
1590 }
1591 if (NULL != pferryboat) {
1592 *pferryboat = NULL;
1593 }
1594 if (NULL != pboattype) {
1595 *pboattype = NULL;
1596 }
1597 if (NULL != pmove_time) {
1598 *pmove_time = move_time;
1599 }
1600 goto_dest_tile = atile;
1601 }
1604
1605 if (NULL != ppath) {
1606 *ppath = (NULL != goto_dest_tile && goto_dest_tile != punit_tile
1607 ? pf_map_path(punit_map, goto_dest_tile) : NULL);
1608 }
1609
1610 pf_map_destroy(punit_map);
1611 if (NULL != ferry_map
1612 && (NULL == pferrymap || *pferrymap != ferry_map)) {
1613 pf_map_destroy(ferry_map);
1614 }
1615
1617
1618 return best;
1619}
1620
1621/**********************************************************************/
1630{
1631 struct pf_parameter parameter;
1632 struct pf_map *pfm;
1633 struct player *pplayer = unit_owner(punit);
1634 struct city *pcity, *best_city = NULL;
1635 int best = FC_INFINITY, cur;
1636 const struct civ_map *nmap = &(wld.map);
1637
1638 pft_fill_unit_parameter(&parameter, nmap, punit);
1639 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1640 pfm = pf_map_new(&parameter);
1641
1642 pf_map_move_costs_iterate(pfm, ptile, move_cost, TRUE) {
1643 if (move_cost > best) {
1644 /* We already found a better city. No need to continue. */
1645 break;
1646 }
1647
1648 pcity = tile_city(ptile);
1649 if (NULL == pcity || !pplayers_allied(pplayer, city_owner(pcity))) {
1650 continue;
1651 }
1652
1653 /* Score based on the move cost. */
1654 cur = move_cost;
1655
1656 /* Note the unit owner may be different from the city owner. */
1657 if (0 == get_unittype_bonus(unit_owner(punit), ptile,
1658 unit_type_get(punit), NULL,
1659 EFT_HP_REGEN)) {
1660 /* If we cannot regen fast our hit points here, let's make some
1661 * penalty. */
1662 cur *= 3;
1663 }
1664
1665 if (cur < best) {
1666 best_city = pcity;
1667 best = cur;
1668 }
1670
1671 pf_map_destroy(pfm);
1672 return best_city;
1673}
1674
1675/**********************************************************************/
1681 struct player *pplayer,
1682 struct unit *punit)
1683{
1684 struct city *pc;
1685 bool only_continent = TRUE;
1686
1687 if (unit_transported(punit)) {
1688 /* If we are in transport, we can go to any continent.
1689 * Actually, we are not currently in a continent where to stay. */
1690 only_continent = FALSE;
1691 }
1692
1693 if ((pc = find_closest_city(unit_tile(punit), NULL, pplayer, FALSE,
1694 only_continent, FALSE, FALSE, TRUE, NULL))) {
1696 UNIT_LOG(LOG_DEBUG, punit, "Barbarian heading to conquer %s",
1697 city_name_get(pc));
1698 (void) dai_gothere(ait, pplayer, punit, pc->tile);
1699 } else {
1700 struct unit *ferry = NULL;
1701
1702 if (unit_transported(punit)) {
1703 ferry = unit_transport_get(punit);
1704
1705 /* We already are in a boat so it needs no
1706 * free capacity */
1707 if (!is_boat_free(ait, ferry, punit, 0)) {
1708 /* We cannot control our ferry. */
1709 ferry = NULL;
1710 }
1711 } else {
1712 /* We are not in a boat yet. Search for one. */
1713 unit_list_iterate(unit_tile(punit)->units, aunit) {
1714 if (is_boat_free(ait, aunit, punit, 1)
1715 && unit_transport_load(punit, aunit, FALSE)) {
1716 ferry = aunit;
1717 break;
1718 }
1720 }
1721
1722 if (ferry) {
1723 UNIT_LOG(LOG_DEBUG, punit, "Barbarian sailing to conquer %s",
1724 city_name_get(pc));
1725 (void) aiferry_goto_amphibious(ait, ferry, punit, pc->tile);
1726 } else {
1727 /* This is not an error. Somebody else might be in charge
1728 * of the ferry. */
1729 UNIT_LOG(LOG_DEBUG, punit, "unable to find barbarian ferry");
1730 }
1731 }
1732 } else {
1733 UNIT_LOG(LOG_DEBUG, punit, "Barbarian find no target city");
1734 }
1735}
1736
1737/**********************************************************************/
1743static void dai_military_attack(struct ai_type *ait, struct player *pplayer,
1744 struct unit *punit)
1745{
1746 struct tile *dest_tile;
1747 int id = punit->id;
1748 int ct = 10;
1749 struct city *pcity = NULL;
1750
1752
1753 /* Barbarians pillage, and might keep on doing that so they sometimes
1754 * even finish it. */
1755 if (punit->activity == ACTIVITY_PILLAGE && is_barbarian(pplayer)
1756 && fc_rand(2) == 1) {
1757 return;
1758 }
1759
1760 /* First find easy nearby enemies, anything better than pillage goes.
1761 * NB: We do not need to repeat dai_military_rampage, it is repeats itself
1762 * until it runs out of targets. */
1763 /* FIXME: 1. dai_military_rampage never checks if it should defend newly
1764 * conquered cities.
1765 * FIXME: 2. would be more convenient if it returned FALSE if we run out
1766 * of moves too.*/
1768 return; /* we died */
1769 }
1770
1771 if (punit->moves_left <= 0) {
1772 return;
1773 }
1774
1775 /* Main attack loop */
1776 do {
1777 struct tile *start_tile = unit_tile(punit);
1778 struct pf_path *path;
1779 struct unit *ferryboat;
1780
1781 /* Then find enemies the hard way */
1782 find_something_to_kill(ait, pplayer, punit, &dest_tile, &path,
1783 NULL, &ferryboat, NULL, NULL);
1784 if (!same_pos(unit_tile(punit), dest_tile)) {
1785 if (!is_tiles_adjacent(unit_tile(punit), dest_tile)
1786 || !can_unit_attack_tile(punit, NULL, dest_tile)) {
1787
1788 /* Adjacent and can't attack usually means we are not marines
1789 * and on a ferry. This fixes the problem (usually). */
1790 UNIT_LOG(LOG_DEBUG, punit, "mil att gothere -> (%d, %d)",
1791 TILE_XY(dest_tile));
1792
1793 /* Set ACTIVITY_GOTO more permanently than just inside
1794 * adv_follow_path(). This way other units will know we're
1795 * on our way even if we don't reach target yet. */
1796 punit->goto_tile = dest_tile;
1797 unit_activity_handling(punit, ACTIVITY_GOTO);
1798 if (NULL != path && !adv_follow_path(punit, path, dest_tile)) {
1799 /* Died. */
1800 pf_path_destroy(path);
1801 return;
1802 }
1803 if (NULL != ferryboat) {
1804 /* Need a boat. */
1805 aiferry_gobyboat(ait, pplayer, punit, dest_tile, FALSE);
1806 pf_path_destroy(path);
1807 return;
1808 }
1809 if (0 >= punit->moves_left) {
1810 /* No moves left. */
1811 pf_path_destroy(path);
1812 return;
1813 }
1814
1815 /* Either we're adjacent or we sitting on the tile. We might be
1816 * sitting on the tile if the enemy that _was_ sitting there
1817 * attacked us and died _and_ we had enough movement to get there */
1818 if (same_pos(unit_tile(punit), dest_tile)) {
1819 UNIT_LOG(LOG_DEBUG, punit, "mil att made it -> (%d, %d)",
1820 TILE_XY(dest_tile));
1821 pf_path_destroy(path);
1822 break;
1823 }
1824 }
1825
1826 if (is_tiles_adjacent(unit_tile(punit), dest_tile)) {
1827 /* Close combat. fstk sometimes want us to attack an adjacent
1828 * enemy that rampage wouldn't */
1829 UNIT_LOG(LOG_DEBUG, punit, "mil att bash -> (%d, %d)",
1830 TILE_XY(dest_tile));
1831 if (!dai_unit_attack(ait, punit, dest_tile)) {
1832 /* Died */
1833 pf_path_destroy(path);
1834 return;
1835 }
1836 } else if (!same_pos(start_tile, unit_tile(punit))) {
1837 /* Got stuck. Possibly because of adjacency to an
1838 * enemy unit. Perhaps we are in luck and are now next to a
1839 * tempting target? Let's find out... */
1842 pf_path_destroy(path);
1843 return;
1844 }
1845
1846 } else {
1847 /* FIXME: This happens a bit too often! */
1848 UNIT_LOG(LOG_DEBUG, punit, "fstk didn't find us a worthy target!");
1849 /* No worthy enemies found, so abort loop */
1850 ct = 0;
1851 }
1852 pf_path_destroy(path);
1853
1854 ct--; /* infinite loops from railroads must be stopped */
1855 } while (punit->moves_left > 0 && ct > 0);
1856
1857 /* Cleanup phase */
1858 if (punit->moves_left == 0) {
1859 return;
1860 }
1862 if (pcity != NULL
1863 && (dai_is_ferry(punit, ait)
1864 || punit->hp < unit_type_get(punit)->hp * 0.50)) { /* WAG */
1865 /* Go somewhere safe */
1866 UNIT_LOG(LOG_DEBUG, punit, "heading to nearest safe house.");
1867 (void) dai_unit_goto(ait, punit, pcity->tile);
1868 } else if (!is_barbarian(pplayer)) {
1869 /* Nothing else to do, so try exploring. */
1870 switch (manage_auto_explorer(punit)) {
1871 case MR_DEATH:
1872 /* don't use punit! */
1873 return;
1874 case MR_OK:
1875 UNIT_LOG(LOG_DEBUG, punit, "nothing else to do, so exploring");
1876 break;
1877 default:
1878 UNIT_LOG(LOG_DEBUG, punit, "nothing to do - no more exploring either");
1879 break;
1880 };
1881 } else {
1882 /* You can still have some moves left here, but barbarians should
1883 not sit helplessly, but advance towards nearest known enemy city */
1884 UNIT_LOG(LOG_DEBUG, punit, "attack: barbarian");
1885 dai_military_attack_barbarian(ait, pplayer, punit);
1886 }
1887 if ((punit = game_unit_by_number(id)) && punit->moves_left > 0) {
1888 UNIT_LOG(LOG_DEBUG, punit, "attack: giving up unit to defense");
1889 dai_military_defend(ait, pplayer, punit);
1890 }
1891}
1892
1893/**********************************************************************/
1897static bool dai_find_boat_for_unit(struct ai_type *ait, struct unit *punit)
1898{
1899 bool alive = TRUE;
1900 int ferryboat = 0;
1901 struct pf_path *path_to_ferry = NULL;
1902
1903 UNIT_LOG(LOG_CARAVAN, punit, "requesting a boat!");
1904 ferryboat = aiferry_find_boat(ait, punit, 1, &path_to_ferry);
1905 /* going to meet the boat */
1906 if ((ferryboat <= 0)) {
1908 "in find_boat_for_unit cannot find any boats.");
1909 /* if we are undefended on the country side go to a city */
1910 struct city *current_city = tile_city(unit_tile(punit));
1911 if (current_city == NULL) {
1912 struct city *city_near = find_nearest_safe_city(punit);
1913 if (city_near != NULL) {
1914 alive = dai_unit_goto(ait, punit, city_near->tile);
1915 }
1916 }
1917 } else {
1918 if (path_to_ferry != NULL) {
1919 if (!adv_unit_execute_path(punit, path_to_ferry)) {
1920 /* Died. */
1921 pf_path_destroy(path_to_ferry);
1922 path_to_ferry = NULL;
1923 alive = FALSE;
1924 } else {
1925 pf_path_destroy(path_to_ferry);
1926 path_to_ferry = NULL;
1927 alive = TRUE;
1928 }
1929 }
1930 }
1931 return alive;
1932}
1933
1934/**********************************************************************/
1943 struct tile *ctile, struct tile *ptile)
1944{
1945 /* We usually have Inaccessible terrain, so not testing MOVE_FULL == */
1946 bool lm = MOVE_NONE != pclass->adv.land_move,
1947 sm = MOVE_NONE != pclass->adv.sea_move;
1948 struct civ_map *pmap = &(wld.map);
1949
1950 if (lm && sm) {
1951 return FALSE;
1952 }
1953
1954 /* We could use adjc_iterate() but likely often tiles are on the same
1955 * continent and it will be more time to find where they connect */
1956 iterate_outward(pmap, ctile, 1, atile) {
1957 Continent_id acont = tile_continent(atile);
1958
1959 if (is_ocean_tile(atile) ? sm : lm) {
1960 iterate_outward(pmap, ptile, 1, btile) {
1961 if (tile_continent(btile) == acont) {
1962 return FALSE;
1963 }
1965 }
1967
1968 if (is_tiles_adjacent(ctile, ptile)) {
1969 return FALSE;
1970 }
1971
1972 return TRUE;
1973}
1974
1975/**********************************************************************/
1981static void dai_caravan_goto(struct ai_type *ait, struct player *pplayer,
1982 struct unit *punit,
1983 const struct city *dest_city,
1984 bool help_wonder,
1985 bool required_boat, bool request_boat)
1986{
1987 bool alive = TRUE;
1988 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
1989 const struct civ_map *nmap = &(wld.map);
1990
1991 fc_assert_ret(NULL != dest_city);
1992
1993 /* if we're not there yet, and we can move, move... */
1994 if (!same_pos(dest_city->tile, unit_tile(punit))
1995 && punit->moves_left != 0) {
1996 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) task %s going to %s in %s %s",
1999 dai_unit_task_rule_name(unit_data->task),
2000 help_wonder ? "help a wonder" : "trade", city_name_get(dest_city),
2001 required_boat ? "with a boat" : "");
2002 if (required_boat) {
2003 /* to trade with boat */
2004 if (request_boat) {
2005 /* Try to find new boat */
2006 alive = dai_find_boat_for_unit(ait, punit);
2007 } else {
2008 /* if we are not being transported then ask for a boat again */
2009 alive = TRUE;
2012 unit_tile(punit), dest_city->tile)) {
2013 alive = dai_find_boat_for_unit(ait, punit);
2014 }
2015 }
2016 if (alive) {
2017 /* FIXME: sometimes we get FALSE here just because
2018 * a trireme that we've boarded can't go over an ocean. */
2019 alive = dai_gothere(ait, pplayer, punit, dest_city->tile);
2020 }
2021 } else {
2022 /* to trade without boat */
2023 alive = dai_unit_goto(ait, punit, dest_city->tile);
2024 }
2025 }
2026
2027 /* if moving didn't kill us, and we got to the destination, handle it. */
2028 if (alive && real_map_distance(dest_city->tile, unit_tile(punit)) <= 1) {
2029 /* release the boat! */
2030 if (unit_transported(punit)) {
2032 }
2033 if (help_wonder && is_action_enabled_unit_on_city(nmap, ACTION_HELP_WONDER,
2034 punit, dest_city)) {
2035 /*
2036 * We really don't want to just drop all caravans in immediately.
2037 * Instead, we want to aggregate enough caravans to build instantly.
2038 * -AJS, 990704
2039 */
2040 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) helps build wonder in %s",
2043 punit->id,
2045 city_name_get(dest_city));
2046 unit_do_action(pplayer, punit->id, dest_city->id,
2047 0, "", ACTION_HELP_WONDER);
2048 } else if (is_action_enabled_unit_on_city(nmap, ACTION_TRADE_ROUTE,
2049 punit, dest_city)) {
2050 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) creates trade route in %s",
2053 punit->id,
2055 city_name_get(dest_city));
2056 unit_do_action(pplayer, punit->id, dest_city->id,
2057 0, "", ACTION_TRADE_ROUTE);
2058 } else if (is_action_enabled_unit_on_city(nmap, ACTION_MARKETPLACE,
2059 punit, dest_city)) {
2060 /* Get the one time bonus. */
2061 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) enters marketplace of %s",
2064 punit->id,
2066 city_name_get(dest_city));
2067 unit_do_action(pplayer, punit->id, dest_city->id,
2068 0, "", ACTION_MARKETPLACE);
2069 } else {
2070 enum log_level level = LOG_NORMAL;
2071
2072 if (help_wonder) {
2073 /* A Caravan ordered to help build wonder may arrive after
2074 * enough shields to build the wonder is produced. */
2076 }
2077
2079 "%s %s[%d](%d,%d) unable to trade with %s",
2082 punit->id,
2084 city_name_get(dest_city));
2085 }
2086 }
2087}
2088
2089/**********************************************************************/
2093static void caravan_optimize_callback(const struct caravan_result *result,
2094 void *data)
2095{
2096 const struct unit *caravan = data;
2097
2098 log_base(LOG_CARAVAN3, "%s %s[%d](%d,%d) %s: %s %s worth %g",
2100 unit_rule_name(caravan),
2101 caravan->id,
2102 TILE_XY(unit_tile(caravan)),
2103 city_name_get(result->src),
2104 result->help_wonder ? "wonder in" : "trade to",
2105 city_name_get(result->dest),
2106 result->value);
2107}
2108
2109/**********************************************************************/
2113 struct unit *punit)
2114{
2115 struct tile *src = NULL, *dest = NULL, *src_home_city = NULL;
2116 struct city *phome_city = NULL;
2117 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2118
2119 if ((unit_data->task != AIUNIT_NONE)) {
2120 src = unit_tile(punit);
2121 phome_city = game_city_by_number(punit->homecity);
2122 if (phome_city != NULL) {
2123 src_home_city = city_tile(phome_city);
2124 }
2125 dest = punit->goto_tile;
2126
2127 if (src == NULL || dest == NULL) {
2128 return FALSE;
2129 }
2130
2131 /* If we have a home continent, and are not there.
2132 * (FIXME: well, why?)
2133 * (I guess because home continent is which we were supposed to leave,
2134 * not the target continent) */
2135 if (src_home_city != NULL
2136 && tile_continent(src) != tile_continent(src_home_city)) {
2137 return FALSE;
2138 }
2139
2140 if (!goto_is_sane(punit, dest)) {
2141 if (unit_transported(punit)) {
2142 /* if we're being transported */
2143 return FALSE;
2144 }
2145 if ((punit->server.birth_turn + 15 < game.info.turn)) {
2146 /* we are tired of waiting */
2147 int ferrys = aiferry_avail_boats(ait, punit->owner);
2148
2149 if (ferrys <= 0) {
2150 /* there are no ferrys available... give up */
2151 return TRUE;
2152 } else {
2153 if (punit->server.birth_turn + 20 < game.info.turn) {
2154 /* we are feed up! */
2155 return TRUE;
2156 }
2157 }
2158 }
2159 }
2160 }
2161
2162 return FALSE;
2163}
2164
2165/**********************************************************************/
2172 struct unit *punit)
2173{
2174 struct city *pcity = game_city_by_number(punit->homecity);
2175 Continent_id continent;
2176
2177 fc_assert(pcity != NULL);
2178
2179 if (unit_class_get(punit)->adv.ferry_types <= 0) {
2180 /* There is just no possible transporters. */
2181 return FALSE;
2182 }
2183 continent = tile_continent(pcity->tile);
2184
2185 /* Look for proper destination city at different continent. */
2186 city_list_iterate(pplayer->cities, acity) {
2187 if (can_cities_trade(pcity, acity)) {
2188 if (tile_continent(acity->tile) != continent) {
2189 return TRUE;
2190 }
2191 }
2193
2194 players_iterate(aplayer) {
2195 if (aplayer == pplayer || !aplayer->is_alive) {
2196 continue;
2197 }
2198 if (pplayers_allied(pplayer, aplayer)) {
2199 city_list_iterate(aplayer->cities, acity) {
2200 if (can_cities_trade(pcity, acity)) {
2201 if (tile_continent(acity->tile) != continent) {
2202 return TRUE;
2203 }
2204 }
2207 }
2208
2209 return FALSE;
2210}
2211
2212/**********************************************************************/
2216static bool search_homecity_for_caravan(struct ai_type *ait, struct unit *punit)
2217{
2218 struct city *nearest = NULL;
2219 int min_dist = FC_INFINITY;
2220 struct tile *current_loc = unit_tile(punit);
2221 Continent_id continent = tile_continent(current_loc);
2222 bool alive = TRUE;
2223
2225 struct tile *ctile = city_tile(pcity);
2226
2227 if (tile_continent(ctile) == continent) {
2228 int this_dist = map_distance(current_loc, ctile);
2229
2230 if (this_dist < min_dist) {
2231 min_dist = this_dist;
2232 nearest = pcity;
2233 }
2234 }
2236
2237 if (nearest != NULL) {
2238 alive = dai_unit_goto(ait, punit, nearest->tile);
2239 if (alive && same_pos(unit_tile(punit), nearest->tile)) {
2240 dai_unit_make_homecity(punit, nearest);
2241 }
2242 }
2243
2244 return alive;
2245}
2246
2247/**********************************************************************/
2253static void dai_manage_caravan(struct ai_type *ait, struct player *pplayer,
2254 struct unit *punit)
2255{
2256 struct caravan_parameter parameter;
2257 struct caravan_result result;
2258 const struct city *homecity;
2259 const struct city *dest = NULL;
2260 struct unit_ai *unit_data;
2261 struct unit_class *pclass = unit_class_get(punit);
2262 bool expect_boats = pclass->adv.ferry_types > 0;
2263 /* TODO: will pplayer have a boat for punit in a reasonable time? */
2264 bool help_wonder = FALSE;
2265 bool required_boat = FALSE;
2266 bool request_boat = FALSE;
2267 bool tired_of_waiting_boat = FALSE;
2268 const struct civ_map *nmap = &(wld.map);
2269
2271
2272 if (!unit_can_do_action(punit, ACTION_TRADE_ROUTE)
2273 && !unit_can_do_action(punit, ACTION_MARKETPLACE)
2274 && !unit_can_do_action(punit, ACTION_HELP_WONDER)) {
2275 /* we only want units that can establish trade, enter marketplace or
2276 * help build wonders */
2277 return;
2278 }
2279
2280 unit_data = def_ai_unit_data(punit, ait);
2281
2282 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d) task %s to (%d,%d)",
2285 dai_unit_task_rule_name(unit_data->task),
2287
2288 homecity = game_city_by_number(punit->homecity);
2289 if (homecity == NULL && unit_data->task == AIUNIT_TRADE) {
2291 return;
2292 }
2293 homecity = game_city_by_number(punit->homecity);
2294 if (homecity == NULL) {
2295 return;
2296 }
2297 }
2298
2299 if ((unit_data->task == AIUNIT_TRADE
2300 || unit_data->task == AIUNIT_WONDER)) {
2301 /* we are moving to our destination */
2302 /* we check to see if our current goal is feasible */
2303 struct city *city_dest = tile_city(punit->goto_tile);
2304
2305 if ((city_dest == NULL)
2306 || !pplayers_allied(unit_owner(punit), city_dest->owner)
2307 || (unit_data->task == AIUNIT_TRADE
2308 && !(can_cities_trade(homecity, city_dest)
2309 && can_establish_trade_route(homecity, city_dest)))
2310 || (unit_data->task == AIUNIT_WONDER
2311 /* Helping the (new) production is illegal. */
2313 || (unit_data->task == AIUNIT_TRADE
2314 && real_map_distance(city_dest->tile, unit_tile(punit)) <= 1
2315 && !(is_action_enabled_unit_on_city(nmap, ACTION_TRADE_ROUTE,
2316 punit, city_dest)
2317 || is_action_enabled_unit_on_city(nmap, ACTION_MARKETPLACE,
2318 punit, city_dest)))
2319 || (unit_data->task == AIUNIT_WONDER
2320 && real_map_distance(city_dest->tile, unit_tile(punit)) <= 1
2321 && !is_action_enabled_unit_on_city(nmap, ACTION_HELP_WONDER,
2322 punit, city_dest))) {
2323 /* destination invalid! */
2324 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
2325 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d) destination invalid!",
2328 } else {
2329 /* destination valid, are we tired of waiting for a boat? */
2330 if (expect_boats && dai_is_unit_tired_waiting_boat(ait, punit)) {
2332 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
2333 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d) unit tired of waiting!",
2336 tired_of_waiting_boat = TRUE;
2337 } else {
2338 dest = city_dest;
2339 help_wonder = (unit_data->task == AIUNIT_WONDER) ? TRUE : FALSE;
2340 required_boat = uclass_need_trans_between(pclass, unit_tile(punit), dest->tile);
2341 request_boat = FALSE;
2342 }
2343 }
2344 }
2345
2346 if (unit_data->task == AIUNIT_NONE) {
2347 if (homecity == NULL) {
2348 /* FIXME: We shouldn't bother in getting homecity for
2349 * caravan that will then be used for wonder building. */
2351 return;
2352 }
2353 homecity = game_city_by_number(punit->homecity);
2354 if (homecity == NULL) {
2355 return;
2356 }
2357 }
2358
2360 /* Make more trade with allies than other peaceful nations
2361 * by considering only allies 50% of the time.
2362 * (the other 50% allies are still considered, but so are other nations) */
2363 if (fc_rand(2)) {
2364 /* Be optimistic about development of relations with no-contact and
2365 * cease-fire nations. */
2366 parameter.allow_foreign_trade = FTL_NONWAR;
2367 } else {
2368 parameter.allow_foreign_trade = FTL_ALLIED;
2369 }
2370
2373 parameter.callback_data = punit;
2374 }
2376 parameter.ignore_transit_time = TRUE;
2377 }
2378 if (tired_of_waiting_boat) {
2380 parameter.ignore_transit_time = FALSE;
2381 }
2382 caravan_find_best_destination(nmap, punit, &parameter, &result,
2383 !has_handicap(pplayer, H_MAP));
2384 if (result.dest != NULL) {
2385 /* We did find a new destination for the unit */
2386 dest = result.dest;
2387 help_wonder = result.help_wonder;
2388 required_boat = uclass_need_trans_between(pclass, unit_tile(punit), dest->tile);
2389 request_boat = required_boat;
2391 (help_wonder) ? AIUNIT_WONDER : AIUNIT_TRADE,
2392 dest->tile);
2393 } else {
2394 dest = NULL;
2395 }
2396 }
2397
2398 if (required_boat && !expect_boats) {
2399 /* Would require boat, but can't have them. Render destination invalid. */
2400 dest = NULL;
2401 }
2402
2403 if (dest != NULL) {
2404 dai_caravan_goto(ait, pplayer, punit, dest, help_wonder,
2405 required_boat, request_boat);
2406 return; /* that may have clobbered the unit */
2407 } else {
2408 /* We have nowhere to go! */
2409 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d), nothing to do!",
2413 /* Should we become a defensive unit? */
2414 }
2415}
2416
2417/**********************************************************************/
2422 struct unit *punit)
2423{
2424 struct player *pplayer = unit_owner(punit);
2425 struct city *pcity = tile_city(unit_tile(punit));
2426 struct city *safe = NULL;
2427 const struct unit_type *punittype = unit_type_get(punit);
2428 bool no_recovery;
2429
2431
2432 if (pcity != NULL) {
2433 /* Rest in the city until the hitpoints are recovered, but attempt
2434 * to protect city from attack (and be opportunistic too)*/
2437 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "recovering hit points.");
2438 } else {
2439 return; /* We died heroically defending our city */
2440 }
2441 } else {
2442 /* Goto to nearest city to recover hit points */
2443 /* Just before, check to see if we can occupy an undefended enemy city */
2446 return; /* Oops, we died */
2447 }
2448
2449 /* Find a city to stay and go there */
2451 if (safe) {
2452 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "going to %s to recover",
2453 city_name_get(safe));
2454 if (!dai_unit_goto(ait, punit, safe->tile)) {
2455 log_base(LOGLEVEL_RECOVERY, "died trying to hide and recover");
2456 return;
2457 }
2458 } else {
2459 /* Oops */
2460 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "didn't find a city to recover in!");
2461 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
2462 dai_military_attack(ait, pplayer, punit);
2463 return;
2464 }
2465 }
2466
2467 /* Is the unit still damaged? If true, and could recover hit points, do so.
2468 * Don't wait if would be losing hitpoints that way! */
2469 no_recovery = FALSE;
2470 if (punit->hp == punittype->hp) {
2471 no_recovery = TRUE;
2472 } else {
2473 int gain = unit_gain_hitpoints(punit);
2474
2475 if (gain < 0) {
2476 no_recovery = TRUE;
2477 } else if (gain == 0 && !punit->moved) {
2478 /* Isn't gaining even though has not moved. */
2479 no_recovery = TRUE;
2480 }
2481 }
2482 if (no_recovery) {
2483 /* We are ready to go out and kick ass again */
2484 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "ready to kick ass again!");
2485 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
2486 return;
2487 } else {
2488 def_ai_unit_data(punit, ait)->done = TRUE; /* Sit tight */
2489 }
2490}
2491
2492/**********************************************************************/
2496void dai_manage_military(struct ai_type *ait, const struct civ_map *nmap,
2497 struct player *pplayer, struct unit *punit)
2498{
2499 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2500 int id = punit->id;
2501
2503
2504 /* "Escorting" aircraft should not do anything. They are activated
2505 * by their transport or charge. We do _NOT_ set them to 'done'
2506 * since they may need be activated once our charge moves. */
2507 if (unit_data->task == AIUNIT_ESCORT
2509 return;
2510 }
2511
2512 if ((punit->activity == ACTIVITY_SENTRY
2513 || punit->activity == ACTIVITY_FORTIFIED)
2514 && has_handicap(pplayer, H_AWAY)) {
2515 /* Don't move sentried or fortified units controlled by a player
2516 * in away mode. */
2517 unit_data->done = TRUE;
2518 return;
2519 }
2520
2521 /* Since military units re-evaluate their actions every turn,
2522 we must make sure that previously reserved ferry is freed. */
2524
2526 /* Try hunting with this unit */
2527 if (dai_hunter_qualify(pplayer, punit)) {
2528 int result, sanity = punit->id;
2529
2530 UNIT_LOG(LOGLEVEL_HUNT, punit, "is qualified as hunter");
2531 result = dai_hunter_manage(ait, pplayer, punit);
2532 if (NULL == game_unit_by_number(sanity)) {
2534 return; /* died */
2535 }
2536 if (result == -1) {
2537 (void) dai_hunter_manage(ait, pplayer, punit); /* More carnage */
2539 return;
2540 } else if (result >= 1) {
2542 return; /* Done moving */
2543 } else if (unit_data->task == AIUNIT_HUNTER) {
2544 /* This should be very rare */
2545 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
2546 }
2547 } else if (unit_data->task == AIUNIT_HUNTER) {
2548 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
2549 }
2551
2552 /* Do we have a specific job for this unit? If not, we default
2553 * to attack. */
2554 dai_military_findjob(ait, nmap, pplayer, punit);
2555
2556 switch (unit_data->task) {
2558 case AIUNIT_BUILD_CITY:
2559 fc_assert(FALSE); /* This is not the place for this role */
2560 break;
2561 case AIUNIT_DEFEND_HOME:
2563 dai_military_defend(ait, pplayer, punit);
2565 break;
2566 case AIUNIT_ATTACK:
2567 case AIUNIT_NONE:
2569 dai_military_attack(ait, pplayer, punit);
2571 break;
2572 case AIUNIT_ESCORT:
2574 dai_military_bodyguard(ait, pplayer, punit);
2576 break;
2577 case AIUNIT_EXPLORE:
2578 switch (manage_auto_explorer(punit)) {
2579 case MR_DEATH:
2580 /* don't use punit! */
2581 return;
2582 case MR_OK:
2583 UNIT_LOG(LOG_DEBUG, punit, "more exploring");
2584 break;
2585 default:
2586 UNIT_LOG(LOG_DEBUG, punit, "no more exploring either");
2587 break;
2588 };
2589 def_ai_unit_data(punit, ait)->done = (punit->moves_left <= 0);
2590 break;
2591 case AIUNIT_RECOVER:
2595 break;
2596 case AIUNIT_HUNTER:
2597 fc_assert(FALSE); /* dealt with above */
2598 break;
2599 default:
2601 }
2602
2603 /* If we are still alive, either sentry or fortify. */
2604 if ((punit = game_unit_by_number(id))) {
2605 unit_data = def_ai_unit_data(punit, ait);
2606 struct city *pcity = tile_city(unit_tile(punit));
2607
2608 if (unit_list_find(unit_tile(punit)->units,
2609 unit_data->ferryboat)) {
2610 unit_activity_handling(punit, ACTIVITY_SENTRY);
2611 } else if (pcity || punit->activity == ACTIVITY_IDLE) {
2612 /* We do not need to fortify in cities - we fortify and sentry
2613 * according to home defense setup, for easy debugging. */
2614 if (!pcity || unit_data->task == AIUNIT_DEFEND_HOME) {
2615 if (punit->activity == ACTIVITY_IDLE
2616 || punit->activity == ACTIVITY_SENTRY) {
2617 unit_activity_handling(punit, ACTIVITY_FORTIFYING);
2618 }
2619 } else {
2620 unit_activity_handling(punit, ACTIVITY_SENTRY);
2621 }
2622 }
2623 }
2624}
2625
2626/**********************************************************************/
2629static void dai_manage_settler(struct ai_type *ait, struct player *pplayer,
2630 struct unit *punit)
2631{
2632 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2633
2634 unit_server_side_agent_set(pplayer, punit, SSA_AUTOSETTLER);
2635 unit_data->done = TRUE; /* we will manage this unit later... ugh */
2636 /* if BUILD_CITY must remain BUILD_CITY, otherwise turn into autosettler */
2637 if (unit_data->task == AIUNIT_NONE) {
2639 }
2640 return;
2641}
2642
2643/**********************************************************************/
2651void dai_manage_unit(struct ai_type *ait, struct player *pplayer,
2652 struct unit *punit)
2653{
2654 struct unit_ai *unit_data;
2655 struct unit *bodyguard = aiguard_guard_of(ait, punit);
2656 bool is_ferry = FALSE;
2657 const struct unit_type *ptype;
2658 const struct civ_map *nmap = &(wld.map);
2659
2661
2662 /* Don't manage the unit if it is under human orders. */
2663 if (unit_has_orders(punit)) {
2664 unit_data = def_ai_unit_data(punit, ait);
2665
2666 UNIT_LOG(LOG_VERBOSE, punit, "is under human orders, aborting AI control.");
2667 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
2668 unit_data->done = TRUE;
2669 return;
2670 }
2671
2672 /* Check if we have lost our bodyguard. If we never had one, all
2673 * fine. If we had one and lost it, ask for a new one. */
2674 if (!bodyguard && aiguard_has_guard(ait, punit)) {
2675 UNIT_LOG(LOGLEVEL_BODYGUARD, punit, "lost bodyguard, asking for new");
2677 }
2678
2679 unit_data = def_ai_unit_data(punit, ait);
2680
2681 if (punit->moves_left <= 0) {
2682 /* Can do nothing */
2683 unit_data->done = TRUE;
2684 return;
2685 }
2686
2687 is_ferry = dai_is_ferry(punit, ait);
2688
2689 ptype = unit_type_get(punit);
2690
2691 if (utype_has_flag(ptype, UTYF_DIPLOMAT)) {
2693 dai_manage_diplomat(ait, pplayer, punit);
2695 return;
2696 } else if (ptype->adv.worker
2698 dai_manage_settler(ait, pplayer, punit);
2699 return;
2700 } else if (unit_can_do_action(punit, ACTION_TRADE_ROUTE)
2701 || unit_can_do_action(punit, ACTION_MARKETPLACE)
2702 || unit_can_do_action(punit, ACTION_HELP_WONDER)) {
2704 dai_manage_caravan(ait, pplayer, punit);
2706 return;
2707 } else if (unit_has_type_role(punit, L_BARBARIAN_LEADER)) {
2708 dai_manage_barbarian_leader(ait, pplayer, punit);
2709 return;
2710 } else if (unit_can_do_action_result(punit, ACTRES_PARADROP)
2711 || unit_can_do_action_result(punit, ACTRES_PARADROP_CONQUER)) {
2712 dai_manage_paratrooper(ait, pplayer, punit);
2713 return;
2714 } else if (is_ferry && unit_data->task != AIUNIT_HUNTER) {
2716 dai_manage_ferryboat(ait, pplayer, punit);
2718 return;
2719 } else if (utype_fuel(ptype)
2720 && unit_data->task != AIUNIT_ESCORT) {
2722 dai_manage_airunit(ait, pplayer, punit);
2724 return;
2725 } else if (is_losing_hp(punit)) {
2726 /* This unit is losing hitpoints over time */
2727
2728 /* TODO: We can try using air-unit code for helicopters, just
2729 * pretend they have fuel = HP / 3 or something. */
2730 unit_data->done = TRUE; /* we did our best, which was ...
2731 nothing */
2732 return;
2733 } else if (is_military_unit(punit)) {
2735 UNIT_LOG(LOG_DEBUG, punit, "recruit unit for the military");
2736 dai_manage_military(ait, nmap, pplayer, punit);
2738 return;
2739 } else {
2740 /* what else could this be? -- Syela */
2741 switch (manage_auto_explorer(punit)) {
2742 case MR_DEATH:
2743 /* don't use punit! */
2744 break;
2745 case MR_OK:
2746 UNIT_LOG(LOG_DEBUG, punit, "now exploring");
2747 break;
2748 default:
2749 UNIT_LOG(LOG_DEBUG, punit, "fell through all unit tasks, defending");
2751 dai_military_defend(ait, pplayer, punit);
2752 break;
2753 };
2754 return;
2755 }
2756}
2757
2758/**********************************************************************/
2764static void dai_set_defenders(struct ai_type *ait, struct player *pplayer)
2765{
2766 city_list_iterate(pplayer->cities, pcity) {
2767 /* The idea here is that we should never keep more than two
2768 * units in permanent defense. */
2769 int total_defense = 0;
2770 int total_attack = def_ai_city_data(pcity, ait)->danger;
2771 bool emergency = FALSE;
2772 int count = 0;
2773 int mart_max = get_city_bonus(pcity, EFT_MARTIAL_LAW_MAX);
2774 int mart_each = get_city_bonus(pcity, EFT_MARTIAL_LAW_EACH);
2775 int martless_unhappy = pcity->feel[CITIZEN_UNHAPPY][FEELING_NATIONALITY]
2776 + pcity->feel[CITIZEN_ANGRY][FEELING_NATIONALITY];
2777 int entertainers = 0;
2778 bool enough = FALSE;
2779
2781 if (get_specialist_output(pcity, sp, O_LUXURY) > 0) {
2782 entertainers += pcity->specialists[sp];
2783 }
2785
2786 martless_unhappy += entertainers; /* We want to use martial law instead
2787 * of entertainers. */
2788
2789 while (!enough
2790 && (total_defense <= total_attack
2791 || (count < mart_max && mart_each > 0
2792 && martless_unhappy > mart_each * count))) {
2793 int best_want = 0;
2794 struct unit *best = NULL;
2795 bool defense_needed = total_defense <= total_attack; /* Defense or martial */
2796
2797 unit_list_iterate(pcity->tile->units, punit) {
2798 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2799
2800 if ((unit_data->task == AIUNIT_NONE || emergency)
2801 && unit_data->task != AIUNIT_DEFEND_HOME
2802 && unit_owner(punit) == pplayer) {
2803 int want = assess_defense_unit(ait, pcity, punit, FALSE);
2804
2805 if (want > best_want) {
2806 best_want = want;
2807 best = punit;
2808 }
2809 }
2811
2812 if (best == NULL) {
2813 if (defense_needed) {
2814 /* Ooops - try to grab any unit as defender! */
2815 if (emergency) {
2816 CITY_LOG(LOG_DEBUG, pcity, "Not defended properly");
2817 break;
2818 }
2819 emergency = TRUE;
2820 } else {
2821 break;
2822 }
2823 } else {
2824 const struct unit_type *btype = unit_type_get(best);
2825
2826 if ((martless_unhappy < mart_each * count
2827 || count >= mart_max || mart_each <= 0)
2828 && ((count >= 2
2829 && btype->attack_strength > btype->defense_strength)
2830 || (count >= 4
2831 && btype->attack_strength == btype->defense_strength))) {
2832 /* In this case attack would be better defense than fortifying
2833 * to city. */
2834 enough = TRUE;
2835 } else {
2836 int loglevel = pcity->server.debug ? LOG_AI_TEST : LOG_DEBUG;
2837
2838 total_defense += best_want;
2839 UNIT_LOG(loglevel, best, "Defending city");
2840 dai_unit_new_task(ait, best, AIUNIT_DEFEND_HOME, pcity->tile);
2841 count++;
2842 }
2843 }
2844 }
2845 CITY_LOG(LOG_DEBUG, pcity, "Evaluating defense: %d defense, %d incoming"
2846 ", %d defenders (out of %d)", total_defense, total_attack, count,
2847 unit_list_size(pcity->tile->units));
2849}
2850
2851/**********************************************************************/
2859void dai_manage_units(struct ai_type *ait, struct player *pplayer)
2860{
2862 dai_airlift(ait, pplayer);
2864
2865 /* Clear previous orders, if desirable, here. */
2866 unit_list_iterate(pplayer->units, punit) {
2867 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2868
2869 unit_data->done = FALSE;
2870 if (unit_data->task == AIUNIT_DEFEND_HOME) {
2871 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
2872 }
2874
2875 /* Find and set city defenders first - figure out which units are
2876 * allowed to leave home. */
2877 dai_set_defenders(ait, pplayer);
2878
2881 && !def_ai_unit_data(punit, ait)->done) {
2882 /* Though it is usually the passenger who drives the transport,
2883 * the transporter is responsible for managing its passengers. */
2884 dai_manage_unit(ait, pplayer, punit);
2885 }
2887}
2888
2889/**********************************************************************/
2894const struct impr_type *utype_needs_improvement(const struct unit_type *putype,
2895 const struct city *pcity)
2896{
2897 const struct impr_type *impr_req = NULL;
2898 const struct req_context context = {
2899 .player = city_owner(pcity),
2900 .city = pcity,
2901 .tile = city_tile(pcity),
2902 .unittype = putype,
2903 };
2904
2905 requirement_vector_iterate(&putype->build_reqs, preq) {
2906 if (is_req_active(&context, NULL, preq, RPT_CERTAIN)) {
2907 /* Already there. */
2908 continue;
2909 }
2911 city_owner(pcity), pcity)) {
2912 /* The unit type can't be built at all. */
2913 return NULL;
2914 }
2915 if (VUT_IMPROVEMENT == preq->source.kind && preq->present) {
2916 /* This is (one of) the building(s) required. */
2917 impr_req = preq->source.value.building;
2918 }
2920
2921 return impr_req;
2922}
2923
2924/**********************************************************************/
2928bool is_on_unit_upgrade_path(const struct unit_type *test,
2929 const struct unit_type *base)
2930{
2931 /* This is the real function: */
2932 do {
2933 base = base->obsoleted_by;
2934 if (base == test) {
2935 return TRUE;
2936 }
2937 } while (base);
2938 return FALSE;
2939}
2940
2941/**********************************************************************/
2946static void dai_manage_barbarian_leader(struct ai_type *ait,
2947 struct player *pplayer,
2948 struct unit *leader)
2949{
2950 struct tile *leader_tile = unit_tile(leader), *safest_tile;
2951 struct pf_parameter parameter;
2952 struct pf_map *pfm;
2953 struct pf_reverse_map *pfrm;
2954 struct unit *worst_danger;
2955 int move_cost, best_move_cost;
2956 int body_guards;
2957 bool alive = TRUE;
2958 const struct civ_map *nmap = &(wld.map);
2959
2960 CHECK_UNIT(leader);
2961
2962 if (leader->moves_left == 0
2963 || (can_unit_survive_at_tile(&(wld.map), leader, leader_tile)
2964 && 1 < unit_list_size(leader_tile->units))) {
2965 unit_activity_handling(leader, ACTIVITY_SENTRY);
2966
2967 return;
2968 }
2969
2970 if (is_boss_of_boat(ait, leader)) {
2971 /* We are in charge. Of course, since we are the leader...
2972 * But maybe somebody more militaristic should lead our ship to battle! */
2973
2974 /* First release boat from leaders lead */
2975 aiferry_clear_boat(ait, leader);
2976
2977 unit_list_iterate(leader_tile->units, warrior) {
2978 if (!unit_has_type_role(warrior, L_BARBARIAN_LEADER)
2979 && get_transporter_capacity(warrior) == 0
2980 && warrior->moves_left > 0) {
2981 /* This seems like a good warrior to lead us in to conquest! */
2982 dai_manage_unit(ait, pplayer, warrior);
2983
2984 /* If we reached our destination, ferryboat already called
2985 * ai_manage_unit() for leader. So no need to continue here.
2986 * Leader might even be dead.
2987 * If this return is removed, surronding unit_list_iterate()
2988 * has to be replaced with unit_list_iterate_safe()*/
2989 return;
2990 }
2992 }
2993
2994 /* If we are not in charge of the boat, continue as if we
2995 * were not in a boat - we may want to leave the ship now. */
2996
2997 /* Check the total number of units able to protect our leader. */
2998 body_guards = 0;
2999 unit_list_iterate(pplayer->units, punit) {
3000 if (!unit_has_type_role(punit, L_BARBARIAN_LEADER)
3001 && goto_is_sane(punit, leader_tile)) {
3002 body_guards++;
3003 }
3005
3006 if (0 < body_guards) {
3007 pft_fill_unit_parameter(&parameter, nmap, leader);
3008 parameter.omniscience = !has_handicap(pplayer, H_MAP);
3009 pfm = pf_map_new(&parameter);
3010
3011 /* Find the closest body guard.
3012 * FIXME: maybe choose the strongest too? */
3013 pf_map_tiles_iterate(pfm, ptile, FALSE) {
3014 unit_list_iterate(ptile->units, punit) {
3015 if (unit_owner(punit) == pplayer
3016 && !unit_has_type_role(punit, L_BARBARIAN_LEADER)
3017 && goto_is_sane(punit, leader_tile)) {
3018 struct pf_path *path = pf_map_path(pfm, ptile);
3019
3020 adv_follow_path(leader, path, ptile);
3021 pf_path_destroy(path);
3022 pf_map_destroy(pfm);
3023 return;
3024 }
3027
3028 pf_map_destroy(pfm);
3029 }
3030
3031 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader needs to flee");
3032
3033 /* Check for units we could fear. */
3034 pfrm = pf_reverse_map_new(nmap, pplayer, leader_tile, 3,
3035 !has_handicap(pplayer, H_MAP));
3036 worst_danger = NULL;
3037 best_move_cost = FC_INFINITY;
3038
3039 players_iterate(other_player) {
3040 if (other_player == pplayer) {
3041 continue;
3042 }
3043
3044 unit_list_iterate(other_player->units, punit) {
3045 move_cost = pf_reverse_map_unit_move_cost(pfrm, punit);
3046 if (PF_IMPOSSIBLE_MC != move_cost && move_cost < best_move_cost) {
3047 best_move_cost = move_cost;
3048 worst_danger = punit;
3049 }
3052
3054
3055 if (NULL == worst_danger) {
3056 unit_activity_handling(leader, ACTIVITY_IDLE);
3057 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader: no close enemy.");
3058 return;
3059 }
3060
3061 pft_fill_unit_parameter(&parameter, nmap, worst_danger);
3062 parameter.omniscience = !has_handicap(pplayer, H_MAP);
3063 pfm = pf_map_new(&parameter);
3064 best_move_cost = pf_map_move_cost(pfm, leader_tile);
3065
3066 /* Try to escape. */
3067 do {
3068 safest_tile = leader_tile;
3069
3070 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader: moves left: %d.",
3071 leader->moves_left);
3072
3073 adjc_iterate(&(wld.map), leader_tile, near_tile) {
3074 if (adv_could_unit_move_to_tile(leader, near_tile) != 1) {
3075 continue;
3076 }
3077
3078 move_cost = pf_map_move_cost(pfm, near_tile);
3079 if (PF_IMPOSSIBLE_MC != move_cost
3080 && move_cost > best_move_cost) {
3081 UNIT_LOG(LOG_DEBUG, leader,
3082 "Barbarian leader: safest is (%d, %d), safeness %d",
3083 TILE_XY(near_tile), best_move_cost);
3084 best_move_cost = move_cost;
3085 safest_tile = near_tile;
3086 }
3088
3089 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader: fleeing to (%d, %d).",
3090 TILE_XY(safest_tile));
3091 if (same_pos(unit_tile(leader), safest_tile)) {
3092 UNIT_LOG(LOG_DEBUG, leader,
3093 "Barbarian leader: reached the safest position.");
3094 unit_activity_handling(leader, ACTIVITY_IDLE);
3095 pf_map_destroy(pfm);
3096 return;
3097 }
3098
3099 alive = dai_unit_goto(ait, leader, safest_tile);
3100 if (alive) {
3101 if (same_pos(unit_tile(leader), leader_tile)) {
3102 /* Didn't move. No point to retry. */
3103 pf_map_destroy(pfm);
3104 return;
3105 }
3106 leader_tile = unit_tile(leader);
3107 }
3108 } while (alive && 0 < leader->moves_left);
3109
3110 pf_map_destroy(pfm);
3111}
3112
3113/**********************************************************************/
3119void dai_consider_tile_dangerous(struct ai_type *ait, struct tile *ptile,
3120 struct unit *punit,
3121 enum override_bool *result)
3122{
3123 int a = 0, d, db;
3124 struct player *pplayer = unit_owner(punit);
3125 struct city *pcity = tile_city(ptile);
3126 int extras_bonus = 0;
3127
3128 if (is_human(pplayer)) {
3129 /* Use advisors code for humans. */
3130 return;
3131 }
3132
3133 if (pcity && pplayers_allied(city_owner(pcity), unit_owner(punit))
3134 && !is_non_allied_unit_tile(ptile, pplayer)) {
3135 /* We will be safe in a friendly city */
3136 *result = OVERRIDE_FALSE;
3137 return;
3138 }
3139
3140 /* Calculate how well we can defend at (x,y) */
3141 db = 10 + tile_terrain(ptile)->defense_bonus / 10;
3142 extras_bonus += tile_extras_defense_bonus(ptile, unit_type_get(punit));
3143
3144 db += (db * extras_bonus) / 100;
3146
3147 adjc_iterate(&(wld.map), ptile, ptile1) {
3148 if (has_handicap(pplayer, H_FOG)
3149 && !map_is_known_and_seen(ptile1, unit_owner(punit), V_MAIN)) {
3150 /* We cannot see danger at (ptile1) => assume there is none */
3151 continue;
3152 }
3153 unit_list_iterate(ptile1->units, enemy) {
3155 && (unit_attack_unit_at_tile_result(enemy, NULL, punit, ptile)
3156 == ATT_OK)
3157 && (unit_attack_units_at_tile_result(enemy, NULL, ptile)
3158 == ATT_OK)) {
3159 a += adv_unit_att_rating(enemy);
3160 if ((a * a * 10) >= d) {
3161 /* The enemies combined strength is too big! */
3162 *result = OVERRIDE_TRUE;
3163 return;
3164 }
3165 }
3168
3169 *result = OVERRIDE_FALSE;
3170}
3171
3172/**********************************************************************/
3175static void update_simple_ai_types(void)
3176{
3177 int i = 0;
3178
3179 unit_type_iterate(punittype) {
3180 struct unit_class *pclass = utype_class(punittype);
3181
3182 if (A_NEVER != punittype->require_advance
3183 && !utype_has_flag(punittype, UTYF_CIVILIAN)
3184 && !utype_can_do_action(punittype, ACTION_SUICIDE_ATTACK)
3185 && !(pclass->adv.land_move == MOVE_NONE
3186 && !can_attack_non_native(punittype))
3187 && !utype_fuel(punittype)
3188 && punittype->transport_capacity < 8) {
3189 simple_ai_types[i] = punittype;
3190 i++;
3191 }
3193
3194 simple_ai_types[i] = NULL;
3195}
3196
3197/**********************************************************************/
3201{
3202 /* TODO: remove the simple_ai_types cache or merge it with a general ai
3203 * cache; see the comment to struct unit_type *simple_ai_types at
3204 * the beginning of this file. */
3206
3207 unit_type_iterate(ptype) {
3208 struct unit_type_ai *utai = fc_malloc(sizeof(*utai));
3209
3210 utai->low_firepower = FALSE;
3211 utai->ferry = FALSE;
3212 utai->missile_platform = FALSE;
3213 utai->carries_occupiers = FALSE;
3214 utai->potential_charges = unit_type_list_new();
3215
3216 utype_set_ai_data(ptype, ait, utai);
3218
3219 unit_type_iterate(punittype) {
3220 struct unit_class *pclass = utype_class(punittype);
3221
3222 /* Confirm firepower */
3223 combat_bonus_list_iterate(punittype->bonuses, pbonus) {
3224 if (pbonus->type == CBONUS_LOW_FIREPOWER) {
3225 unit_type_iterate(penemy) {
3226 if (utype_has_flag(penemy, pbonus->flag)) {
3227 struct unit_type_ai *utai = utype_ai_data(penemy, ait);
3228
3229 utai->low_firepower = TRUE;
3230 }
3232 }
3234
3235 /* Consider potential cargo */
3236 if (punittype->transport_capacity > 0) {
3237 struct unit_type_ai *utai = utype_ai_data(punittype, ait);
3238
3239 unit_type_iterate(pctype) {
3240 struct unit_class *pcargo = utype_class(pctype);
3241
3242 if (can_unit_type_transport(punittype, pcargo)) {
3243 if (utype_can_do_action(pctype, ACTION_SUICIDE_ATTACK)) {
3244 utai->missile_platform = TRUE;
3245 } else if (pclass->adv.sea_move != MOVE_NONE
3246 && pcargo->adv.land_move != MOVE_NONE) {
3247 if (pcargo->adv.sea_move != MOVE_FULL) {
3248 utai->ferry = TRUE;
3249 } else {
3250 if (0 != utype_fuel(pctype)) {
3251 utai->ferry = TRUE;
3252 }
3253 }
3254 }
3255
3256 if (utype_can_take_over(pctype)) {
3257 utai->carries_occupiers = TRUE;
3258 }
3259 }
3261 }
3262
3263 /* Consider potential charges */
3264 unit_type_iterate(pcharge) {
3265 bool can_move_like_charge = FALSE;
3266
3267 if (0 < utype_fuel(punittype)
3268 && (0 == utype_fuel(pcharge)
3269 || utype_fuel(pcharge) > utype_fuel(punittype))) {
3270 continue;
3271 }
3272
3274 if (chgcls == utype_class(pcharge)) {
3275 can_move_like_charge = TRUE;
3276 }
3278
3279 if (can_move_like_charge) {
3280 struct unit_type_ai *utai = utype_ai_data(punittype, ait);
3281 unit_type_list_append(utai->potential_charges, pcharge);
3282 }
3283
3286}
3287
3288/**********************************************************************/
3292{
3293 unit_type_iterate(ptype) {
3294 struct unit_type_ai *utai = utype_ai_data(ptype, ait);
3295
3296 if (utai == NULL) {
3297 continue;
3298 }
3299 utype_set_ai_data(ptype, ait, NULL);
3300
3301 unit_type_list_destroy(utai->potential_charges);
3302 free(utai);
3304}
3305
3306/**********************************************************************/
3309void dai_unit_init(struct ai_type *ait, struct unit *punit)
3310{
3311 /* Make sure that contents of unit_ai structure are correctly initialized,
3312 * if you ever allocate it by some other mean than fc_calloc() */
3313 struct unit_ai *unit_data = fc_calloc(1, sizeof(struct unit_ai));
3314
3315 unit_data->done = FALSE;
3316 unit_data->cur_pos = NULL;
3317 unit_data->prev_pos = NULL;
3318 unit_data->target = 0;
3319 BV_CLR_ALL(unit_data->hunted);
3320 unit_data->ferryboat = 0;
3321 unit_data->passenger = 0;
3322 unit_data->bodyguard = 0;
3323 unit_data->charge = 0;
3324
3325 unit_set_ai_data(punit, ait, unit_data);
3326}
3327
3328/**********************************************************************/
3331void dai_unit_turn_end(struct ai_type *ait, struct unit *punit)
3332{
3333 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3334
3335 fc_assert_ret(unit_data != NULL);
3336
3337 BV_CLR_ALL(unit_data->hunted);
3338}
3339
3340/**********************************************************************/
3343void dai_unit_close(struct ai_type *ait, struct unit *punit)
3344{
3345 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3346
3347 fc_assert_ret(unit_data != NULL);
3348
3351
3352 if (unit_data != NULL) {
3353 unit_set_ai_data(punit, ait, NULL);
3354 FC_FREE(unit_data);
3355 }
3356}
3357
3358/**********************************************************************/
3361void dai_unit_save(struct ai_type *ait, const char *aitstr,
3362 struct section_file *file,
3363 const struct unit *punit, const char *unitstr)
3364{
3365 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3366
3367 secfile_insert_int(file, unit_data->passenger, "%s.%spassenger",
3368 unitstr, aitstr);
3369 secfile_insert_int(file, unit_data->ferryboat, "%s.%sferryboat",
3370 unitstr, aitstr);
3371 secfile_insert_int(file, unit_data->charge, "%s.%scharge",
3372 unitstr, aitstr);
3373 secfile_insert_int(file, unit_data->bodyguard, "%s.%sbodyguard",
3374 unitstr, aitstr);
3375}
3376
3377/**********************************************************************/
3380void dai_unit_load(struct ai_type *ait, const char *aitstr,
3381 const struct section_file *file,
3382 struct unit *punit, const char *unitstr)
3383{
3384 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3385
3386 unit_data->passenger
3387 = secfile_lookup_int_default(file, 0, "%s.%spassenger",
3388 unitstr, aitstr);
3389 unit_data->ferryboat
3390 = secfile_lookup_int_default(file, 0, "%s.%sferryboat",
3391 unitstr, aitstr);
3392 unit_data->charge
3393 = secfile_lookup_int_default(file, 0, "%s.%scharge",
3394 unitstr, aitstr);
3395 unit_data->bodyguard
3396 = secfile_lookup_int_default(file, 0, "%s.%sbodyguard",
3397 unitstr, aitstr);
3398}
3399
3401{
3402 enum terrain_class tc;
3404};
3405
3406/**********************************************************************/
3409static bool role_unit_cb(struct unit_type *ptype, void *data)
3410{
3411 struct role_unit_cb_data *cb_data = (struct role_unit_cb_data *)data;
3412 struct unit_class *pclass = utype_class(ptype);
3413 const struct civ_map *nmap = &(wld.map);
3414
3415 if ((cb_data->tc == TC_LAND && pclass->adv.land_move == MOVE_NONE)
3416 || (cb_data->tc == TC_OCEAN && pclass->adv.sea_move == MOVE_NONE)) {
3417 return FALSE;
3418 }
3419
3420 if (cb_data->build_city == NULL
3421 || can_city_build_unit_now(nmap, cb_data->build_city, ptype)) {
3422 return TRUE;
3423 }
3424
3425 return FALSE;
3426}
3427
3428/**********************************************************************/
3431struct unit_type *dai_role_utype_for_terrain_class(struct city *pcity, int role,
3432 enum terrain_class tc)
3433{
3434 struct role_unit_cb_data cb_data = { .build_city = pcity, .tc = tc };
3435
3436 return role_units_iterate_backwards(role, role_unit_cb, &cb_data);
3437}
3438
3439/**********************************************************************/
3442bool dai_unit_can_strike_my_unit(const struct unit *attacker,
3443 const struct unit *defender)
3444{
3445 struct pf_parameter parameter;
3446 struct pf_map *pfm;
3447 const struct tile *ptarget = unit_tile(defender);
3448 int max_move_cost = attacker->moves_left;
3449 bool able_to_strike = FALSE;
3450 const struct civ_map *nmap = &(wld.map);
3451
3452 pft_fill_unit_parameter(&parameter, nmap, attacker);
3453 parameter.omniscience = !has_handicap(unit_owner(defender), H_MAP);
3454 pfm = pf_map_new(&parameter);
3455
3456 pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
3457 if (move_cost > max_move_cost) {
3458 break;
3459 }
3460
3461 if (ptile == ptarget) {
3462 able_to_strike = TRUE;
3463 break;
3464 }
3466
3467 pf_map_destroy(pfm);
3468
3469 return able_to_strike;
3470}
3471
3472/**********************************************************************/
3475void dai_switch_to_explore(struct ai_type *ait, struct unit *punit,
3476 struct tile *target, enum override_bool *allow)
3477{
3478 struct unit_ai *udata = def_ai_unit_data(punit, ait);
3479
3480 if (udata->task != AIUNIT_NONE && udata->task != AIUNIT_EXPLORE) {
3481 *allow = OVERRIDE_FALSE;
3482
3483 return;
3484 }
3485}
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:4755
static struct action * action_by_number(action_id act_id)
Definition actions.h:638
#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:404
int adv_unit_def_rating_basic(const struct unit *punit)
Definition advgoto.c:395
int adv_unittype_att_rating(const struct unit_type *punittype, int veteran, int moves_left, int hp)
Definition advgoto.c:374
int adv_unit_att_rating(const struct unit *punit)
Definition advgoto.c:385
int adv_could_unit_move_to_tile(struct unit *punit, struct tile *dest_tile)
Definition advgoto.c:348
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:488
void dai_manage_diplomat(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aidiplomat.c:721
bool aiferry_gobyboat(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct tile *dest_tile, bool with_bodyguard)
Definition aiferry.c:766
int aiferry_find_boat(struct ai_type *ait, struct unit *punit, int cap, struct pf_path **path)
Definition aiferry.c:497
void dai_manage_ferryboat(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aiferry.c:1111
bool is_boat_free(struct ai_type *ait, struct unit *boat, struct unit *punit, int cap)
Definition aiferry.c:440
bool aiferry_goto_amphibious(struct ai_type *ait, struct unit *ferry, struct unit *passenger, struct tile *ptile)
Definition aiferry.c:732
bool is_boss_of_boat(struct ai_type *ait, struct unit *punit)
Definition aiferry.c:473
int aiferry_avail_boats(struct ai_type *ait, struct player *pplayer)
Definition aiferry.c:355
bool dai_is_ferry(struct unit *pferry, struct ai_type *ait)
Definition aiferry.c:161
void aiferry_clear_boat(struct ai_type *ait, struct unit *punit)
Definition aiferry.c:253
struct city * aiguard_charge_city(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:290
void aiguard_clear_charge(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:118
void aiguard_request_guard(struct ai_type *ait, struct unit *punit)
Definition aiguard.c:228
bool aiguard_has_guard(struct ai_type *ait, struct unit *charge)
Definition aiguard.c:260
void aiguard_assign_guard_unit(struct ai_type *ait, struct unit *charge, struct unit *guard)
Definition aiguard.c:174
bool aiguard_wanted(struct ai_type *ait, struct unit *charge)
Definition aiguard.c:242
void aiguard_assign_guard_city(struct ai_type *ait, struct city *charge, struct unit *guard)
Definition aiguard.c:197
struct unit * aiguard_charge_unit(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:280
void aiguard_clear_guard(struct ai_type *ait, struct unit *charge)
Definition aiguard.c:147
struct unit * aiguard_guard_of(struct ai_type *ait, struct unit *charge)
Definition aiguard.c:270
bool aiguard_has_charge(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:251
void aiguard_update_charge(struct ai_type *ait, struct unit *guard)
Definition aiguard.c:300
#define CHECK_GUARD(ait, guard)
Definition aiguard.h:21
bool dai_hunter_qualify(struct player *pplayer, struct unit *punit)
Definition aihunt.c:291
int dai_hunter_manage(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aihunt.c:439
#define BODYGUARD_LOG(ait, loglevel, punit, msg,...)
Definition ailog.h:69
void dai_manage_paratrooper(struct ai_type *ait, struct player *pplayer, struct unit *punit)
static struct ai_city * def_ai_city_data(const struct city *pcity, struct ai_type *deftype)
Definition aiplayer.h:42
static struct unit_ai * def_ai_unit_data(const struct unit *punit, struct ai_type *deftype)
Definition aiplayer.h:48
int stack_cost(struct unit *pattacker, struct unit *pdefender)
Definition aitools.c:1264
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:1399
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
void dai_unit_save(struct ai_type *ait, const char *aitstr, struct section_file *file, const struct unit *punit, const char *unitstr)
Definition aiunit.c:3361
static void dai_military_findjob(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct unit *punit)
Definition aiunit.c:851
static bool has_defense(struct city *pcity)
Definition aiunit.c:221
adv_want kill_desire(adv_want benefit, int attack, int loss, int vuln, int victim_count)
Definition aiunit.c:341
static bool search_homecity_for_caravan(struct ai_type *ait, struct unit *punit)
Definition aiunit.c:2216
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 aiunit.c:1981
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 aiunit.c:303
static bool unit_role_defender(const struct unit_type *punittype)
Definition aiunit.c:699
void dai_units_ruleset_init(struct ai_type *ait)
Definition aiunit.c:3200
#define LOG_CARAVAN
Definition aiunit.c:87
static int unit_att_rating_now(const struct unit *punit)
Definition aiunit.c:258
static void dai_military_attack_barbarian(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aiunit.c:1680
static void invasion_funct(struct ai_type *ait, struct unit *punit, bool dest, int radius, int which)
Definition aiunit.c:1016
static void update_simple_ai_types(void)
Definition aiunit.c:3175
const struct impr_type * utype_needs_improvement(const struct unit_type *putype, const struct city *pcity)
Definition aiunit.c:2894
void dai_switch_to_explore(struct ai_type *ait, struct unit *punit, struct tile *target, enum override_bool *allow)
Definition aiunit.c:3475
void dai_manage_military(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct unit *punit)
Definition aiunit.c:2496
static bool dai_find_boat_for_unit(struct ai_type *ait, struct unit *punit)
Definition aiunit.c:1897
static void reinforcements_cost_and_value(struct unit *punit, struct tile *ptile0, int *value, int *cost)
Definition aiunit.c:374
struct unit_type * simple_ai_types[U_LAST]
Definition aiunit.c:125
static void dai_airlift(struct ai_type *ait, struct player *pplayer)
Definition aiunit.c:168
int build_cost_balanced(const struct unit_type *punittype)
Definition aiunit.c:249
bool dai_unit_can_strike_my_unit(const struct unit *attacker, const struct unit *defender)
Definition aiunit.c:3442
bool is_on_unit_upgrade_path(const struct unit_type *test, const struct unit_type *base)
Definition aiunit.c:2928
static void dai_military_bodyguard(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aiunit.c:633
static void single_invader(struct ai_city *city_data, const struct unit_type *utype, int which)
Definition aiunit.c:988
#define LOG_CARAVAN3
Definition aiunit.c:89
void dai_manage_units(struct ai_type *ait, struct player *pplayer)
Definition aiunit.c:2859
static void dai_manage_caravan(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aiunit.c:2253
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 aiunit.c:1133
static void dai_set_defenders(struct ai_type *ait, struct player *pplayer)
Definition aiunit.c:2764
void dai_manage_unit(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aiunit.c:2651
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 aiunit.c:714
static bool role_unit_cb(struct unit_type *ptype, void *data)
Definition aiunit.c:3409
static void dai_military_attack(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aiunit.c:1743
void dai_unit_turn_end(struct ai_type *ait, struct unit *punit)
Definition aiunit.c:3331
static void dai_manage_settler(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aiunit.c:2629
static int avg_benefit(int benefit, int loss, double chance)
Definition aiunit.c:365
#define LOG_CARAVAN2
Definition aiunit.c:88
static struct city * find_neediest_airlift_city(struct ai_type *ait, const struct player *pplayer)
Definition aiunit.c:137
static int unit_def_rating(const struct unit *attacker, const struct unit *defender)
Definition aiunit.c:277
static bool dai_is_unit_tired_waiting_boat(struct ai_type *ait, struct unit *punit)
Definition aiunit.c:2112
static int dai_rampage_want(struct unit *punit, struct tile *ptile)
Definition aiunit.c:456
bool dai_can_unit_type_follow_unit_type(const struct unit_type *follower, const struct unit_type *followee, struct ai_type *ait)
Definition aiunit.c:833
struct city * find_nearest_safe_city(struct unit *punit)
Definition aiunit.c:1629
static void dai_manage_barbarian_leader(struct ai_type *ait, struct player *pplayer, struct unit *leader)
Definition aiunit.c:2946
static void dai_manage_hitpoint_recovery(struct ai_type *ait, struct unit *punit)
Definition aiunit.c:2421
static int unit_att_rating_squared(const struct unit *punit)
Definition aiunit.c:267
static struct pf_path * find_rampage_target(struct unit *punit, int thresh_adj, int thresh_move)
Definition aiunit.c:521
static bool is_my_turn(struct unit *punit, struct unit *pdef)
Definition aiunit.c:399
static int unit_def_rating_squared(const struct unit *punit, const struct unit *pdef)
Definition aiunit.c:290
void dai_unit_init(struct ai_type *ait, struct unit *punit)
Definition aiunit.c:3309
void dai_consider_tile_dangerous(struct ai_type *ait, struct tile *ptile, struct unit *punit, enum override_bool *result)
Definition aiunit.c:3119
bool uclass_need_trans_between(struct unit_class *pclass, struct tile *ctile, struct tile *ptile)
Definition aiunit.c:1942
void dai_unit_load(struct ai_type *ait, const char *aitstr, const struct section_file *file, struct unit *punit, const char *unitstr)
Definition aiunit.c:3380
static void caravan_optimize_callback(const struct caravan_result *result, void *data)
Definition aiunit.c:2093
#define LOGLEVEL_RECOVERY
Definition aiunit.c:86
void dai_unit_close(struct ai_type *ait, struct unit *punit)
Definition aiunit.c:3343
void dai_units_ruleset_close(struct ai_type *ait)
Definition aiunit.c:3291
struct unit_type * dai_role_utype_for_terrain_class(struct city *pcity, int role, enum terrain_class tc)
Definition aiunit.c:3431
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 aiunit.c:1058
static void dai_military_defend(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aiunit.c:942
bool dai_military_rampage(struct unit *punit, int thresh_adj, int thresh_move)
Definition aiunit.c:600
static bool dai_caravan_can_trade_cities_diff_cont(struct player *pplayer, struct unit *punit)
Definition aiunit.c:2171
#define POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer)
Definition aiunit.h:72
@ AIUNIT_BUILD_CITY
Definition aiunit.h:27
@ AIUNIT_NONE
Definition aiunit.h:27
@ AIUNIT_ATTACK
Definition aiunit.h:28
@ AIUNIT_EXPLORE
Definition aiunit.h:29
@ AIUNIT_HUNTER
Definition aiunit.h:29
@ AIUNIT_RECOVER
Definition aiunit.h:29
@ AIUNIT_TRADE
Definition aiunit.h:30
@ AIUNIT_DEFEND_HOME
Definition aiunit.h:28
@ AIUNIT_ESCORT
Definition aiunit.h:28
@ AIUNIT_AUTO_SETTLER
Definition aiunit.h:27
@ AIUNIT_WONDER
Definition aiunit.h:30
#define RAMPAGE_ANYTHING
Definition aiunit.h:85
#define RAMPAGE_FREE_CITY_OR_BETTER
Definition aiunit.h:87
#define INVASION_ATTACK
Definition aiunit.h:81
#define INVASION_OCCUPY
Definition aiunit.h:80
#define RAMPAGE_HUT_OR_BETTER
Definition aiunit.h:86
#define DEFENSE_POWER(ptype)
Definition aiunit.h:66
#define IS_ATTACKER(ptype)
Definition aiunit.h:70
#define BODYGUARD_RAMPAGE_THRESHOLD
Definition aiunit.h:88
#define ATTACK_POWER(ptype)
Definition aiunit.h:68
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:751
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:1833
const char * city_name_get(const struct city *pcity)
Definition city.c:1115
int city_production_unit_veteran_level(struct city *pcity, const struct unit_type *punittype)
Definition city.c:789
bool can_city_build_unit_now(const struct civ_map *nmap, const struct city *pcity, const struct unit_type *punittype)
Definition city.c:927
#define city_list_iterate(citylist, pcity)
Definition city.h:488
#define city_tile(_pcity_)
Definition city.h:544
@ CITIZEN_ANGRY
Definition city.h:263
@ CITIZEN_UNHAPPY
Definition city.h:262
#define city_owner(_pcity_)
Definition city.h:543
#define city_list_iterate_end
Definition city.h:490
@ FEELING_NATIONALITY
Definition city.h:274
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:854
bool is_stack_vulnerable(const struct tile *ptile)
Definition combat.c:930
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:659
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:714
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
double unit_win_chance(const struct civ_map *nmap, const struct unit *attacker, const struct unit *defender)
Definition combat.c:438
bool can_unit_attack_tile(const struct unit *punit, const struct action *paction, const struct tile *dest_tile)
Definition combat.c:271
int base_get_defense_power(const struct unit *punit)
Definition combat.c:528
struct unit * get_defender(const struct civ_map *nmap, const struct unit *attacker, const struct tile *ptile)
Definition combat.c:783
@ ATT_OK
Definition combat.h:35
bool dai_can_requirement_be_met_in_city(const struct requirement *preq, const struct player *pplayer, const struct city *pcity)
Definition daieffects.c:718
struct unit_type * dai_choose_defender_versus(struct city *pcity, struct unit *attacker)
Definition daimilitary.c:92
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 void attack(QVariant data1, QVariant data2)
Definition dialogs.cpp:2918
static void base(QVariant data1, QVariant data2)
Definition dialogs.cpp:2840
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:73
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:73
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:789
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:957
bool unit_can_enter_hut(const struct unit *punit, const struct tile *ptile)
Definition extras.c:687
float adv_want
Definition fc_types.h:1206
@ RPT_CERTAIN
Definition fc_types.h:586
@ AUT_AUTO_SETTLER
Definition fc_types.h:340
#define ADV_WANT_PRINTF
Definition fc_types.h:1207
@ O_LUXURY
Definition fc_types.h:91
signed short Continent_id
Definition fc_types.h:342
override_bool
Definition fc_types.h:84
@ OVERRIDE_TRUE
Definition fc_types.h:84
@ OVERRIDE_FALSE
Definition fc_types.h:84
struct civ_game game
Definition game.c:57
struct world wld
Definition game.c:58
struct unit * game_unit_by_number(int id)
Definition game.c:111
struct city * game_city_by_number(int id)
Definition game.c:102
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:929
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:938
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:628
int map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:652
#define iterate_outward(nmap, start_tile, max_dist, itr_tile)
Definition map.h:361
#define iterate_outward_end
Definition map.h:365
#define adjc_iterate_end
Definition map.h:427
static int index_to_map_pos_y(int mindex)
Definition map.h:696
#define square_iterate(nmap, center_tile, radius, tile_itr)
Definition map.h:385
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:422
#define square_iterate_end
Definition map.h:388
static int index_to_map_pos_x(int mindex)
Definition map.h:687
#define pmap(_tile)
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Definition maphand.c:886
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Definition maphand.c:900
#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:304
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:316
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:215
bool can_unit_survive_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:476
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Definition movement.c:826
bool can_attack_non_native(const struct unit_type *utype)
Definition movement.c:202
#define SINGLE_MOVE
Definition movement.h:24
static bool is_native_tile_to_class(const struct unit_class *punitclass, const struct tile *ptile)
Definition movement.h:80
@ MR_OK
Definition movement.h:33
@ MR_DEATH
Definition movement.h:34
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:137
struct nation_type * nation_of_unit(const struct unit *punit)
Definition nation.c:462
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:1205
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1364
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1381
#define players_iterate_end
Definition player.h:535
#define players_iterate(_pplayer)
Definition player.h:530
static bool is_barbarian(const struct player *pplayer)
Definition player.h:488
#define is_human(plr)
Definition player.h:233
#define fc_rand(_size)
Definition rand.h:34
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:183
#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
unsigned int urgency
Definition daicity.h:49
adv_want worth
Definition daicity.h:35
int attack
Definition daicity.h:44
struct ai_invasion invasion
Definition daicity.h:43
unsigned int grave_danger
Definition daicity.h:48
int attack
Definition daicity.h:30
int occupy
Definition daicity.h:31
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:309
int id
Definition city.h:315
struct player * owner
Definition city.h:312
struct universal production
Definition city.h:382
struct adv_city * adv
Definition city.h:435
struct tile * tile
Definition city.h:311
struct civ_game::@30::@34 server
struct packet_game_info info
Definition game.h:89
int occupychance
Definition game.h:169
struct city_list * cities
Definition player.h:281
struct unit_list * units
Definition player.h:282
bool is_alive
Definition player.h:268
const struct player * player
enum terrain_class tc
Definition aiunit.c:3402
struct city * build_city
Definition aiunit.c:3403
Definition tile.h:49
struct unit_list * units
Definition tile.h:57
Continent_id continent
Definition tile.h:53
struct tile ** prev_pos
Definition aiunit.h:40
int bodyguard
Definition aiunit.h:36
bv_player hunted
Definition aiunit.h:43
bool done
Definition aiunit.h:44
int ferryboat
Definition aiunit.h:34
enum ai_unit_task task
Definition aiunit.h:46
struct tile ** cur_pos
Definition aiunit.h:40
int passenger
Definition aiunit.h:35
int charge
Definition aiunit.h:37
int target
Definition aiunit.h:42
int non_native_def_pct
Definition unittype.h:143
enum move_level sea_move
Definition unittype.h:150
struct unit_class_list * subset_movers
Definition unittype.h:160
struct unit_class::@85 cache
int ferry_types
Definition unittype.h:151
enum move_level land_move
Definition unittype.h:149
struct unit_class::@84 adv
bool carries_occupiers
Definition aiunit.h:54
struct unit_type_list * potential_charges
Definition aiunit.h:55
bool ferry
Definition aiunit.h:52
bool missile_platform
Definition aiunit.h:53
bool low_firepower
Definition aiunit.h:51
struct unit_type::@87 adv
struct requirement_vector build_reqs
Definition unittype.h:501
int defense_strength
Definition unittype.h:496
bv_unit_classes cargo
Definition unittype.h:539
int firepower
Definition unittype.h:506
bool worker
Definition unittype.h:556
struct veteran_system * veteran
Definition unittype.h:525
int move_rate
Definition unittype.h:497
int attack_strength
Definition unittype.h:495
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::@80::@83 server
int homecity
Definition unit.h:146
int birth_turn
Definition unit.h:235
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
#define A_NEVER
Definition tech.h:51
bool is_terrain_class_near_tile(const struct civ_map *nmap, const struct tile *ptile, enum terrain_class tclass)
Definition terrain.c:600
#define is_ocean_tile(ptile)
Definition terrain.h:289
int tile_extras_defense_bonus(const struct tile *ptile, const struct unit_type *punittype)
Definition tile.c:227
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_index(_pt_)
Definition tile.h:87
#define tile_terrain(_tile)
Definition tile.h:109
#define TILE_XY(ptile)
Definition tile.h:42
#define tile_continent(_tile)
Definition tile.h:91
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:2274
bool unit_transport_load(struct unit *pcargo, struct unit *ptrans, bool force)
Definition unit.c:2354
bool is_losing_hp(const struct unit *punit)
Definition unit.c:2212
bool unit_can_airlift_to(const struct civ_map *nmap, const struct unit *punit, const struct city *pdest_city)
Definition unit.c:188
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2425
int unit_gain_hitpoints(const struct unit *punit)
Definition unit.c:2167
bool is_military_unit(const struct unit *punit)
Definition unit.c:319
bool unit_is_cityfounder(const struct unit *punit)
Definition unit.c:2623
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:328
bool unit_can_do_action_result(const struct unit *punit, enum action_result result)
Definition unit.c:338
int get_transporter_capacity(const struct unit *punit)
Definition unit.c:299
bool can_unit_do_activity(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity)
Definition unit.c:872
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2409
bool unit_has_orders(const struct unit *punit)
Definition unit.c:204
#define unit_tile(_pu)
Definition unit.h:395
#define unit_cargo_iterate_end
Definition unit.h:570
#define unit_cargo_iterate(_ptrans, _pcargo)
Definition unit.h:567
#define CHECK_UNIT(punit)
Definition unit.h:268
#define unit_owner(_pu)
Definition unit.h:394
static bool is_non_allied_unit_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.h:430
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity)
Definition unithand.c:6179
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:3155
bool unit_server_side_agent_set(struct player *pplayer, struct unit *punit, enum server_side_agent agent)
Definition unithand.c:6078
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:1243
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:2284
struct unit_type * get_role_unit(int role, int role_index)
Definition unittype.c:2301
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1639
bool utype_has_role(const struct unit_type *punittype, int role)
Definition unittype.c:193
int utype_build_shield_cost_base(const struct unit_type *punittype)
Definition unittype.c:1520
int unit_build_shield_cost_base(const struct unit *punit)
Definition unittype.c:1536
struct unit_type * best_role_unit_for_player(const struct player *pplayer, int role)
Definition unittype.c:2346
struct unit_class * unit_class_get(const struct unit *punit)
Definition unittype.c:2547
bool utype_can_do_action_result(const struct unit_type *putype, enum action_result result)
Definition unittype.c:459
bool unit_has_type_role(const struct unit *punit, enum unit_role_id role)
Definition unittype.c:202
bool unit_can_take_over(const struct unit *punit)
Definition unittype.c:258
void * utype_ai_data(const struct unit_type *ptype, const struct ai_type *ai)
Definition unittype.c:2755
bool utype_can_take_over(const struct unit_type *punittype)
Definition unittype.c:270
void utype_set_ai_data(struct unit_type *ptype, const struct ai_type *ai, void *data)
Definition unittype.c:2763
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1490
bool utype_acts_hostile(const struct unit_type *putype)
Definition unittype.c:515
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:443
#define utype_class(_t_)
Definition unittype.h:736
#define utype_fuel(ptype)
Definition unittype.h:825
#define combat_bonus_list_iterate_end
Definition unittype.h:463
#define combat_bonus_list_iterate(bonuslist, pbonus)
Definition unittype.h:461
@ MOVE_FULL
Definition unittype.h:131
@ MOVE_NONE
Definition unittype.h:131
#define unit_type_list_iterate(utype_list, ptype)
Definition unittype.h:911
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:604
#define unit_class_list_iterate(uclass_list, pclass)
Definition unittype.h:903
#define unit_type_iterate(_p)
Definition unittype.h:841
#define unit_type_list_iterate_end
Definition unittype.h:913
#define U_LAST
Definition unittype.h:40
#define unit_type_iterate_end
Definition unittype.h:848
#define unit_class_list_iterate_end
Definition unittype.h:905