Freeciv21
Develop your civilization from humble roots to a global empire
aihunt.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 1996-2021 Freeciv21 and Freeciv contributors. This file is
3  part of Freeciv21. Freeciv21 is free software: you can
4  ^oo^ redistribute it and/or modify it under the terms of the GNU
5  (..) General Public License as published by the Free Software
6  () () Foundation, either version 3 of the License, or (at your
7  ()__() option) any later version. You should have received
8  a copy of the GNU General Public License along with Freeciv21. If not,
9  see https://www.gnu.org/licenses/.
10  */
11 
12 // utility
13 #include "bitvector.h"
14 #include "log.h"
15 
16 // common
17 #include "city.h"
18 #include "combat.h"
19 #include "game.h"
20 #include "map.h"
21 #include "movement.h"
22 #include "nation.h"
23 #include "player.h"
24 #include "unit.h"
25 #include "unitlist.h"
26 
27 // aicore
28 #include "pf_tools.h"
29 
30 // server
31 #include "srv_log.h"
32 #include "unithand.h"
33 #include "unittools.h"
34 
35 /* server/advisors */
36 #include "advdata.h"
37 #include "advgoto.h"
38 #include "advtools.h"
39 
40 // ai
41 #include "handicaps.h"
42 
43 /* ai/default */
44 #include "ailog.h"
45 #include "aiplayer.h"
46 #include "aitools.h"
47 #include "aiunit.h"
48 #include "daicity.h"
49 
50 #include "aihunt.h"
51 
52 class PFPath;
53 
58 static struct unit *dai_hunter_find(struct player *pplayer,
59  struct city *pcity)
60 {
61  unit_list_iterate(pcity->units_supported, punit)
62  {
63  if (dai_hunter_qualify(pplayer, punit)) {
64  return punit;
65  }
66  }
68  unit_list_iterate(pcity->tile->units, punit)
69  {
70  if (dai_hunter_qualify(pplayer, punit)) {
71  return punit;
72  }
73  }
75 
76  return nullptr;
77 }
78 
82 static struct unit_type *dai_hunter_guess_best(struct city *pcity,
83  enum terrain_class tc,
84  struct ai_type *ait,
85  bool allow_gold_upkeep)
86 {
87  struct unit_type *bestid = nullptr;
88  int best = 0;
89  struct player *pplayer = city_owner(pcity);
90 
92  {
93  struct unit_type_ai *utai =
94  static_cast<unit_type_ai *>(utype_ai_data(ut, ait));
95  int desire;
96 
97  if (!allow_gold_upkeep && utype_upkeep_cost(ut, pplayer, O_GOLD) > 0) {
98  continue;
99  }
100 
101  // Temporary hack because pathfinding can't handle Fighters.
102  if (!utype_is_consumed_by_action_result(ACTRES_ATTACK, ut)
103  && 1 == utype_fuel(ut)) {
104  continue;
105  }
106 
107  if (!can_city_build_unit_now(pcity, ut)
108  || ut->attack_strength < ut->transport_capacity
109  || (tc == TC_OCEAN && utype_class(ut)->adv.sea_move == MOVE_NONE)
110  || (tc == TC_LAND && utype_class(ut)->adv.land_move == MOVE_NONE)) {
111  continue;
112  }
113 
114  desire = (ut->hp * ut->attack_strength * ut->firepower * ut->move_rate
115  + ut->defense_strength)
116  / MAX(UNITTYPE_COSTS(ut), 1);
117 
118  if (utai->missile_platform) {
119  desire += desire / 6;
120  }
121 
122  if (utype_has_flag(ut, UTYF_IGTER)) {
123  desire += desire / 2;
124  }
125  if (ut->vlayer == V_INVIS) {
126  desire += desire / 4;
127  }
128  if (!can_attack_non_native(ut)) {
129  desire -= desire / 4; // less flexibility
130  }
131  // Causes continual unhappiness
132  if (utype_has_flag(ut, UTYF_FIELDUNIT)) {
133  desire /= 2;
134  }
135 
136  desire = amortize(desire, (utype_build_shield_cost(pcity, ut)
137  / MAX(pcity->surplus[O_SHIELD], 1)));
138 
139  if (desire > best) {
140  best = desire;
141  bestid = ut;
142  }
143  }
145 
146  return bestid;
147 }
148 
152 static void dai_hunter_missile_want(struct player *pplayer,
153  struct city *pcity,
154  struct adv_choice *choice)
155 {
156  adv_want best = -1;
157  struct unit_type *best_unit_type = nullptr;
158  struct unit *hunter = nullptr;
159 
160  unit_list_iterate(pcity->tile->units, punit)
161  {
162  if (dai_hunter_qualify(pplayer, punit)) {
163  unit_type_iterate(pcargo)
164  {
166  utype_class(pcargo))
167  && utype_can_do_action(pcargo, ACTION_SUICIDE_ATTACK)) {
168  hunter = punit;
169  break;
170  }
171  }
173  if (hunter) {
174  break;
175  }
176  }
177  }
179 
180  if (!hunter) {
181  return;
182  }
183 
185  {
186  int desire;
187 
188  if (!utype_can_do_action(ut, ACTION_SUICIDE_ATTACK)
189  || !can_city_build_unit_now(pcity, ut)) {
190  continue;
191  }
192 
194  continue;
195  }
196 
197  /* FIXME: We need to store some data that can tell us if
198  * enemy transports are protected by anti-missile technology.
199  * In this case, want nuclear much more! */
200  desire = (ut->hp * MIN(ut->attack_strength, 30) // nuke fix
201  * ut->firepower * ut->move_rate)
202  / UNITTYPE_COSTS(ut)
203  + 1;
204 
205  // Causes continual unhappiness
206  if (utype_has_flag(ut, UTYF_FIELDUNIT)) {
207  desire /= 2;
208  }
209 
210  desire = amortize(desire, (utype_build_shield_cost(pcity, ut)
211  / MAX(pcity->surplus[O_SHIELD], 1)));
212 
213  if (desire > best) {
214  best = desire;
215  best_unit_type = ut;
216  }
217  }
219 
220  if (best > choice->want) {
221  CITY_LOG(LOGLEVEL_HUNT, pcity, "pri missile w/ want " ADV_WANT_PRINTF,
222  best);
223  choice->value.utype = best_unit_type;
224  choice->want = best;
225  choice->type = CT_ATTACKER;
226  choice->need_boat = false;
227  adv_choice_set_use(choice, "missile");
228  } else if (best >= 0) {
229  CITY_LOG(LOGLEVEL_HUNT, pcity,
230  "not pri missile w/ want " ADV_WANT_PRINTF
231  "(old want " ADV_WANT_PRINTF ")",
232  best, choice->want);
233  }
234 }
235 
239 static void eval_hunter_want(struct ai_type *ait, struct player *pplayer,
240  struct city *pcity, struct adv_choice *choice,
241  struct unit_type *best_type, int veteran)
242 {
243  struct unit *virtualunit;
244  int want = 0;
245 
246  virtualunit = unit_virtual_create(pplayer, pcity, best_type, veteran);
247  want = dai_hunter_manage(ait, pplayer, virtualunit);
248  unit_virtual_destroy(virtualunit);
249  if (want > choice->want) {
250  CITY_LOG(LOGLEVEL_HUNT, pcity, "pri hunter w/ want %d", want);
251  choice->value.utype = best_type;
252  choice->want = want;
253  choice->type = CT_ATTACKER;
254  choice->need_boat = false;
255  adv_choice_set_use(choice, "hunter");
256  }
257 }
258 
262 void dai_hunter_choice(struct ai_type *ait, struct player *pplayer,
263  struct city *pcity, struct adv_choice *choice,
264  bool allow_gold_upkeep)
265 {
266  struct unit_type *best_land_hunter =
267  dai_hunter_guess_best(pcity, TC_LAND, ait, allow_gold_upkeep);
268  struct unit_type *best_sea_hunter =
269  dai_hunter_guess_best(pcity, TC_OCEAN, ait, allow_gold_upkeep);
270  struct unit *hunter = dai_hunter_find(pplayer, pcity);
271 
272  if ((!best_land_hunter && !best_sea_hunter) || is_barbarian(pplayer)
273  || !pplayer->is_alive || has_handicap(pplayer, H_TARGETS)) {
274  return; // None available
275  }
276  if (hunter) {
277  // Maybe want missiles to go with a hunter instead?
278  dai_hunter_missile_want(pplayer, pcity, choice);
279  return;
280  }
281 
282  if (best_sea_hunter) {
284  ait, pplayer, pcity, choice, best_sea_hunter,
285  city_production_unit_veteran_level(pcity, best_sea_hunter));
286  }
287  if (best_land_hunter) {
289  ait, pplayer, pcity, choice, best_land_hunter,
290  city_production_unit_veteran_level(pcity, best_land_hunter));
291  }
292 }
293 
297 bool dai_hunter_qualify(struct player *pplayer, struct unit *punit)
298 {
299  if (is_barbarian(pplayer) || unit_owner(punit) != pplayer) {
300  return false;
301  }
302  return unit_has_type_role(punit, L_HUNTER);
303 }
304 
310 static void dai_hunter_try_launch(struct ai_type *ait,
311  struct player *pplayer, struct unit *punit,
312  struct unit *target)
313 {
314  int target_sanity = target->id;
315  struct pf_parameter parameter;
316  struct pf_map *pfm;
317 
318  unit_list_iterate_safe(unit_tile(punit)->units, missile)
319  {
320  struct unit *sucker = nullptr;
321 
322  if (unit_owner(missile) == pplayer
324  ACTION_SUICIDE_ATTACK)) {
325  UNIT_LOG(LOGLEVEL_HUNT, missile, "checking for hunt targets");
326  pft_fill_unit_parameter(&parameter, punit);
327  parameter.omniscience = !has_handicap(pplayer, H_MAP);
328  pfm = pf_map_new(&parameter);
329 
330  pf_map_move_costs_iterate(pfm, ptile, move_cost, false)
331  {
332  if (move_cost > missile->moves_left / SINGLE_MOVE) {
333  break;
334  }
335  if (tile_city(ptile) || !can_unit_attack_tile(punit, ptile)) {
336  continue;
337  }
338  unit_list_iterate(ptile->units, victim)
339  {
340  enum diplstate_type ds =
341  player_diplstate_get(pplayer, unit_owner(victim))->type;
342  const struct unit_type *ptype;
343  const struct unit_type *victim_type;
344 
345  if (ds != DS_WAR) {
346  continue;
347  }
348  if (victim == target) {
349  sucker = victim;
350  UNIT_LOG(LOGLEVEL_HUNT, missile,
351  "found primary target %d(%d, %d)"
352  " dist %d",
353  victim->id, TILE_XY(unit_tile(victim)), move_cost);
354  break; // Our target! Get him!!!
355  }
356 
357  victim_type = unit_type_get(victim);
358  ptype = unit_type_get(punit);
359 
360  if (ATTACK_POWER(victim_type) > DEFENSE_POWER(ptype)
361  && dai_unit_can_strike_my_unit(victim, punit)) {
362  sucker = victim;
363  UNIT_LOG(LOGLEVEL_HUNT, missile, "found aux target %d(%d, %d)",
364  victim->id, TILE_XY(unit_tile(victim)));
365  break;
366  }
367  }
369  if (sucker) {
370  break; // found something - kill it!
371  }
372  }
374  pf_map_destroy(pfm);
375  if (sucker) {
376  if (unit_transported(missile)) {
377  struct unit *ptrans = unit_transport_get(missile);
378 
379  if (is_action_enabled_unit_on_unit(ACTION_TRANSPORT_ALIGHT,
380  missile, ptrans)) {
381  unit_do_action(unit_owner(punit), punit->id, ptrans->id, 0, "",
382  ACTION_TRANSPORT_ALIGHT);
383  }
384  }
385 
386  missile->goto_tile = unit_tile(sucker);
387  if (dai_unit_goto(ait, missile, unit_tile(sucker))) {
388  // We survived; did they?
389  sucker = game_unit_by_number(target_sanity); // Sanity
390  if (sucker
391  && is_tiles_adjacent(unit_tile(sucker), unit_tile(missile))) {
392  dai_unit_attack(ait, missile, unit_tile(sucker));
393  }
394  }
395  target = game_unit_by_number(target_sanity); // Sanity
396  break; // try next missile, if any
397  }
398  } // if
399  }
401 }
402 
406 static void dai_hunter_juiciness(struct player *pplayer, struct unit *punit,
407  struct unit *target, int *stackthreat,
408  int *stackcost)
409 {
410  *stackthreat = 0;
411  *stackcost = 0;
412 
413  unit_list_iterate(unit_tile(target)->units, sucker)
414  {
415  const struct unit_type *suck_type = unit_type_get(sucker);
416 
417  *stackthreat += ATTACK_POWER(suck_type);
418  if (unit_has_type_flag(sucker, UTYF_GAMELOSS)) {
419  *stackcost += 1000;
420  *stackthreat += 5000;
421  }
422  if (utype_acts_hostile(unit_type_get(sucker))) {
423  *stackthreat += 500; // extra threatening
424  }
425  *stackcost += unit_build_shield_cost_base(sucker);
426  }
428 
429  *stackthreat *= 9; // WAG - reduced by distance later
430  *stackthreat += *stackcost;
431 }
432 
445 int dai_hunter_manage(struct ai_type *ait, struct player *pplayer,
446  struct unit *punit)
447 {
448  bool is_virtual = (punit->id == 0);
449  struct pf_parameter parameter;
450  struct pf_map *pfm;
451  int limit = unit_move_rate(punit) * 6;
452  struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
453  struct unit *original_target = game_unit_by_number(unit_data->target);
454  int original_threat = 0, original_cost = 0;
455 
456  fc_assert_ret_val(!is_barbarian(pplayer), 0);
457  fc_assert_ret_val(pplayer->is_alive, 0);
458 
459  pft_fill_unit_parameter(&parameter, punit);
460  parameter.omniscience = !has_handicap(pplayer, H_MAP);
461  pfm = pf_map_new(&parameter);
462 
463  if (original_target) {
464  dai_hunter_juiciness(pplayer, punit, original_target, &original_threat,
465  &original_cost);
466  }
467 
468  pf_map_move_costs_iterate(pfm, ptile, move_cost, false)
469  {
470  // End faster if we have a target
471  if (move_cost > limit) {
472  UNIT_LOG(LOGLEVEL_HUNT, punit, "gave up finding hunt target");
473  pf_map_destroy(pfm);
474  return 0;
475  }
476 
477  if (tile_city(ptile) || !can_unit_attack_tile(punit, ptile)) {
478  continue;
479  }
480 
481  unit_list_iterate_safe(ptile->units, target)
482  {
483  struct player *aplayer = unit_owner(target);
484  int dist1, dist2, stackthreat = 0, stackcost = 0;
485  int sanity_target = target->id;
486  struct unit_ai *target_data;
487 
488  // Note that we need not (yet) be at war with aplayer
489  if (!adv_is_player_dangerous(pplayer, aplayer)) {
490  continue;
491  }
492 
493  target_data = def_ai_unit_data(target, ait);
494  if (BV_ISSET(target_data->hunted, player_index(pplayer))) {
495  /* Can't hunt this one. The bit is cleared in the beginning
496  * of each turn. */
497  continue;
498  }
501  && !unit_has_type_flag(target, UTYF_GAMELOSS)) {
502  // Won't hunt this one.
503  continue;
504  }
505 
506  // Figure out whether unit is coming closer
507  if (target_data->cur_pos && target_data->prev_pos) {
508  dist1 = real_map_distance(unit_tile(punit), *target_data->cur_pos);
509  dist2 = real_map_distance(unit_tile(punit), *target_data->prev_pos);
510  } else {
511  dist1 = dist2 = 0;
512  }
513  UNIT_LOG(LOGLEVEL_HUNT, punit,
514  "considering chasing %s[%d](%d, %d) "
515  "dist1 %d dist2 %d",
517  TILE_XY(unit_tile(target)), dist1, dist2);
518 
519  // We can't chase if we aren't faster or on intercept vector
520  if (unit_type_get(punit)->move_rate < unit_type_get(target)->move_rate
521  && dist1 >= dist2) {
522  UNIT_LOG(LOGLEVEL_HUNT, punit,
523  "giving up racing %s (%d, %d)->(%d, %d)",
525  target_data->prev_pos
526  ? index_to_map_pos_x(tile_index(*target_data->prev_pos))
527  : -1,
528  target_data->prev_pos
529  ? index_to_map_pos_y(tile_index(*target_data->prev_pos))
530  : -1,
532  continue;
533  }
534 
535  /* Calculate juiciness of target, compare with existing target,
536  * if any. */
537  dai_hunter_juiciness(pplayer, punit, target, &stackthreat, &stackcost);
538  stackcost *=
539  unit_win_chance(punit, get_defender(punit, unit_tile(target)));
540  if (stackcost < unit_build_shield_cost_base(punit)) {
541  UNIT_LOG(LOGLEVEL_HUNT, punit,
542  "%d is too expensive (it %d vs us %d)", target->id,
543  stackcost, unit_build_shield_cost_base(punit));
544  continue; // Too expensive
545  }
546  stackthreat /= move_cost + 1;
547  if (!is_virtual && original_target != target
548  && original_threat > stackthreat) {
549  UNIT_LOG(LOGLEVEL_HUNT, punit, "Unit %d is not worse than %d",
550  target->id, original_target->id);
551  continue; // The threat we found originally was worse than this!
552  }
553  if (stackthreat < unit_build_shield_cost_base(punit)) {
554  UNIT_LOG(LOGLEVEL_HUNT, punit, "%d is not worth it", target->id);
555  continue; // Not worth it
556  }
557 
558  UNIT_LOG(LOGLEVEL_HUNT, punit,
559  "hunting %s %s[%d](%d,%d) "
560  "with want %d, dist1 %d, dist2 %d",
563  TILE_XY(unit_tile(target)), stackthreat, dist1, dist2);
564  // Ok, now we FINALLY have a target worth destroying!
565  unit_data->target = target->id;
566  if (is_virtual) {
567  pf_map_destroy(pfm);
568  return stackthreat;
569  }
570 
571  // This assigns missiles to us
573 
574  // Check if we can nuke it
575  dai_hunter_try_launch(ait, pplayer, punit, target);
576 
577  // Check if we have nuked it
578  if (target != game_unit_by_number(sanity_target)) {
579  UNIT_LOG(LOGLEVEL_HUNT, punit,
580  "mission accomplished by cargo (pre)");
581  dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
582  pf_map_destroy(pfm);
583  return -1; // try again
584  }
585 
586  // Go towards it.
587  auto path = pf_map_path(pfm, unit_tile(target));
588  if (!adv_unit_execute_path(punit, path)) {
589  pf_map_destroy(pfm);
590  return 0;
591  }
592 
593  if (target != game_unit_by_number(sanity_target)) {
594  UNIT_LOG(LOGLEVEL_HUNT, punit, "mission accomplished");
595  dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
596  pf_map_destroy(pfm);
597  return -1; // try again
598  }
599 
600  // Check if we can nuke it now
601  dai_hunter_try_launch(ait, pplayer, punit, target);
602  if (target != game_unit_by_number(sanity_target)) {
603  UNIT_LOG(LOGLEVEL_HUNT, punit,
604  "mission accomplished by cargo (post)");
605  dai_unit_new_task(ait, punit, AIUNIT_NONE, nullptr);
606  pf_map_destroy(pfm);
607  return -1; // try again
608  }
609 
610  pf_map_destroy(pfm);
611  unit_data->done = true;
612  return stackthreat; // still have work to do
613  }
615  }
617 
618  UNIT_LOG(LOGLEVEL_HUNT, punit, "ran out of map finding hunt target");
619  pf_map_destroy(pfm);
620  return 0; // found nothing
621 }
bool is_action_enabled_unit_on_unit(const action_id wanted_action, const struct unit *actor_unit, const struct unit *target_unit)
Returns TRUE if actor_unit can do wanted_action to target_unit as far as action enablers are concerne...
Definition: actions.cpp:4007
#define adv_choice_set_use(_choice, _use)
Definition: advchoice.h:69
@ CT_ATTACKER
Definition: advchoice.h:26
bool adv_is_player_dangerous(struct player *pplayer, struct player *aplayer)
There are some signs that a player might be dangerous: We are at war with him, he has done lots of ig...
Definition: advdata.cpp:1062
bool adv_unit_execute_path(struct unit *punit, const PFPath &path)
This is a function to execute paths returned by the path-finding engine, for units controlled by advi...
Definition: advgoto.cpp:78
adv_want amortize(adv_want benefit, int delay)
Amortize means gradually paying off a cost or debt over time.
Definition: advtools.cpp:25
static struct unit * dai_hunter_find(struct player *pplayer, struct city *pcity)
We don't need a hunter in this city if we already have one.
Definition: aihunt.cpp:58
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)
Support function for ai_hunter_choice()
Definition: aihunt.cpp:239
bool dai_hunter_qualify(struct player *pplayer, struct unit *punit)
Does this unit qualify as a hunter?
Definition: aihunt.cpp:297
static void dai_hunter_juiciness(struct player *pplayer, struct unit *punit, struct unit *target, int *stackthreat, int *stackcost)
Calculate desire to crush this target.
Definition: aihunt.cpp:406
static void dai_hunter_missile_want(struct player *pplayer, struct city *pcity, struct adv_choice *choice)
Check if we want to build a missile for our hunter.
Definition: aihunt.cpp:152
static struct unit_type * dai_hunter_guess_best(struct city *pcity, enum terrain_class tc, struct ai_type *ait, bool allow_gold_upkeep)
Guess best hunter unit type.
Definition: aihunt.cpp:82
void dai_hunter_choice(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct adv_choice *choice, bool allow_gold_upkeep)
Check if we want to build a hunter.
Definition: aihunt.cpp:262
int dai_hunter_manage(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Manage a (possibly virtual) hunter.
Definition: aihunt.cpp:445
static void dai_hunter_try_launch(struct ai_type *ait, struct player *pplayer, struct unit *punit, struct unit *target)
Try to shoot our target with a missile.
Definition: aihunt.cpp:310
static struct unit_ai * def_ai_unit_data(const struct unit *punit, struct ai_type *deftype)
Definition: aiplayer.h:41
bool dai_unit_attack(struct ai_type *ait, struct unit *punit, struct tile *ptile)
Move and attack with an ai unit.
Definition: aitools.cpp:825
bool dai_unit_goto(struct ai_type *ait, struct unit *punit, struct tile *ptile)
Go to specified destination but do not disturb existing role or activity and do not clear the role's ...
Definition: aitools.cpp:609
void dai_unit_new_task(struct ai_type *ait, struct unit *punit, enum ai_unit_task task, struct tile *ptile)
Ensure unit sanity by telling charge that we won't bodyguard it anymore, tell bodyguard it can roam f...
Definition: aitools.cpp:648
bool dai_unit_can_strike_my_unit(const struct unit *attacker, const struct unit *defender)
Returns whether 'attacker' can attack 'defender' immediately.
Definition: aiunit.cpp:3356
@ AIUNIT_NONE
Definition: aiunit.h:26
@ AIUNIT_HUNTER
Definition: aiunit.h:34
#define DEFENSE_POWER(ptype)
Definition: aiunit.h:71
#define ATTACK_POWER(ptype)
Definition: aiunit.h:73
#define UNITTYPE_COSTS(ut)
Definition: aiunit.h:80
bool BV_ISSET(const BV &bv, int bit)
Definition: bitvector.h:37
struct player * city_owner(const struct city *pcity)
Return the owner of the city.
Definition: city.cpp:1083
int city_production_unit_veteran_level(struct city *pcity, const struct unit_type *punittype)
How many veteran levels will created unit of this type get?
Definition: city.cpp:768
bool can_city_build_unit_now(const struct city *pcity, const struct unit_type *punittype)
Return whether given city can build given unit; returns FALSE if unit is obsolete.
Definition: city.cpp:894
struct unit * get_defender(const struct unit *attacker, const struct tile *ptile)
Finds the best defender on the tile, given an attacker.
Definition: combat.cpp:721
double unit_win_chance(const struct unit *attacker, const struct unit *defender)
Returns a double in the range [0;1] indicating the attackers chance of winning.
Definition: combat.cpp:408
bool can_unit_attack_tile(const struct unit *punit, const struct tile *dest_tile)
Is unit (1) diplomatically allowed to attack and (2) physically able to do so?
Definition: combat.cpp:251
float adv_want
Definition: fc_types.h:1144
#define ADV_WANT_PRINTF
Definition: fc_types.h:1145
@ O_SHIELD
Definition: fc_types.h:86
@ O_GOLD
Definition: fc_types.h:88
struct unit * game_unit_by_number(int id)
Find unit out of all units in game: now uses fast idex method, instead of looking through all units o...
Definition: game.cpp:112
bool has_handicap(const struct player *pplayer, enum handicap_type htype)
AI players may have handicaps - allowing them to cheat or preventing them from using certain algorith...
Definition: handicaps.cpp:62
@ H_MAP
Definition: handicaps.h:27
@ H_TARGETS
Definition: handicaps.h:23
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
Are two tiles adjacent to each other.
Definition: map.cpp:878
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Return real distance between two tiles.
Definition: map.cpp:599
static int index_to_map_pos_y(int mindex)
Definition: map.h:616
static int index_to_map_pos_x(int mindex)
Definition: map.h:607
int unit_move_rate(const struct unit *punit)
This function calculates the move rate of the unit.
Definition: movement.cpp:78
bool can_unit_type_transport(const struct unit_type *transporter, const struct unit_class *transported)
Return TRUE iff transporter type has ability to transport transported class.
Definition: movement.cpp:698
bool can_attack_non_native(const struct unit_type *utype)
This unit can attack non-native tiles (eg.
Definition: movement.cpp:164
#define SINGLE_MOVE
Definition: movement.h:17
const char * nation_rule_name(const struct nation_type *pnation)
Return the (untranslated) rule name of the nation (adjective form).
Definition: nation.cpp:115
struct nation_type * nation_of_unit(const struct unit *punit)
Return the nation of the player who owns the unit.
Definition: nation.cpp:438
struct pf_map * pf_map_new(const struct pf_parameter *parameter)
Factory function to create a new map according to the parameter.
PFPath pf_map_path(struct pf_map *pfm, struct tile *ptile)
CHECK DOCS AFTER FULL CONVERSTION OF pf_path to class PFPath Tries to find the best path in the given...
void pf_map_destroy(struct pf_map *pfm)
After usage the map must be destroyed.
#define pf_map_move_costs_iterate_end
Definition: path_finding.h:542
#define pf_map_move_costs_iterate(ARG_pfm, NAME_tile, NAME_cost, COND_from_start)
Definition: path_finding.h:532
void pft_fill_unit_parameter(struct pf_parameter *parameter, const struct unit *punit)
Fill classic parameters for an unit.
Definition: pf_tools.cpp:822
int player_index(const struct player *pplayer)
Return the player index.
Definition: player.cpp:748
struct player_diplstate * player_diplstate_get(const struct player *plr1, const struct player *plr2)
Returns diplomatic state type between two players.
Definition: player.cpp:288
static bool is_barbarian(const struct player *pplayer)
Definition: player.h:474
#define MIN(x, y)
Definition: shared.h:49
#define MAX(x, y)
Definition: shared.h:48
#define LOGLEVEL_HUNT
Definition: srv_log.h:37
#define UNIT_LOG(_, punit, msg,...)
Definition: srv_log.h:95
#define CITY_LOG(_, pcity, msg,...)
Definition: srv_log.h:80
enum choice_type type
Definition: advchoice.h:32
adv_want want
Definition: advchoice.h:34
universals_u value
Definition: advchoice.h:33
bool need_boat
Definition: advchoice.h:35
Definition: ai.h:42
Definition: city.h:291
int surplus[O_LAST]
Definition: city.h:324
struct tile * tile
Definition: city.h:293
struct unit_list * units_supported
Definition: city.h:377
enum diplstate_type type
Definition: player.h:193
Definition: player.h:231
bool is_alive
Definition: player.h:250
struct unit_list * units
Definition: tile.h:50
Definition: aiunit.h:39
struct tile ** prev_pos
Definition: aiunit.h:47
bv_player hunted
Definition: aiunit.h:50
bool done
Definition: aiunit.h:51
struct tile ** cur_pos
Definition: aiunit.h:47
int target
Definition: aiunit.h:49
bool missile_platform
Definition: aiunit.h:59
Definition: unit.h:134
int id
Definition: unit.h:141
int veteran
Definition: unit.h:149
struct city * tile_city(const struct tile *ptile)
Return the city on this tile (or nullptr), checking for city center.
Definition: tile.cpp:72
#define tile_index(_pt_)
Definition: tile.h:70
#define TILE_XY(ptile)
Definition: tile.h:36
const struct unit_type * utype
Definition: fc_types.h:585
struct unit * unit_transport_get(const struct unit *pcargo)
Returns the transporter of the unit or nullptr if it is not transported.
Definition: unit.cpp:2189
int get_transporter_capacity(const struct unit *punit)
Return the number of units the transporter can hold (or 0).
Definition: unit.cpp:280
void unit_virtual_destroy(struct unit *punit)
Free the memory used by virtual unit.
Definition: unit.cpp:1588
struct unit * unit_virtual_create(struct player *pplayer, struct city *pcity, const struct unit_type *punittype, int veteran_level)
Create a virtual unit skeleton.
Definition: unit.cpp:1490
bool unit_transported(const struct unit *pcargo)
Returns TRUE iff the unit is transported.
Definition: unit.cpp:2176
#define unit_tile(_pu)
Definition: unit.h:371
#define unit_owner(_pu)
Definition: unit.h:370
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)
Handle unit action.
Definition: unithand.cpp:2718
#define unit_list_iterate(unitlist, punit)
Definition: unitlist.h:25
#define unit_list_iterate_safe(unitlist, _unit)
Definition: unitlist.h:33
#define unit_list_iterate_end
Definition: unitlist.h:27
#define unit_list_iterate_safe_end
Definition: unitlist.h:54
const char * unit_rule_name(const struct unit *punit)
Return the (untranslated) rule name of the unit.
Definition: unittype.cpp:1283
const struct unit_type * unit_type_get(const struct unit *punit)
Return the unit type for this unit.
Definition: unittype.cpp:114
int utype_upkeep_cost(const struct unit_type *ut, struct player *pplayer, Output_type_id otype)
Returns the upkeep of a unit of this type under the given government.
Definition: unittype.cpp:123
int utype_build_shield_cost(const struct city *pcity, const struct unit_type *punittype)
Returns the number of shields it takes to build this unit type.
Definition: unittype.cpp:1141
bool utype_is_consumed_by_action_result(enum action_result result, const struct unit_type *utype)
Returns TRUE iff performing an action with the specified action result will consume an actor unit of ...
Definition: unittype.cpp:947
int unit_build_shield_cost_base(const struct unit *punit)
Returns the number of shields this unit represents.
Definition: unittype.cpp:1185
bool unit_has_type_role(const struct unit *punit, enum unit_role_id role)
Return whether the unit has the given role.
Definition: unittype.cpp:195
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Return whether the unit has the given flag.
Definition: unittype.cpp:176
bool utype_acts_hostile(const struct unit_type *putype)
Return TRUE iff units of this type can do hostile actions controlled by generalized (ruleset defined)...
Definition: unittype.cpp:432
bool utype_can_do_action(const struct unit_type *putype, const action_id act_id)
Return TRUE iff units of the given type can do the specified generalized (ruleset defined) action ena...
Definition: unittype.cpp:386
void * utype_ai_data(const struct unit_type *ptype, const struct ai_type *ai)
Return pointer to ai data of given unit type and ai type.
Definition: unittype.cpp:2332
#define utype_class(_t_)
Definition: unittype.h:691
#define utype_fuel(ptype)
Definition: unittype.h:772
@ MOVE_NONE
Definition: unittype.h:115
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition: unittype.h:584
#define unit_type_iterate(_p)
Definition: unittype.h:785
#define unit_type_iterate_end
Definition: unittype.h:791