Freeciv-3.1
Loading...
Searching...
No Matches
aitools.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/* utility */
19#include "bitvector.h"
20#include "log.h"
21#include "mem.h"
22#include "shared.h"
23
24/* common */
25#include "city.h"
26#include "combat.h"
27#include "game.h"
28#include "government.h"
29#include "map.h"
30#include "movement.h"
31#include "packets.h"
32#include "player.h"
33#include "unit.h"
34#include "unitlist.h"
35
36/* common/aicore */
37#include "citymap.h"
38#include "pf_tools.h"
39
40/* server */
41#include "barbarian.h"
42#include "citytools.h"
43#include "cityturn.h"
44#include "maphand.h"
45#include "plrhand.h"
46#include "score.h"
47#include "srv_log.h"
48#include "unithand.h"
49#include "unittools.h"
50
51/* server/advisors */
52#include "advdata.h"
53#include "advgoto.h"
54#include "advtools.h"
55#include "autosettlers.h"
56#include "infracache.h" /* adv_city */
57
58/* ai */
59#include "handicaps.h"
60
61/* ai/default */
62#include "aidata.h"
63#include "aiferry.h"
64#include "aiguard.h"
65#include "ailog.h"
66#include "aiplayer.h"
67#include "aitech.h"
68#include "aiunit.h"
69#include "daimilitary.h"
70
71#include "aitools.h"
72
73/**********************************************************************/
77const char *dai_unit_task_rule_name(const enum ai_unit_task task)
78{
79 switch (task) {
80 case AIUNIT_NONE:
81 return "None";
83 return "Auto settler";
85 return "Build city";
87 return "Defend home";
88 case AIUNIT_ATTACK:
89 return "Attack";
90 case AIUNIT_ESCORT:
91 return "Escort";
92 case AIUNIT_EXPLORE:
93 return "Explore";
94 case AIUNIT_RECOVER:
95 return "Recover";
96 case AIUNIT_HUNTER:
97 return "Hunter";
98 case AIUNIT_TRADE:
99 return "Trade";
100 case AIUNIT_WONDER:
101 return "Wonder";
102 }
103
104 /* No default, ensure all types handled somehow */
105 log_error("Unsupported ai_unit_task %d.", task);
106
107 return NULL;
108}
109
110/**********************************************************************/
118adv_want military_amortize(struct player *pplayer, struct city *pcity,
119 adv_want value, int delay, int build_cost)
120{
121 struct adv_data *ai = adv_data_get(pplayer, NULL);
122 int city_output = (pcity ? pcity->surplus[O_SHIELD] : 1);
123 int output = MAX(city_output, ai->stats.average_production);
124 int build_time = build_cost / MAX(output, 1);
125
126 if (value <= 0) {
127 return 0;
128 }
129
130 return amortize(value, delay + build_time);
131}
132
133/**********************************************************************/
142void dai_consider_plr_dangerous(struct ai_type *ait, struct player *plr1,
143 struct player *plr2,
144 enum override_bool *result)
145{
146 struct ai_dip_intel *adip;
147
148 adip = dai_diplomacy_get(ait, plr1, plr2);
149
150 if (adip->countdown >= 0) {
151 /* Don't trust our war target */
152 *result = OVERRIDE_TRUE;
153 }
154}
155
156/**********************************************************************/
161static bool dai_gothere_bodyguard(struct ai_type *ait,
162 struct unit *punit, struct tile *dest_tile)
163{
164 struct player *pplayer = unit_owner(punit);
165 unsigned int danger = 0;
166 struct city *dcity;
167 struct unit *guard = aiguard_guard_of(ait, punit);
168 const struct veteran_level *vlevel;
169 bool bg_needed = FALSE;
170 const struct unit_type *ptype;
171
173 /* Barbarians must have more courage (ie less brains) */
175 return FALSE;
176 }
177
178 /* Estimate enemy attack power. */
179 unit_list_iterate(dest_tile->units, aunit) {
180 if (POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, unit_owner(aunit))) {
181 danger += adv_unit_att_rating(aunit);
182 }
184 dcity = tile_city(dest_tile);
185 if (dcity && POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, city_owner(dcity))) {
186 /* Assume enemy will build another defender, add it's attack strength */
187 struct unit_type *d_type = dai_choose_defender_versus(dcity, punit);
188
189 if (d_type) {
190 /* Enemy really can build something */
191 danger +=
193 d_type, city_production_unit_veteran_level(dcity, d_type),
194 SINGLE_MOVE, d_type->hp);
195 }
196 }
197 danger *= POWER_DIVIDER;
198
199 /* If we are fast, there is less danger.
200 * FIXME: that assumes that most units have move_rate == SINGLE_MOVE;
201 * not true for all rulesets */
202 ptype = unit_type_get(punit);
203 danger /= (ptype->move_rate / SINGLE_MOVE);
204 if (unit_has_type_flag(punit, UTYF_IGTER)) {
205 danger /= 1.5;
206 }
207
208 vlevel = utype_veteran_level(ptype, punit->veteran);
209 fc_assert_ret_val(vlevel != NULL, FALSE);
210
211 /* We look for the bodyguard where we stand. */
212 if (guard == NULL || unit_tile(guard) != unit_tile(punit)) {
213 int my_def = (punit->hp * ptype->defense_strength
214 * POWER_FACTOR * vlevel->power_fact / 100);
215
216 if (danger >= my_def) {
218 "want bodyguard @(%d, %d) danger=%d, my_def=%d",
219 TILE_XY(dest_tile), danger, my_def);
221 bg_needed = TRUE;
222 } else {
224 bg_needed = FALSE;
225 }
226 } else if (guard != NULL) {
227 bg_needed = TRUE;
228 }
229
230 /* What if we have a bodyguard, but don't need one? */
231
232 return bg_needed;
233}
234
235#define LOGLEVEL_GOTHERE LOG_DEBUG
236/**********************************************************************/
245bool dai_gothere(struct ai_type *ait, struct player *pplayer,
246 struct unit *punit, struct tile *dest_tile)
247{
249 bool bg_needed;
250
251 if (same_pos(dest_tile, unit_tile(punit)) || punit->moves_left <= 0) {
252 /* Nowhere to go */
253 return TRUE;
254 }
255
256 /* See if we need a bodyguard at our destination */
257 /* FIXME: If bodyguard is _really_ necessary, don't go anywhere */
258 bg_needed = dai_gothere_bodyguard(ait, punit, dest_tile);
259
261 || !goto_is_sane(punit, dest_tile)) {
262 /* Must go by boat, call an aiferryboat function */
263 if (!aiferry_gobyboat(ait, pplayer, punit, dest_tile,
264 bg_needed)) {
265 return FALSE;
266 }
267 }
268
269 /* Go where we should be going if we can, and are at our destination
270 * if we are on a ferry */
271 if (goto_is_sane(punit, dest_tile) && punit->moves_left > 0) {
272 punit->goto_tile = dest_tile;
273 UNIT_LOG(LOGLEVEL_GOTHERE, punit, "Walking to (%d,%d)", TILE_XY(dest_tile));
274 if (!dai_unit_goto(ait, punit, dest_tile)) {
275 /* died */
276 return FALSE;
277 }
278 /* liable to bump into someone that will kill us. Should avoid? */
279 } else {
280 UNIT_LOG(LOGLEVEL_GOTHERE, punit, "Not moving");
281 return FALSE;
282 }
283
284 if (def_ai_unit_data(punit, ait)->ferryboat > 0
285 && !unit_transported(punit)) {
286 /* We probably just landed, release our boat */
288 }
289
290 /* Dead unit shouldn't reach this point */
292
293 return (same_pos(unit_tile(punit), dest_tile)
294 || is_tiles_adjacent(unit_tile(punit), dest_tile));
295}
296
297/**********************************************************************/
304 struct tile *dest_tile)
305{
306 const struct civ_map *nmap = &(wld.map);
307
308 if (!same_pos(unit_tile(punit), dest_tile)
310 struct pf_parameter parameter;
311 struct pf_map *pfm;
312 struct pf_path *path;
313 size_t i;
314 struct player *pplayer = unit_owner(punit);
315
316 pft_fill_unit_parameter(&parameter, nmap, punit);
317 parameter.omniscience = !has_handicap(pplayer, H_MAP);
318 pfm = pf_map_new(&parameter);
319 path = pf_map_path(pfm, punit->goto_tile);
320
321 if (path) {
322 for (i = 1; i < path->length; i++) {
323 if (path->positions[i].tile == path->positions[i - 1].tile) {
324 /* The path-finding code advices us to wait there to refuel. */
325 struct tile *ptile = path->positions[i].tile;
326
327 pf_path_destroy(path);
328 pf_map_destroy(pfm);
329 return ptile;
330 }
331 }
332 pf_path_destroy(path);
333 pf_map_destroy(pfm);
334 /* Seems it's the immediate destination */
335 return punit->goto_tile;
336 }
337
338 pf_map_destroy(pfm);
339 log_verbose("Did not find an air-route for "
340 "%s %s[%d] (%d,%d)->(%d,%d)",
343 punit->id,
345 TILE_XY(dest_tile));
346 /* Prevent take off */
347 return unit_tile(punit);
348 }
349
350 /* else does not need way-points */
351 return dest_tile;
352}
353
354/**********************************************************************/
358 struct pf_path *path, struct pf_parameter *parameter)
359{
360 const struct pf_position *last = pf_path_last_position(path);
361 const unsigned cc = PF_TURN_FACTOR * last->total_MC
362 + parameter->move_rate * last->total_EC;
363 const unsigned tc = cc / (PF_TURN_FACTOR * parameter->move_rate);
364
365 UNIT_LOG(LOG_DEBUG, punit, "path L=%d T=%d(%u) MC=%u EC=%u CC=%u",
366 path->length - 1, last->turn, tc,
367 last->total_MC, last->total_EC, cc);
368}
369
370/**********************************************************************/
379bool dai_unit_goto_constrained(struct ai_type *ait, struct unit *punit,
380 struct tile *ptile,
381 struct pf_parameter *parameter)
382{
383 bool alive = TRUE;
384 struct pf_map *pfm;
385 struct pf_path *path;
386
387 UNIT_LOG(LOG_DEBUG, punit, "constrained goto to %d,%d", TILE_XY(ptile));
388
389 if (same_pos(unit_tile(punit), ptile)) {
390 /* Was not an error in previous versions but now is dubious... */
391 UNIT_LOG(LOG_DEBUG, punit, "constrained goto: already there!");
392 send_unit_info(NULL, punit);
393
394 return TRUE;
395 } else if (!goto_is_sane(punit, ptile)) {/* FIXME: why do we check it? */
396 UNIT_LOG(LOG_DEBUG, punit, "constrained goto: 'insane' goto!");
397 punit->activity = ACTIVITY_IDLE;
398 send_unit_info(NULL, punit);
399
400 return TRUE;
401 } else if (punit->moves_left == 0) {
402 UNIT_LOG(LOG_DEBUG, punit, "constrained goto: no moves left!");
403 send_unit_info(NULL, punit);
404
405 return TRUE;
406 }
407
408 pfm = pf_map_new(parameter);
409 path = pf_map_path(pfm, ptile);
410
411 if (path) {
412 dai_log_path(punit, path, parameter);
413 UNIT_LOG(LOG_DEBUG, punit, "constrained goto: following path.");
414 alive = adv_follow_path(punit, path, ptile);
415 } else {
416 UNIT_LOG(LOG_DEBUG, punit, "no path to destination");
417 }
418
419 pf_path_destroy(path);
420 pf_map_destroy(pfm);
421
422 return alive;
423}
424
425/**********************************************************************/
430bool goto_is_sane(struct unit *punit, struct tile *ptile)
431{
432 bool can_get_there = FALSE;
433 const struct civ_map *nmap = &(wld.map);
434
435 if (same_pos(unit_tile(punit), ptile)) {
436 can_get_there = TRUE;
437 } else {
438 struct pf_parameter parameter;
439 struct pf_map *pfm;
440
441 pft_fill_unit_attack_param(&parameter, nmap, punit);
442 pfm = pf_map_new(&parameter);
443
444 if (pf_map_move_cost(pfm, ptile) != PF_IMPOSSIBLE_MC) {
445 can_get_there = TRUE;
446 }
447 pf_map_destroy(pfm);
448 }
449 return can_get_there;
450}
451
452/*
453 * The length of time, in turns, which is long enough to be optimistic
454 * that enemy units will have moved from their current position.
455 * WAG
456 */
457#define LONG_TIME 4
458/**********************************************************************/
470void dai_fill_unit_param(struct ai_type *ait, struct pf_parameter *parameter,
471 struct adv_risk_cost *risk_cost,
472 struct unit *punit, struct tile *ptile)
473{
474 const bool long_path = LONG_TIME < (map_distance(unit_tile(punit),
478 const bool barbarian = is_barbarian(unit_owner(punit));
479 bool is_ferry;
480 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
481 struct player *pplayer = unit_owner(punit);
482 const struct civ_map *nmap = &(wld.map);
483
484 /* This function is now always omniscient and should not be used
485 * for human players any more. */
486 fc_assert(is_ai(pplayer));
487
488 /* If a unit is hunting, don't expect it to be a ferry. */
489 is_ferry = (unit_data->task != AIUNIT_HUNTER
490 && dai_is_ferry(punit, ait));
491
492 if (is_ferry) {
493 /* The destination may be a coastal land tile,
494 * in which case the ferry should stop on an adjacent tile. */
495 pft_fill_unit_overlap_param(parameter, nmap, punit);
496 } else if (!utype_fuel(unit_type_get(punit))
498 ACTRES_ATTACK)
499 && (unit_data->task == AIUNIT_DEFEND_HOME
500 || unit_data->task == AIUNIT_ATTACK
501 || unit_data->task == AIUNIT_ESCORT
502 || unit_data->task == AIUNIT_HUNTER)) {
503 /* Use attack movement for defenders and escorts so they can
504 * make defensive attacks */
505 pft_fill_unit_attack_param(parameter, nmap, punit);
506 } else {
507 pft_fill_unit_parameter(parameter, nmap, punit);
508 }
509 parameter->omniscience = !has_handicap(pplayer, H_MAP);
510
511 /* Should we use the risk avoidance code?
512 * The risk avoidance code uses omniscience, so do not use for
513 * human-player units under temporary AI control.
514 * Barbarians bravely/stupidly ignore risks
515 */
516 if (!uclass_has_flag(unit_class_get(punit), UCF_UNREACHABLE)
517 && !barbarian) {
518 adv_avoid_risks(parameter, risk_cost, punit, NORMAL_STACKING_FEARFULNESS);
519 }
520
521 /* Should we absolutely forbid ending a turn on a dangerous tile?
522 * Do not annoy human players by killing their units for them.
523 * For AI units be optimistic; allows attacks across dangerous terrain,
524 * and polar settlements.
525 * TODO: This is compatible with old code,
526 * but probably ought to be more cautious for non military units
527 */
528 if (!is_ferry && !utype_fuel(unit_type_get(punit))) {
529 parameter->get_moves_left_req = NULL;
530 }
531
532 if (long_path) {
533 /* Move as far along the path to the destination as we can;
534 * that is, ignore the presence of enemy units when computing the
535 * path.
536 * Hopefully, ai_avoid_risks will have produced a path that avoids enemy
537 * ZoCs. Ignoring ZoCs allows us to move closer to a destination
538 * for which there is not yet a clear path.
539 * That is good if the destination is several turns away,
540 * so we can reasonably expect blocking enemy units to move or
541 * be destroyed. But it can be bad if the destination is one turn away
542 * or our destination is far but there are enemy units near us and on the
543 * shortest path to the destination.
544 */
545 parameter->get_zoc = NULL;
546 }
547
548 if (unit_has_type_flag(punit, UTYF_SETTLERS)) {
549 parameter->get_TB = no_fights;
550 } else if (long_path && unit_is_cityfounder(punit)) {
551 /* Default tile behaviour;
552 * move as far along the path to the destination as we can;
553 * that is, ignore the presence of enemy units when computing the
554 * path.
555 */
556 } else if (unit_is_cityfounder(punit)) {
557 /* Short path */
558 parameter->get_TB = no_fights;
559 } else if (unit_has_type_role(punit, L_BARBARIAN_LEADER)) {
560 /* Avoid capture */
561 parameter->get_TB = no_fights;
562 } else if (is_ferry) {
563 /* Ferries are not warships */
564 parameter->get_TB = no_fights;
565 } else if (is_losing_hp(punit)) {
566 /* Losing hitpoints over time (helicopter in default rules) */
567 /* Default tile behaviour */
569 switch (unit_data->task) {
572 /* Strange, but not impossible */
573 parameter->get_TB = no_fights;
574 break;
576 case AIUNIT_ATTACK: /* Includes spy actions */
577 case AIUNIT_ESCORT:
578 case AIUNIT_HUNTER:
579 case AIUNIT_TRADE:
580 case AIUNIT_WONDER:
581 parameter->get_TB = no_intermediate_fights;
582 break;
583 case AIUNIT_EXPLORE:
584 case AIUNIT_RECOVER:
585 parameter->get_TB = no_fights;
586 break;
587 case AIUNIT_NONE:
588 /* Default tile behaviour */
589 break;
590 }
591 } else {
592 /* Probably an explorer */
593 parameter->get_TB = no_fights;
594 }
595
596 if (is_ferry) {
597 /* Show the destination in the client when watching an AI: */
598 punit->goto_tile = ptile;
599 }
600}
601
602/**********************************************************************/
606bool dai_unit_goto(struct ai_type *ait, struct unit *punit, struct tile *ptile)
607{
608 struct pf_parameter parameter;
609 struct adv_risk_cost risk_cost;
610
611 UNIT_LOG(LOG_DEBUG, punit, "dai_unit_goto to %d,%d", TILE_XY(ptile));
612 dai_fill_unit_param(ait, &parameter, &risk_cost, punit, ptile);
613
614 return dai_unit_goto_constrained(ait, punit, ptile, &parameter);
615}
616
617/**********************************************************************/
620void dai_unit_new_adv_task(struct ai_type *ait, struct unit *punit,
621 enum adv_unit_task task, struct tile *ptile)
622{
623 /* Keep ai_unit_task in sync with adv task */
624 switch (task) {
625 case AUT_AUTO_SETTLER:
627 break;
628 case AUT_BUILD_CITY:
630 break;
631 case AUT_NONE:
632 dai_unit_new_task(ait, punit, AIUNIT_NONE, ptile);
633 break;
634 }
635}
636
637/**********************************************************************/
644void dai_unit_new_task(struct ai_type *ait, struct unit *punit,
645 enum ai_unit_task task, struct tile *ptile)
646{
647 struct unit *bodyguard = aiguard_guard_of(ait, punit);
648 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
649
650 /* If the unit is under (human) orders we shouldn't control it.
651 * Allow removal of old role with AIUNIT_NONE. */
653
654 UNIT_LOG(LOG_DEBUG, punit, "changing task from %s to %s",
655 dai_unit_task_rule_name(unit_data->task),
657
658 /* Free our ferry. Most likely it has been done already. */
661 }
662
663 if (punit->activity == ACTIVITY_GOTO) {
664 /* It would indicate we're going somewhere otherwise */
665 unit_activity_handling(punit, ACTIVITY_IDLE);
666 }
667
668 if (unit_data->task == AIUNIT_BUILD_CITY) {
669 if (punit->goto_tile) {
671 } else {
672 /* Print error message instead of crashing in citymap_free_city_spot()
673 * This probably means that some city spot reservation has not been
674 * properly cleared; bad for the AI, as it will leave that area
675 * uninhabited. */
676 log_error("%s was on city founding mission without target tile.",
678 }
679 }
680
681 if (unit_data->task == AIUNIT_HUNTER) {
682 /* Clear victim's hunted bit - we're no longer chasing. */
683 struct unit *target = game_unit_by_number(unit_data->target);
684
685 if (target) {
686 BV_CLR(def_ai_unit_data(target, ait)->hunted,
688 UNIT_LOG(LOGLEVEL_HUNT, target, "no longer hunted (new task %d, old %d)",
689 task, unit_data->task);
690 }
691 }
692
694 /* Record the city to defend; our goto may be to transport. */
695 if (task == AIUNIT_DEFEND_HOME && ptile && tile_city(ptile)) {
697 }
698
699 unit_data->task = task;
700
701 /* Verify and set the goto destination. Eventually this can be a lot more
702 * stringent, but for now we don't want to break things too badly. */
703 punit->goto_tile = ptile; /* May be NULL. */
704
705 if (unit_data->task == AIUNIT_NONE && bodyguard) {
706 dai_unit_new_task(ait, bodyguard, AIUNIT_NONE, NULL);
707 }
708
709 /* Reserve city spot, _unless_ we want to add ourselves to a city. */
710 if (unit_data->task == AIUNIT_BUILD_CITY && !tile_city(ptile)) {
712 }
713 if (unit_data->task == AIUNIT_HUNTER) {
714 /* Set victim's hunted bit - the hunt is on! */
715 struct unit *target = game_unit_by_number(unit_data->target);
716
717 fc_assert_ret(target != NULL);
718 BV_SET(def_ai_unit_data(target, ait)->hunted, player_index(unit_owner(punit)));
719 UNIT_LOG(LOGLEVEL_HUNT, target, "is being hunted");
720
721 /* Grab missiles lying around and bring them along */
722 unit_list_iterate(unit_tile(punit)->units, missile) {
723 if (unit_owner(missile) == unit_owner(punit)
724 && def_ai_unit_data(missile, ait)->task != AIUNIT_ESCORT
725 && !unit_transported(missile)
726 && unit_owner(missile) == unit_owner(punit)
728 ACTION_SUICIDE_ATTACK)
729 && can_unit_load(missile, punit)) {
730 UNIT_LOG(LOGLEVEL_HUNT, missile, "loaded on hunter");
731 dai_unit_new_task(ait, missile, AIUNIT_ESCORT, unit_tile(target));
733 }
735 }
736
737 /* Map ai tasks to advisor tasks. For most ai tasks there is
738 no advisor, so AUT_NONE is set. */
739 switch (unit_data->task) {
742 break;
745 break;
746 default:
748 break;
749 }
750}
751
752/**********************************************************************/
756bool dai_unit_make_homecity(struct unit *punit, struct city *pcity)
757{
760
761 if (punit->homecity == 0 && !unit_has_type_role(punit, L_EXPLORER)) {
762 /* This unit doesn't pay any upkeep while it doesn't have a homecity,
763 * so it would be stupid to give it one. There can also be good reasons
764 * why it doesn't have a homecity. */
765 /* However, until we can do something more useful with them, we
766 will assign explorers to a city so that they can be disbanded for
767 the greater good -- Per */
768 return FALSE;
769 }
771 && pcity->surplus[O_FOOD] >= unit_type_get(punit)->upkeep[O_FOOD]) {
773 0, "", ACTION_HOME_CITY);
774 return TRUE;
775 }
776 return FALSE;
777}
778
779/**********************************************************************/
785static void dai_unit_bodyguard_move(struct ai_type *ait,
786 struct unit *bodyguard, struct tile *ptile)
787{
788 fc_assert_ret(bodyguard != NULL);
789 fc_assert_ret(unit_owner(bodyguard) != NULL);
790
791#ifndef FREECIV_NDEBUG
792 struct unit *punit =
793#endif
794 aiguard_charge_unit(ait, bodyguard);
795
796 fc_assert_ret(punit != NULL);
797
798 CHECK_GUARD(ait, bodyguard);
800
801 if (!is_tiles_adjacent(ptile, unit_tile(bodyguard))) {
802 return;
803 }
804
805 if (bodyguard->moves_left <= 0) {
806 /* should generally should not happen */
807 BODYGUARD_LOG(ait, LOG_DEBUG, bodyguard, "was left behind by charge");
808 return;
809 }
810
811 unit_activity_handling(bodyguard, ACTIVITY_IDLE);
812 (void) dai_unit_move(ait, bodyguard, ptile);
813}
814
815/**********************************************************************/
818bool dai_unit_attack(struct ai_type *ait, struct unit *punit, struct tile *ptile)
819{
820 struct unit *ptrans;
821 struct unit *bodyguard = aiguard_guard_of(ait, punit);
822 int sanity = punit->id;
823 bool alive;
824 struct city *tcity;
825 const struct civ_map *nmap = &(wld.map);
826
830
831 unit_activity_handling(punit, ACTIVITY_IDLE);
832 /* FIXME: try the next action if the unit tried to do an illegal action.
833 * That would allow the AI to stop using the omniscient
834 * is_action_enabled_unit_on_*() functions. */
835 if (is_action_enabled_unit_on_units(nmap, ACTION_CAPTURE_UNITS,
836 punit, ptile)) {
837 /* Choose capture. */
839 0, "", ACTION_CAPTURE_UNITS);
840 } else if (is_action_enabled_unit_on_units(nmap, ACTION_BOMBARD,
841 punit, ptile)) {
842 /* Choose "Bombard". */
844 0, "", ACTION_BOMBARD);
845 } else if (is_action_enabled_unit_on_units(nmap, ACTION_BOMBARD2,
846 punit, ptile)) {
847 /* Choose "Bombard 2". */
849 0, "", ACTION_BOMBARD2);
850 } else if (is_action_enabled_unit_on_units(nmap, ACTION_BOMBARD3,
851 punit, ptile)) {
852 /* Choose "Bombard 3". */
854 0, "", ACTION_BOMBARD3);
855 } else if (is_action_enabled_unit_on_units(nmap, ACTION_NUKE_UNITS,
856 punit, ptile)) {
857 /* Choose "Nuke Units". */
859 0, "", ACTION_NUKE_UNITS);
860 } else if (action_id_get_target_kind(ACTION_NUKE) == ATK_TILE
861 && is_action_enabled_unit_on_tile(nmap, ACTION_NUKE,
862 punit, ptile, NULL)) {
863 /* Choose "Explode Nuclear". */
865 0, "", ACTION_NUKE);
866 } else if (action_id_get_target_kind(ACTION_NUKE) == ATK_CITY
867 && (tcity = tile_city(ptile))
868 && is_action_enabled_unit_on_city(nmap, ACTION_NUKE,
869 punit, tcity)) {
870 /* Choose "Explode Nuclear". */
872 0, "", ACTION_NUKE);
873 } else if (action_id_get_target_kind(ACTION_NUKE_CITY) == ATK_TILE
874 && is_action_enabled_unit_on_tile(nmap, ACTION_NUKE_CITY,
875 punit, ptile, NULL)) {
876 /* Choose "Nuke City". */
878 0, "", ACTION_NUKE_CITY);
879 } else if (action_id_get_target_kind(ACTION_NUKE_CITY) == ATK_CITY
880 && (tcity = tile_city(ptile))
881 && is_action_enabled_unit_on_city(nmap, ACTION_NUKE_CITY,
882 punit, tcity)) {
883 /* Choose "Nuke City". */
885 0, "", ACTION_NUKE_CITY);
886 } else if (is_action_enabled_unit_on_units(nmap, ACTION_ATTACK,
887 punit, ptile)) {
888 /* Choose regular attack. */
890 0, "", ACTION_ATTACK);
891 } else if (is_action_enabled_unit_on_units(nmap, ACTION_SUICIDE_ATTACK,
892 punit, ptile)) {
893 /* Choose suicide attack (explode missile). */
895 0, "", ACTION_SUICIDE_ATTACK);
896 } else if ((tcity = tile_city(ptile))
897 && is_action_enabled_unit_on_city(nmap, ACTION_CONQUER_CITY,
898 punit, tcity)) {
899 /* Choose "Conquer City". */
901 0, "", ACTION_CONQUER_CITY);
902 } else if ((tcity = tile_city(ptile))
903 && is_action_enabled_unit_on_city(nmap, ACTION_CONQUER_CITY2,
904 punit, tcity)) {
905 /* Choose "Conquer City 2". */
907 0, "", ACTION_CONQUER_CITY2);
908 } else if ((tcity = tile_city(ptile))
909 && is_action_enabled_unit_on_city(nmap, ACTION_CONQUER_CITY3,
910 punit, tcity)) {
911 /* Choose "Conquer City 3". */
913 0, "", ACTION_CONQUER_CITY3);
914 } else if ((tcity = tile_city(ptile))
915 && is_action_enabled_unit_on_city(nmap, ACTION_CONQUER_CITY4,
916 punit, tcity)) {
917 /* Choose "Conquer City 4". */
919 0, "", ACTION_CONQUER_CITY4);
920 } else if (!can_unit_survive_at_tile(nmap, punit, ptile)
921 && ((ptrans = transporter_for_unit_at(punit, ptile)))
922 && is_action_enabled_unit_on_unit(nmap, ACTION_TRANSPORT_EMBARK,
923 punit, ptrans)) {
924 /* "Transport Embark". */
926 0, "", ACTION_TRANSPORT_EMBARK);
927 } else if (!can_unit_survive_at_tile(nmap, punit, ptile)
928 && ((ptrans = transporter_for_unit_at(punit, ptile)))
929 && is_action_enabled_unit_on_unit(nmap, ACTION_TRANSPORT_EMBARK2,
930 punit, ptrans)) {
931 /* "Transport Embark 2". */
933 0, "", ACTION_TRANSPORT_EMBARK2);
934 } else if (!can_unit_survive_at_tile(nmap, punit, ptile)
935 && ((ptrans = transporter_for_unit_at(punit, ptile)))
936 && is_action_enabled_unit_on_unit(nmap, ACTION_TRANSPORT_EMBARK3,
937 punit, ptrans)) {
938 /* "Transport Embark 3". */
940 0, "", ACTION_TRANSPORT_EMBARK3);
941 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_TRANSPORT_DISEMBARK1,
942 punit, ptile, NULL)) {
943 /* "Transport Disembark". */
945 0, "", ACTION_TRANSPORT_DISEMBARK1);
946 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_TRANSPORT_DISEMBARK2,
947 punit, ptile, NULL)) {
948 /* "Transport Disembark 2". */
950 0, "", ACTION_TRANSPORT_DISEMBARK2);
951 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_TRANSPORT_DISEMBARK3,
952 punit, ptile, NULL)) {
953 /* "Transport Disembark 3". */
955 0, "", ACTION_TRANSPORT_DISEMBARK3);
956 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_TRANSPORT_DISEMBARK4,
957 punit, ptile, NULL)) {
958 /* "Transport Disembark 4". */
960 0, "", ACTION_TRANSPORT_DISEMBARK4);
962 && is_action_enabled_unit_on_extras(nmap, ACTION_CONQUER_EXTRAS,
963 punit, ptile, NULL)) {
964 /* Choose "Conquer Extras". */
966 0, "", ACTION_CONQUER_EXTRAS);
968 && is_action_enabled_unit_on_extras(nmap, ACTION_CONQUER_EXTRAS2,
969 punit, ptile, NULL)) {
970 /* Choose "Conquer Extras 2". */
972 0, "", ACTION_CONQUER_EXTRAS2);
974 && is_action_enabled_unit_on_extras(nmap, ACTION_CONQUER_EXTRAS3,
975 punit, ptile, NULL)) {
976 /* Choose "Conquer Extras 3". */
978 0, "", ACTION_CONQUER_EXTRAS3);
980 && is_action_enabled_unit_on_extras(nmap, ACTION_CONQUER_EXTRAS4,
981 punit, ptile, NULL)) {
982 /* Choose "Conquer Extras 4". */
984 0, "", ACTION_CONQUER_EXTRAS4);
985 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_HUT_ENTER,
986 punit, ptile, NULL)) {
987 /* Choose "Enter Hut". */
989 0, "", ACTION_HUT_ENTER);
990 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_HUT_ENTER2,
991 punit, ptile, NULL)) {
992 /* Choose "Enter Hut 2". */
994 0, "", ACTION_HUT_ENTER2);
995 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_HUT_ENTER3,
996 punit, ptile, NULL)) {
997 /* Choose "Enter Hut 3". */
999 0, "", ACTION_HUT_ENTER3);
1000 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_HUT_ENTER4,
1001 punit, ptile, NULL)) {
1002 /* Choose "Enter Hut 4". */
1004 0, "", ACTION_HUT_ENTER4);
1005 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_HUT_FRIGHTEN,
1006 punit, ptile, NULL)) {
1007 /* Choose "Frighten Hut". */
1009 0, "", ACTION_HUT_FRIGHTEN);
1010 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_HUT_FRIGHTEN2,
1011 punit, ptile, NULL)) {
1012 /* Choose "Frighten Hut 2". */
1014 0, "", ACTION_HUT_FRIGHTEN2);
1015 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_HUT_FRIGHTEN3,
1016 punit, ptile, NULL)) {
1017 /* Choose "Frighten Hut 3". */
1019 0, "", ACTION_HUT_FRIGHTEN3);
1020 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_HUT_FRIGHTEN4,
1021 punit, ptile, NULL)) {
1022 /* Choose "Frighten Hut 4". */
1024 0, "", ACTION_HUT_FRIGHTEN4);
1025 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_UNIT_MOVE,
1026 punit, ptile, NULL)) {
1027 /* Choose "Unit Move". */
1029 0, "", ACTION_UNIT_MOVE);
1030 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_UNIT_MOVE2,
1031 punit, ptile, NULL)) {
1032 /* Choose "Unit Move 2". */
1034 0, "", ACTION_UNIT_MOVE2);
1035 } else {
1036 /* Choose "Unit Move 3". */
1038 0, "", ACTION_UNIT_MOVE3);
1039 }
1040 alive = (game_unit_by_number(sanity) != NULL);
1041
1042 if (alive && same_pos(ptile, unit_tile(punit))
1043 && bodyguard != NULL && def_ai_unit_data(bodyguard, ait)->charge == punit->id) {
1044 dai_unit_bodyguard_move(ait, bodyguard, ptile);
1045 /* Clumsy bodyguard might trigger an auto-attack */
1046 alive = (game_unit_by_number(sanity) != NULL);
1047 }
1048
1049 return alive;
1050}
1051
1052/**********************************************************************/
1055void dai_unit_move_or_attack(struct ai_type *ait, struct unit *punit,
1056 struct tile *ptile, struct pf_path *path, int step)
1057{
1058 if (step == path->length - 1) {
1059 (void) dai_unit_attack(ait, punit, ptile);
1060 } else {
1061 (void) dai_unit_move(ait, punit, ptile);
1062 }
1063}
1064
1065/**********************************************************************/
1073bool dai_unit_move(struct ai_type *ait, struct unit *punit, struct tile *ptile)
1074{
1075 struct action *paction;
1076 struct unit *bodyguard;
1077 struct unit *ptrans = NULL;
1078 int sanity = punit->id;
1079 struct player *pplayer = unit_owner(punit);
1080 const bool is_plr_ai = is_ai(pplayer);
1081 const struct civ_map *nmap = &(wld.map);
1082
1085 "Tiles not adjacent: Unit = %d, "
1086 "from = (%d, %d]) to = (%d, %d).",
1088 TILE_XY(ptile));
1089
1090 /* if enemy, stop and give a chance for the ai attack function
1091 * to handle this case */
1092 if (is_enemy_unit_tile(ptile, pplayer)
1093 || is_enemy_city_tile(ptile, pplayer)) {
1094 UNIT_LOG(LOG_DEBUG, punit, "movement halted due to enemy presence");
1095 return FALSE;
1096 }
1097
1098 /* barbarians shouldn't enter huts */
1099 /* FIXME: use unit_can_displace_hut(punit, ptile) better */
1100 if (is_barbarian(pplayer) && hut_on_tile(ptile)) {
1101 return FALSE;
1102 }
1103
1104 /* don't leave bodyguard behind */
1105 if (is_plr_ai
1106 && (bodyguard = aiguard_guard_of(ait, punit))
1107 && same_pos(unit_tile(punit), unit_tile(bodyguard))
1108 && bodyguard->moves_left == 0) {
1109 UNIT_LOG(LOGLEVEL_BODYGUARD, punit, "does not want to leave "
1110 "its bodyguard");
1111 return FALSE;
1112 }
1113
1114 /* Select move kind. */
1115 if (!can_unit_survive_at_tile(nmap, punit, ptile)
1116 && ((ptrans = transporter_for_unit_at(punit, ptile)))
1117 && is_action_enabled_unit_on_unit(nmap, ACTION_TRANSPORT_EMBARK,
1118 punit, ptrans)) {
1119 /* "Transport Embark". */
1120 paction = action_by_number(ACTION_TRANSPORT_EMBARK);
1121 } else if (!can_unit_survive_at_tile(nmap, punit, ptile)
1122 && ptrans != NULL
1123 && is_action_enabled_unit_on_unit(nmap, ACTION_TRANSPORT_EMBARK2,
1124 punit, ptrans)) {
1125 /* "Transport Embark 2". */
1126 paction = action_by_number(ACTION_TRANSPORT_EMBARK2);
1127 } else if (!can_unit_survive_at_tile(nmap, punit, ptile)
1128 && ptrans != NULL
1129 && is_action_enabled_unit_on_unit(nmap, ACTION_TRANSPORT_EMBARK3,
1130 punit, ptrans)) {
1131 /* "Transport Embark 3". */
1132 paction = action_by_number(ACTION_TRANSPORT_EMBARK3);
1133 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_TRANSPORT_DISEMBARK1,
1134 punit, ptile, NULL)) {
1135 /* "Transport Disembark". */
1136 paction = action_by_number(ACTION_TRANSPORT_DISEMBARK1);
1137 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_TRANSPORT_DISEMBARK2,
1138 punit, ptile, NULL)) {
1139 /* "Transport Disembark 2". */
1140 paction = action_by_number(ACTION_TRANSPORT_DISEMBARK2);
1141 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_TRANSPORT_DISEMBARK3,
1142 punit, ptile, NULL)) {
1143 /* "Transport Disembark 3". */
1144 paction = action_by_number(ACTION_TRANSPORT_DISEMBARK3);
1145 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_TRANSPORT_DISEMBARK4,
1146 punit, ptile, NULL)) {
1147 /* "Transport Disembark 4". */
1148 paction = action_by_number(ACTION_TRANSPORT_DISEMBARK4);
1149 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_HUT_ENTER,
1150 punit, ptile, NULL)) {
1151 /* "Enter Hut". */
1152 paction = action_by_number(ACTION_HUT_ENTER);
1153 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_HUT_ENTER2,
1154 punit, ptile, NULL)) {
1155 /* "Enter Hut 2". */
1156 paction = action_by_number(ACTION_HUT_ENTER2);
1157 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_HUT_ENTER3,
1158 punit, ptile, NULL)) {
1159 /* "Enter Hut 3". */
1160 paction = action_by_number(ACTION_HUT_ENTER3);
1161 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_HUT_ENTER4,
1162 punit, ptile, NULL)) {
1163 /* "Enter Hut 4". */
1164 paction = action_by_number(ACTION_HUT_ENTER4);
1165 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_HUT_FRIGHTEN,
1166 punit, ptile, NULL)) {
1167 /* "Frighten Hut". */
1168 paction = action_by_number(ACTION_HUT_FRIGHTEN);
1169 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_HUT_FRIGHTEN2,
1170 punit, ptile, NULL)) {
1171 /* "Frighten Hut 2". */
1172 paction = action_by_number(ACTION_HUT_FRIGHTEN2);
1173 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_HUT_FRIGHTEN3,
1174 punit, ptile, NULL)) {
1175 /* "Frighten Hut 3". */
1176 paction = action_by_number(ACTION_HUT_FRIGHTEN3);
1177 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_HUT_FRIGHTEN4,
1178 punit, ptile, NULL)) {
1179 /* "Frighten Hut 4". */
1180 paction = action_by_number(ACTION_HUT_FRIGHTEN4);
1181 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_UNIT_MOVE,
1182 punit, ptile, NULL)) {
1183 /* "Unit Move". */
1184 paction = action_by_number(ACTION_UNIT_MOVE);
1185 } else if (is_action_enabled_unit_on_tile(nmap, ACTION_UNIT_MOVE2,
1186 punit, ptile, NULL)) {
1187 /* "Unit Move 2". */
1188 paction = action_by_number(ACTION_UNIT_MOVE2);
1189 } else {
1190 /* "Unit Move 3". */
1191 paction = action_by_number(ACTION_UNIT_MOVE3);
1192 }
1193
1194 /* Try not to end move next to an enemy if we can avoid it by waiting */
1195 if (action_has_result(paction, ACTRES_UNIT_MOVE)
1196 || action_has_result(paction, ACTRES_TRANSPORT_DISEMBARK)) {
1197 /* The unit will have to move it self rather than being moved. */
1198 int mcost = map_move_cost_unit(nmap, punit, ptile);
1199
1200 if (paction) {
1201 struct tile *from_tile;
1202
1203 /* Ugly hack to understand the OnNativeTile unit state requirements
1204 * used in the Action_Success_Actor_Move_Cost effect. */
1207 from_tile = unit_tile(punit);
1208 punit->tile = ptile;
1209
1210 mcost += unit_pays_mp_for_action(paction, punit);
1211
1212 punit->tile = from_tile;
1213 }
1214
1215 if (punit->moves_left <= mcost
1216 && unit_move_rate(punit) > mcost
1217 && adv_danger_at(punit, ptile)
1220 "ending move early to stay out of trouble");
1221 return FALSE;
1222 }
1223 }
1224
1225 /* go */
1226 unit_activity_handling(punit, ACTIVITY_IDLE);
1227 /* Move */
1228 if (paction && ptrans
1229 && action_has_result(paction, ACTRES_TRANSPORT_EMBARK)) {
1230 /* "Transport Embark". */
1232 0, "", action_number(paction));
1233 } else if (paction
1234 && (action_has_result(paction,
1235 ACTRES_TRANSPORT_DISEMBARK)
1236 || action_has_result(paction, ACTRES_UNIT_MOVE)
1237 || action_has_result(paction,
1238 ACTRES_HUT_ENTER)
1239 || action_has_result(paction,
1240 ACTRES_HUT_FRIGHTEN))) {
1241 /* "Transport Disembark", "Transport Disembark 2", "Enter Hut",
1242 * "Frighten Hut" or "Unit Move". */
1244 0, "", action_number(paction));
1245 }
1246
1247 /* handle the results */
1248 if (game_unit_by_number(sanity) && same_pos(ptile, unit_tile(punit))) {
1249 bodyguard = aiguard_guard_of(ait, punit);
1250
1251 if (is_plr_ai && bodyguard != NULL
1252 && def_ai_unit_data(bodyguard, ait)->charge == punit->id) {
1253 dai_unit_bodyguard_move(ait, bodyguard, ptile);
1254 }
1255 return TRUE;
1256 }
1257 return FALSE;
1258}
1259
1260/**********************************************************************/
1264int stack_cost(struct unit *pattacker, struct unit *pdefender)
1265{
1266 struct tile *ptile = unit_tile(pdefender);
1267 int victim_cost = 0;
1268
1269 if (is_stack_vulnerable(ptile)) {
1270 /* lotsa people die */
1271 unit_list_iterate(ptile->units, aunit) {
1272 if (unit_attack_unit_at_tile_result(pattacker, NULL, aunit, ptile)
1273 == ATT_OK) {
1274 victim_cost += unit_build_shield_cost_base(aunit);
1275 }
1277 } else if (unit_attack_unit_at_tile_result(pattacker, NULL,
1278 pdefender, ptile)
1279 == ATT_OK) {
1280 /* Only one unit dies if attack is successful */
1281 victim_cost = unit_build_shield_cost_base(pdefender);
1282 }
1283
1284 return victim_cost;
1285}
1286
1287/**********************************************************************/
1290void dai_government_change(struct player *pplayer, struct government *gov)
1291{
1292 if (gov == government_of_player(pplayer)) {
1293 return;
1294 }
1295
1297
1298 city_list_iterate(pplayer->cities, pcity) {
1299 auto_arrange_workers(pcity); /* update cities */
1301}
1302
1303/**********************************************************************/
1309int dai_gold_reserve(struct player *pplayer)
1310{
1311 int i = total_player_citizens(pplayer) * 2;
1312
1313 return MAX(pplayer->ai_common.maxbuycost, i);
1314}
1315
1316/**********************************************************************/
1319void adjust_choice(int pct, struct adv_choice *choice)
1320{
1321 choice->want = (choice->want * pct) / 100;
1322}
1323
1324/**********************************************************************/
1328bool dai_choose_role_unit(struct ai_type *ait, struct player *pplayer,
1329 struct city *pcity, struct adv_choice *choice,
1330 enum choice_type type, int role, int want,
1331 bool need_boat)
1332{
1333 struct unit_type *iunit = dai_wants_role_unit(ait, pplayer, pcity, role, want);
1334
1335 if (iunit != NULL) {
1336 choice->type = type;
1337 choice->value.utype = iunit;
1338 choice->want = want;
1339
1340 choice->need_boat = need_boat;
1341
1342 return TRUE;
1343 }
1344
1345 return FALSE;
1346}
1347
1348/**********************************************************************/
1351void dai_build_adv_override(struct ai_type *ait, struct city *pcity,
1352 struct adv_choice *choice)
1353{
1354 const struct impr_type *chosen;
1355 adv_want want;
1356
1357 if (choice->type == CT_NONE) {
1358 want = 0;
1359 chosen = NULL;
1360 } else {
1361 want = choice->want;
1362 chosen = choice->value.building;
1363 }
1364
1365 improvement_iterate(pimprove) {
1366 /* Advisor code did not consider wonders, let's do it here */
1367 if (is_wonder(pimprove)) {
1368 int id = improvement_index(pimprove);
1369
1370 if (pcity->server.adv->building_want[id] > want
1371 && can_city_build_improvement_now(pcity, pimprove)) {
1372 want = pcity->server.adv->building_want[id];
1373 chosen = pimprove;
1374 }
1375 }
1377
1378 choice->want = want;
1379 choice->value.building = chosen;
1380
1381 if (chosen) {
1382 choice->type = CT_BUILDING; /* In case advisor had not chosen anything */
1383
1384 CITY_LOG(LOG_DEBUG, pcity, "AI wants to build %s with want "
1386 improvement_rule_name(chosen), want);
1387 }
1388}
1389
1390/**********************************************************************/
1400 struct city *pcity)
1401{
1402 int free_unhappy = get_city_bonus(pcity, EFT_MAKE_CONTENT_MIL);
1403 int unhap = 0;
1404
1405 /* bail out now if happy_cost is 0 */
1406 if (get_player_bonus(city_owner(pcity), EFT_UNHAPPY_FACTOR) == 0) {
1407 return FALSE;
1408 }
1409
1411 int happy_cost = city_unit_unhappiness(nmap, punit, &free_unhappy);
1412
1413 if (happy_cost > 0) {
1414 unhap += happy_cost;
1415 }
1417
1418 if (unhap < 0) {
1419 unhap = 0;
1420 }
1421 return (unhap > 0);
1422}
int action_number(const struct action *action)
Definition actions.c:1868
bool is_action_enabled_unit_on_tile(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:4996
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
bool is_action_enabled_unit_on_unit(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct unit *target_unit)
Definition actions.c:4832
bool is_action_enabled_unit_on_extras(const struct civ_map *nmap, const action_id wanted_action, const struct unit *actor_unit, const struct tile *target_tile, const struct extra_type *target_extra)
Definition actions.c:5073
static struct action * action_by_number(action_id act_id)
Definition actions.h:638
#define action_has_result(_act_, _res_)
Definition actions.h:448
#define action_id_get_target_kind(act_id)
Definition actions.h:655
choice_type
Definition advchoice.h:36
@ CT_NONE
Definition advchoice.h:37
@ CT_BUILDING
Definition advchoice.h:38
struct adv_data * adv_data_get(struct player *pplayer, bool *caller_closes)
Definition advdata.c:593
bool adv_follow_path(struct unit *punit, struct pf_path *path, struct tile *ptile)
Definition advgoto.c:47
bool adv_danger_at(struct unit *punit, struct tile *ptile)
Definition advgoto.c:414
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
void adv_avoid_risks(struct pf_parameter *parameter, struct adv_risk_cost *risk_cost, struct unit *punit, const double fearfulness)
Definition advgoto.c:581
#define NORMAL_STACKING_FEARFULNESS
Definition advgoto.h:23
adv_want amortize(adv_want benefit, int delay)
Definition advtools.c:29
#define POWER_DIVIDER
Definition advtools.h:32
struct ai_dip_intel * dai_diplomacy_get(struct ai_type *ait, const struct player *plr1, const struct player *plr2)
Definition aidata.c:402
bool aiferry_gobyboat(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct tile *dest_tile, bool with_bodyguard)
Definition aiferry.c:766
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
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
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
#define CHECK_CHARGE_UNIT(ait, charge)
Definition aiguard.h:22
#define CHECK_GUARD(ait, guard)
Definition aiguard.h:21
#define BODYGUARD_LOG(ait, loglevel, punit, msg,...)
Definition ailog.h:69
static struct unit_ai * def_ai_unit_data(const struct unit *punit, struct ai_type *deftype)
Definition aiplayer.h:48
struct unit_type * dai_wants_role_unit(struct ai_type *ait, struct player *pplayer, struct city *pcity, int role, int want)
Definition aitech.c:513
void dai_government_change(struct player *pplayer, struct government *gov)
Definition aitools.c:1290
void dai_fill_unit_param(struct ai_type *ait, struct pf_parameter *parameter, struct adv_risk_cost *risk_cost, struct unit *punit, struct tile *ptile)
Definition aitools.c:470
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
#define LONG_TIME
Definition aitools.c:457
struct tile * immediate_destination(struct unit *punit, struct tile *dest_tile)
Definition aitools.c:303
static bool dai_gothere_bodyguard(struct ai_type *ait, struct unit *punit, struct tile *dest_tile)
Definition aitools.c:161
void dai_build_adv_override(struct ai_type *ait, struct city *pcity, struct adv_choice *choice)
Definition aitools.c:1351
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
bool dai_unit_goto_constrained(struct ai_type *ait, struct unit *punit, struct tile *ptile, struct pf_parameter *parameter)
Definition aitools.c:379
void dai_log_path(struct unit *punit, struct pf_path *path, struct pf_parameter *parameter)
Definition aitools.c:357
void dai_consider_plr_dangerous(struct ai_type *ait, struct player *plr1, struct player *plr2, enum override_bool *result)
Definition aitools.c:142
void dai_unit_new_task(struct ai_type *ait, struct unit *punit, enum ai_unit_task task, struct tile *ptile)
Definition aitools.c:644
int dai_gold_reserve(struct player *pplayer)
Definition aitools.c:1309
bool dai_assess_military_unhappiness(const struct civ_map *nmap, struct city *pcity)
Definition aitools.c:1399
void adjust_choice(int pct, struct adv_choice *choice)
Definition aitools.c:1319
bool dai_unit_make_homecity(struct unit *punit, struct city *pcity)
Definition aitools.c:756
bool dai_choose_role_unit(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct adv_choice *choice, enum choice_type type, int role, int want, bool need_boat)
Definition aitools.c:1328
static void dai_unit_bodyguard_move(struct ai_type *ait, struct unit *bodyguard, struct tile *ptile)
Definition aitools.c:785
const char * dai_unit_task_rule_name(const enum ai_unit_task task)
Definition aitools.c:77
#define LOGLEVEL_GOTHERE
Definition aitools.c:235
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
bool dai_unit_move(struct ai_type *ait, struct unit *punit, struct tile *ptile)
Definition aitools.c:1073
void dai_unit_new_adv_task(struct ai_type *ait, struct unit *punit, enum adv_unit_task task, struct tile *ptile)
Definition aitools.c:620
void dai_unit_move_or_attack(struct ai_type *ait, struct unit *punit, struct tile *ptile, struct pf_path *path, int step)
Definition aitools.c:1055
#define POTENTIALLY_HOSTILE_PLAYER(ait, pplayer, aplayer)
Definition aiunit.h:72
ai_unit_task
Definition aiunit.h:27
@ 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 BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_CLR(bv, bit)
Definition bitvector.h:86
int city_production_unit_veteran_level(struct city *pcity, const struct unit_type *punittype)
Definition city.c:789
bool can_city_build_improvement_now(const struct city *pcity, const struct impr_type *pimprove)
Definition city.c:839
int city_unit_unhappiness(const struct civ_map *nmap, struct unit *punit, int *free_unhappy)
Definition city.c:2943
#define city_list_iterate(citylist, pcity)
Definition city.h:488
static bool is_enemy_city_tile(const struct tile *ptile, const struct player *pplayer)
Definition city.h:712
#define city_owner(_pcity_)
Definition city.h:543
#define city_list_iterate_end
Definition city.h:490
void citymap_free_city_spot(struct tile *ptile, int id)
Definition citymap.c:150
void citymap_reserve_city_spot(struct tile *ptile, int id)
Definition citymap.c:122
void auto_arrange_workers(struct city *pcity)
Definition cityturn.c:369
bool is_stack_vulnerable(const struct tile *ptile)
Definition combat.c:930
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
#define POWER_FACTOR
Definition combat.h:32
@ ATT_OK
Definition combat.h:35
struct unit_type * dai_choose_defender_versus(struct city *pcity, struct unit *attacker)
Definition daimilitary.c:92
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
int int id
Definition editgui_g.h:28
int get_city_bonus(const struct city *pcity, enum effect_type effect_type)
Definition effects.c:789
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:771
bool hut_on_tile(const struct tile *ptile)
Definition extras.c:672
float adv_want
Definition fc_types.h:1206
adv_unit_task
Definition fc_types.h:340
@ AUT_BUILD_CITY
Definition fc_types.h:340
@ AUT_NONE
Definition fc_types.h:340
@ AUT_AUTO_SETTLER
Definition fc_types.h:340
#define ADV_WANT_PRINTF
Definition fc_types.h:1207
@ O_SHIELD
Definition fc_types.h:91
@ O_FOOD
Definition fc_types.h:91
override_bool
Definition fc_types.h:84
@ OVERRIDE_TRUE
Definition fc_types.h:84
struct world wld
Definition game.c:58
struct unit * game_unit_by_number(int id)
Definition game.c:111
struct government * government_of_player(const struct player *pplayer)
Definition government.c:113
Government_type_id government_number(const struct government *pgovern)
Definition government.c:90
GType type
Definition repodlgs.c:1312
void handle_player_change_government(struct player *pplayer, Government_type_id government)
Definition plrhand.c:454
bool has_handicap(const struct player *pplayer, enum handicap_type htype)
Definition handicaps.c:66
@ H_MAP
Definition handicaps.h:28
const char * improvement_rule_name(const struct impr_type *pimprove)
Impr_type_id improvement_index(const struct impr_type *pimprove)
bool is_wonder(const struct impr_type *pimprove)
#define improvement_iterate_end
#define improvement_iterate(_p)
#define fc_assert_ret(condition)
Definition log.h:191
#define log_verbose(message,...)
Definition log.h:109
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
@ LOG_DEBUG
Definition log.h:34
#define log_error(message,...)
Definition log.h:103
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition log.h:208
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 map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:652
static int map_move_cost_unit(const struct civ_map *nmap, struct unit *punit, const struct tile *ptile)
Definition map.h:287
int unit_move_rate(const struct unit *punit)
Definition movement.c:90
bool can_unit_survive_at_tile(const struct civ_map *nmap, const struct unit *punit, const struct tile *ptile)
Definition movement.c:476
#define SINGLE_MOVE
Definition movement.h:24
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
const struct pf_position * pf_path_last_position(const struct pf_path *path)
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)
void pf_map_destroy(struct pf_map *pfm)
int pf_map_move_cost(struct pf_map *pfm, struct tile *ptile)
#define PF_IMPOSSIBLE_MC
#define PF_TURN_FACTOR
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
enum tile_behavior no_fights(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
Definition pf_tools.c:509
enum tile_behavior no_intermediate_fights(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
Definition pf_tools.c:524
int player_index(const struct player *pplayer)
Definition player.c:820
static bool is_barbarian(const struct player *pplayer)
Definition player.h:488
#define is_ai(plr)
Definition player.h:234
int total_player_citizens(const struct player *pplayer)
Definition score.c:382
#define MAX(x, y)
Definition shared.h:54
int step
Definition specpq.h:92
#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 LOGLEVEL_BODYGUARD
Definition srv_log.h:30
enum choice_type type
Definition advchoice.h:46
adv_want want
Definition advchoice.h:48
universals_u value
Definition advchoice.h:47
bool need_boat
Definition advchoice.h:49
adv_want building_want[B_LAST]
Definition infracache.h:32
struct adv_data::@92 stats
int average_production
Definition advdata.h:92
int countdown
Definition aidata.h:61
Definition ai.h:50
Definition city.h:309
int surplus[O_LAST]
Definition city.h:343
int id
Definition city.h:315
struct adv_city * adv
Definition city.h:435
struct city::@17::@19 server
struct unit_list * units_supported
Definition city.h:391
enum tile_behavior(* get_TB)(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
int(* get_moves_left_req)(const struct tile *ptile, enum known_type, const struct pf_parameter *param)
bool(* get_zoc)(const struct player *pplayer, const struct tile *ptile, const struct civ_map *zmap)
unsigned length
struct pf_position * positions
unsigned total_MC
unsigned total_EC
struct tile * tile
int maxbuycost
Definition player.h:120
struct city_list * cities
Definition player.h:281
struct player_ai ai_common
Definition player.h:288
Definition tile.h:49
struct unit_list * units
Definition tile.h:57
enum adv_unit_task task
Definition unit.h:89
enum ai_unit_task task
Definition aiunit.h:46
int charge
Definition aiunit.h:37
int target
Definition aiunit.h:42
int defense_strength
Definition unittype.h:496
int move_rate
Definition unittype.h:497
Definition unit.h:138
int upkeep[O_LAST]
Definition unit.h:148
enum unit_activity activity
Definition unit.h:157
int moves_left
Definition unit.h:150
int id
Definition unit.h:145
int hp
Definition unit.h:151
struct tile * tile
Definition unit.h:140
struct unit_adv * adv
Definition unit.h:233
struct unit::@80::@83 server
int homecity
Definition unit.h:146
struct tile * goto_tile
Definition unit.h:155
int veteran
Definition unit.h:152
struct civ_map map
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
bool tile_has_claimable_base(const struct tile *ptile, const struct unit_type *punittype)
Definition tile.c:209
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_index(_pt_)
Definition tile.h:87
#define TILE_XY(ptile)
Definition tile.h:42
const struct unit_type * utype
Definition fc_types.h:604
const struct impr_type * building
Definition fc_types.h:598
int unit_pays_mp_for_action(const struct action *paction, const struct unit *punit)
Definition unit.c:2119
struct unit * transporter_for_unit_at(const struct unit *pcargo, const struct tile *ptile)
Definition unit.c:1906
bool is_losing_hp(const struct unit *punit)
Definition unit.c:2212
bool can_unit_load(const struct unit *pcargo, const struct unit *ptrans)
Definition unit.c:744
bool unit_is_cityfounder(const struct unit *punit)
Definition unit.c:2623
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2409
bool unit_has_orders(const struct unit *punit)
Definition unit.c:204
#define unit_tile(_pu)
Definition unit.h:395
static bool is_enemy_unit_tile(const struct tile *ptile, const struct player *pplayer)
Definition unit.h:418
#define CHECK_UNIT(punit)
Definition unit.h:268
#define unit_owner(_pu)
Definition unit.h:394
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
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
void send_unit_info(struct conn_list *dest, struct unit *punit)
Definition unittools.c:2794
void unit_transport_load_send(struct unit *punit, struct unit *ptrans)
Definition unittools.c:3276
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
bool utype_is_moved_to_tgt_by_action(const struct action *paction, const struct unit_type *utype)
Definition unittype.c:1301
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1639
bool utype_may_act_at_all(const struct unit_type *putype)
Definition unittype.c:431
int unit_build_shield_cost_base(const struct unit *punit)
Definition unittype.c:1536
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
const struct veteran_level * utype_veteran_level(const struct unit_type *punittype, int level)
Definition unittype.c:2645
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:184
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:443
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:753
#define utype_fuel(ptype)
Definition unittype.h:825