Freeciv-3.1
Loading...
Searching...
No Matches
aiair.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2002 - The Freeciv Team
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 "log.h"
20
21/* common */
22#include "combat.h"
23#include "game.h"
24#include "map.h"
25#include "movement.h"
26#include "player.h"
27#include "pf_tools.h"
28#include "unit.h"
29
30/* server */
31#include "citytools.h"
32#include "maphand.h"
33#include "srv_log.h"
34#include "unithand.h"
35#include "unittools.h"
36
37/* server/advisors */
38#include "advbuilding.h"
39#include "advgoto.h"
40
41/* ai */
42#include "handicaps.h"
43
44/* ai/default */
45#include "aiplayer.h"
46#include "ailog.h"
47#include "aitools.h"
48#include "aiunit.h"
49#include "daicity.h"
50
51#include "aiair.h"
52
53/******************************************************************/
57static inline int regen_turns(struct unit *punit, struct tile *ptile,
58 int lost_hp)
59{
60 struct tile *real_tile = unit_tile(punit);
61 int res, regen, recov;
62
63 punit->tile = ptile;
64 /* unit_list_prepend(ptile, punit); ... (handle "MaxUnitsOnTile" etc.) */
65 regen = hp_gain_coord(punit);
66 recov = get_unit_bonus(punit, EFT_UNIT_RECOVER);
67 if (lost_hp - recov <= 0) {
68 res = 0;
69 } else {
70 res = 1 + (lost_hp - recov) / (recov + regen);
71 }
72 punit->tile = real_tile;
73
74 return res;
75}
76
77/******************************************************************/
88static struct tile *find_nearest_airbase(struct unit *punit,
89 struct pf_path **path)
90{
91 struct player *pplayer = unit_owner(punit);
92 struct pf_parameter parameter;
93 struct pf_map *pfm;
94 struct tile *best = NULL;
95 int lost_hp = unit_type_get(punit)->hp - punit->hp;
96 int best_regt = FC_INFINITY;
97 const struct civ_map *nmap = &(wld.map);
98
99 pft_fill_unit_parameter(&parameter, nmap, punit);
100 parameter.omniscience = !has_handicap(pplayer, H_MAP);
101 pfm = pf_map_new(&parameter);
102
103 pf_map_move_costs_iterate(pfm, ptile, move_cost, TRUE) {
104 if (move_cost > punit->moves_left) {
105 /* Too far! */
106 break;
107 }
108
109 if (is_refuel_point(ptile, pplayer, punit)) {
110 if (lost_hp > 0) {
111 int regt = regen_turns(punit, ptile, lost_hp);
112
113 if (regt <= 0) {
114 /* Nothing better to search */
115 best = ptile;
116 break;
117 } else if (!best || regt < best_regt) {
118 /* Regenerates faster */
119 best_regt = regt;
120 best = ptile;
121 }
122 } else {
123 best = ptile;
124 break;
125 }
126 }
128
129 if (path && best) {
130 *path = pf_map_path(pfm, best);
131 }
132 pf_map_destroy(pfm);
133 return best;
134}
135
136/******************************************************************/
141 struct unit *punit, struct tile *ptile)
142{
143 struct city *acity = tile_city(ptile);
144
145 /* For a virtual unit (punit->id == 0), all targets are good */
146 /* TODO: There is a danger of producing too many units that will not
147 * attack anything. Production should not happen if there is an idle
148 * unit of the same type nearby */
149 if (acity && punit->id != 0
150 && def_ai_city_data(acity, ait)->invasion.occupy == 0
152 /* No units capable of occupying are invading */
153 log_debug("Don't want to attack %s, although we could",
154 city_name_get(acity));
155 return FALSE;
156 }
157
158 return TRUE;
159}
160
161/******************************************************************/
166 struct unit *punit,
167 struct tile *dst_tile)
168{
169 struct unit *pdefender;
170 /* Unit costs in shields */
171 int balanced_cost, unit_cost, victim_cost = 0;
172 /* Unit stats */
173 int unit_attack, victim_defense;
174 /* Final answer */
175 adv_want profit;
176 /* Time spent in the air */
177 int sortie_time;
178
179#define PROB_MULTIPLIER 100 /* Should unify with those in combat.c */
180
181 if (!can_unit_attack_tile(punit, NULL, dst_tile)
182 || !(pdefender = get_defender(nmap, punit, dst_tile))) {
183 return 0;
184 }
185
186 /* Ok, we can attack, but is it worth it? */
187
188 /* Cost of our unit */
190 /* This is to say "wait, ill unit will get better!" */
191 unit_cost = unit_cost * unit_type_get(punit)->hp / punit->hp;
192
193 /* Determine cost of enemy units */
194 victim_cost = stack_cost(punit, pdefender);
195 if (0 == victim_cost) {
196 return 0;
197 }
198
199 /* Missile would die 100% so we adjust the victim_cost -- GB */
200 if (utype_can_do_action(unit_type_get(punit), ACTION_SUICIDE_ATTACK)) {
201 /* Assume that the attack will be a suicide attack even if a regular
202 * attack may be legal. */
203 victim_cost -= unit_build_shield_cost_base(punit);
204 }
205
206 unit_attack = (int) (PROB_MULTIPLIER
207 * unit_win_chance(nmap, punit, pdefender));
208
209 victim_defense = PROB_MULTIPLIER - unit_attack;
210
211 balanced_cost = build_cost_balanced(unit_type_get(punit));
212
213 sortie_time
215 action_by_number(ACTION_ATTACK),
217 /* Assume that dst_tile is closer to the tile the actor
218 * unit will attack from than its current tile. */
219 dst_tile,
220 dst_tile) >= MAX_MOVE_FRAGS ? 1 : 0);
221
222 profit = kill_desire(victim_cost, unit_attack, unit_cost, victim_defense, 1)
224 if (profit > 0) {
227 profit, sortie_time, balanced_cost);
228 log_debug("%s at (%d, %d) is a worthy target with profit " ADV_WANT_PRINTF,
229 unit_rule_name(pdefender), TILE_XY(dst_tile), profit);
230 } else {
231 log_debug("%s(%d, %d): %s at (%d, %d) is unworthy with profit " ADV_WANT_PRINTF,
233 unit_rule_name(pdefender), TILE_XY(dst_tile), profit);
234 profit = 0;
235 }
236
237 return profit;
238}
239
240/******************************************************************/
250 const struct civ_map *nmap,
251 struct unit *punit, struct pf_path **path,
252 struct tile **pptile)
253{
254 struct player *pplayer = unit_owner(punit);
255 struct pf_parameter parameter;
256 struct pf_map *pfm;
257 struct tile *best_tile = NULL;
258 adv_want best = 0;
259
260 pft_fill_unit_parameter(&parameter, nmap, punit);
261 parameter.omniscience = !has_handicap(pplayer, H_MAP);
262 pfm = pf_map_new(&parameter);
263
264 /* Let's find something to bomb */
265 pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
266 if (move_cost >= punit->moves_left) {
267 /* Too far! */
268 break;
269 }
270
271 if (has_handicap(pplayer, H_MAP) && !map_is_known(ptile, pplayer)) {
272 /* The target tile is unknown */
273 continue;
274 }
275
276 if (has_handicap(pplayer, H_FOG)
277 && !map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
278 /* The tile is fogged */
279 continue;
280 }
281
282 if (is_enemy_unit_tile(ptile, pplayer)
284 && can_unit_attack_tile(punit, NULL, ptile)) {
286 ptile);
287
288 if (new_best > best) {
289 best_tile = ptile;
290 best = new_best;
291 log_debug("%s wants to attack tile (%d, %d)",
292 unit_rule_name(punit), TILE_XY(ptile));
293 }
294 }
296
297 /* Return the best values. */
298 if (pptile) {
299 *pptile = best_tile;
300 }
301 if (path) {
302 *path = best_tile ? pf_map_path(pfm, best_tile) : NULL;
303 }
304
305 pf_map_destroy(pfm);
306
307 return best;
308}
309
310/******************************************************************/
321static struct tile *dai_find_strategic_airbase(struct ai_type *ait,
322 struct unit *punit,
323 struct pf_path **path)
324{
325 struct player *pplayer = unit_owner(punit);
326 struct pf_parameter parameter;
327 struct pf_map *pfm;
328 struct tile *best_tile = NULL;
329 struct city *pcity;
330 struct unit *pvirtual = NULL;
331 adv_want best_worth = 0, target_worth;
332 int lost_hp = unit_type_get(punit)->hp - punit->hp;
333 int regen_turns_min = FC_INFINITY;
334 bool defend = FALSE; /* Used only for lost_hp > 0 */
335 bool refuel_start = FALSE; /* Used for not a "grave danger" start */
336 const struct civ_map *nmap = &(wld.map);
337
338 /* Consider staying at the current position
339 * before we generate the map, maybe we should not */
341 /* We suppose here for speed that the recovery effect is global.
342 * It's so in the standard rulesets but might be not elsewhere */
343 int recov = get_unit_bonus(punit, EFT_UNIT_RECOVER);
344 int regen = hp_gain_coord(punit);
345 const struct tile *ptile = unit_tile(punit);
346
347 if (lost_hp > 0 && regen + recov > 0) {
348 regen_turns_min =
349 punit->moved ? lost_hp - recov : lost_hp - (regen + recov);
350 if (regen_turns_min <= 0) {
351 if (lost_hp - recov > 0) {
352 /* Probably, nothing can repair us faster */
353 log_debug("Repairment of %s is almost finished, stays here",
356 return NULL;
357 } else {
358 regen_turns_min = 0;
359 }
360 } else {
361 regen_turns_min /= regen + recov;
362 regen_turns_min += 1;
363 }
364 }
365 pcity = tile_city(ptile);
366 if (pcity
367 && def_ai_city_data(pcity, ait)->grave_danger
368 > (unit_list_size(ptile->units) - 1) << 1) {
369 if (lost_hp <= 0 || regen_turns_min <= 1) {
370 log_debug("%s stays defending %s",
372 return NULL;
373 } else {
374 /* We may find a city in grave danger that restores faster */
375 defend = TRUE;
376 }
377 } else {
378 refuel_start = TRUE;
379 }
380 }
381
382 pft_fill_unit_parameter(&parameter, nmap, punit);
383 parameter.omniscience = !has_handicap(pplayer, H_MAP);
384 pfm = pf_map_new(&parameter);
385 pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
386 bool chg_for_regen = FALSE;
387
388 if (move_cost >= punit->moves_left) {
389 break; /* Too far! */
390 }
391
392 if (!is_refuel_point(ptile, pplayer, punit)) {
393 continue; /* Cannot refuel here. */
394 }
395
396 if (lost_hp > 0) {
397 /* Don't fly to a point where we'll regenerate longer */
398 int regen_tn = regen_turns(punit, ptile, lost_hp);
399
400 if (regen_turns_min < regen_tn) {
401 log_debug("%s knows a better repair base than %d,%d",
402 unit_rule_name(punit), TILE_XY(ptile));
403 continue;
404 } else if (regen_turns_min > regen_tn) {
405 regen_turns_min = regen_tn;
406 best_tile = ptile;
407 best_worth = 0; /* to be calculated if necessary */
408 chg_for_regen = TRUE;
409 }
410 }
411
412 if ((pcity = tile_city(ptile))
413 /* Two defenders per attacker is enough,
414 * at least considering that planes are usually
415 * expensive and weak city defenders */
416 && def_ai_city_data(pcity, ait)->grave_danger
417 > unit_list_size(ptile->units) << 1) {
418 if (lost_hp <= 0) {
419 best_tile = ptile;
420 break; /* Fly there immediately!! */
421 } else {
422 if (!defend) {
423 /* We maybe have equally regenerating base but not in danger */
424 best_tile = ptile;
425 defend = TRUE;
426 }
427 continue;
428 }
429 } else if (defend) {
430 if (chg_for_regen) {
431 /* We better regenerate faster and take a revenge a bit later */
432 defend = FALSE;
433 } else {
434 /* We already have a base in grave danger that restores not worse */
435 continue;
436 }
437 }
438
439 if (!pvirtual) {
440 pvirtual =
441 unit_virtual_create(pplayer,
444 if (refuel_start) {
445 /* What worth really worth moving out? */
446 adv_want start_worth;
447
448 unit_tile_set(pvirtual, unit_tile(punit));
449 start_worth = find_something_to_bomb(ait, nmap, pvirtual,
450 NULL, NULL);
451 best_worth = MAX(start_worth, 0);
452 }
453 }
454
455 unit_tile_set(pvirtual, ptile);
456 target_worth = find_something_to_bomb(ait, nmap, pvirtual, NULL, NULL);
457 if (target_worth > best_worth) {
458 /* It's either a first find or it's better than the previous. */
459 best_worth = target_worth;
460 best_tile = ptile;
461 /* We can still look for something better. */
462 }
464
465 if (pvirtual) {
466 unit_virtual_destroy(pvirtual);
467 }
468
469 if (path) {
470 /* Stores the path. */
471 *path = best_tile ? pf_map_path(pfm, best_tile) : NULL;
472 }
473 pf_map_destroy(pfm);
474
475 return best_tile;
476}
477
478/******************************************************************/
491void dai_manage_airunit(struct ai_type *ait, struct player *pplayer,
492 struct unit *punit)
493{
494 struct tile *dst_tile = unit_tile(punit);
495 /* Loop prevention */
496 int moves = punit->moves_left;
497 int id = punit->id;
498 struct pf_parameter parameter;
499 struct pf_map *pfm;
500 struct pf_path *path;
501 const struct civ_map *nmap = &(wld.map);
502
504
506 /* We are out in the open, what shall we do? */
507 if (punit->activity == ACTIVITY_GOTO
508 /* We are on a GOTO. Check if it will get us anywhere */
509 && NULL != punit->goto_tile
511 && is_refuel_point(punit->goto_tile, pplayer, punit)) {
512 pft_fill_unit_parameter(&parameter, nmap, punit);
513 pfm = pf_map_new(&parameter);
514 path = pf_map_path(pfm, punit->goto_tile);
515 if (path) {
516 bool alive = adv_follow_path(punit, path, punit->goto_tile);
517
518 pf_path_destroy(path);
519 pf_map_destroy(pfm);
520 if (alive && punit->moves_left > 0) {
521 /* Maybe do something else. */
522 dai_manage_airunit(ait, pplayer, punit);
523 }
524 return;
525 }
526 pf_map_destroy(pfm);
527 } else if ((dst_tile = find_nearest_airbase(punit, &path))) {
528 /* Go refuelling */
529 if (!adv_follow_path(punit, path, dst_tile)) {
530 pf_path_destroy(path);
531 return; /* The unit died. */
532 }
533 pf_path_destroy(path);
534 } else {
535 if (punit->fuel == 1) {
536 UNIT_LOG(LOG_DEBUG, punit, "Oops, fallin outta the sky");
537 }
538 def_ai_unit_data(punit, ait)->done = TRUE; /* Won't help trying again */
539 return;
540 }
541
542 } else if (punit->fuel == unit_type_get(punit)->fuel) {
543 /* We only leave a refuel point when we are on full fuel */
544
545 if (find_something_to_bomb(ait, nmap, punit, &path, &dst_tile) > 0) {
546 /* Found target, coordinates are in punit's goto_dest.
547 * TODO: separate attacking into a function, check for the best
548 * tile to attack from */
549 fc_assert_ret(path != NULL && dst_tile != NULL);
550 if (!adv_follow_path(punit, path, dst_tile)) {
551 pf_path_destroy(path);
552 return; /* The unit died. */
553 }
554 pf_path_destroy(path);
555 unit_activity_handling(punit, ACTIVITY_IDLE);
556 } else if ((dst_tile = dai_find_strategic_airbase(ait, punit, &path))) {
557 log_debug("%s will fly to (%i, %i) (%s) to fight there",
558 unit_rule_name(punit), TILE_XY(dst_tile),
559 tile_city(dst_tile) ? city_name_get(tile_city(dst_tile)) : "");
560 def_ai_unit_data(punit, ait)->done = TRUE; /* Wait for next turn */
561 if (!adv_follow_path(punit, path, dst_tile)) {
562 pf_path_destroy(path);
563 return; /* The unit died. */
564 }
565 pf_path_destroy(path);
566 } else {
567 log_debug("%s cannot find anything to kill and is staying put",
570 unit_activity_handling(punit, ACTIVITY_IDLE);
571 }
572 }
573
574 if ((punit = game_unit_by_number(id)) != NULL && punit->moves_left > 0
575 && punit->moves_left != moves) {
576 /* We have moved this turn, might have ended up stuck out in the fields
577 * so, as a safety measure, let's manage again */
578 dai_manage_airunit(ait, pplayer, punit);
579 }
580
581}
582
583/******************************************************************/
589bool dai_choose_attacker_air(struct ai_type *ait, const struct civ_map *nmap,
590 struct player *pplayer,
591 struct city *pcity, struct adv_choice *choice,
592 bool allow_gold_upkeep)
593{
594 bool want_something = FALSE;
595
596 /* This AI doesn't know how to build planes */
597 if (has_handicap(pplayer, H_NOPLANES)) {
598 return FALSE;
599 }
600
601 /* military_advisor_choose_build() does something idiotic,
602 * this function should not be called if there is danger... */
603 if (choice->want >= DAI_WANT_MILITARY_EMERGENCY
604 && choice->type != CT_ATTACKER) {
605 return FALSE;
606 }
607
608 if (!player_knows_techs_with_flag(pplayer, TF_BUILD_AIRBORNE)) {
609 return FALSE;
610 }
611
612 unit_type_iterate(punittype) {
613 struct unit_class *pclass = utype_class(punittype);
614
615 if (pclass->adv.land_move == MOVE_NONE
616 || pclass->adv.sea_move == MOVE_NONE
617 || uclass_has_flag(pclass, UCF_TERRAIN_SPEED)
618 || unit_type_is_losing_hp(pplayer, punittype)) {
619 /* We don't consider this a plane */
620 continue;
621 }
622
623 if (!allow_gold_upkeep && utype_upkeep_cost(punittype, pplayer, O_GOLD) > 0) {
624 continue;
625 }
626
627 if (can_city_build_unit_now(nmap, pcity, punittype)) {
628 struct unit *virtual_unit =
630 pplayer, pcity, punittype,
631 city_production_unit_veteran_level(pcity, punittype));
632 adv_want profit = find_something_to_bomb(ait, nmap, virtual_unit,
633 NULL, NULL);
634
635 if (profit > choice->want) {
636 /* Update choice */
637 choice->want = profit;
638 choice->value.utype = punittype;
639 choice->type = CT_ATTACKER;
640 choice->need_boat = FALSE;
641 adv_choice_set_use(choice, "offensive air");
642 want_something = TRUE;
643 log_debug("%s wants to build %s (want = " ADV_WANT_PRINTF ")",
644 city_name_get(pcity), utype_rule_name(punittype), profit);
645 } else {
646 log_debug("%s doesn't want to build %s (want = " ADV_WANT_PRINTF ")",
647 city_name_get(pcity), utype_rule_name(punittype), profit);
648 }
649 unit_virtual_destroy(virtual_unit);
650 }
652
653 return want_something;
654}
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
#define adv_choice_set_use(_choice, _use)
Definition advchoice.h:85
@ CT_ATTACKER
Definition advchoice.h:40
bool adv_follow_path(struct unit *punit, struct pf_path *path, struct tile *ptile)
Definition advgoto.c:47
static struct tile * find_nearest_airbase(struct unit *punit, struct pf_path **path)
Definition aiair.c:88
void dai_manage_airunit(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aiair.c:491
static adv_want find_something_to_bomb(struct ai_type *ait, const struct civ_map *nmap, struct unit *punit, struct pf_path **path, struct tile **pptile)
Definition aiair.c:249
static adv_want dai_evaluate_tile_for_air_attack(const struct civ_map *nmap, struct unit *punit, struct tile *dst_tile)
Definition aiair.c:165
#define PROB_MULTIPLIER
static int regen_turns(struct unit *punit, struct tile *ptile, int lost_hp)
Definition aiair.c:57
bool dai_choose_attacker_air(struct ai_type *ait, const struct civ_map *nmap, struct player *pplayer, struct city *pcity, struct adv_choice *choice, bool allow_gold_upkeep)
Definition aiair.c:589
static bool dai_should_we_air_attack_tile(struct ai_type *ait, struct unit *punit, struct tile *ptile)
Definition aiair.c:140
static struct tile * dai_find_strategic_airbase(struct ai_type *ait, struct unit *punit, struct pf_path **path)
Definition aiair.c:321
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
adv_want military_amortize(struct player *pplayer, struct city *pcity, adv_want value, int delay, int build_cost)
Definition aitools.c:118
#define DAI_WANT_MILITARY_EMERGENCY
Definition aitools.h:32
adv_want kill_desire(adv_want benefit, int attack, int loss, int vuln, int victim_count)
Definition aiunit.c:341
int build_cost_balanced(const struct unit_type *punittype)
Definition aiunit.c:249
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
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
struct unit * get_defender(const struct civ_map *nmap, const struct unit *attacker, const struct tile *ptile)
Definition combat.c:783
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 get_unit_bonus(const struct unit *punit, enum effect_type effect_type)
Definition effects.c:992
float adv_want
Definition fc_types.h:1206
#define ADV_WANT_PRINTF
Definition fc_types.h:1207
@ O_GOLD
Definition fc_types.h:91
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
bool has_handicap(const struct player *pplayer, enum handicap_type htype)
Definition handicaps.c:66
@ H_MAP
Definition handicaps.h:28
@ H_NOPLANES
Definition handicaps.h:27
@ H_FOG
Definition handicaps.h:26
#define fc_assert_ret(condition)
Definition log.h:191
#define log_debug(message,...)
Definition log.h:115
@ LOG_DEBUG
Definition log.h:34
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:938
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 MAX_MOVE_FRAGS
Definition movement.h:27
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)
#define pf_map_move_costs_iterate_end
#define pf_map_move_costs_iterate(ARG_pfm, NAME_tile, NAME_cost, COND_from_start)
void pft_fill_unit_parameter(struct pf_parameter *parameter, const struct civ_map *nmap, const struct unit *punit)
Definition pf_tools.c:840
bool player_knows_techs_with_flag(const struct player *pplayer, enum tech_flag_id flag)
Definition player.c:1304
struct city * player_city_by_number(const struct player *pplayer, int city_id)
Definition player.c:1179
#define FC_INFINITY
Definition shared.h:36
#define MAX(x, y)
Definition shared.h:54
#define UNIT_LOG(loglevel, punit, msg,...)
Definition srv_log.h:98
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
Definition ai.h:50
Definition city.h:309
Definition tile.h:49
struct unit_list * units
Definition tile.h:57
bool done
Definition aiunit.h:44
enum move_level sea_move
Definition unittype.h:150
enum move_level land_move
Definition unittype.h:149
struct unit_class::@84 adv
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
int fuel
Definition unit.h:153
struct tile * tile
Definition unit.h:140
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
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define TILE_XY(ptile)
Definition tile.h:42
const struct unit_type * utype
Definition fc_types.h:604
bool unit_type_is_losing_hp(const struct player *pplayer, const struct unit_type *punittype)
Definition unit.c:2232
int hp_gain_coord(const struct unit *punit)
Definition unit.c:2154
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1625
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1721
void unit_tile_set(struct unit *punit, struct tile *ptile)
Definition unit.c:1289
#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
bool is_refuel_point(const struct tile *ptile, const struct player *pplayer, const struct unit *punit)
Definition unittools.c:1544
bool is_unit_being_refueled(const struct unit *punit)
Definition unittools.c:1535
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
int utype_upkeep_cost(const struct unit_type *ut, struct player *pplayer, Output_type_id otype)
Definition unittype.c:132
const char * unit_rule_name(const struct unit *punit)
Definition unittype.c:1639
int unit_build_shield_cost_base(const struct unit *punit)
Definition unittype.c:1536
int utype_pays_mp_for_action_estimate(const struct civ_map *nmap, const struct action *paction, const struct unit_type *putype, const struct player *act_player, const struct tile *act_tile, const struct tile *tgt_tile)
Definition unittype.c:1445
const char * utype_rule_name(const struct unit_type *punittype)
Definition unittype.c:1630
bool unit_can_take_over(const struct unit *punit)
Definition unittype.c:258
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_class(_t_)
Definition unittype.h:736
@ MOVE_NONE
Definition unittype.h:131
#define unit_type_iterate(_p)
Definition unittype.h:841
#define unit_type_iterate_end
Definition unittype.h:848