Freeciv-3.1
Loading...
Searching...
No Matches
aihunt.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2003 - 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 "bitvector.h"
20#include "log.h"
21
22/* common */
23#include "city.h"
24#include "combat.h"
25#include "game.h"
26#include "map.h"
27#include "movement.h"
28#include "player.h"
29#include "unit.h"
30#include "unitlist.h"
31
32/* aicore */
33#include "pf_tools.h"
34
35/* server */
36#include "citytools.h"
37#include "srv_log.h"
38#include "unithand.h"
39#include "unittools.h"
40
41/* server/advisors */
42#include "advdata.h"
43#include "advgoto.h"
44#include "advtools.h"
45#include "autosettlers.h"
46
47/* ai */
48#include "handicaps.h"
49
50/* ai/default */
51#include "ailog.h"
52#include "aiplayer.h"
53#include "aitools.h"
54#include "aiunit.h"
55#include "daicity.h"
56
57#include "aihunt.h"
58
59
60/**********************************************************************/
64static struct unit *dai_hunter_find(struct player *pplayer,
65 struct city *pcity)
66{
68 if (dai_hunter_qualify(pplayer, punit)) {
69 return punit;
70 }
73 if (dai_hunter_qualify(pplayer, punit)) {
74 return punit;
75 }
77
78 return NULL;
79}
80
81/**********************************************************************/
84static struct unit_type *dai_hunter_guess_best(struct city *pcity,
85 enum terrain_class tc,
86 struct ai_type *ait,
87 bool allow_gold_upkeep)
88{
89 struct unit_type *bestid = NULL;
90 int best = 0;
91 struct player *pplayer = city_owner(pcity);
92 const struct civ_map *nmap = &(wld.map);
93
95 struct unit_type_ai *utai = utype_ai_data(ut, ait);
96 int desire;
97
98 if (!allow_gold_upkeep && utype_upkeep_cost(ut, pplayer, O_GOLD) > 0) {
99 continue;
100 }
101
102 if (!can_city_build_unit_now(nmap, pcity, ut)
103 || ut->attack_strength < ut->transport_capacity
104 || (tc == TC_OCEAN && utype_class(ut)->adv.sea_move == MOVE_NONE)
105 || (tc == TC_LAND && utype_class(ut)->adv.land_move == MOVE_NONE)) {
106 continue;
107 }
108
109 desire = (ut->hp
110 * ut->attack_strength
111 * ut->firepower
112 * ut->move_rate
113 + ut->defense_strength) / MAX(UNITTYPE_COSTS(ut), 1);
114
115 if (utai->missile_platform) {
116 desire += desire / 6;
117 }
118
119 if (utype_has_flag(ut, UTYF_IGTER)) {
120 desire += desire / 2;
121 }
122 if (ut->vlayer == V_INVIS) {
123 desire += desire / 4;
124 }
125 if (!can_attack_non_native(ut)) {
126 desire -= desire / 4; /* less flexibility */
127 }
128 /* Causes continual unhappiness */
129 if (utype_has_flag(ut, UTYF_FIELDUNIT)) {
130 desire /= 2;
131 }
132
133 desire = amortize(desire,
134 (utype_build_shield_cost(pcity, NULL, ut)
135 / MAX(pcity->surplus[O_SHIELD], 1)));
136
137 if (desire > best) {
138 best = desire;
139 bestid = ut;
140 }
142
143 return bestid;
144}
145
146/**********************************************************************/
149static void dai_hunter_missile_want(struct player *pplayer,
150 struct city *pcity,
151 struct adv_choice *choice)
152{
153 adv_want best = -1;
154 struct unit_type *best_unit_type = NULL;
155 struct unit *hunter = NULL;
156 const struct civ_map *nmap = &(wld.map);
157
159 if (dai_hunter_qualify(pplayer, punit)) {
160 unit_type_iterate(pcargo) {
162 utype_class(pcargo))
163 && utype_can_do_action(pcargo, ACTION_SUICIDE_ATTACK)) {
164 hunter = punit;
165 break;
166 }
168 if (hunter) {
169 break;
170 }
171 }
173
174 if (!hunter) {
175 return;
176 }
177
179 int desire;
180
181 if (!utype_can_do_action(ut, ACTION_SUICIDE_ATTACK)
182 || !can_city_build_unit_now(nmap, pcity, ut)) {
183 continue;
184 }
185
187 continue;
188 }
189
190 /* FIXME: We need to store some data that can tell us if
191 * enemy transports are protected by anti-missile technology.
192 * In this case, want nuclear much more! */
193 desire = (ut->hp
194 * MIN(ut->attack_strength, 30) /* nuke fix */
195 * ut->firepower
196 * ut->move_rate) / UNITTYPE_COSTS(ut) + 1;
197
198 /* Causes continual unhappiness */
199 if (utype_has_flag(ut, UTYF_FIELDUNIT)) {
200 desire /= 2;
201 }
202
203 desire = amortize(desire,
204 (utype_build_shield_cost(pcity, NULL, ut)
205 / MAX(pcity->surplus[O_SHIELD], 1)));
206
207 if (desire > best) {
208 best = desire;
209 best_unit_type = ut;
210 }
212
213 if (best > choice->want) {
214 CITY_LOG(LOGLEVEL_HUNT, pcity,
215 "pri missile w/ want " ADV_WANT_PRINTF, best);
216 choice->value.utype = best_unit_type;
217 choice->want = best;
218 choice->type = CT_ATTACKER;
219 choice->need_boat = FALSE;
220 adv_choice_set_use(choice, "missile");
221 } else if (best >= 0) {
222 CITY_LOG(LOGLEVEL_HUNT, pcity, "not pri missile w/ want " ADV_WANT_PRINTF
223 "(old want " ADV_WANT_PRINTF ")", best, choice->want);
224 }
225}
226
227/**********************************************************************/
230static void eval_hunter_want(struct ai_type *ait, struct player *pplayer,
231 struct city *pcity,
232 struct adv_choice *choice,
233 struct unit_type *best_type,
234 int veteran)
235{
236 struct unit *virtualunit;
237 int want = 0;
238
239 virtualunit = unit_virtual_create(pplayer, pcity, best_type, veteran);
240 want = dai_hunter_manage(ait, pplayer, virtualunit);
241 unit_virtual_destroy(virtualunit);
242 if (want > choice->want) {
243 CITY_LOG(LOGLEVEL_HUNT, pcity, "pri hunter w/ want %d", want);
244 choice->value.utype = best_type;
245 choice->want = want;
246 choice->type = CT_ATTACKER;
247 choice->need_boat = FALSE;
248 adv_choice_set_use(choice, "hunter");
249 }
250}
251
252/**********************************************************************/
255void dai_hunter_choice(struct ai_type *ait, struct player *pplayer,
256 struct city *pcity, struct adv_choice *choice,
257 bool allow_gold_upkeep)
258{
259 struct unit_type *best_land_hunter
260 = dai_hunter_guess_best(pcity, TC_LAND, ait, allow_gold_upkeep);
261 struct unit_type *best_sea_hunter
262 = dai_hunter_guess_best(pcity, TC_OCEAN, ait, allow_gold_upkeep);
263 struct unit *hunter = dai_hunter_find(pplayer, pcity);
264
265 if ((!best_land_hunter && !best_sea_hunter)
266 || is_barbarian(pplayer) || !pplayer->is_alive
267 || has_handicap(pplayer, H_TARGETS)) {
268 return; /* None available */
269 }
270 if (hunter) {
271 /* Maybe want missiles to go with a hunter instead? */
272 dai_hunter_missile_want(pplayer, pcity, choice);
273 return;
274 }
275
276 if (best_sea_hunter) {
278 ait, pplayer, pcity, choice, best_sea_hunter,
279 city_production_unit_veteran_level(pcity, best_sea_hunter));
280 }
281 if (best_land_hunter) {
283 ait, pplayer, pcity, choice, best_land_hunter,
284 city_production_unit_veteran_level(pcity, best_land_hunter));
285 }
286}
287
288/**********************************************************************/
291bool dai_hunter_qualify(struct player *pplayer, struct unit *punit)
292{
293 if (is_barbarian(pplayer) || unit_owner(punit) != pplayer) {
294 return FALSE;
295 }
296 if (unit_has_type_role(punit, L_HUNTER)) {
297 return TRUE;
298 }
299 return FALSE;
300}
301
302/**********************************************************************/
307static void dai_hunter_try_launch(struct ai_type *ait,
308 struct player *pplayer,
309 struct unit *punit,
310 struct unit *target)
311{
312 int target_sanity = target->id;
313 struct pf_parameter parameter;
314 struct pf_map *pfm;
315 const struct civ_map *nmap = &(wld.map);
316
317 /* Only directly transported units. Not launching cargo of cargo */
319 struct unit *sucker = NULL;
320
321 if (unit_owner(missile) == pplayer
323 ACTION_SUICIDE_ATTACK)) {
324 UNIT_LOG(LOGLEVEL_HUNT, missile, "checking for hunt targets");
325 pft_fill_unit_parameter(&parameter, nmap, punit);
326 parameter.omniscience = !has_handicap(pplayer, H_MAP);
327 pfm = pf_map_new(&parameter);
328
329 pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
330 if (move_cost > missile->moves_left / SINGLE_MOVE) {
331 break;
332 }
333 if (tile_city(ptile)
334 || !can_unit_attack_tile(punit, NULL, ptile)) {
335 continue;
336 }
337 unit_list_iterate(ptile->units, victim) {
338 enum diplstate_type ds =
339 player_diplstate_get(pplayer, unit_owner(victim))->type;
340 const struct unit_type *ptype;
341 const struct unit_type *victim_type;
342
343 if (ds != DS_WAR) {
344 continue;
345 }
346 if (victim == target) {
347 sucker = victim;
348 UNIT_LOG(LOGLEVEL_HUNT, missile, "found primary target %d(%d, %d)"
349 " dist %d", victim->id, TILE_XY(unit_tile(victim)),
350 move_cost);
351 break; /* Our target! Get it!!! */
352 }
353
354 victim_type = unit_type_get(victim);
355 ptype = unit_type_get(punit);
356
357 if (ATTACK_POWER(victim_type) > DEFENSE_POWER(ptype)
359 sucker = victim;
360 UNIT_LOG(LOGLEVEL_HUNT, missile, "found aux target %d(%d, %d)",
361 victim->id, TILE_XY(unit_tile(victim)));
362 break;
363 }
365 if (sucker) {
366 break; /* Found something - kill it! */
367 }
369 pf_map_destroy(pfm);
370
371 if (sucker) {
372 if (unit_transported(missile)) {
373 struct unit *ptrans = unit_transport_get(missile);
374
375 if (is_action_enabled_unit_on_unit(nmap, ACTION_TRANSPORT_ALIGHT,
376 missile, ptrans)) {
378 0, "", ACTION_TRANSPORT_ALIGHT);
379 }
380 }
381
382 missile->goto_tile = unit_tile(sucker);
383 if (dai_unit_goto(ait, missile, unit_tile(sucker))) {
384 /* We survived; did they? */
385 sucker = game_unit_by_number(target_sanity); /* Sanity */
386 if (sucker && is_tiles_adjacent(unit_tile(sucker),
387 unit_tile(missile))) {
388 dai_unit_attack(ait, missile, unit_tile(sucker));
389 }
390 }
391 if (game_unit_by_number(target_sanity) == NULL) {
392 return; /* Target killed */
393 }
394 }
395 } /* if */
397}
398
399/**********************************************************************/
402static void dai_hunter_juiciness(struct player *pplayer, struct unit *punit,
403 struct unit *target, unsigned *stackthreat,
404 unsigned *stackcost)
405{
406 *stackthreat = 0;
407 *stackcost = 0;
408
409 unit_list_iterate(unit_tile(target)->units, sucker) {
410 const struct unit_type *suck_type = unit_type_get(sucker);
411
412 *stackthreat += ATTACK_POWER(suck_type);
413 if (unit_has_type_flag(sucker, UTYF_GAMELOSS)) {
414 *stackcost += 1000;
415 *stackthreat += 5000;
416 }
417 if (utype_acts_hostile(unit_type_get(sucker))) {
418 *stackthreat += 500; /* Extra threatening */
419 }
420 *stackcost += unit_build_shield_cost_base(sucker);
422
423 *stackthreat *= 9; /* WAG - reduced by distance later */
424 *stackthreat += *stackcost;
425}
426
427/**********************************************************************/
439int dai_hunter_manage(struct ai_type *ait, struct player *pplayer,
440 struct unit *punit)
441{
442 bool is_virtual = (punit->id == 0);
443 struct pf_parameter parameter;
444 struct pf_map *pfm;
445 int limit = unit_move_rate(punit) * 6;
446 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
447 struct unit *original_target = game_unit_by_number(unit_data->target);
448 unsigned original_threat = 0, original_cost = 0;
449 struct civ_map *nmap = &(wld.map);
450
451 fc_assert_ret_val(!is_barbarian(pplayer), 0);
452 fc_assert_ret_val(pplayer->is_alive, 0);
453
454 pft_fill_unit_parameter(&parameter, nmap, punit);
455 parameter.omniscience = !has_handicap(pplayer, H_MAP);
456 pfm = pf_map_new(&parameter);
457
458 if (original_target) {
459 dai_hunter_juiciness(pplayer, punit, original_target,
460 &original_threat, &original_cost);
461 }
462
463 pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
464 /* End faster if we have a target */
465 if (move_cost > limit) {
466 UNIT_LOG(LOGLEVEL_HUNT, punit, "gave up finding hunt target");
467 pf_map_destroy(pfm);
468 return 0;
469 }
470
471 if (tile_city(ptile)
472 || !can_unit_attack_tile(punit, NULL, ptile)) {
473 continue;
474 }
475
476 unit_list_iterate_safe(ptile->units, target) {
477 struct player *aplayer = unit_owner(target);
478 int dist1, dist2;
479 unsigned stackthreat = 0, stackcost = 0;
480 int sanity_target = target->id;
481 struct pf_path *path;
482 struct unit_ai *target_data;
483 struct tile *target_tile;
484 struct unit *defender;
485
486 /* Note that we need not (yet) be at war with aplayer */
487 if (!adv_is_player_dangerous(pplayer, aplayer)) {
488 continue;
489 }
490
491 target_data = def_ai_unit_data(target, ait);
492 if (BV_ISSET(target_data->hunted, player_index(pplayer))) {
493 /* Can't hunt this one. The bit is cleared in the beginning
494 * of each turn. */
495 continue;
496 }
498 && get_transporter_capacity(target) == 0
499 && !unit_has_type_flag(target, UTYF_GAMELOSS)) {
500 /* Won't hunt this one. */
501 continue;
502 }
503
504 target_tile = unit_tile(target);
506 /* We can't attack the target */
507 continue;
508 }
509
510 /* Figure out whether unit is coming closer */
511 if (target_data->cur_pos && target_data->prev_pos) {
512 dist1 = real_map_distance(unit_tile(punit), *target_data->cur_pos);
513 dist2 = real_map_distance(unit_tile(punit), *target_data->prev_pos);
514 } else {
515 dist1 = dist2 = 0;
516 }
517 UNIT_LOG(LOGLEVEL_HUNT, punit, "considering chasing %s[%d](%d, %d) "
518 "dist1 %d dist2 %d",
519 unit_rule_name(target), target->id, TILE_XY(target_tile),
520 dist1, dist2);
521
522 /* We can't chase if we aren't faster or on intercept vector */
523 if (unit_type_get(punit)->move_rate < unit_type_get(target)->move_rate
524 && dist1 >= dist2) {
526 "giving up racing %s (%d, %d)->(%d, %d)",
527 unit_rule_name(target),
528 target_data->prev_pos
529 ? index_to_map_pos_x(tile_index(*target_data->prev_pos))
530 : -1,
531 target_data->prev_pos
532 ? index_to_map_pos_y(tile_index(*target_data->prev_pos))
533 : -1,
535 continue;
536 }
537
538 /* Calculate juiciness of target, compare with existing target,
539 * if any. */
540 dai_hunter_juiciness(pplayer, punit, target, &stackthreat, &stackcost);
541 defender = get_defender(nmap, punit, target_tile);
542 if (defender != NULL) {
543 stackcost *= unit_win_chance(nmap, punit, defender);
544 }
545 if (stackcost < unit_build_shield_cost_base(punit)) {
546 UNIT_LOG(LOGLEVEL_HUNT, punit, "%d is too expensive (it %d vs us %d)",
547 target->id, stackcost,
549 continue; /* Too expensive */
550 }
551 stackthreat /= move_cost + 1;
552 if (!is_virtual
553 && original_target != target
554 && original_threat > stackthreat) {
555 UNIT_LOG(LOGLEVEL_HUNT, punit, "Unit %d is not worse than %d",
556 target->id, original_target->id);
557 continue; /* The threat we found originally was worse than this! */
558 }
559 if (stackthreat < unit_build_shield_cost_base(punit)) {
560 UNIT_LOG(LOGLEVEL_HUNT, punit, "%d is not worth it", target->id);
561 continue; /* Not worth it */
562 }
563
564 UNIT_LOG(LOGLEVEL_HUNT, punit, "hunting %s %s[%d](%d,%d) "
565 "with want %d, dist1 %d, dist2 %d",
567 unit_rule_name(target),
568 target->id,
570 stackthreat,
571 dist1,
572 dist2);
573 /* Ok, now we FINALLY have a target worth destroying! */
574 unit_data->target = target->id;
575 if (is_virtual) {
576 pf_map_destroy(pfm);
577 return stackthreat;
578 }
579
580 /* This assigns missiles to us */
582
583 /* Check if we can nuke it */
584 dai_hunter_try_launch(ait, pplayer, punit, target);
585
586 /* Check if we have nuked it */
587 if (target != game_unit_by_number(sanity_target)) {
588 UNIT_LOG(LOGLEVEL_HUNT, punit, "mission accomplished by cargo (pre)");
590 pf_map_destroy(pfm);
591 return -1; /* try again */
592 }
593
594 /* Go towards it. */
595 path = pf_map_path(pfm, target_tile);
596 if (!adv_unit_execute_path(punit, path)) {
597 pf_path_destroy(path);
598 pf_map_destroy(pfm);
599 return 0;
600 }
601 pf_path_destroy(path);
602
603 if (target != game_unit_by_number(sanity_target)) {
604 UNIT_LOG(LOGLEVEL_HUNT, punit, "mission accomplished");
606 pf_map_destroy(pfm);
607 return -1; /* try again */
608 }
609
610 /* Check if we can nuke it now */
611 dai_hunter_try_launch(ait, pplayer, punit, target);
612 if (target != game_unit_by_number(sanity_target)) {
613 UNIT_LOG(LOGLEVEL_HUNT, punit, "mission accomplished by cargo (post)");
615 pf_map_destroy(pfm);
616 return -1; /* try again */
617 }
618
619 pf_map_destroy(pfm);
620 unit_data->done = TRUE;
621 return stackthreat; /* still have work to do */
624
625 UNIT_LOG(LOGLEVEL_HUNT, punit, "ran out of map finding hunt target");
626 pf_map_destroy(pfm);
627 return 0; /* found nothing */
628}
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
#define adv_choice_set_use(_choice, _use)
Definition advchoice.h:85
@ CT_ATTACKER
Definition advchoice.h:40
bool adv_is_player_dangerous(struct player *pplayer, struct player *aplayer)
Definition advdata.c:1087
bool adv_unit_execute_path(struct unit *punit, struct pf_path *path)
Definition advgoto.c:82
adv_want amortize(adv_want benefit, int delay)
Definition advtools.c:29
static void dai_hunter_juiciness(struct player *pplayer, struct unit *punit, struct unit *target, unsigned *stackthreat, unsigned *stackcost)
Definition aihunt.c:402
static void eval_hunter_want(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct adv_choice *choice, struct unit_type *best_type, int veteran)
Definition aihunt.c:230
static struct unit * dai_hunter_find(struct player *pplayer, struct city *pcity)
Definition aihunt.c:64
bool dai_hunter_qualify(struct player *pplayer, struct unit *punit)
Definition aihunt.c:291
static void dai_hunter_missile_want(struct player *pplayer, struct city *pcity, struct adv_choice *choice)
Definition aihunt.c:149
static struct unit_type * dai_hunter_guess_best(struct city *pcity, enum terrain_class tc, struct ai_type *ait, bool allow_gold_upkeep)
Definition aihunt.c:84
void dai_hunter_choice(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct adv_choice *choice, bool allow_gold_upkeep)
Definition aihunt.c:255
int dai_hunter_manage(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition aihunt.c:439
static void dai_hunter_try_launch(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct unit *target)
Definition aihunt.c:307
static struct unit_ai * def_ai_unit_data(const struct unit *punit, struct ai_type *deftype)
Definition aiplayer.h:48
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_unit_can_strike_my_unit(const struct unit *attacker, const struct unit *defender)
Definition aiunit.c:3442
@ AIUNIT_NONE
Definition aiunit.h:27
@ AIUNIT_HUNTER
Definition aiunit.h:29
#define DEFENSE_POWER(ptype)
Definition aiunit.h:66
#define ATTACK_POWER(ptype)
Definition aiunit.h:68
#define UNITTYPE_COSTS(ut)
Definition aiunit.h:75
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
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_owner(_pcity_)
Definition city.h:543
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
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 * target_tile
Definition dialogs_g.h:56
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
float adv_want
Definition fc_types.h:1206
#define ADV_WANT_PRINTF
Definition fc_types.h:1207
@ O_SHIELD
Definition fc_types.h:91
@ 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
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
#define fc_assert_ret_val(condition, val)
Definition log.h:194
bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
Definition map.c:929
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:628
static int index_to_map_pos_y(int mindex)
Definition map.h:696
static int index_to_map_pos_x(int mindex)
Definition map.h:687
int unit_move_rate(const struct unit *punit)
Definition movement.c:90
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Definition movement.c:826
bool can_attack_non_native(const struct unit_type *utype)
Definition movement.c:202
#define SINGLE_MOVE
Definition movement.h:24
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)
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
int player_index(const struct player *pplayer)
Definition player.c:820
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:317
static bool is_barbarian(const struct player *pplayer)
Definition player.h:488
#define MIN(x, y)
Definition shared.h:55
#define MAX(x, y)
Definition shared.h:54
#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
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
int surplus[O_LAST]
Definition city.h:343
struct tile * tile
Definition city.h:311
struct unit_list * units_supported
Definition city.h:391
enum diplstate_type type
Definition player.h:201
bool is_alive
Definition player.h:268
Definition tile.h:49
struct unit_list * units
Definition tile.h:57
struct tile ** prev_pos
Definition aiunit.h:40
bv_player hunted
Definition aiunit.h:43
bool done
Definition aiunit.h:44
struct tile ** cur_pos
Definition aiunit.h:40
int target
Definition aiunit.h:42
bool missile_platform
Definition aiunit.h:53
Definition unit.h:138
int id
Definition unit.h:145
struct unit_list * transporting
Definition unit.h:184
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_index(_pt_)
Definition tile.h:87
#define TILE_XY(ptile)
Definition tile.h:42
const struct unit_type * utype
Definition fc_types.h:604
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2425
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1617
int get_transporter_capacity(const struct unit *punit)
Definition unit.c:299
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1713
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2409
#define unit_tile(_pu)
Definition unit.h:395
#define unit_owner(_pu)
Definition unit.h:394
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_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
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
bool unit_has_type_role(const struct unit *punit, enum unit_role_id role)
Definition unittype.c:202
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:184
void * utype_ai_data(const struct unit_type *ptype, const struct ai_type *ai)
Definition unittype.c:2755
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
@ MOVE_NONE
Definition unittype.h:131
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:604
#define unit_type_iterate(_p)
Definition unittype.h:841
#define unit_type_iterate_end
Definition unittype.h:848