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 /* action enablers might prevent attacking */
467 && is_action_enabled_unit_on_units(nmap, ACTION_ATTACK,
468 punit, ptile)) {
469 /* See description of kill_desire() about these variables. */
471 int benefit = stack_cost(punit, pdef);
473
474 attack *= attack;
475
476 /* If the victim is in the city/fortress, we correct the benefit
477 * with our health because there could be reprisal attacks. We
478 * shouldn't send already injured units to useless suicide.
479 * Note that we do not specially encourage attacks against
480 * cities: rampage is a hit-n-run operation. */
481 if (!is_stack_vulnerable(ptile)
482 && unit_list_size(ptile->units) > 1) {
483 benefit = (benefit * punit->hp) / unit_type_get(punit)->hp;
484 }
485
486 /* If we have non-zero attack rating... */
487 if (attack > 0 && is_my_turn(punit, pdef)) {
488 double chance = unit_win_chance(nmap, punit, pdef);
489 int desire = avg_benefit(benefit, loss, chance);
490
491 /* No need to amortize, our operation takes one turn. */
492 UNIT_LOG(LOG_DEBUG, punit, "Rampage: Desire %d to kill %s(%d,%d)",
493 desire,
494 unit_rule_name(pdef),
495 TILE_XY(unit_tile(pdef)));
496
497 return MAX(0, desire);
498 }
499 } else if (0 == unit_list_size(ptile->units)) {
500 /* No defender. */
501 struct city *pcity = tile_city(ptile);
502
503 /* ...and free foreign city waiting for us. Who would resist! */
504 if (NULL != pcity
505 && pplayers_at_war(pplayer, city_owner(pcity))
508 }
509
510 /* ...or tiny pleasant hut here! */
511 /* FIXME: unhardcode and variate the desire to enter a hut. */
512 if (unit_can_enter_hut(punit, ptile) && !is_barbarian(pplayer)
513 && is_native_tile(unit_type_get(punit), ptile)) {
514 return -RAMPAGE_HUT_OR_BETTER;
515 }
516 }
517
518 return 0;
519}
520
521/**********************************************************************/
524static struct pf_path *find_rampage_target(struct unit *punit,
525 int thresh_adj, int thresh_move)
526{
527 struct pf_map *tgt_map;
528 struct pf_path *path = NULL;
529 struct pf_parameter parameter;
530 /* Coordinates of the best target (initialize to silence compiler) */
531 struct tile *ptile = unit_tile(punit);
532 /* Want of the best target */
533 int max_want = 0;
534 struct player *pplayer = unit_owner(punit);
535 const struct civ_map *nmap = &(wld.map);
536
537 pft_fill_unit_attack_param(&parameter, nmap, punit);
538 parameter.omniscience = !has_handicap(pplayer, H_MAP);
539 /* When trying to find rampage targets we ignore risks such as
540 * enemy units because we are looking for trouble!
541 * Hence no call ai_avoid_risks()
542 */
543
544 tgt_map = pf_map_new(&parameter);
545 pf_map_move_costs_iterate(tgt_map, iter_tile, move_cost, FALSE) {
546 int want;
547 bool move_needed;
548 int thresh;
549
550 if (move_cost > punit->moves_left) {
551 /* This is too far */
552 break;
553 }
554
555 if (has_handicap(pplayer, H_TARGETS)
556 && !map_is_known_and_seen(iter_tile, pplayer, V_MAIN)) {
557 /* The target is under fog of war */
558 continue;
559 }
560
561 want = dai_rampage_want(punit, iter_tile);
562
563 /* Negative want means move needed even though the tiles are adjacent */
564 move_needed = (!is_tiles_adjacent(unit_tile(punit), iter_tile)
565 || want < 0);
566 /* Select the relevant threshold */
567 thresh = (move_needed ? thresh_move : thresh_adj);
568 want = (want < 0 ? -want : want);
569
570 if (want > max_want && want > thresh) {
571 /* The new want exceeds both the previous maximum
572 * and the relevant threshold, so it's worth recording */
573 max_want = want;
574 ptile = iter_tile;
575 }
577
578 if (max_want > 0) {
579 /* We found something */
580 path = pf_map_path(tgt_map, ptile);
581 fc_assert(path != NULL);
582 }
583
584 pf_map_destroy(tgt_map);
585
586 return path;
587}
588
589/**********************************************************************/
603bool dai_military_rampage(struct unit *punit, int thresh_adj,
604 int thresh_move)
605{
606 int count = punit->moves_left + 1; /* break any infinite loops */
607 struct pf_path *path = NULL;
608
611
612 fc_assert_ret_val(thresh_adj <= thresh_move, TRUE);
613 /* This teaches the AI about the dangers inherent in occupychance. */
614 thresh_adj += ((thresh_move - thresh_adj) * game.server.occupychance / 100);
615
616 while (count-- > 0 && punit->moves_left > 0
617 && (path = find_rampage_target(punit, thresh_adj, thresh_move))) {
618 if (!adv_unit_execute_path(punit, path)) {
619 /* Died */
620 count = -1;
621 }
622 pf_path_destroy(path);
623 path = NULL;
624 }
625
626 fc_assert(NULL == path);
627
629 return (count >= 0);
630}
631
632/**********************************************************************/
636static void dai_military_bodyguard(struct ai_type *ait, struct player *pplayer,
637 struct unit *punit)
638{
639 struct unit *aunit = aiguard_charge_unit(ait, punit);
640 struct city *acity = aiguard_charge_city(ait, punit);
641 struct tile *ptile;
642
644 CHECK_GUARD(ait, punit);
645
646 if (aunit && unit_owner(aunit) == unit_owner(punit)) {
647 /* protect a unit */
648 if (aunit->goto_tile != NULL) {
649 /* Our charge is going somewhere: maybe we should meet them there */
650 /* FIXME: This probably isn't the best algorithm for this. */
651 int me2them = real_map_distance(unit_tile(punit), unit_tile(aunit));
652 int me2goal = real_map_distance(unit_tile(punit), aunit->goto_tile);
653 int them2goal = real_map_distance(unit_tile(aunit), aunit->goto_tile);
654
655 if (me2goal < me2them
656 || (me2goal/unit_move_rate(punit) < them2goal/unit_move_rate(aunit)
657 && me2goal/unit_move_rate(punit) < me2them/unit_move_rate(punit)
658 && unit_move_rate(punit) > unit_move_rate(aunit))) {
659 ptile = aunit->goto_tile;
660 } else {
661 ptile = unit_tile(aunit);
662 }
663 } else {
664 ptile = unit_tile(aunit);
665 }
666 } else if (acity && city_owner(acity) == unit_owner(punit)) {
667 /* protect a city */
668 ptile = acity->tile;
669 } else {
670 /* should be impossible */
671 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "we lost our charge");
673 return;
674 }
675
676 if (same_pos(unit_tile(punit), ptile)) {
677 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "at RV");
678 } else {
679 if (goto_is_sane(punit, ptile)) {
680 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "meeting charge");
681 if (!dai_gothere(ait, pplayer, punit, ptile)) {
682 /* We died */
683 return;
684 }
685 } else {
686 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "can not meet charge");
688 }
689 }
690 /* We might have stopped because of an enemy nearby.
691 * Perhaps we can kill it.*/
694 && same_pos(unit_tile(punit), ptile)) {
695 def_ai_unit_data(punit, ait)->done = TRUE; /* Stay with charge */
696 }
697}
698
699/**********************************************************************/
702static bool unit_role_defender(const struct unit_type *punittype)
703{
704 return (utype_has_role(punittype, L_DEFEND_GOOD));
705}
706
707/**********************************************************************/
717adv_want look_for_charge(struct ai_type *ait, const struct civ_map *nmap,
718 struct player *pplayer, struct unit *punit,
719 struct unit **aunit, struct city **acity)
720{
721 struct pf_parameter parameter;
722 struct pf_map *pfm;
723 struct city *pcity;
724 struct ai_city *data, *best_data = NULL;
725 const int toughness = adv_unit_def_rating_basic_squared(punit);
726 int def, best_def = -1;
727 /* Arbitrary: 3 turns. */
728 const int max_move_cost = 3 * unit_move_rate(punit);
729
730 *aunit = NULL;
731 *acity = NULL;
732
733 if (0 == toughness) {
734 /* useless */
735 return 0;
736 }
737
738 pft_fill_unit_parameter(&parameter, nmap, punit);
739 parameter.omniscience = !has_handicap(pplayer, H_MAP);
740 pfm = pf_map_new(&parameter);
741
742 pf_map_move_costs_iterate(pfm, ptile, move_cost, TRUE) {
743 if (move_cost > max_move_cost) {
744 /* Consider too far. */
745 break;
746 }
747
748 pcity = tile_city(ptile);
749
750 /* Consider unit bodyguard. */
751 unit_list_iterate(ptile->units, buddy) {
752 const struct unit_type *ptype = unit_type_get(punit);
753 const struct unit_type *buddy_type = unit_type_get(buddy);
754
755 /* TODO: allied unit bodyguard? */
756 if (!dai_can_unit_type_follow_unit_type(ptype, buddy_type, ait)
757 || unit_owner(buddy) != pplayer
758 || !aiguard_wanted(ait, buddy)
760 || DEFENSE_POWER(buddy_type) >= DEFENSE_POWER(ptype)
761 || (utype_can_do_action_result(buddy_type, ACTRES_ATTACK)
762 && 0 == get_transporter_capacity(buddy)
763 && ATTACK_POWER(buddy_type) <= ATTACK_POWER(ptype))) {
764
765 continue;
766 }
767
768 def = (toughness - adv_unit_def_rating_basic_squared(buddy));
769 if (0 >= def) {
770 continue;
771 }
772
773 if (0 == get_transporter_capacity(buddy)) {
774 /* Reduce want based on move cost. We can't do this for
775 * transports since they move around all the time, leading
776 * to hilarious flip-flops. */
777 def >>= move_cost / (2 * unit_move_rate(punit));
778 }
779 if (def > best_def) {
780 *aunit = buddy;
781 *acity = NULL;
782 best_def = def;
783 }
785
786 /* City bodyguard. TODO: allied city bodyguard? */
787 if (ai_fuzzy(pplayer, TRUE)
788 && NULL != pcity
789 && city_owner(pcity) == pplayer
790 && (data = def_ai_city_data(pcity, ait))
791 && 0 < data->urgency) {
792 if (NULL != best_data
793 && (0 < best_data->grave_danger
794 || best_data->urgency > data->urgency
795 || ((best_data->danger > data->danger
796 || AIUNIT_DEFEND_HOME == def_ai_unit_data(punit, ait)->task)
797 && 0 == data->grave_danger))) {
798 /* Chances are we'll be between cities when we are needed the most!
799 * Resuming pf_map_move_costs_iterate()... */
800 continue;
801 }
802 def = (data->danger - assess_defense_quadratic(ait, pcity));
803 if (def <= 0) {
804 continue;
805 }
806 /* Reduce want based on move cost. */
807 def >>= move_cost / (2 * unit_move_rate(punit));
808 if (def > best_def && ai_fuzzy(pplayer, TRUE)) {
809 *acity = pcity;
810 *aunit = NULL;
811 best_def = def;
812 best_data = data;
813 }
814 }
816
817 pf_map_destroy(pfm);
818
819 UNIT_LOG(LOGLEVEL_BODYGUARD, punit, "%s(), best_def=%d, type=%s (%d, %d)",
820 __FUNCTION__, best_def * 100 / toughness,
821 (NULL != *acity ? city_name_get(*acity)
822 : (NULL != *aunit ? unit_rule_name(*aunit) : "")),
823 (NULL != *acity ? index_to_map_pos_x(tile_index(city_tile(*acity)))
824 : (NULL != *aunit ?
825 index_to_map_pos_x(tile_index(unit_tile(*aunit))) : -1)),
826 (NULL != *acity ? index_to_map_pos_y(tile_index(city_tile(*acity)))
827 : (NULL != *aunit ?
828 index_to_map_pos_y(tile_index(unit_tile(*aunit))) : -1)));
829
830 return ((best_def * 100) / toughness);
831}
832
833/**********************************************************************/
837 const struct unit_type *followee,
838 struct ai_type *ait)
839{
840 struct unit_type_ai *utai = utype_ai_data(follower, ait);
841
843 if (pcharge == followee) {
844 return TRUE;
845 }
847
848 return FALSE;
849}
850
851/**********************************************************************/
854static void dai_military_findjob(struct ai_type *ait, const struct civ_map *nmap,
855 struct player *pplayer, struct unit *punit)
856{
857 const struct unit_type *punittype = unit_type_get(punit);
858 struct unit_ai *unit_data;
859
861
862 /* Keep barbarians aggressive and primitive */
863 if (is_barbarian(pplayer)) {
864 if (can_unit_do_activity(nmap, punit, ACTIVITY_PILLAGE)
865 && is_land_barbarian(pplayer)) {
866 /* Land barbarians pillage */
867 unit_activity_handling(punit, ACTIVITY_PILLAGE);
868 }
870
871 return;
872 }
873
874 unit_data = def_ai_unit_data(punit, ait);
875
876 /* If I am a bodyguard, check whether I can do my job. */
877 if (unit_data->task == AIUNIT_ESCORT
878 || unit_data->task == AIUNIT_DEFEND_HOME) {
880 }
881
882 if (aiguard_has_charge(ait, punit)
883 && unit_data->task == AIUNIT_ESCORT) {
884 struct unit *aunit = aiguard_charge_unit(ait, punit);
885 struct city *acity = aiguard_charge_city(ait, punit);
886 struct ai_city *city_data = NULL;
887
888 if (acity != NULL) {
889 city_data = def_ai_city_data(acity, ait);
890 }
891
892 /* Check if the city we are on our way to rescue is still in danger,
893 * or the unit we should protect is still alive... */
894 if ((aunit && (aiguard_has_guard(ait, aunit) || aiguard_wanted(ait, aunit))
896 || (acity && city_owner(acity) == unit_owner(punit)
897 && city_data->urgency != 0
898 && city_data->danger > assess_defense_quadratic(ait, acity))) {
899 return; /* Yep! */
900 } else {
901 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL); /* Nope! */
902 }
903 }
904
905 /* Is the unit badly damaged? */
906 if ((unit_data->task == AIUNIT_RECOVER
907 && punit->hp < punittype->hp)
908 || punit->hp < punittype->hp * 0.25) { /* WAG */
909 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "set to hp recovery");
911 return;
912 }
913
916 /* This is a defending unit that doesn't need to stay put.
917 * It needs to defend something, but not necessarily where it's at.
918 * Therefore, it will consider becoming a bodyguard. -- Syela */
919 struct city *acity;
920 struct unit *aunit;
921
922 look_for_charge(ait, nmap, pplayer, punit, &aunit, &acity);
923 if (acity) {
925 aiguard_assign_guard_city(ait, acity, punit);
926 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "going to defend city");
927 } else if (aunit) {
929 aiguard_assign_guard_unit(ait, aunit, punit);
930 BODYGUARD_LOG(ait, LOG_DEBUG, punit, "going to defend unit");
931 }
932 }
934}
935
936/**********************************************************************/
945static void dai_military_defend(struct ai_type *ait, struct player *pplayer,
946 struct unit *punit)
947{
948 struct city *pcity = aiguard_charge_city(ait, punit);
949
951
952 if (!pcity || city_owner(pcity) != pplayer) {
953 pcity = tile_city(unit_tile(punit));
954 /* Do not stay defending an allied city forever */
956 }
957
958 if (!pcity) {
959 /* Try to find a place to rest. Sitting duck out in the wilderness
960 * is generally a bad idea, since we protect no cities that way, and
961 * it looks silly. */
962 pcity = find_closest_city(unit_tile(punit), NULL, pplayer,
965 }
966
967 if (!pcity) {
969 }
970
973 /* ... we survived */
974 if (pcity) {
975 UNIT_LOG(LOG_DEBUG, punit, "go to defend %s", city_name_get(pcity));
976 if (same_pos(unit_tile(punit), pcity->tile)) {
977 UNIT_LOG(LOG_DEBUG, punit, "go defend successful");
979 } else {
980 (void) dai_gothere(ait, pplayer, punit, pcity->tile);
981 }
982 } else {
983 UNIT_LOG(LOG_VERBOSE, punit, "defending nothing...?");
984 }
985 }
986}
987
988/**********************************************************************/
991static void single_invader(struct ai_city *city_data,
992 const struct unit_type *utype,
993 int which)
994{
995 int attacks;
996
998 action_by_number(ACTION_ATTACK))) {
999 attacks = 1;
1000 } else {
1001 attacks = utype->move_rate;
1002 }
1003 city_data->invasion.attack += attacks;
1004 if (which == INVASION_OCCUPY) {
1005 city_data->invasion.occupy++;
1006 }
1007}
1008
1009/**********************************************************************/
1019static void invasion_funct(struct ai_type *ait, struct unit *punit,
1020 bool dest, int radius, int which)
1021{
1022 struct tile *ptile;
1023 struct player *pplayer = unit_owner(punit);
1024
1026
1027 if (dest) {
1028 ptile = punit->goto_tile;
1029 } else {
1030 ptile = unit_tile(punit);
1031 }
1032
1033 square_iterate(&(wld.map), ptile, radius, tile1) {
1034 struct city *pcity = tile_city(tile1);
1035
1036 if (pcity
1037 && POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, city_owner(pcity))
1038 && (dest || !has_defense(pcity))) {
1039 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1040
1041 /* Unit itself */
1042 single_invader(city_data, unit_type_get(punit), which);
1043
1044 /* Cargo */
1045 unit_cargo_iterate(punit, cargo) {
1046 const struct unit_type *utype = unit_type_get(cargo);
1047
1048 if (IS_ATTACKER(utype)) {
1049 single_invader(city_data, utype,
1052 }
1054 }
1056}
1057
1058/**********************************************************************/
1061bool find_beachhead(const struct player *pplayer, struct pf_map *ferry_map,
1062 struct tile *dest_tile,
1063 const struct unit_type *cargo_type,
1064 struct tile **ferry_dest, struct tile **beachhead_tile)
1065{
1066 if (NULL == tile_city(dest_tile)
1067 || can_attack_from_non_native(cargo_type)) {
1068 /* Unit can directly go to 'dest_tile'. */
1069 struct tile *best_tile = NULL;
1070 int best_cost = PF_IMPOSSIBLE_MC, cost;
1071
1072 if (NULL != beachhead_tile) {
1073 *beachhead_tile = dest_tile;
1074 }
1075
1076 adjc_iterate(&(wld.map), dest_tile, ptile) {
1077 cost = pf_map_move_cost(ferry_map, ptile);
1078 if (cost != PF_IMPOSSIBLE_MC
1079 && (NULL == best_tile || cost < best_cost)) {
1080 best_tile = ptile;
1081 best_cost = cost;
1082 }
1084
1085 if (NULL != ferry_dest) {
1086 *ferry_dest = best_tile;
1087 }
1088
1089 return (PF_IMPOSSIBLE_MC != best_cost);
1090 } else {
1091 /* We need to find a beach around 'dest_tile'. */
1092 struct tile *best_tile = NULL, *best_beach = NULL;
1093 struct tile_list *checked_tiles = tile_list_new();
1094 int best_cost = PF_IMPOSSIBLE_MC, cost;
1095
1096 tile_list_append(checked_tiles, dest_tile);
1097 adjc_iterate(&(wld.map), dest_tile, beach) {
1098 if (is_native_tile(cargo_type, beach)) {
1099 /* Can land there. */
1100 adjc_iterate(&(wld.map), beach, ptile) {
1101 if (!tile_list_search(checked_tiles, ptile)
1102 && !is_non_allied_unit_tile(ptile, pplayer)) {
1103 tile_list_append(checked_tiles, ptile);
1104 cost = pf_map_move_cost(ferry_map, ptile);
1105 if (cost != PF_IMPOSSIBLE_MC
1106 && (NULL == best_tile || cost < best_cost)) {
1107 best_beach = beach;
1108 best_tile = ptile;
1109 best_cost = cost;
1110 }
1111 }
1113 }
1115
1116 tile_list_destroy(checked_tiles);
1117
1118 if (NULL != beachhead_tile) {
1119 *beachhead_tile = best_beach;
1120 }
1121 if (NULL != ferry_dest) {
1122 *ferry_dest = best_tile;
1123 }
1124 return (PF_IMPOSSIBLE_MC != best_cost);
1125 }
1126}
1127
1128/**********************************************************************/
1136adv_want find_something_to_kill(struct ai_type *ait, struct player *pplayer,
1137 struct unit *punit,
1138 struct tile **pdest_tile, struct pf_path **ppath,
1139 struct pf_map **pferrymap,
1140 struct unit **pferryboat,
1141 const struct unit_type **pboattype, int *pmove_time)
1142{
1143 const int attack_value = adv_unit_att_rating(punit); /* basic attack. */
1144 struct pf_parameter parameter;
1145 struct pf_map *punit_map, *ferry_map;
1146 struct pf_position pos;
1147 struct unit_class *punit_class = unit_class_get(punit);
1148 const struct unit_type *punit_type = unit_type_get(punit);
1149 struct tile *punit_tile = unit_tile(punit);
1150 /* Type of our boat (a future one if ferryboat == NULL). */
1151 const struct unit_type *boattype = NULL;
1152 struct unit *ferryboat = NULL;
1153 struct city *pcity;
1154 struct ai_city *acity_data;
1155 int bcost, bcost_bal; /* Build cost of the attacker (+adjustments). */
1156 bool handicap = has_handicap(pplayer, H_TARGETS);
1157 bool unhap = FALSE; /* Do we make unhappy citizen. */
1158 bool harbor = FALSE; /* Do we have access to sea? */
1159 bool go_by_boat; /* Whether we need a boat or not. */
1160 int vulnerability; /* Enemy defense rating. */
1161 adv_want benefit; /* Benefit from killing the target. */
1162 struct unit *pdefender; /* Enemy city defender. */
1163 int move_time; /* Turns needed to target. */
1164 int reserves;
1165 int attack; /* Our total attack value with reinforcements. */
1166 int victim_count; /* Number of enemies there. */
1167 int needferry; /* Cost of building a ferry boat. */
1168 /* This is a kluge, because if we don't set x and y with !punit->id,
1169 * p_a_w isn't called, and we end up not wanting ironclads and therefore
1170 * never learning steam engine, even though ironclads would be very
1171 * useful. -- Syela */
1172 adv_want bk = 0;
1173 adv_want want; /* Want (amortized) of the operation. */
1174 adv_want best = 0; /* Best of all wants. */
1175 struct tile *goto_dest_tile = NULL;
1176 bool can_occupy;
1177 struct civ_map *nmap = &(wld.map);
1178
1179 /* Very preliminary checks. */
1180 *pdest_tile = punit_tile;
1181 if (NULL != pferrymap) {
1182 *pferrymap = NULL;
1183 }
1184 if (NULL != pferryboat) {
1185 *pferryboat = NULL;
1186 }
1187 if (NULL != pboattype) {
1188 *pboattype = NULL;
1189 }
1190 if (NULL != pmove_time) {
1191 *pmove_time = 0;
1192 }
1193 if (NULL != ppath) {
1194 *ppath = NULL;
1195 }
1196
1197 if (0 == attack_value) {
1198 /* A very poor attacker... probably low on HP. */
1199 return 0;
1200 }
1201
1203
1204
1205 /*** Part 1: Calculate targets ***/
1206
1207 /* This horrible piece of code attempts to calculate the attractiveness of
1208 * enemy cities as targets for our units, by checking how many units are
1209 * going towards it or are near it already. */
1210
1211 /* Reset enemy cities data. */
1212 players_iterate(aplayer) {
1213 /* See comment below in next usage of POTENTIALLY_HOSTILE_PLAYER. */
1214 if ((punit->id == 0 && !POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer))
1215 || (punit->id != 0 && !pplayers_at_war(pplayer, aplayer))) {
1216 continue;
1217 }
1218 city_list_iterate(aplayer->cities, acity) {
1219 struct ai_city *city_data = def_ai_city_data(acity, ait);
1220
1222 &city_data->attack,
1223 &city_data->bcost);
1224 city_data->invasion.attack = 0;
1225 city_data->invasion.occupy = 0;
1228
1229 /* Second, calculate in units on their way there, and mark targets for
1230 * invasion */
1231 unit_list_iterate(pplayer->units, aunit) {
1232 const struct unit_type *atype;
1233
1234 if (aunit == punit) {
1235 continue;
1236 }
1237
1238 atype = unit_type_get(aunit);
1239
1240 /* Dealing with invasion stuff */
1241 if (IS_ATTACKER(atype)) {
1242 if (aunit->activity == ACTIVITY_GOTO) {
1243 invasion_funct(ait, aunit, TRUE, 0,
1244 (unit_can_take_over(aunit)
1246 if ((pcity = tile_city(aunit->goto_tile))) {
1247 struct ai_city *city_data = def_ai_city_data(pcity, ait);
1248
1249 city_data->attack += adv_unit_att_rating(aunit);
1250 city_data->bcost += unit_build_shield_cost_base(aunit);
1251 }
1252 }
1253 invasion_funct(ait, aunit, FALSE, unit_move_rate(aunit) / SINGLE_MOVE,
1254 (unit_can_take_over(aunit)
1256 } else if (def_ai_unit_data(aunit, ait)->passenger != 0
1257 && !same_pos(unit_tile(aunit), unit_tile(punit))) {
1258 /* It's a transport with reinforcements */
1259 if (aunit->activity == ACTIVITY_GOTO) {
1260 invasion_funct(ait, aunit, TRUE, 1, INVASION_OCCUPY);
1261 }
1262 invasion_funct(ait, aunit, FALSE, 2, INVASION_OCCUPY);
1263 }
1265 /* end horrible initialization subroutine */
1266
1267
1268 /*** Part 2: Now pick one target ***/
1269
1270 /* We first iterate through all cities, then all units, looking
1271 * for a viable target. We also try to gang up on the target
1272 * to avoid spreading out attacks too widely to be inefficient.
1273 */
1274
1275 pcity = tile_city(punit_tile);
1276 if (NULL != pcity && (0 == punit->id || pcity->id == punit->homecity)) {
1277 /* I would have thought unhappiness should be taken into account
1278 * irrespectfully the city in which it will surface... -- GB */
1279 unhap = dai_assess_military_unhappiness(nmap, pcity);
1280 }
1281
1283 bcost_bal = build_cost_balanced(punit_type);
1284
1285 pft_fill_unit_attack_param(&parameter, nmap, punit);
1286 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1287 punit_map = pf_map_new(&parameter);
1288
1289 if (MOVE_NONE == punit_class->adv.sea_move) {
1290 /* We need boat to move over sea. */
1291 ferryboat = unit_transport_get(punit);
1292
1293 /* First check if we can use the boat we are currently loaded to. */
1294 if (ferryboat == NULL || !is_boat_free(ait, ferryboat, punit, 0)) {
1295 /* No, we cannot control current boat */
1296 ferryboat = NULL;
1297 }
1298
1299 if (NULL == ferryboat) {
1300 /* Try to find new boat */
1301 ferryboat = player_unit_by_number(pplayer,
1302 aiferry_find_boat(ait, punit, 1, NULL));
1303 }
1304
1305 if (punit->id == 0 && is_terrain_class_near_tile(nmap, punit_tile, TC_OCEAN)) {
1306 harbor = TRUE;
1307 }
1308 }
1309
1310 if (NULL != ferryboat) {
1311 boattype = unit_type_get(ferryboat);
1312 pft_fill_unit_overlap_param(&parameter, nmap, ferryboat);
1313 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1314 ferry_map = pf_map_new(&parameter);
1315 } else {
1316 boattype = best_role_unit_for_player(pplayer, L_FERRYBOAT);
1317 if (NULL == boattype) {
1318 /* We pretend that we can have the simplest boat to stimulate tech. */
1319 boattype = get_role_unit(L_FERRYBOAT, 0);
1320 }
1321 if (NULL != boattype && harbor) {
1322 /* Let's simulate a boat at 'punit' position. */
1323 pft_fill_utype_overlap_param(&parameter, nmap, boattype,
1324 punit_tile, pplayer);
1325 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1326 ferry_map = pf_map_new(&parameter);
1327 } else {
1328 ferry_map = NULL;
1329 }
1330 }
1331
1332 can_occupy = unit_can_take_over(punit);
1333
1334 players_iterate(aplayer) {
1335 /* For the virtual unit case, which is when we are called to evaluate
1336 * which units to build, we want to calculate in danger and which
1337 * players we want to make war with in the future. We do _not_ want
1338 * to do this when actually making attacks. */
1339 if ((punit->id == 0 && !POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer))
1340 || (punit->id != 0 && !pplayers_at_war(pplayer, aplayer))) {
1341 continue; /* Not an enemy. */
1342 }
1343
1344 city_list_iterate(aplayer->cities, acity) {
1345 struct tile *atile = city_tile(acity);
1346
1347 if (!is_native_tile(punit_type, atile)
1348 && !can_attack_non_native(punit_type)) {
1349 /* Can't attack this city. It is on land. */
1350 continue;
1351 }
1352
1353 if (handicap && !map_is_known(atile, pplayer)) {
1354 /* Can't see it */
1355 continue;
1356 }
1357
1358 if (pf_map_position(punit_map, atile, &pos)) {
1359 go_by_boat = FALSE;
1360 move_time = pos.turn;
1361 } else if (NULL == ferry_map) {
1362 continue; /* Impossible to handle. */
1363 } else {
1364 struct tile *dest, *beach;
1365
1366 if (!find_beachhead(pplayer, ferry_map, atile, punit_type,
1367 &dest, &beach)) {
1368 continue; /* Impossible to go by boat. */
1369 }
1370 if (!pf_map_position(ferry_map, dest, &pos)) {
1371 fc_assert(pf_map_position(ferry_map, dest, &pos));
1372 continue;
1373 }
1374 move_time = pos.turn; /* Sailing time. */
1375 if (dest != beach) {
1376 move_time++; /* Land time. */
1377 }
1378 if (NULL != ferryboat && unit_tile(ferryboat) != punit_tile) {
1379 if (pf_map_position(punit_map, unit_tile(ferryboat), &pos)) {
1380 move_time += pos.turn; /* Time to reach the boat. */
1381 } else {
1382 continue; /* Cannot reach the boat. */
1383 }
1384 }
1385 go_by_boat = TRUE;
1386 }
1387
1388 if (can_unit_attack_tile(punit, NULL, city_tile(acity))
1389 && (pdefender = get_defender(nmap, punit, city_tile(acity)))) {
1390 vulnerability = unit_def_rating_squared(punit, pdefender);
1391 benefit = unit_build_shield_cost_base(pdefender);
1392 } else {
1393 pdefender = NULL;
1394 vulnerability = 0;
1395 benefit = 0;
1396 }
1397
1398 if (1 < move_time) {
1399 struct unit_type *def_type = dai_choose_defender_versus(acity, punit);
1400
1401 if (def_type) {
1403 punit_type, def_type, aplayer, atile, FALSE,
1404 city_production_unit_veteran_level(acity, def_type));
1405 if (v > vulnerability) {
1406 /* They can build a better defender! */
1407 vulnerability = v;
1408 benefit = utype_build_shield_cost(acity, NULL, def_type);
1409 }
1410 }
1411 }
1412
1413 acity_data = def_ai_city_data(acity, ait);
1414
1415 reserves = (acity_data->invasion.attack
1416 - unit_list_size(acity->tile->units));
1417
1418 if (punit->id == 0) {
1419 /* Real unit would add to reserves once built. */
1421 action_by_number(ACTION_ATTACK))) {
1422 reserves++;
1423 } else {
1424 reserves += punit_type->move_rate;
1425 }
1426 }
1427
1428 if (0 < reserves && (can_occupy
1429 || 0 < acity_data->invasion.occupy)) {
1430 /* There are units able to occupy the city after all defenders
1431 * are killed! */
1432 benefit += acity_data->worth * reserves / 5;
1433 }
1434
1435 attack = attack_value + acity_data->attack;
1436 attack *= attack;
1437 /* Avoiding handling upkeep aggregation this way -- Syela */
1438
1439 /* AI was not sending enough reinforcements to totally wipe out a city
1440 * and conquer it in one turn.
1441 * This variable enables total carnage. -- Syela */
1442 victim_count = unit_list_size(atile->units);
1443
1444 if (!can_occupy && NULL == pdefender) {
1445 /* Nothing there to bash and we can't occupy!
1446 * Not having this check caused warships yoyoing */
1447 want = 0;
1448 } else if (10 < move_time) {
1449 /* Too far! */
1450 want = 0;
1451 } else if (can_occupy && 0 == acity_data->invasion.occupy
1452 && (0 < acity_data->invasion.attack
1453 || victim_count == 0)) {
1454 /* Units able to occupy really needed there! */
1455 want = bcost * SHIELD_WEIGHTING;
1456 } else {
1457 want = kill_desire(benefit, attack, bcost + acity_data->bcost,
1458 vulnerability, victim_count + 1);
1459 }
1460 want -= move_time * (unhap ? SHIELD_WEIGHTING + 2 * TRADE_WEIGHTING
1462 /* Build_cost of ferry. */
1463 needferry = (go_by_boat && NULL == ferryboat
1464 ? utype_build_shield_cost(acity, NULL, boattype) : 0);
1465 /* FIXME: add time to build the ferry? */
1467 want, MAX(1, move_time),
1468 bcost_bal + needferry);
1469
1470 /* BEGIN STEAM-ENGINES-ARE-OUR-FRIENDS KLUGE. */
1471 if (0 >= want && 0 == punit->id && 0 >= best) {
1472 adv_want bk_e = military_amortize(pplayer,
1474 benefit * SHIELD_WEIGHTING,
1475 MAX(1, move_time),
1476 bcost_bal + needferry);
1477
1478 if (bk_e > bk) {
1479 *pdest_tile = atile;
1480 if (NULL != pferrymap) {
1481 *pferrymap = go_by_boat ? ferry_map : NULL;
1482 }
1483 if (NULL != pferryboat) {
1484 *pferryboat = go_by_boat ? ferryboat : NULL;
1485 }
1486 if (NULL != pboattype) {
1487 *pboattype = go_by_boat ? boattype : NULL;
1488 }
1489 if (NULL != pmove_time) {
1490 *pmove_time = move_time;
1491 }
1492 goto_dest_tile = (go_by_boat && NULL != ferryboat
1493 ? unit_tile(ferryboat) : atile);
1494 bk = bk_e;
1495 }
1496 }
1497 /* END STEAM-ENGINES KLUGE */
1498
1499 if (0 != punit->id
1500 && NULL != ferryboat
1501 && punit_class->adv.sea_move == MOVE_NONE) {
1503 "%s(): with boat %s@(%d, %d) -> %s@(%d, %d)"
1504 " (go_by_boat = %d, move_time = %d, want = " ADV_WANT_PRINTF
1505 ", best = " ADV_WANT_PRINTF ")",
1506 __FUNCTION__, unit_rule_name(ferryboat),
1507 TILE_XY(unit_tile(ferryboat)), city_name_get(acity),
1508 TILE_XY(atile), go_by_boat, move_time, want, best);
1509 }
1510
1511 if (want > best && ai_fuzzy(pplayer, TRUE)) {
1512 /* Yes, we like this target */
1513 best = want;
1514 *pdest_tile = atile;
1515 if (NULL != pferrymap) {
1516 *pferrymap = go_by_boat ? ferry_map : NULL;
1517 }
1518 if (NULL != pferryboat) {
1519 *pferryboat = go_by_boat ? ferryboat : NULL;
1520 }
1521 if (NULL != pboattype) {
1522 *pboattype = go_by_boat ? boattype : NULL;
1523 }
1524 if (NULL != pmove_time) {
1525 *pmove_time = move_time;
1526 }
1527 goto_dest_tile = (go_by_boat && NULL != ferryboat
1528 ? unit_tile(ferryboat) : atile);
1529 }
1531
1533 /* I'm not sure the following code is good but it seems to be adequate.
1534 * I am deliberately not adding ferryboat code to the unit_list_iterate.
1535 * -- Syela */
1536 unit_list_iterate(aplayer->units, aunit) {
1537 struct tile *atile = unit_tile(aunit);
1538
1539 if (NULL != tile_city(atile)) {
1540 /* already dealt with it. */
1541 continue;
1542 }
1543
1544 if (handicap && !map_is_known(atile, pplayer)) {
1545 /* Can't see the target. */
1546 continue;
1547 }
1548
1550 && 0 == punit->id) {
1551 /* We will not build units just to chase caravans and
1552 * ambassadors. */
1553 continue;
1554 }
1555
1556 /* We have to assume the attack is diplomatically ok.
1557 * We cannot use can_player_attack_tile, because we might not
1558 * be at war with aplayer yet */
1559 if (!can_unit_attack_tile(punit, NULL, atile)
1560 || aunit != get_defender(nmap, punit, atile)) {
1561 /* We cannot attack it, or it is not the main defender. */
1562 continue;
1563 }
1564
1565 if (!pf_map_position(punit_map, atile, &pos)) {
1566 /* Cannot reach it. */
1567 continue;
1568 }
1569
1570 vulnerability = unit_def_rating_squared(punit, aunit);
1571 benefit = unit_build_shield_cost_base(aunit);
1572
1573 move_time = pos.turn;
1574 if (10 < move_time) {
1575 /* Too far. */
1576 want = 0;
1577 } else {
1578 want = kill_desire(benefit, attack, bcost, vulnerability, 1);
1579 /* Take into account maintenance of the unit. */
1580 /* FIXME: Depends on the government. */
1581 want -= move_time * SHIELD_WEIGHTING;
1582 /* Take into account unhappiness
1583 * (costs 2 luxuries to compensate). */
1584 want -= (unhap ? 2 * move_time * TRADE_WEIGHTING : 0);
1585 }
1587 want, MAX(1, move_time), bcost_bal);
1588 if (want > best && ai_fuzzy(pplayer, TRUE)) {
1589 best = want;
1590 *pdest_tile = atile;
1591 if (NULL != pferrymap) {
1592 *pferrymap = NULL;
1593 }
1594 if (NULL != pferryboat) {
1595 *pferryboat = NULL;
1596 }
1597 if (NULL != pboattype) {
1598 *pboattype = NULL;
1599 }
1600 if (NULL != pmove_time) {
1601 *pmove_time = move_time;
1602 }
1603 goto_dest_tile = atile;
1604 }
1607
1608 if (NULL != ppath) {
1609 *ppath = (NULL != goto_dest_tile && goto_dest_tile != punit_tile
1610 ? pf_map_path(punit_map, goto_dest_tile) : NULL);
1611 }
1612
1613 pf_map_destroy(punit_map);
1614 if (NULL != ferry_map
1615 && (NULL == pferrymap || *pferrymap != ferry_map)) {
1616 pf_map_destroy(ferry_map);
1617 }
1618
1620
1621 return best;
1622}
1623
1624/**********************************************************************/
1633{
1634 struct pf_parameter parameter;
1635 struct pf_map *pfm;
1636 struct player *pplayer = unit_owner(punit);
1637 struct city *pcity, *best_city = NULL;
1638 int best = FC_INFINITY, cur;
1639 const struct civ_map *nmap = &(wld.map);
1640
1641 pft_fill_unit_parameter(&parameter, nmap, punit);
1642 parameter.omniscience = !has_handicap(pplayer, H_MAP);
1643 pfm = pf_map_new(&parameter);
1644
1645 pf_map_move_costs_iterate(pfm, ptile, move_cost, TRUE) {
1646 if (move_cost > best) {
1647 /* We already found a better city. No need to continue. */
1648 break;
1649 }
1650
1651 pcity = tile_city(ptile);
1652 if (NULL == pcity || !pplayers_allied(pplayer, city_owner(pcity))) {
1653 continue;
1654 }
1655
1656 /* Score based on the move cost. */
1657 cur = move_cost;
1658
1659 /* Note the unit owner may be different from the city owner. */
1660 if (0 == get_unittype_bonus(unit_owner(punit), ptile,
1661 unit_type_get(punit), NULL,
1662 EFT_HP_REGEN)) {
1663 /* If we cannot regen fast our hit points here, let's make some
1664 * penalty. */
1665 cur *= 3;
1666 }
1667
1668 if (cur < best) {
1669 best_city = pcity;
1670 best = cur;
1671 }
1673
1674 pf_map_destroy(pfm);
1675 return best_city;
1676}
1677
1678/**********************************************************************/
1684 struct player *pplayer,
1685 struct unit *punit)
1686{
1687 struct city *pc;
1688 bool only_continent = TRUE;
1689
1690 if (unit_transported(punit)) {
1691 /* If we are in transport, we can go to any continent.
1692 * Actually, we are not currently in a continent where to stay. */
1693 only_continent = FALSE;
1694 }
1695
1696 if ((pc = find_closest_city(unit_tile(punit), NULL, pplayer, FALSE,
1697 only_continent, FALSE, FALSE, TRUE, NULL))) {
1699 UNIT_LOG(LOG_DEBUG, punit, "Barbarian heading to conquer %s",
1700 city_name_get(pc));
1701 (void) dai_gothere(ait, pplayer, punit, pc->tile);
1702 } else {
1703 struct unit *ferry = NULL;
1704
1705 if (unit_transported(punit)) {
1706 ferry = unit_transport_get(punit);
1707
1708 /* We already are in a boat so it needs no
1709 * free capacity */
1710 if (!is_boat_free(ait, ferry, punit, 0)) {
1711 /* We cannot control our ferry. */
1712 ferry = NULL;
1713 }
1714 } else {
1715 /* We are not in a boat yet. Search for one. */
1716 unit_list_iterate(unit_tile(punit)->units, aunit) {
1717 if (is_boat_free(ait, aunit, punit, 1)
1718 && unit_transport_load(punit, aunit, FALSE)) {
1719 ferry = aunit;
1720 break;
1721 }
1723 }
1724
1725 if (ferry) {
1726 UNIT_LOG(LOG_DEBUG, punit, "Barbarian sailing to conquer %s",
1727 city_name_get(pc));
1728 (void) aiferry_goto_amphibious(ait, ferry, punit, pc->tile);
1729 } else {
1730 /* This is not an error. Somebody else might be in charge
1731 * of the ferry. */
1732 UNIT_LOG(LOG_DEBUG, punit, "unable to find barbarian ferry");
1733 }
1734 }
1735 } else {
1736 UNIT_LOG(LOG_DEBUG, punit, "Barbarian find no target city");
1737 }
1738}
1739
1740/**********************************************************************/
1746static void dai_military_attack(struct ai_type *ait, struct player *pplayer,
1747 struct unit *punit)
1748{
1749 struct tile *dest_tile;
1750 int id = punit->id;
1751 int ct = 10;
1752 struct city *pcity = NULL;
1753
1755
1756 /* Barbarians pillage, and might keep on doing that so they sometimes
1757 * even finish it. */
1758 if (punit->activity == ACTIVITY_PILLAGE && is_barbarian(pplayer)
1759 && fc_rand(2) == 1) {
1760 return;
1761 }
1762
1763 /* First find easy nearby enemies, anything better than pillage goes.
1764 * NB: We do not need to repeat dai_military_rampage, it is repeats itself
1765 * until it runs out of targets. */
1766 /* FIXME: 1. dai_military_rampage never checks if it should defend newly
1767 * conquered cities.
1768 * FIXME: 2. would be more convenient if it returned FALSE if we run out
1769 * of moves too.*/
1771 return; /* we died */
1772 }
1773
1774 if (punit->moves_left <= 0) {
1775 return;
1776 }
1777
1778 /* Main attack loop */
1779 do {
1780 struct tile *start_tile = unit_tile(punit);
1781 struct pf_path *path;
1782 struct unit *ferryboat;
1783
1784 /* Then find enemies the hard way */
1785 find_something_to_kill(ait, pplayer, punit, &dest_tile, &path,
1786 NULL, &ferryboat, NULL, NULL);
1787 if (!same_pos(unit_tile(punit), dest_tile)) {
1788 if (!is_tiles_adjacent(unit_tile(punit), dest_tile)
1789 || !can_unit_attack_tile(punit, NULL, dest_tile)) {
1790
1791 /* Adjacent and can't attack usually means we are not marines
1792 * and on a ferry. This fixes the problem (usually). */
1793 UNIT_LOG(LOG_DEBUG, punit, "mil att gothere -> (%d, %d)",
1794 TILE_XY(dest_tile));
1795
1796 /* Set ACTIVITY_GOTO more permanently than just inside
1797 * adv_follow_path(). This way other units will know we're
1798 * on our way even if we don't reach target yet. */
1799 punit->goto_tile = dest_tile;
1800 unit_activity_handling(punit, ACTIVITY_GOTO);
1801 if (NULL != path && !adv_follow_path(punit, path, dest_tile)) {
1802 /* Died. */
1803 pf_path_destroy(path);
1804 return;
1805 }
1806 if (NULL != ferryboat) {
1807 /* Need a boat. */
1808 aiferry_gobyboat(ait, pplayer, punit, dest_tile, FALSE);
1809 pf_path_destroy(path);
1810 return;
1811 }
1812 if (0 >= punit->moves_left) {
1813 /* No moves left. */
1814 pf_path_destroy(path);
1815 return;
1816 }
1817
1818 /* Either we're adjacent or we sitting on the tile. We might be
1819 * sitting on the tile if the enemy that _was_ sitting there
1820 * attacked us and died _and_ we had enough movement to get there */
1821 if (same_pos(unit_tile(punit), dest_tile)) {
1822 UNIT_LOG(LOG_DEBUG, punit, "mil att made it -> (%d, %d)",
1823 TILE_XY(dest_tile));
1824 pf_path_destroy(path);
1825 break;
1826 }
1827 }
1828
1829 if (is_tiles_adjacent(unit_tile(punit), dest_tile)) {
1830 /* Close combat. fstk sometimes want us to attack an adjacent
1831 * enemy that rampage wouldn't */
1832 UNIT_LOG(LOG_DEBUG, punit, "mil att bash -> (%d, %d)",
1833 TILE_XY(dest_tile));
1834 if (!dai_unit_attack(ait, punit, dest_tile)) {
1835 /* Died */
1836 pf_path_destroy(path);
1837 return;
1838 }
1839 } else if (!same_pos(start_tile, unit_tile(punit))) {
1840 /* Got stuck. Possibly because of adjacency to an
1841 * enemy unit. Perhaps we are in luck and are now next to a
1842 * tempting target? Let's find out... */
1845 pf_path_destroy(path);
1846 return;
1847 }
1848
1849 } else {
1850 /* FIXME: This happens a bit too often! */
1851 UNIT_LOG(LOG_DEBUG, punit, "fstk didn't find us a worthy target!");
1852 /* No worthy enemies found, so abort loop */
1853 ct = 0;
1854 }
1855 pf_path_destroy(path);
1856
1857 ct--; /* infinite loops from railroads must be stopped */
1858 } while (punit->moves_left > 0 && ct > 0);
1859
1860 /* Cleanup phase */
1861 if (punit->moves_left == 0) {
1862 return;
1863 }
1865 if (pcity != NULL
1866 && (dai_is_ferry(punit, ait)
1867 || punit->hp < unit_type_get(punit)->hp * 0.50)) { /* WAG */
1868 /* Go somewhere safe */
1869 UNIT_LOG(LOG_DEBUG, punit, "heading to nearest safe house.");
1870 (void) dai_unit_goto(ait, punit, pcity->tile);
1871 } else if (!is_barbarian(pplayer)) {
1872 /* Nothing else to do, so try exploring. */
1873 switch (manage_auto_explorer(punit)) {
1874 case MR_DEATH:
1875 /* don't use punit! */
1876 return;
1877 case MR_OK:
1878 UNIT_LOG(LOG_DEBUG, punit, "nothing else to do, so exploring");
1879 break;
1880 default:
1881 UNIT_LOG(LOG_DEBUG, punit, "nothing to do - no more exploring either");
1882 break;
1883 };
1884 } else {
1885 /* You can still have some moves left here, but barbarians should
1886 not sit helplessly, but advance towards nearest known enemy city */
1887 UNIT_LOG(LOG_DEBUG, punit, "attack: barbarian");
1888 dai_military_attack_barbarian(ait, pplayer, punit);
1889 }
1890 if ((punit = game_unit_by_number(id)) && punit->moves_left > 0) {
1891 UNIT_LOG(LOG_DEBUG, punit, "attack: giving up unit to defense");
1892 dai_military_defend(ait, pplayer, punit);
1893 }
1894}
1895
1896/**********************************************************************/
1900static bool dai_find_boat_for_unit(struct ai_type *ait, struct unit *punit)
1901{
1902 bool alive = TRUE;
1903 int ferryboat = 0;
1904 struct pf_path *path_to_ferry = NULL;
1905
1906 UNIT_LOG(LOG_CARAVAN, punit, "requesting a boat!");
1907 ferryboat = aiferry_find_boat(ait, punit, 1, &path_to_ferry);
1908 /* going to meet the boat */
1909 if ((ferryboat <= 0)) {
1911 "in find_boat_for_unit cannot find any boats.");
1912 /* if we are undefended on the country side go to a city */
1913 struct city *current_city = tile_city(unit_tile(punit));
1914 if (current_city == NULL) {
1915 struct city *city_near = find_nearest_safe_city(punit);
1916 if (city_near != NULL) {
1917 alive = dai_unit_goto(ait, punit, city_near->tile);
1918 }
1919 }
1920 } else {
1921 if (path_to_ferry != NULL) {
1922 if (!adv_unit_execute_path(punit, path_to_ferry)) {
1923 /* Died. */
1924 pf_path_destroy(path_to_ferry);
1925 path_to_ferry = NULL;
1926 alive = FALSE;
1927 } else {
1928 pf_path_destroy(path_to_ferry);
1929 path_to_ferry = NULL;
1930 alive = TRUE;
1931 }
1932 }
1933 }
1934 return alive;
1935}
1936
1937/**********************************************************************/
1946 struct tile *ctile, struct tile *ptile)
1947{
1948 /* We usually have Inaccessible terrain, so not testing MOVE_FULL == */
1949 bool lm = MOVE_NONE != pclass->adv.land_move,
1950 sm = MOVE_NONE != pclass->adv.sea_move;
1951 struct civ_map *pmap = &(wld.map);
1952
1953 if (lm && sm) {
1954 return FALSE;
1955 }
1956
1957 /* We could use adjc_iterate() but likely often tiles are on the same
1958 * continent and it will be more time to find where they connect */
1959 iterate_outward(pmap, ctile, 1, atile) {
1960 Continent_id acont = tile_continent(atile);
1961
1962 if (is_ocean_tile(atile) ? sm : lm) {
1963 iterate_outward(pmap, ptile, 1, btile) {
1964 if (tile_continent(btile) == acont) {
1965 return FALSE;
1966 }
1968 }
1970
1971 if (is_tiles_adjacent(ctile, ptile)) {
1972 return FALSE;
1973 }
1974
1975 return TRUE;
1976}
1977
1978/**********************************************************************/
1984static void dai_caravan_goto(struct ai_type *ait, struct player *pplayer,
1985 struct unit *punit,
1986 const struct city *dest_city,
1987 bool help_wonder,
1988 bool required_boat, bool request_boat)
1989{
1990 bool alive = TRUE;
1991 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
1992 const struct civ_map *nmap = &(wld.map);
1993
1994 fc_assert_ret(NULL != dest_city);
1995
1996 /* if we're not there yet, and we can move, move... */
1997 if (!same_pos(dest_city->tile, unit_tile(punit))
1998 && punit->moves_left != 0) {
1999 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) task %s going to %s in %s %s",
2002 dai_unit_task_rule_name(unit_data->task),
2003 help_wonder ? "help a wonder" : "trade", city_name_get(dest_city),
2004 required_boat ? "with a boat" : "");
2005 if (required_boat) {
2006 /* to trade with boat */
2007 if (request_boat) {
2008 /* Try to find new boat */
2009 alive = dai_find_boat_for_unit(ait, punit);
2010 } else {
2011 /* if we are not being transported then ask for a boat again */
2012 alive = TRUE;
2015 unit_tile(punit), dest_city->tile)) {
2016 alive = dai_find_boat_for_unit(ait, punit);
2017 }
2018 }
2019 if (alive) {
2020 /* FIXME: sometimes we get FALSE here just because
2021 * a trireme that we've boarded can't go over an ocean. */
2022 alive = dai_gothere(ait, pplayer, punit, dest_city->tile);
2023 }
2024 } else {
2025 /* to trade without boat */
2026 alive = dai_unit_goto(ait, punit, dest_city->tile);
2027 }
2028 }
2029
2030 /* if moving didn't kill us, and we got to the destination, handle it. */
2031 if (alive && real_map_distance(dest_city->tile, unit_tile(punit)) <= 1) {
2032 /* release the boat! */
2033 if (unit_transported(punit)) {
2035 }
2036 if (help_wonder && is_action_enabled_unit_on_city(nmap, ACTION_HELP_WONDER,
2037 punit, dest_city)) {
2038 /*
2039 * We really don't want to just drop all caravans in immediately.
2040 * Instead, we want to aggregate enough caravans to build instantly.
2041 * -AJS, 990704
2042 */
2043 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) helps build wonder in %s",
2046 punit->id,
2048 city_name_get(dest_city));
2049 unit_do_action(pplayer, punit->id, dest_city->id,
2050 0, "", ACTION_HELP_WONDER);
2051 } else if (is_action_enabled_unit_on_city(nmap, ACTION_TRADE_ROUTE,
2052 punit, dest_city)) {
2053 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) creates trade route in %s",
2056 punit->id,
2058 city_name_get(dest_city));
2059 unit_do_action(pplayer, punit->id, dest_city->id,
2060 0, "", ACTION_TRADE_ROUTE);
2061 } else if (is_action_enabled_unit_on_city(nmap, ACTION_MARKETPLACE,
2062 punit, dest_city)) {
2063 /* Get the one time bonus. */
2064 log_base(LOG_CARAVAN, "%s %s[%d](%d,%d) enters marketplace of %s",
2067 punit->id,
2069 city_name_get(dest_city));
2070 unit_do_action(pplayer, punit->id, dest_city->id,
2071 0, "", ACTION_MARKETPLACE);
2072 } else {
2073 enum log_level level = LOG_NORMAL;
2074
2075 if (help_wonder) {
2076 /* A Caravan ordered to help build wonder may arrive after
2077 * enough shields to build the wonder is produced. */
2079 }
2080
2082 "%s %s[%d](%d,%d) unable to trade with %s",
2085 punit->id,
2087 city_name_get(dest_city));
2088 }
2089 }
2090}
2091
2092/**********************************************************************/
2096static void caravan_optimize_callback(const struct caravan_result *result,
2097 void *data)
2098{
2099 const struct unit *caravan = data;
2100
2101 log_base(LOG_CARAVAN3, "%s %s[%d](%d,%d) %s: %s %s worth %g",
2103 unit_rule_name(caravan),
2104 caravan->id,
2105 TILE_XY(unit_tile(caravan)),
2106 city_name_get(result->src),
2107 result->help_wonder ? "wonder in" : "trade to",
2108 city_name_get(result->dest),
2109 result->value);
2110}
2111
2112/**********************************************************************/
2116 struct unit *punit)
2117{
2118 struct tile *src = NULL, *dest = NULL, *src_home_city = NULL;
2119 struct city *phome_city = NULL;
2120 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2121
2122 if ((unit_data->task != AIUNIT_NONE)) {
2123 src = unit_tile(punit);
2124 phome_city = game_city_by_number(punit->homecity);
2125 if (phome_city != NULL) {
2126 src_home_city = city_tile(phome_city);
2127 }
2128 dest = punit->goto_tile;
2129
2130 if (src == NULL || dest == NULL) {
2131 return FALSE;
2132 }
2133
2134 /* If we have a home continent, and are not there.
2135 * (FIXME: well, why?)
2136 * (I guess because home continent is which we were supposed to leave,
2137 * not the target continent) */
2138 if (src_home_city != NULL
2139 && tile_continent(src) != tile_continent(src_home_city)) {
2140 return FALSE;
2141 }
2142
2143 if (!goto_is_sane(punit, dest)) {
2144 if (unit_transported(punit)) {
2145 /* if we're being transported */
2146 return FALSE;
2147 }
2148 if ((punit->server.birth_turn + 15 < game.info.turn)) {
2149 /* we are tired of waiting */
2150 int ferrys = aiferry_avail_boats(ait, punit->owner);
2151
2152 if (ferrys <= 0) {
2153 /* there are no ferrys available... give up */
2154 return TRUE;
2155 } else {
2156 if (punit->server.birth_turn + 20 < game.info.turn) {
2157 /* we are feed up! */
2158 return TRUE;
2159 }
2160 }
2161 }
2162 }
2163 }
2164
2165 return FALSE;
2166}
2167
2168/**********************************************************************/
2175 struct unit *punit)
2176{
2177 struct city *pcity = game_city_by_number(punit->homecity);
2178 Continent_id continent;
2179
2180 fc_assert(pcity != NULL);
2181
2182 if (unit_class_get(punit)->adv.ferry_types <= 0) {
2183 /* There is just no possible transporters. */
2184 return FALSE;
2185 }
2186 continent = tile_continent(pcity->tile);
2187
2188 /* Look for proper destination city at different continent. */
2189 city_list_iterate(pplayer->cities, acity) {
2190 if (can_cities_trade(pcity, acity)) {
2191 if (tile_continent(acity->tile) != continent) {
2192 return TRUE;
2193 }
2194 }
2196
2197 players_iterate(aplayer) {
2198 if (aplayer == pplayer || !aplayer->is_alive) {
2199 continue;
2200 }
2201 if (pplayers_allied(pplayer, aplayer)) {
2202 city_list_iterate(aplayer->cities, acity) {
2203 if (can_cities_trade(pcity, acity)) {
2204 if (tile_continent(acity->tile) != continent) {
2205 return TRUE;
2206 }
2207 }
2210 }
2211
2212 return FALSE;
2213}
2214
2215/**********************************************************************/
2219static bool search_homecity_for_caravan(struct ai_type *ait, struct unit *punit)
2220{
2221 struct city *nearest = NULL;
2222 int min_dist = FC_INFINITY;
2223 struct tile *current_loc = unit_tile(punit);
2224 Continent_id continent = tile_continent(current_loc);
2225 bool alive = TRUE;
2226
2228 struct tile *ctile = city_tile(pcity);
2229
2230 if (tile_continent(ctile) == continent) {
2231 int this_dist = map_distance(current_loc, ctile);
2232
2233 if (this_dist < min_dist) {
2234 min_dist = this_dist;
2235 nearest = pcity;
2236 }
2237 }
2239
2240 if (nearest != NULL) {
2241 alive = dai_unit_goto(ait, punit, nearest->tile);
2242 if (alive && same_pos(unit_tile(punit), nearest->tile)) {
2243 dai_unit_make_homecity(punit, nearest);
2244 }
2245 }
2246
2247 return alive;
2248}
2249
2250/**********************************************************************/
2256static void dai_manage_caravan(struct ai_type *ait, struct player *pplayer,
2257 struct unit *punit)
2258{
2259 struct caravan_parameter parameter;
2260 struct caravan_result result;
2261 const struct city *homecity;
2262 const struct city *dest = NULL;
2263 struct unit_ai *unit_data;
2264 struct unit_class *pclass = unit_class_get(punit);
2265 bool expect_boats = pclass->adv.ferry_types > 0;
2266 /* TODO: will pplayer have a boat for punit in a reasonable time? */
2267 bool help_wonder = FALSE;
2268 bool required_boat = FALSE;
2269 bool request_boat = FALSE;
2270 bool tired_of_waiting_boat = FALSE;
2271 const struct civ_map *nmap = &(wld.map);
2272
2274
2275 if (!unit_can_do_action(punit, ACTION_TRADE_ROUTE)
2276 && !unit_can_do_action(punit, ACTION_MARKETPLACE)
2277 && !unit_can_do_action(punit, ACTION_HELP_WONDER)) {
2278 /* we only want units that can establish trade, enter marketplace or
2279 * help build wonders */
2280 return;
2281 }
2282
2283 unit_data = def_ai_unit_data(punit, ait);
2284
2285 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d) task %s to (%d,%d)",
2288 dai_unit_task_rule_name(unit_data->task),
2290
2291 homecity = game_city_by_number(punit->homecity);
2292 if (homecity == NULL && unit_data->task == AIUNIT_TRADE) {
2294 return;
2295 }
2296 homecity = game_city_by_number(punit->homecity);
2297 if (homecity == NULL) {
2298 return;
2299 }
2300 }
2301
2302 if ((unit_data->task == AIUNIT_TRADE
2303 || unit_data->task == AIUNIT_WONDER)) {
2304 /* we are moving to our destination */
2305 /* we check to see if our current goal is feasible */
2306 struct city *city_dest = tile_city(punit->goto_tile);
2307
2308 if ((city_dest == NULL)
2309 || !pplayers_allied(unit_owner(punit), city_dest->owner)
2310 || (unit_data->task == AIUNIT_TRADE
2311 && !(can_cities_trade(homecity, city_dest)
2312 && can_establish_trade_route(homecity, city_dest)))
2313 || (unit_data->task == AIUNIT_WONDER
2314 /* Helping the (new) production is illegal. */
2316 || (unit_data->task == AIUNIT_TRADE
2317 && real_map_distance(city_dest->tile, unit_tile(punit)) <= 1
2318 && !(is_action_enabled_unit_on_city(nmap, ACTION_TRADE_ROUTE,
2319 punit, city_dest)
2320 || is_action_enabled_unit_on_city(nmap, ACTION_MARKETPLACE,
2321 punit, city_dest)))
2322 || (unit_data->task == AIUNIT_WONDER
2323 && real_map_distance(city_dest->tile, unit_tile(punit)) <= 1
2324 && !is_action_enabled_unit_on_city(nmap, ACTION_HELP_WONDER,
2325 punit, city_dest))) {
2326 /* destination invalid! */
2327 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
2328 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d) destination invalid!",
2331 } else {
2332 /* destination valid, are we tired of waiting for a boat? */
2333 if (expect_boats && dai_is_unit_tired_waiting_boat(ait, punit)) {
2335 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
2336 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d) unit tired of waiting!",
2339 tired_of_waiting_boat = TRUE;
2340 } else {
2341 dest = city_dest;
2342 help_wonder = (unit_data->task == AIUNIT_WONDER) ? TRUE : FALSE;
2343 required_boat = uclass_need_trans_between(pclass, unit_tile(punit), dest->tile);
2344 request_boat = FALSE;
2345 }
2346 }
2347 }
2348
2349 if (unit_data->task == AIUNIT_NONE) {
2350 if (homecity == NULL) {
2351 /* FIXME: We shouldn't bother in getting homecity for
2352 * caravan that will then be used for wonder building. */
2354 return;
2355 }
2356 homecity = game_city_by_number(punit->homecity);
2357 if (homecity == NULL) {
2358 return;
2359 }
2360 }
2361
2363 /* Make more trade with allies than other peaceful nations
2364 * by considering only allies 50% of the time.
2365 * (the other 50% allies are still considered, but so are other nations) */
2366 if (fc_rand(2)) {
2367 /* Be optimistic about development of relations with no-contact and
2368 * cease-fire nations. */
2369 parameter.allow_foreign_trade = FTL_NONWAR;
2370 } else {
2371 parameter.allow_foreign_trade = FTL_ALLIED;
2372 }
2373
2376 parameter.callback_data = punit;
2377 }
2379 parameter.ignore_transit_time = TRUE;
2380 }
2381 if (tired_of_waiting_boat) {
2383 parameter.ignore_transit_time = FALSE;
2384 }
2385 caravan_find_best_destination(nmap, punit, &parameter, &result,
2386 !has_handicap(pplayer, H_MAP));
2387 if (result.dest != NULL) {
2388 /* We did find a new destination for the unit */
2389 dest = result.dest;
2390 help_wonder = result.help_wonder;
2391 required_boat = uclass_need_trans_between(pclass, unit_tile(punit), dest->tile);
2392 request_boat = required_boat;
2394 (help_wonder) ? AIUNIT_WONDER : AIUNIT_TRADE,
2395 dest->tile);
2396 } else {
2397 dest = NULL;
2398 }
2399 }
2400
2401 if (required_boat && !expect_boats) {
2402 /* Would require boat, but can't have them. Render destination invalid. */
2403 dest = NULL;
2404 }
2405
2406 if (dest != NULL) {
2407 dai_caravan_goto(ait, pplayer, punit, dest, help_wonder,
2408 required_boat, request_boat);
2409 return; /* that may have clobbered the unit */
2410 } else {
2411 /* We have nowhere to go! */
2412 log_base(LOG_CARAVAN2, "%s %s[%d](%d,%d), nothing to do!",
2416 /* Should we become a defensive unit? */
2417 }
2418}
2419
2420/**********************************************************************/
2425 struct unit *punit)
2426{
2427 struct player *pplayer = unit_owner(punit);
2428 struct city *pcity = tile_city(unit_tile(punit));
2429 struct city *safe = NULL;
2430 const struct unit_type *punittype = unit_type_get(punit);
2431 bool no_recovery;
2432
2434
2435 if (pcity != NULL) {
2436 /* Rest in the city until the hitpoints are recovered, but attempt
2437 * to protect city from attack (and be opportunistic too)*/
2440 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "recovering hit points.");
2441 } else {
2442 return; /* We died heroically defending our city */
2443 }
2444 } else {
2445 /* Goto to nearest city to recover hit points */
2446 /* Just before, check to see if we can occupy an undefended enemy city */
2449 return; /* Oops, we died */
2450 }
2451
2452 /* Find a city to stay and go there */
2454 if (safe) {
2455 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "going to %s to recover",
2456 city_name_get(safe));
2457 if (!dai_unit_goto(ait, punit, safe->tile)) {
2458 log_base(LOGLEVEL_RECOVERY, "died trying to hide and recover");
2459 return;
2460 }
2461 } else {
2462 /* Oops */
2463 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "didn't find a city to recover in!");
2464 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
2465 dai_military_attack(ait, pplayer, punit);
2466 return;
2467 }
2468 }
2469
2470 /* Is the unit still damaged? If true, and could recover hit points, do so.
2471 * Don't wait if would be losing hitpoints that way! */
2472 no_recovery = FALSE;
2473 if (punit->hp == punittype->hp) {
2474 no_recovery = TRUE;
2475 } else {
2476 int gain = unit_gain_hitpoints(punit);
2477
2478 if (gain < 0) {
2479 no_recovery = TRUE;
2480 } else if (gain == 0 && !punit->moved) {
2481 /* Isn't gaining even though has not moved. */
2482 no_recovery = TRUE;
2483 }
2484 }
2485 if (no_recovery) {
2486 /* We are ready to go out and kick ass again */
2487 UNIT_LOG(LOGLEVEL_RECOVERY, punit, "ready to kick ass again!");
2488 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
2489 return;
2490 } else {
2491 def_ai_unit_data(punit, ait)->done = TRUE; /* Sit tight */
2492 }
2493}
2494
2495/**********************************************************************/
2499void dai_manage_military(struct ai_type *ait, const struct civ_map *nmap,
2500 struct player *pplayer, struct unit *punit)
2501{
2502 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2503 int id = punit->id;
2504
2506
2507 /* "Escorting" aircraft should not do anything. They are activated
2508 * by their transport or charge. We do _NOT_ set them to 'done'
2509 * since they may need be activated once our charge moves. */
2510 if (unit_data->task == AIUNIT_ESCORT
2512 return;
2513 }
2514
2515 if ((punit->activity == ACTIVITY_SENTRY
2516 || punit->activity == ACTIVITY_FORTIFIED)
2517 && has_handicap(pplayer, H_AWAY)) {
2518 /* Don't move sentried or fortified units controlled by a player
2519 * in away mode. */
2520 unit_data->done = TRUE;
2521 return;
2522 }
2523
2524 /* Since military units re-evaluate their actions every turn,
2525 we must make sure that previously reserved ferry is freed. */
2527
2529 /* Try hunting with this unit */
2530 if (dai_hunter_qualify(pplayer, punit)) {
2531 int result, sanity = punit->id;
2532
2533 UNIT_LOG(LOGLEVEL_HUNT, punit, "is qualified as hunter");
2534 result = dai_hunter_manage(ait, pplayer, punit);
2535 if (NULL == game_unit_by_number(sanity)) {
2537 return; /* died */
2538 }
2539 if (result == -1) {
2540 (void) dai_hunter_manage(ait, pplayer, punit); /* More carnage */
2542 return;
2543 } else if (result >= 1) {
2545 return; /* Done moving */
2546 } else if (unit_data->task == AIUNIT_HUNTER) {
2547 /* This should be very rare */
2548 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
2549 }
2550 } else if (unit_data->task == AIUNIT_HUNTER) {
2551 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
2552 }
2554
2555 /* Do we have a specific job for this unit? If not, we default
2556 * to attack. */
2557 dai_military_findjob(ait, nmap, pplayer, punit);
2558
2559 switch (unit_data->task) {
2561 case AIUNIT_BUILD_CITY:
2562 fc_assert(FALSE); /* This is not the place for this role */
2563 break;
2564 case AIUNIT_DEFEND_HOME:
2566 dai_military_defend(ait, pplayer, punit);
2568 break;
2569 case AIUNIT_ATTACK:
2570 case AIUNIT_NONE:
2572 dai_military_attack(ait, pplayer, punit);
2574 break;
2575 case AIUNIT_ESCORT:
2577 dai_military_bodyguard(ait, pplayer, punit);
2579 break;
2580 case AIUNIT_EXPLORE:
2581 switch (manage_auto_explorer(punit)) {
2582 case MR_DEATH:
2583 /* don't use punit! */
2584 return;
2585 case MR_OK:
2586 UNIT_LOG(LOG_DEBUG, punit, "more exploring");
2587 break;
2588 default:
2589 UNIT_LOG(LOG_DEBUG, punit, "no more exploring either");
2590 break;
2591 };
2592 def_ai_unit_data(punit, ait)->done = (punit->moves_left <= 0);
2593 break;
2594 case AIUNIT_RECOVER:
2598 break;
2599 case AIUNIT_HUNTER:
2600 fc_assert(FALSE); /* dealt with above */
2601 break;
2602 default:
2604 }
2605
2606 /* If we are still alive, either sentry or fortify. */
2607 if ((punit = game_unit_by_number(id))) {
2608 unit_data = def_ai_unit_data(punit, ait);
2609 struct city *pcity = tile_city(unit_tile(punit));
2610
2611 if (unit_list_find(unit_tile(punit)->units,
2612 unit_data->ferryboat)) {
2613 unit_activity_handling(punit, ACTIVITY_SENTRY);
2614 } else if (pcity || punit->activity == ACTIVITY_IDLE) {
2615 /* We do not need to fortify in cities - we fortify and sentry
2616 * according to home defense setup, for easy debugging. */
2617 if (!pcity || unit_data->task == AIUNIT_DEFEND_HOME) {
2618 if (punit->activity == ACTIVITY_IDLE
2619 || punit->activity == ACTIVITY_SENTRY) {
2620 unit_activity_handling(punit, ACTIVITY_FORTIFYING);
2621 }
2622 } else {
2623 unit_activity_handling(punit, ACTIVITY_SENTRY);
2624 }
2625 }
2626 }
2627}
2628
2629/**********************************************************************/
2632static void dai_manage_settler(struct ai_type *ait, struct player *pplayer,
2633 struct unit *punit)
2634{
2635 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2636
2637 unit_server_side_agent_set(pplayer, punit, SSA_AUTOSETTLER);
2638 unit_data->done = TRUE; /* we will manage this unit later... ugh */
2639 /* if BUILD_CITY must remain BUILD_CITY, otherwise turn into autosettler */
2640 if (unit_data->task == AIUNIT_NONE) {
2642 }
2643 return;
2644}
2645
2646/**********************************************************************/
2654void dai_manage_unit(struct ai_type *ait, struct player *pplayer,
2655 struct unit *punit)
2656{
2657 struct unit_ai *unit_data;
2658 struct unit *bodyguard = aiguard_guard_of(ait, punit);
2659 bool is_ferry = FALSE;
2660 const struct unit_type *ptype;
2661 const struct civ_map *nmap = &(wld.map);
2662
2664
2665 /* Don't manage the unit if it is under human orders. */
2666 if (unit_has_orders(punit)) {
2667 unit_data = def_ai_unit_data(punit, ait);
2668
2669 UNIT_LOG(LOG_VERBOSE, punit, "is under human orders, aborting AI control.");
2670 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
2671 unit_data->done = TRUE;
2672 return;
2673 }
2674
2675 /* Check if we have lost our bodyguard. If we never had one, all
2676 * fine. If we had one and lost it, ask for a new one. */
2677 if (!bodyguard && aiguard_has_guard(ait, punit)) {
2678 UNIT_LOG(LOGLEVEL_BODYGUARD, punit, "lost bodyguard, asking for new");
2680 }
2681
2682 unit_data = def_ai_unit_data(punit, ait);
2683
2684 if (punit->moves_left <= 0) {
2685 /* Can do nothing */
2686 unit_data->done = TRUE;
2687 return;
2688 }
2689
2690 is_ferry = dai_is_ferry(punit, ait);
2691
2692 ptype = unit_type_get(punit);
2693
2694 if (utype_has_flag(ptype, UTYF_DIPLOMAT)) {
2696 dai_manage_diplomat(ait, pplayer, punit);
2698 return;
2699 } else if (ptype->adv.worker
2701 dai_manage_settler(ait, pplayer, punit);
2702 return;
2703 } else if (unit_can_do_action(punit, ACTION_TRADE_ROUTE)
2704 || unit_can_do_action(punit, ACTION_MARKETPLACE)
2705 || unit_can_do_action(punit, ACTION_HELP_WONDER)) {
2707 dai_manage_caravan(ait, pplayer, punit);
2709 return;
2710 } else if (unit_has_type_role(punit, L_BARBARIAN_LEADER)) {
2711 dai_manage_barbarian_leader(ait, pplayer, punit);
2712 return;
2713 } else if (unit_can_do_action_result(punit, ACTRES_PARADROP)
2714 || unit_can_do_action_result(punit, ACTRES_PARADROP_CONQUER)) {
2715 dai_manage_paratrooper(ait, pplayer, punit);
2716 return;
2717 } else if (is_ferry && unit_data->task != AIUNIT_HUNTER) {
2719 dai_manage_ferryboat(ait, pplayer, punit);
2721 return;
2722 } else if (utype_fuel(ptype)
2723 && unit_data->task != AIUNIT_ESCORT) {
2725 dai_manage_airunit(ait, pplayer, punit);
2727 return;
2728 } else if (is_losing_hp(punit)) {
2729 /* This unit is losing hitpoints over time */
2730
2731 /* TODO: We can try using air-unit code for helicopters, just
2732 * pretend they have fuel = HP / 3 or something. */
2733 unit_data->done = TRUE; /* we did our best, which was ...
2734 nothing */
2735 return;
2736 } else if (is_military_unit(punit)) {
2738 UNIT_LOG(LOG_DEBUG, punit, "recruit unit for the military");
2739 dai_manage_military(ait, nmap, pplayer, punit);
2741 return;
2742 } else {
2743 /* what else could this be? -- Syela */
2744 switch (manage_auto_explorer(punit)) {
2745 case MR_DEATH:
2746 /* don't use punit! */
2747 break;
2748 case MR_OK:
2749 UNIT_LOG(LOG_DEBUG, punit, "now exploring");
2750 break;
2751 default:
2752 UNIT_LOG(LOG_DEBUG, punit, "fell through all unit tasks, defending");
2754 dai_military_defend(ait, pplayer, punit);
2755 break;
2756 };
2757 return;
2758 }
2759}
2760
2761/**********************************************************************/
2767static void dai_set_defenders(struct ai_type *ait, struct player *pplayer)
2768{
2769 city_list_iterate(pplayer->cities, pcity) {
2770 /* The idea here is that we should never keep more than two
2771 * units in permanent defense. */
2772 int total_defense = 0;
2773 int total_attack = def_ai_city_data(pcity, ait)->danger;
2774 bool emergency = FALSE;
2775 int count = 0;
2776 int mart_max = get_city_bonus(pcity, EFT_MARTIAL_LAW_MAX);
2777 int mart_each = get_city_bonus(pcity, EFT_MARTIAL_LAW_EACH);
2778 int martless_unhappy = pcity->feel[CITIZEN_UNHAPPY][FEELING_NATIONALITY]
2779 + pcity->feel[CITIZEN_ANGRY][FEELING_NATIONALITY];
2780 int entertainers = 0;
2781 bool enough = FALSE;
2782
2784 if (get_specialist_output(pcity, sp, O_LUXURY) > 0) {
2785 entertainers += pcity->specialists[sp];
2786 }
2788
2789 martless_unhappy += entertainers; /* We want to use martial law instead
2790 * of entertainers. */
2791
2792 while (!enough
2793 && (total_defense <= total_attack
2794 || (count < mart_max && mart_each > 0
2795 && martless_unhappy > mart_each * count))) {
2796 int best_want = 0;
2797 struct unit *best = NULL;
2798 bool defense_needed = total_defense <= total_attack; /* Defense or martial */
2799
2800 unit_list_iterate(pcity->tile->units, punit) {
2801 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2802
2803 if ((unit_data->task == AIUNIT_NONE || emergency)
2804 && unit_data->task != AIUNIT_DEFEND_HOME
2805 && unit_owner(punit) == pplayer) {
2806 int want = assess_defense_unit(ait, pcity, punit, FALSE);
2807
2808 if (want > best_want) {
2809 best_want = want;
2810 best = punit;
2811 }
2812 }
2814
2815 if (best == NULL) {
2816 if (defense_needed) {
2817 /* Ooops - try to grab any unit as defender! */
2818 if (emergency) {
2819 CITY_LOG(LOG_DEBUG, pcity, "Not defended properly");
2820 break;
2821 }
2822 emergency = TRUE;
2823 } else {
2824 break;
2825 }
2826 } else {
2827 const struct unit_type *btype = unit_type_get(best);
2828
2829 if ((martless_unhappy < mart_each * count
2830 || count >= mart_max || mart_each <= 0)
2831 && ((count >= 2
2832 && btype->attack_strength > btype->defense_strength)
2833 || (count >= 4
2834 && btype->attack_strength == btype->defense_strength))) {
2835 /* In this case attack would be better defense than fortifying
2836 * to city. */
2837 enough = TRUE;
2838 } else {
2839 int loglevel = pcity->server.debug ? LOG_AI_TEST : LOG_DEBUG;
2840
2841 total_defense += best_want;
2842 UNIT_LOG(loglevel, best, "Defending city");
2843 dai_unit_new_task(ait, best, AIUNIT_DEFEND_HOME, pcity->tile);
2844 count++;
2845 }
2846 }
2847 }
2848 CITY_LOG(LOG_DEBUG, pcity, "Evaluating defense: %d defense, %d incoming"
2849 ", %d defenders (out of %d)", total_defense, total_attack, count,
2850 unit_list_size(pcity->tile->units));
2852}
2853
2854/**********************************************************************/
2862void dai_manage_units(struct ai_type *ait, struct player *pplayer)
2863{
2865 dai_airlift(ait, pplayer);
2867
2868 /* Clear previous orders, if desirable, here. */
2869 unit_list_iterate(pplayer->units, punit) {
2870 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
2871
2872 unit_data->done = FALSE;
2873 if (unit_data->task == AIUNIT_DEFEND_HOME) {
2874 dai_unit_new_task(ait, punit, AIUNIT_NONE, NULL);
2875 }
2877
2878 /* Find and set city defenders first - figure out which units are
2879 * allowed to leave home. */
2880 dai_set_defenders(ait, pplayer);
2881
2884 && !def_ai_unit_data(punit, ait)->done) {
2885 /* Though it is usually the passenger who drives the transport,
2886 * the transporter is responsible for managing its passengers. */
2887 dai_manage_unit(ait, pplayer, punit);
2888 }
2890}
2891
2892/**********************************************************************/
2897const struct impr_type *utype_needs_improvement(const struct unit_type *putype,
2898 const struct city *pcity)
2899{
2900 const struct impr_type *impr_req = NULL;
2901 const struct req_context context = {
2902 .player = city_owner(pcity),
2903 .city = pcity,
2904 .tile = city_tile(pcity),
2905 .unittype = putype,
2906 };
2907
2908 requirement_vector_iterate(&putype->build_reqs, preq) {
2909 if (is_req_active(&context, NULL, preq, RPT_CERTAIN)) {
2910 /* Already there. */
2911 continue;
2912 }
2914 city_owner(pcity), pcity)) {
2915 /* The unit type can't be built at all. */
2916 return NULL;
2917 }
2918 if (VUT_IMPROVEMENT == preq->source.kind && preq->present) {
2919 /* This is (one of) the building(s) required. */
2920 impr_req = preq->source.value.building;
2921 }
2923
2924 return impr_req;
2925}
2926
2927/**********************************************************************/
2931bool is_on_unit_upgrade_path(const struct unit_type *test,
2932 const struct unit_type *base)
2933{
2934 /* This is the real function: */
2935 do {
2936 base = base->obsoleted_by;
2937 if (base == test) {
2938 return TRUE;
2939 }
2940 } while (base);
2941 return FALSE;
2942}
2943
2944/**********************************************************************/
2949static void dai_manage_barbarian_leader(struct ai_type *ait,
2950 struct player *pplayer,
2951 struct unit *leader)
2952{
2953 struct tile *leader_tile = unit_tile(leader), *safest_tile;
2954 struct pf_parameter parameter;
2955 struct pf_map *pfm;
2956 struct pf_reverse_map *pfrm;
2957 struct unit *worst_danger;
2958 int move_cost, best_move_cost;
2959 int body_guards;
2960 bool alive = TRUE;
2961 const struct civ_map *nmap = &(wld.map);
2962
2963 CHECK_UNIT(leader);
2964
2965 if (leader->moves_left == 0
2966 || (can_unit_survive_at_tile(&(wld.map), leader, leader_tile)
2967 && 1 < unit_list_size(leader_tile->units))) {
2968 unit_activity_handling(leader, ACTIVITY_SENTRY);
2969
2970 return;
2971 }
2972
2973 if (is_boss_of_boat(ait, leader)) {
2974 /* We are in charge. Of course, since we are the leader...
2975 * But maybe somebody more militaristic should lead our ship to battle! */
2976
2977 /* First release boat from leaders lead */
2978 aiferry_clear_boat(ait, leader);
2979
2980 unit_list_iterate(leader_tile->units, warrior) {
2981 if (!unit_has_type_role(warrior, L_BARBARIAN_LEADER)
2982 && get_transporter_capacity(warrior) == 0
2983 && warrior->moves_left > 0) {
2984 /* This seems like a good warrior to lead us in to conquest! */
2985 dai_manage_unit(ait, pplayer, warrior);
2986
2987 /* If we reached our destination, ferryboat already called
2988 * ai_manage_unit() for leader. So no need to continue here.
2989 * Leader might even be dead.
2990 * If this return is removed, surrounding unit_list_iterate()
2991 * has to be replaced with unit_list_iterate_safe()*/
2992 return;
2993 }
2995 }
2996
2997 /* If we are not in charge of the boat, continue as if we
2998 * were not in a boat - we may want to leave the ship now. */
2999
3000 /* Check the total number of units able to protect our leader. */
3001 body_guards = 0;
3002 unit_list_iterate(pplayer->units, punit) {
3003 if (!unit_has_type_role(punit, L_BARBARIAN_LEADER)
3004 && goto_is_sane(punit, leader_tile)) {
3005 body_guards++;
3006 }
3008
3009 if (0 < body_guards) {
3010 pft_fill_unit_parameter(&parameter, nmap, leader);
3011 parameter.omniscience = !has_handicap(pplayer, H_MAP);
3012 pfm = pf_map_new(&parameter);
3013
3014 /* Find the closest body guard.
3015 * FIXME: maybe choose the strongest too? */
3016 pf_map_tiles_iterate(pfm, ptile, FALSE) {
3017 unit_list_iterate(ptile->units, punit) {
3018 if (unit_owner(punit) == pplayer
3019 && !unit_has_type_role(punit, L_BARBARIAN_LEADER)
3020 && goto_is_sane(punit, leader_tile)) {
3021 struct pf_path *path = pf_map_path(pfm, ptile);
3022
3023 adv_follow_path(leader, path, ptile);
3024 pf_path_destroy(path);
3025 pf_map_destroy(pfm);
3026 return;
3027 }
3030
3031 pf_map_destroy(pfm);
3032 }
3033
3034 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader needs to flee");
3035
3036 /* Check for units we could fear. */
3037 pfrm = pf_reverse_map_new(nmap, pplayer, leader_tile, 3,
3038 !has_handicap(pplayer, H_MAP));
3039 worst_danger = NULL;
3040 best_move_cost = FC_INFINITY;
3041
3042 players_iterate(other_player) {
3043 if (other_player == pplayer) {
3044 continue;
3045 }
3046
3047 unit_list_iterate(other_player->units, punit) {
3048 move_cost = pf_reverse_map_unit_move_cost(pfrm, punit);
3049 if (PF_IMPOSSIBLE_MC != move_cost && move_cost < best_move_cost) {
3050 best_move_cost = move_cost;
3051 worst_danger = punit;
3052 }
3055
3057
3058 if (NULL == worst_danger) {
3059 unit_activity_handling(leader, ACTIVITY_IDLE);
3060 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader: no close enemy.");
3061 return;
3062 }
3063
3064 pft_fill_unit_parameter(&parameter, nmap, worst_danger);
3065 parameter.omniscience = !has_handicap(pplayer, H_MAP);
3066 pfm = pf_map_new(&parameter);
3067 best_move_cost = pf_map_move_cost(pfm, leader_tile);
3068
3069 /* Try to escape. */
3070 do {
3071 safest_tile = leader_tile;
3072
3073 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader: moves left: %d.",
3074 leader->moves_left);
3075
3076 adjc_iterate(&(wld.map), leader_tile, near_tile) {
3077 if (adv_could_unit_move_to_tile(leader, near_tile) != 1) {
3078 continue;
3079 }
3080
3081 move_cost = pf_map_move_cost(pfm, near_tile);
3082 if (PF_IMPOSSIBLE_MC != move_cost
3083 && move_cost > best_move_cost) {
3084 UNIT_LOG(LOG_DEBUG, leader,
3085 "Barbarian leader: safest is (%d, %d), safeness %d",
3086 TILE_XY(near_tile), best_move_cost);
3087 best_move_cost = move_cost;
3088 safest_tile = near_tile;
3089 }
3091
3092 UNIT_LOG(LOG_DEBUG, leader, "Barbarian leader: fleeing to (%d, %d).",
3093 TILE_XY(safest_tile));
3094 if (same_pos(unit_tile(leader), safest_tile)) {
3095 UNIT_LOG(LOG_DEBUG, leader,
3096 "Barbarian leader: reached the safest position.");
3097 unit_activity_handling(leader, ACTIVITY_IDLE);
3098 pf_map_destroy(pfm);
3099 return;
3100 }
3101
3102 alive = dai_unit_goto(ait, leader, safest_tile);
3103 if (alive) {
3104 if (same_pos(unit_tile(leader), leader_tile)) {
3105 /* Didn't move. No point to retry. */
3106 pf_map_destroy(pfm);
3107 return;
3108 }
3109 leader_tile = unit_tile(leader);
3110 }
3111 } while (alive && 0 < leader->moves_left);
3112
3113 pf_map_destroy(pfm);
3114}
3115
3116/**********************************************************************/
3122void dai_consider_tile_dangerous(struct ai_type *ait, struct tile *ptile,
3123 struct unit *punit,
3124 enum override_bool *result)
3125{
3126 int a = 0, d, db;
3127 struct player *pplayer = unit_owner(punit);
3128 struct city *pcity = tile_city(ptile);
3129 int extras_bonus = 0;
3130
3131 if (is_human(pplayer)) {
3132 /* Use advisors code for humans. */
3133 return;
3134 }
3135
3136 if (pcity && pplayers_allied(city_owner(pcity), unit_owner(punit))
3137 && !is_non_allied_unit_tile(ptile, pplayer)) {
3138 /* We will be safe in a friendly city */
3139 *result = OVERRIDE_FALSE;
3140 return;
3141 }
3142
3143 /* Calculate how well we can defend at (x,y) */
3144 db = 10 + tile_terrain(ptile)->defense_bonus / 10;
3145 extras_bonus += tile_extras_defense_bonus(ptile, unit_type_get(punit));
3146
3147 db += (db * extras_bonus) / 100;
3149
3150 adjc_iterate(&(wld.map), ptile, ptile1) {
3151 if (has_handicap(pplayer, H_FOG)
3152 && !map_is_known_and_seen(ptile1, unit_owner(punit), V_MAIN)) {
3153 /* We cannot see danger at (ptile1) => assume there is none */
3154 continue;
3155 }
3156 unit_list_iterate(ptile1->units, enemy) {
3158 && (unit_attack_unit_at_tile_result(enemy, NULL, punit, ptile)
3159 == ATT_OK)
3160 && (unit_attack_units_at_tile_result(enemy, NULL, ptile)
3161 == ATT_OK)) {
3162 a += adv_unit_att_rating(enemy);
3163 if ((a * a * 10) >= d) {
3164 /* The enemies combined strength is too big! */
3165 *result = OVERRIDE_TRUE;
3166 return;
3167 }
3168 }
3171
3172 *result = OVERRIDE_FALSE;
3173}
3174
3175/**********************************************************************/
3178static void update_simple_ai_types(void)
3179{
3180 int i = 0;
3181
3182 unit_type_iterate(punittype) {
3183 struct unit_class *pclass = utype_class(punittype);
3184
3185 if (A_NEVER != punittype->require_advance
3186 && !utype_has_flag(punittype, UTYF_CIVILIAN)
3187 && !utype_can_do_action(punittype, ACTION_SUICIDE_ATTACK)
3188 && !(pclass->adv.land_move == MOVE_NONE
3189 && !can_attack_non_native(punittype))
3190 && !utype_fuel(punittype)
3191 && punittype->transport_capacity < 8) {
3192 simple_ai_types[i] = punittype;
3193 i++;
3194 }
3196
3197 simple_ai_types[i] = NULL;
3198}
3199
3200/**********************************************************************/
3204{
3205 /* TODO: remove the simple_ai_types cache or merge it with a general ai
3206 * cache; see the comment to struct unit_type *simple_ai_types at
3207 * the beginning of this file. */
3209
3210 unit_type_iterate(ptype) {
3211 struct unit_type_ai *utai = fc_malloc(sizeof(*utai));
3212
3213 utai->low_firepower = FALSE;
3214 utai->ferry = FALSE;
3215 utai->missile_platform = FALSE;
3216 utai->carries_occupiers = FALSE;
3217 utai->potential_charges = unit_type_list_new();
3218
3219 utype_set_ai_data(ptype, ait, utai);
3221
3222 unit_type_iterate(punittype) {
3223 struct unit_class *pclass = utype_class(punittype);
3224
3225 /* Confirm firepower */
3226 combat_bonus_list_iterate(punittype->bonuses, pbonus) {
3227 if (pbonus->type == CBONUS_LOW_FIREPOWER) {
3228 unit_type_iterate(penemy) {
3229 if (utype_has_flag(penemy, pbonus->flag)) {
3230 struct unit_type_ai *utai = utype_ai_data(penemy, ait);
3231
3232 utai->low_firepower = TRUE;
3233 }
3235 }
3237
3238 /* Consider potential cargo */
3239 if (punittype->transport_capacity > 0) {
3240 struct unit_type_ai *utai = utype_ai_data(punittype, ait);
3241
3242 unit_type_iterate(pctype) {
3243 struct unit_class *pcargo = utype_class(pctype);
3244
3245 if (can_unit_type_transport(punittype, pcargo)) {
3246 if (utype_can_do_action(pctype, ACTION_SUICIDE_ATTACK)) {
3247 utai->missile_platform = TRUE;
3248 } else if (pclass->adv.sea_move != MOVE_NONE
3249 && pcargo->adv.land_move != MOVE_NONE) {
3250 if (pcargo->adv.sea_move != MOVE_FULL) {
3251 utai->ferry = TRUE;
3252 } else {
3253 if (0 != utype_fuel(pctype)) {
3254 utai->ferry = TRUE;
3255 }
3256 }
3257 }
3258
3259 if (utype_can_take_over(pctype)) {
3260 utai->carries_occupiers = TRUE;
3261 }
3262 }
3264 }
3265
3266 /* Consider potential charges */
3267 unit_type_iterate(pcharge) {
3268 bool can_move_like_charge = FALSE;
3269
3270 if (0 < utype_fuel(punittype)
3271 && (0 == utype_fuel(pcharge)
3272 || utype_fuel(pcharge) > utype_fuel(punittype))) {
3273 continue;
3274 }
3275
3277 if (chgcls == utype_class(pcharge)) {
3278 can_move_like_charge = TRUE;
3279 }
3281
3282 if (can_move_like_charge) {
3283 struct unit_type_ai *utai = utype_ai_data(punittype, ait);
3284 unit_type_list_append(utai->potential_charges, pcharge);
3285 }
3286
3289}
3290
3291/**********************************************************************/
3295{
3296 unit_type_iterate(ptype) {
3297 struct unit_type_ai *utai = utype_ai_data(ptype, ait);
3298
3299 if (utai == NULL) {
3300 continue;
3301 }
3302 utype_set_ai_data(ptype, ait, NULL);
3303
3304 unit_type_list_destroy(utai->potential_charges);
3305 free(utai);
3307}
3308
3309/**********************************************************************/
3312void dai_unit_init(struct ai_type *ait, struct unit *punit)
3313{
3314 /* Make sure that contents of unit_ai structure are correctly initialized,
3315 * if you ever allocate it by some other mean than fc_calloc() */
3316 struct unit_ai *unit_data = fc_calloc(1, sizeof(struct unit_ai));
3317
3318 unit_data->done = FALSE;
3319 unit_data->cur_pos = NULL;
3320 unit_data->prev_pos = NULL;
3321 unit_data->target = 0;
3322 BV_CLR_ALL(unit_data->hunted);
3323 unit_data->ferryboat = 0;
3324 unit_data->passenger = 0;
3325 unit_data->bodyguard = 0;
3326 unit_data->charge = 0;
3327
3328 unit_set_ai_data(punit, ait, unit_data);
3329}
3330
3331/**********************************************************************/
3334void dai_unit_turn_end(struct ai_type *ait, struct unit *punit)
3335{
3336 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3337
3338 fc_assert_ret(unit_data != NULL);
3339
3340 BV_CLR_ALL(unit_data->hunted);
3341}
3342
3343/**********************************************************************/
3346void dai_unit_close(struct ai_type *ait, struct unit *punit)
3347{
3348 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3349
3350 fc_assert_ret(unit_data != NULL);
3351
3354
3355 if (unit_data != NULL) {
3356 unit_set_ai_data(punit, ait, NULL);
3357 FC_FREE(unit_data);
3358 }
3359}
3360
3361/**********************************************************************/
3364void dai_unit_save(struct ai_type *ait, const char *aitstr,
3365 struct section_file *file,
3366 const struct unit *punit, const char *unitstr)
3367{
3368 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3369
3370 secfile_insert_int(file, unit_data->passenger, "%s.%spassenger",
3371 unitstr, aitstr);
3372 secfile_insert_int(file, unit_data->ferryboat, "%s.%sferryboat",
3373 unitstr, aitstr);
3374 secfile_insert_int(file, unit_data->charge, "%s.%scharge",
3375 unitstr, aitstr);
3376 secfile_insert_int(file, unit_data->bodyguard, "%s.%sbodyguard",
3377 unitstr, aitstr);
3378}
3379
3380/**********************************************************************/
3383void dai_unit_load(struct ai_type *ait, const char *aitstr,
3384 const struct section_file *file,
3385 struct unit *punit, const char *unitstr)
3386{
3387 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
3388
3389 unit_data->passenger
3390 = secfile_lookup_int_default(file, 0, "%s.%spassenger",
3391 unitstr, aitstr);
3392 unit_data->ferryboat
3393 = secfile_lookup_int_default(file, 0, "%s.%sferryboat",
3394 unitstr, aitstr);
3395 unit_data->charge
3396 = secfile_lookup_int_default(file, 0, "%s.%scharge",
3397 unitstr, aitstr);
3398 unit_data->bodyguard
3399 = secfile_lookup_int_default(file, 0, "%s.%sbodyguard",
3400 unitstr, aitstr);
3401}
3402
3404{
3405 enum terrain_class tc;
3407};
3408
3409/**********************************************************************/
3412static bool role_unit_cb(struct unit_type *ptype, void *data)
3413{
3414 struct role_unit_cb_data *cb_data = (struct role_unit_cb_data *)data;
3415 struct unit_class *pclass = utype_class(ptype);
3416 const struct civ_map *nmap = &(wld.map);
3417
3418 if ((cb_data->tc == TC_LAND && pclass->adv.land_move == MOVE_NONE)
3419 || (cb_data->tc == TC_OCEAN && pclass->adv.sea_move == MOVE_NONE)) {
3420 return FALSE;
3421 }
3422
3423 if (cb_data->build_city == NULL
3424 || can_city_build_unit_now(nmap, cb_data->build_city, ptype)) {
3425 return TRUE;
3426 }
3427
3428 return FALSE;
3429}
3430
3431/**********************************************************************/
3434struct unit_type *dai_role_utype_for_terrain_class(struct city *pcity, int role,
3435 enum terrain_class tc)
3436{
3437 struct role_unit_cb_data cb_data = { .build_city = pcity, .tc = tc };
3438
3439 return role_units_iterate_backwards(role, role_unit_cb, &cb_data);
3440}
3441
3442/**********************************************************************/
3445bool dai_unit_can_strike_my_unit(const struct unit *attacker,
3446 const struct unit *defender)
3447{
3448 struct pf_parameter parameter;
3449 struct pf_map *pfm;
3450 const struct tile *ptarget = unit_tile(defender);
3451 int max_move_cost = attacker->moves_left;
3452 bool able_to_strike = FALSE;
3453 const struct civ_map *nmap = &(wld.map);
3454
3455 pft_fill_unit_parameter(&parameter, nmap, attacker);
3456 parameter.omniscience = !has_handicap(unit_owner(defender), H_MAP);
3457 pfm = pf_map_new(&parameter);
3458
3459 pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
3460 if (move_cost > max_move_cost) {
3461 break;
3462 }
3463
3464 if (ptile == ptarget) {
3465 able_to_strike = TRUE;
3466 break;
3467 }
3469
3470 pf_map_destroy(pfm);
3471
3472 return able_to_strike;
3473}
3474
3475/**********************************************************************/
3478void dai_switch_to_explore(struct ai_type *ait, struct unit *punit,
3479 struct tile *target, enum override_bool *allow)
3480{
3481 struct unit_ai *udata = def_ai_unit_data(punit, ait);
3482
3483 if (udata->task != AIUNIT_NONE && udata->task != AIUNIT_EXPLORE) {
3484 *allow = OVERRIDE_FALSE;
3485
3486 return;
3487 }
3488}
bool is_action_enabled_unit_on_units(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile)
Definition actions.c:4920
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:640
#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:491
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:3364
static void dai_military_findjob(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct unit *punit)
Definition aiunit.c:854
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:2219
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:1984
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:702
void dai_units_ruleset_init(struct ai_type *ait)
Definition aiunit.c:3203
#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:1683
static void invasion_funct(struct ai_type *ait, struct unit *punit, bool dest, int radius, int which)
Definition aiunit.c:1019
static void update_simple_ai_types(void)
Definition aiunit.c:3178
const struct impr_type * utype_needs_improvement(const struct unit_type *putype, const struct city *pcity)
Definition aiunit.c:2897
void dai_switch_to_explore(struct ai_type *ait, struct unit *punit, struct tile *target, enum override_bool *allow)
Definition aiunit.c:3478
void dai_manage_military(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct unit *punit)
Definition aiunit.c:2499
static bool dai_find_boat_for_unit(struct ai_type *ait, struct unit *punit)
Definition aiunit.c:1900
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:3445
bool is_on_unit_upgrade_path(const struct unit_type *test, const struct unit_type *base)
Definition aiunit.c:2931
static void dai_military_bodyguard(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aiunit.c:636
static void single_invader(struct ai_city *city_data, const struct unit_type *utype, int which)
Definition aiunit.c:991
#define LOG_CARAVAN3
Definition aiunit.c:89
void dai_manage_units(struct ai_type *ait, struct player *pplayer)
Definition aiunit.c:2862
static void dai_manage_caravan(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aiunit.c:2256
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:1136
static void dai_set_defenders(struct ai_type *ait, struct player *pplayer)
Definition aiunit.c:2767
void dai_manage_unit(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aiunit.c:2654
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:717
static bool role_unit_cb(struct unit_type *ptype, void *data)
Definition aiunit.c:3412
static void dai_military_attack(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aiunit.c:1746
void dai_unit_turn_end(struct ai_type *ait, struct unit *punit)
Definition aiunit.c:3334
static void dai_manage_settler(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aiunit.c:2632
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:2115
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:836
struct city * find_nearest_safe_city(struct unit *punit)
Definition aiunit.c:1632
static void dai_manage_barbarian_leader(struct ai_type *ait, struct player *pplayer, struct unit *leader)
Definition aiunit.c:2949
static void dai_manage_hitpoint_recovery(struct ai_type *ait, struct unit *punit)
Definition aiunit.c:2424
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:524
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:3312
void dai_consider_tile_dangerous(struct ai_type *ait, struct tile *ptile, struct unit *punit, enum override_bool *result)
Definition aiunit.c:3122
bool uclass_need_trans_between(struct unit_class *pclass, struct tile *ctile, struct tile *ptile)
Definition aiunit.c:1945
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:3383
static void caravan_optimize_callback(const struct caravan_result *result, void *data)
Definition aiunit.c:2096
#define LOGLEVEL_RECOVERY
Definition aiunit.c:86
void dai_unit_close(struct ai_type *ait, struct unit *punit)
Definition aiunit.c:3346
void dai_units_ruleset_close(struct ai_type *ait)
Definition aiunit.c:3294
struct unit_type * dai_role_utype_for_terrain_class(struct city *pcity, int role, enum terrain_class tc)
Definition aiunit.c:3434
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:1061
static void dai_military_defend(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aiunit.c:945
bool dai_military_rampage(struct unit *punit, int thresh_adj, int thresh_move)
Definition aiunit.c:603
static bool dai_caravan_can_trade_cities_diff_cont(struct player *pplayer, struct unit *punit)
Definition aiunit.c:2174
#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:707
#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:694
#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:336
bool is_native_tile(const struct unit_type *punittype, const struct tile *ptile)
Definition movement.c:348
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:508
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Definition movement.c:858
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:84
@ 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:3405
struct city * build_city
Definition aiunit.c:3406
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:113
#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:2282
bool unit_transport_load(struct unit *pcargo, struct unit *ptrans, bool force)
Definition unit.c:2362
bool is_losing_hp(const struct unit *punit)
Definition unit.c:2220
bool unit_can_airlift_to(const struct civ_map *nmap, const struct unit *punit, const struct city *pdest_city)
Definition unit.c:196
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2433
int unit_gain_hitpoints(const struct unit *punit)
Definition unit.c:2175
bool is_military_unit(const struct unit *punit)
Definition unit.c:327
bool unit_is_cityfounder(const struct unit *punit)
Definition unit.c:2631
bool unit_can_do_action(const struct unit *punit, const action_id act_id)
Definition unit.c:336
bool unit_can_do_action_result(const struct unit *punit, enum action_result result)
Definition unit.c:346
int get_transporter_capacity(const struct unit *punit)
Definition unit.c:307
bool can_unit_do_activity(const struct civ_map *nmap, const struct unit *punit, enum unit_activity activity)
Definition unit.c:880
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2417
bool unit_has_orders(const struct unit *punit)
Definition unit.c:212
#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