Freeciv-3.3
Loading...
Searching...
No Matches
daihunter.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 "nation.h"
29#include "player.h"
30#include "unit.h"
31#include "unitlist.h"
32
33/* aicore */
34#include "pf_tools.h"
35
36/* server */
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
45/* ai */
46#include "handicaps.h"
47
48/* ai/default */
49#include "daiplayer.h"
50#include "daitools.h"
51#include "daiunit.h"
52
53#include "daihunter.h"
54
55
56/**********************************************************************/
60static struct unit *dai_hunter_find(struct player *pplayer,
61 struct city *pcity)
62{
63 unit_list_iterate(pcity->units_supported, punit) {
64 if (dai_hunter_qualify(pplayer, punit)) {
65 return punit;
66 }
69 if (dai_hunter_qualify(pplayer, punit)) {
70 return punit;
71 }
73
74 return NULL;
75}
76
77/**********************************************************************/
81 enum terrain_class tc,
82 struct ai_type *ait,
84{
85 struct unit_type *bestid = NULL;
86 int best = 0;
87 struct player *pplayer = city_owner(pcity);
88 const struct civ_map *nmap = &(wld.map);
89
91 struct unit_type_ai *utai = utype_ai_data(ut, ait);
92 int desire;
93
94 if (!allow_gold_upkeep && utype_upkeep_cost(ut, pplayer, O_GOLD) > 0) {
95 continue;
96 }
97
99 || ut->attack_strength < ut->transport_capacity
100 || (tc == TC_OCEAN && utype_class(ut)->adv.sea_move == MOVE_NONE)
101 || (tc == TC_LAND && utype_class(ut)->adv.land_move == MOVE_NONE)) {
102 continue;
103 }
104
105 desire = (ut->hp
106 * ut->attack_strength
107 * ut->firepower
108 * ut->move_rate
109 + ut->defense_strength) / MAX(UNITTYPE_COSTS(ut), 1);
110
111 if (utai->missile_platform) {
112 desire += desire / 6;
113 }
114
116 desire += desire / 2;
117 }
118 if (ut->vlayer == V_INVIS) {
119 desire += desire / 4;
120 }
122 desire -= desire / 4; /* less flexibility */
123 }
124 /* Causes continual unhappiness */
126 desire /= 2;
127 }
128
131 / MAX(pcity->surplus[O_SHIELD], 1)));
132
133 if (desire > best) {
134 best = desire;
135 bestid = ut;
136 }
138
139 return bestid;
140}
141
142/**********************************************************************/
145static void dai_hunter_missile_want(struct player *pplayer,
146 struct city *pcity,
147 struct adv_choice *choice)
148{
149 adv_want best = -1;
150 struct unit_type *best_unit_type = NULL;
151 struct unit *hunter = NULL;
152 const struct civ_map *nmap = &(wld.map);
153
155 if (dai_hunter_qualify(pplayer, punit)) {
160 hunter = punit;
161 break;
162 }
164 if (hunter) {
165 break;
166 }
167 }
169
170 if (!hunter) {
171 return;
172 }
173
175 int desire;
176
179 continue;
180 }
181
183 continue;
184 }
185
186 /* FIXME: We need to store some data that can tell us if
187 * enemy transports are protected by anti-missile technology.
188 * In this case, want nuclear much more! */
189 desire = (ut->hp
190 * MIN(ut->attack_strength, 30) /* nuke fix */
191 * ut->firepower
192 * ut->move_rate) / UNITTYPE_COSTS(ut) + 1;
193
194 /* Causes continual unhappiness */
196 desire /= 2;
197 }
198
201 / MAX(pcity->surplus[O_SHIELD], 1)));
202
203 if (desire > best) {
204 best = desire;
206 }
208
209 if (best > choice->want) {
211 "pri missile w/ want " ADV_WANT_PRINTF, best);
212 choice->value.utype = best_unit_type;
213 choice->want = best;
214 choice->type = CT_ATTACKER;
215 choice->need_boat = FALSE;
216 adv_choice_set_use(choice, "missile");
217 } else if (best >= 0) {
218 CITY_LOG(LOGLEVEL_HUNT, pcity, "not pri missile w/ want " ADV_WANT_PRINTF
219 "(old want " ADV_WANT_PRINTF ")", best, choice->want);
220 }
221}
222
223/**********************************************************************/
226static void eval_hunter_want(struct ai_type *ait, struct player *pplayer,
227 struct city *pcity,
228 struct adv_choice *choice,
229 struct unit_type *best_type,
230 int veteran)
231{
232 struct unit *virtualunit;
233 int want = 0;
234
236 want = dai_hunter_manage(ait, pplayer, virtualunit);
238 if (want > choice->want) {
239 CITY_LOG(LOGLEVEL_HUNT, pcity, "pri hunter w/ want %d", want);
240 choice->value.utype = best_type;
241 choice->want = want;
242 choice->type = CT_ATTACKER;
243 choice->need_boat = FALSE;
244 adv_choice_set_use(choice, "hunter");
245 }
246}
247
248/**********************************************************************/
251void dai_hunter_choice(struct ai_type *ait, struct player *pplayer,
252 struct city *pcity, struct adv_choice *choice,
254{
259 struct unit *hunter = dai_hunter_find(pplayer, pcity);
260
262 || is_barbarian(pplayer) || !pplayer->is_alive
263 || has_handicap(pplayer, H_TARGETS)) {
264 return; /* None available */
265 }
266 if (hunter) {
267 /* Maybe want missiles to go with a hunter instead? */
268 dai_hunter_missile_want(pplayer, pcity, choice);
269 return;
270 }
271
272 if (best_sea_hunter) {
274 ait, pplayer, pcity, choice, best_sea_hunter,
276 }
277 if (best_land_hunter) {
279 ait, pplayer, pcity, choice, best_land_hunter,
281 }
282}
283
284/**********************************************************************/
287bool dai_hunter_qualify(struct player *pplayer, struct unit *punit)
288{
289 if (is_barbarian(pplayer) || unit_owner(punit) != pplayer) {
290 return FALSE;
291 }
293 return TRUE;
294 }
295 return FALSE;
296}
297
298/**********************************************************************/
303static void dai_hunter_try_launch(struct ai_type *ait,
304 struct player *pplayer,
305 struct unit *punit,
306 struct unit *target)
307{
308 int target_sanity = target->id;
309 struct pf_parameter parameter;
310 struct pf_map *pfm;
311 const struct civ_map *nmap = &(wld.map);
312
313 /* Only directly transported units. Not launching cargo of cargo */
315 struct unit *sucker = NULL;
316
317 if (unit_owner(missile) == pplayer
320 UNIT_LOG(LOGLEVEL_HUNT, missile, "checking for hunt targets");
321 pft_fill_unit_parameter(&parameter, nmap, punit);
322 parameter.omniscience = !has_handicap(pplayer, H_MAP);
323 pfm = pf_map_new(&parameter);
324
325 pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
326 if (move_cost > missile->moves_left / SINGLE_MOVE) {
327 break;
328 }
329 if (tile_city(ptile)
330 || !can_unit_attack_tile(punit, NULL, ptile)) {
331 continue;
332 }
333 unit_list_iterate(ptile->units, victim) {
334 enum diplstate_type ds
336 const struct unit_type *ptype;
337 const struct unit_type *victim_type;
338
339 if (ds != DS_WAR) {
340 continue;
341 }
342 if (victim == target) {
343 sucker = victim;
344 UNIT_LOG(LOGLEVEL_HUNT, missile, "found primary target %d(%d, %d)"
345 " dist %d", victim->id, TILE_XY(unit_tile(victim)),
346 move_cost);
347 break; /* Our target! Get it!!! */
348 }
349
352
355 sucker = victim;
356 UNIT_LOG(LOGLEVEL_HUNT, missile, "found aux target %d(%d, %d)",
358 break;
359 }
361 if (sucker) {
362 break; /* Found something - kill it! */
363 }
366
367 if (sucker) {
370
372 missile, ptrans)) {
375 }
376 }
377
378 missile->goto_tile = unit_tile(sucker);
380 /* We survived; did they? */
383 unit_tile(missile))) {
385 }
386 }
388 return; /* Target killed */
389 }
390 }
391 } /* if */
393}
394
395/**********************************************************************/
398static void dai_hunter_juiciness(struct player *pplayer, struct unit *punit,
399 struct unit *target, unsigned *stackthreat,
400 unsigned *stackcost)
401{
402 *stackthreat = 0;
403 *stackcost = 0;
404
405 unit_list_iterate(unit_tile(target)->units, sucker) {
406 const struct unit_type *suck_type = unit_type_get(sucker);
407
410 *stackcost += 1000;
411 *stackthreat += 5000;
412 }
414 *stackthreat += 500; /* Extra threatening */
415 }
418
419 *stackthreat *= 9; /* WAG - reduced by distance later */
421}
422
423/**********************************************************************/
435int dai_hunter_manage(struct ai_type *ait, struct player *pplayer,
436 struct unit *punit)
437{
438 bool is_virtual = (punit->id == 0);
439 struct pf_parameter parameter;
440 struct pf_map *pfm;
441 int limit = unit_move_rate(punit) * 6;
442 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
444 unsigned original_threat = 0, original_cost = 0;
445 struct civ_map *nmap = &(wld.map);
446
447 fc_assert_ret_val(!is_barbarian(pplayer), 0);
448 fc_assert_ret_val(pplayer->is_alive, 0);
449
450 pft_fill_unit_parameter(&parameter, nmap, punit);
451 parameter.omniscience = !has_handicap(pplayer, H_MAP);
452 pfm = pf_map_new(&parameter);
453
454 if (original_target) {
457 }
458
459 pf_map_move_costs_iterate(pfm, ptile, move_cost, FALSE) {
460 /* End faster if we have a target */
461 if (move_cost > limit) {
462 UNIT_LOG(LOGLEVEL_HUNT, punit, "gave up finding hunt target");
464 return 0;
465 }
466
467 if (tile_city(ptile)
468 || !can_unit_attack_tile(punit, NULL, ptile)) {
469 continue;
470 }
471
472 unit_list_iterate_safe(ptile->units, target) {
473 struct player *aplayer = unit_owner(target);
474 int dist1, dist2;
475 unsigned stackthreat = 0, stackcost = 0;
476 int sanity_target = target->id;
477 struct pf_path *path;
478 struct unit_ai *target_data;
479 struct tile *target_tile;
480 struct unit *defender;
481
482 /* Note that we need not (yet) be at war with aplayer */
483 if (!adv_is_player_dangerous(pplayer, aplayer)) {
484 continue;
485 }
486
487 target_data = def_ai_unit_data(target, ait);
488 if (BV_ISSET(target_data->hunted, player_index(pplayer))) {
489 /* Can't hunt this one. The bit is cleared in the beginning
490 * of each turn. */
491 continue;
492 }
494 && get_transporter_capacity(target) == 0
495 && !unit_has_type_flag(target, UTYF_GAMELOSS)) {
496 /* Won't hunt this one. */
497 continue;
498 }
499
500 target_tile = unit_tile(target);
502 /* We can't attack the target */
503 continue;
504 }
505
506 /* Figure out whether unit is coming closer */
507 if (target_data->cur_pos && target_data->prev_pos) {
510 } else {
511 dist1 = dist2 = 0;
512 }
513 UNIT_LOG(LOGLEVEL_HUNT, punit, "considering chasing %s[%d](%d, %d) "
514 "dist1 %d dist2 %d",
515 unit_rule_name(target), target->id, TILE_XY(target_tile),
516 dist1, dist2);
517
518 /* We can't chase if we aren't faster or on intercept vector */
519 if (unit_type_get(punit)->move_rate < unit_type_get(target)->move_rate
520 && dist1 >= dist2) {
522 "giving up racing %s (%d, %d)->(%d, %d)",
523 unit_rule_name(target),
524 target_data->prev_pos
526 : -1,
527 target_data->prev_pos
529 : -1,
531 continue;
532 }
533
534 /* Calculate juiciness of target, compare with existing target,
535 * if any. */
536 dai_hunter_juiciness(pplayer, punit, target, &stackthreat, &stackcost);
537 defender = get_defender(nmap, punit, target_tile, NULL);
538 if (defender != NULL) {
539 stackcost *= unit_win_chance(nmap, punit, defender, NULL);
540 }
542 UNIT_LOG(LOGLEVEL_HUNT, punit, "%d is too expensive (it %d vs us %d)",
543 target->id, stackcost,
545 continue; /* Too expensive */
546 }
547 stackthreat /= move_cost + 1;
548 if (!is_virtual
549 && original_target != target
551 UNIT_LOG(LOGLEVEL_HUNT, punit, "Unit %d is not worse than %d",
552 target->id, original_target->id);
553 continue; /* The threat we found originally was worse than this! */
554 }
556 UNIT_LOG(LOGLEVEL_HUNT, punit, "%d is not worth it", target->id);
557 continue; /* Not worth it */
558 }
559
560 UNIT_LOG(LOGLEVEL_HUNT, punit, "hunting %s %s[%d](%d,%d) "
561 "with want %d, dist1 %d, dist2 %d",
563 unit_rule_name(target),
564 target->id,
567 dist1,
568 dist2);
569 /* Ok, now we FINALLY have a target worth destroying! */
570 unit_data->target = target->id;
571 if (is_virtual) {
573 return stackthreat;
574 }
575
576 /* This assigns missiles to us */
578
579 /* Check if we can nuke it */
580 dai_hunter_try_launch(ait, pplayer, punit, target);
581
582 /* Check if we have nuked it */
583 if (target != game_unit_by_number(sanity_target)) {
584 UNIT_LOG(LOGLEVEL_HUNT, punit, "mission accomplished by cargo (pre)");
587 return -1; /* try again */
588 }
589
590 /* Go towards it. */
591 path = pf_map_path(pfm, target_tile);
592 if (!adv_unit_execute_path(punit, path)) {
593 pf_path_destroy(path);
595 return 0;
596 }
597 pf_path_destroy(path);
598
599 if (target != game_unit_by_number(sanity_target)) {
600 UNIT_LOG(LOGLEVEL_HUNT, punit, "mission accomplished");
603 return -1; /* try again */
604 }
605
606 /* Check if we can nuke it now */
607 dai_hunter_try_launch(ait, pplayer, punit, target);
608 if (target != game_unit_by_number(sanity_target)) {
609 UNIT_LOG(LOGLEVEL_HUNT, punit, "mission accomplished by cargo (post)");
612 return -1; /* try again */
613 }
614
616 unit_data->done = TRUE;
617 return stackthreat; /* still have work to do */
620
621 UNIT_LOG(LOGLEVEL_HUNT, punit, "ran out of map finding hunt target");
623 return 0; /* found nothing */
624}
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:3168
#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:1113
bool adv_unit_execute_path(struct unit *punit, struct pf_path *path)
Definition advgoto.c:86
adv_want amortize(adv_want benefit, int delay)
Definition advtools.c:29
#define BV_ISSET(bv, bit)
Definition bitvector.h:86
int city_production_unit_veteran_level(struct city *pcity, const struct unit_type *punittype)
Definition city.c:804
bool can_city_build_unit_now(const struct civ_map *nmap, const struct city *pcity, const struct unit_type *punittype)
Definition city.c:947
#define city_owner(_pcity_)
Definition city.h:560
double unit_win_chance(const struct civ_map *nmap, const struct unit *attacker, const struct unit *defender, const struct action *paction)
Definition combat.c:480
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:123
struct unit * get_defender(const struct civ_map *nmap, const struct unit *attacker, const struct tile *ptile, const struct action *paction)
Definition combat.c:841
bool can_unit_attack_tile(const struct unit *punit, const struct action *paction, const struct tile *dest_tile)
Definition combat.c:312
char * incite_cost
Definition comments.c:76
static void dai_hunter_juiciness(struct player *pplayer, struct unit *punit, struct unit *target, unsigned *stackthreat, unsigned *stackcost)
Definition daihunter.c:398
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 daihunter.c:226
static struct unit * dai_hunter_find(struct player *pplayer, struct city *pcity)
Definition daihunter.c:60
bool dai_hunter_qualify(struct player *pplayer, struct unit *punit)
Definition daihunter.c:287
static void dai_hunter_missile_want(struct player *pplayer, struct city *pcity, struct adv_choice *choice)
Definition daihunter.c:145
static struct unit_type * dai_hunter_guess_best(struct city *pcity, enum terrain_class tc, struct ai_type *ait, bool allow_gold_upkeep)
Definition daihunter.c:80
void dai_hunter_choice(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct adv_choice *choice, bool allow_gold_upkeep)
Definition daihunter.c:251
int dai_hunter_manage(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Definition daihunter.c:435
static void dai_hunter_try_launch(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct unit *target)
Definition daihunter.c:303
static struct unit_ai * def_ai_unit_data(const struct unit *punit, struct ai_type *deftype)
Definition daiplayer.h:48
bool dai_unit_attack(struct ai_type *ait, struct unit *punit, struct tile *ptile)
Definition daitools.c:817
bool dai_unit_goto(struct ai_type *ait, struct unit *punit, struct tile *ptile)
Definition daitools.c:605
void dai_unit_new_task(struct ai_type *ait, struct unit *punit, enum ai_unit_task task, struct tile *ptile)
Definition daitools.c:643
bool dai_unit_can_strike_my_unit(const struct unit *attacker, const struct unit *defender)
Definition daiunit.c:3450
@ AIUNIT_NONE
Definition daiunit.h:27
@ AIUNIT_HUNTER
Definition daiunit.h:29
#define DEFENSE_POWER(ptype)
Definition daiunit.h:66
#define ATTACK_POWER(ptype)
Definition daiunit.h:68
#define UNITTYPE_COSTS(ut)
Definition daiunit.h:75
struct unit struct city struct unit struct tile * target_tile
Definition dialogs_g.h:57
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:74
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int const struct action *paction struct unit struct city * pcity
Definition dialogs_g.h:78
float adv_want
Definition fc_types.h:1063
#define ADV_WANT_PRINTF
Definition fc_types.h:1064
@ O_SHIELD
Definition fc_types.h:101
@ O_GOLD
Definition fc_types.h:101
struct world wld
Definition game.c:62
struct unit * game_unit_by_number(int id)
Definition game.c:115
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:195
bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
Definition map.c:1067
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:675
static int index_to_map_pos_y(int mindex)
Definition map.h:752
static int index_to_map_pos_x(int mindex)
Definition map.h:743
int unit_move_rate(const struct unit *punit)
Definition movement.c:89
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Definition movement.c:869
bool can_attack_non_native(const struct unit_type *utype)
Definition movement.c:213
#define SINGLE_MOVE
Definition movement.h:26
const char * nation_rule_name(const struct nation_type *pnation)
Definition nation.c:138
struct nation_type * nation_of_unit(const struct unit *punit)
Definition nation.c:463
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:843
int player_index(const struct player *pplayer)
Definition player.c:829
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Definition player.c:324
static bool is_barbarian(const struct player *pplayer)
Definition player.h:491
#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:317
enum diplstate_type type
Definition player.h:199
bool is_alive
Definition player.h:268
Definition tile.h:50
struct unit_list * units
Definition tile.h:58
Definition unit.h:140
int id
Definition unit.h:147
struct unit_list * transporting
Definition unit.h:187
struct tile * tile
Definition unit.h:142
int veteran
Definition unit.h:154
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:89
#define TILE_XY(ptile)
Definition tile.h:43
const struct unit_type * utype
Definition fc_types.h:553
struct unit * unit_transport_get(const struct unit *pcargo)
Definition unit.c:2518
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Definition unit.c:1661
int get_transporter_capacity(const struct unit *punit)
Definition unit.c:297
void unit_virtual_destroy(struct unit *punit)
Definition unit.c:1766
bool unit_transported(const struct unit *pcargo)
Definition unit.c:2502
#define unit_tile(_pu)
Definition unit.h:404
#define unit_owner(_pu)
Definition unit.h:403
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:3338
#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:1593
int unit_build_shield_cost_base(const struct unit *punit)
Definition unittype.c:1490
bool unit_has_type_role(const struct unit *punit, enum unit_role_id role)
Definition unittype.c:214
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:196
void * utype_ai_data(const struct unit_type *ptype, const struct ai_type *ai)
Definition unittype.c:2745
int utype_build_shield_cost(const struct city *pcity, const struct player *pplayer, const struct unit_type *punittype)
Definition unittype.c:1444
bool utype_acts_hostile(const struct unit_type *putype)
Definition unittype.c:449
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Definition unittype.c:377
#define utype_class(_t_)
Definition unittype.h:756
@ MOVE_NONE
Definition unittype.h:144
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:624
#define unit_type_iterate(_p)
Definition unittype.h:862
#define unit_type_iterate_end
Definition unittype.h:869