Freeciv21
Develop your civilization from humble roots to a global empire
aiair.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 "log.h"
14 
15 // common
16 #include "combat.h"
17 #include "game.h"
18 #include "map.h"
19 #include "movement.h"
20 #include "pf_tools.h"
21 #include "player.h"
22 #include "unit.h"
23 
24 // server
25 #include "maphand.h"
26 #include "srv_log.h"
27 #include "unithand.h"
28 #include "unittools.h"
29 
30 /* server/advisors */
31 #include "advbuilding.h"
32 #include "advgoto.h"
33 
34 // ai
35 #include "handicaps.h"
36 
37 /* ai/default */
38 #include "ailog.h"
39 #include "aiplayer.h"
40 #include "aitools.h"
41 #include "aiunit.h"
42 
43 #include "aiair.h"
44 
45 class PFPath;
53 static struct tile *find_nearest_airbase(const struct unit *punit,
54  PFPath *path)
55 {
56  struct player *pplayer = unit_owner(punit);
57  struct pf_parameter parameter;
58  struct pf_map *pfm;
59 
60  pft_fill_unit_parameter(&parameter, punit);
61  parameter.omniscience = !has_handicap(pplayer, H_MAP);
62  pfm = pf_map_new(&parameter);
63 
64  pf_map_move_costs_iterate(pfm, ptile, move_cost, true)
65  {
66  if (move_cost > punit->moves_left) {
67  // Too far!
68  break;
69  }
70 
71  if (is_airunit_refuel_point(ptile, pplayer, punit)) {
72  *path = pf_map_path(pfm, ptile);
73  pf_map_destroy(pfm);
74  return ptile;
75  }
76  }
78 
79  pf_map_destroy(pfm);
80  return nullptr;
81 }
82 
87 static bool dai_should_we_air_attack_tile(struct ai_type *ait,
88  struct unit *punit,
89  struct tile *ptile)
90 {
91  struct city *acity = tile_city(ptile);
92 
93  // For a virtual unit (punit->id == 0), all targets are good
94  /* TODO: There is a danger of producing too many units that will not
95  * attack anything. Production should not happen if there is an idle
96  * unit of the same type nearby */
97  if (acity && punit->id != 0
98  && def_ai_city_data(acity, ait)->invasion.occupy == 0
99  && !unit_can_take_over(punit)) {
100  // No units capable of occupying are invading
101  log_debug("Don't want to attack %s, although we could",
102  city_name_get(acity));
103  return false;
104  }
105 
106  return true;
107 }
108 
113 static int dai_evaluate_tile_for_air_attack(struct unit *punit,
114  struct tile *dst_tile)
115 {
116  struct unit *pdefender;
117  // unit costs in shields
118  int balanced_cost, unit_cost, victim_cost = 0;
119  // unit stats
120  int unit_attack, victim_defence;
121  // final answer
122  int profit;
123  // time spent in the air
124  int sortie_time;
125 #define PROB_MULTIPLIER 100 // should unify with those in combat.c
126 
127  if (!can_unit_attack_tile(punit, dst_tile)
128  || !(pdefender = get_defender(punit, dst_tile))) {
129  return 0;
130  }
131 
132  // Ok, we can attack, but is it worth it?
133 
134  // Cost of our unit
135  unit_cost = unit_build_shield_cost_base(punit);
136  // This is to say "wait, ill unit will get better!"
137  unit_cost = unit_cost * unit_type_get(punit)->hp / punit->hp;
138 
139  // Determine cost of enemy units
140  victim_cost = stack_cost(punit, pdefender);
141  if (0 == victim_cost) {
142  return 0;
143  }
144 
145  // Missile would die 100% so we adjust the victim_cost -- GB
146  if (utype_can_do_action(unit_type_get(punit), ACTION_SUICIDE_ATTACK)) {
147  /* Assume that the attack will be a suicide attack even if a regular
148  * attack may be legal. */
149  victim_cost -= unit_build_shield_cost_base(punit);
150  }
151 
152  unit_attack =
153  static_cast<int>(PROB_MULTIPLIER * unit_win_chance(punit, pdefender));
154 
155  victim_defence = PROB_MULTIPLIER - unit_attack;
156 
157  balanced_cost = build_cost_balanced(unit_type_get(punit));
158 
159  sortie_time = (utype_pays_mp_for_action_estimate(
160  action_by_number(ACTION_ATTACK), unit_type_get(punit),
161  unit_owner(punit),
162  /* Assume that dst_tile is closer to the tile the actor
163  * unit will attack from than its current tile. */
164  dst_tile, dst_tile)
165  >= MAX_MOVE_FRAGS
166  ? 1
167  : 0);
168 
169  profit =
170  kill_desire(victim_cost, unit_attack, unit_cost, victim_defence, 1)
172  if (profit > 0) {
173  profit = military_amortize(unit_owner(punit),
174  game_city_by_number(punit->homecity), profit,
175  sortie_time, balanced_cost);
176  log_debug("%s at (%d, %d) is a worthy target with profit %d",
177  unit_rule_name(pdefender), TILE_XY(dst_tile), profit);
178  } else {
179  log_debug("%s(%d, %d): %s at (%d, %d) is unworthy with profit %d",
180  unit_rule_name(punit), TILE_XY(unit_tile(punit)),
181  unit_rule_name(pdefender), TILE_XY(dst_tile), profit);
182  profit = 0;
183  }
184 
185  return profit;
186 }
187 
197 static int find_something_to_bomb(struct ai_type *ait, struct unit *punit,
198  PFPath *path, struct tile **pptile)
199 {
200  struct player *pplayer = unit_owner(punit);
201  struct pf_parameter parameter;
202  struct pf_map *pfm;
203  struct tile *best_tile = nullptr;
204  int best = 0;
205 
206  pft_fill_unit_parameter(&parameter, punit);
207  parameter.omniscience = !has_handicap(pplayer, H_MAP);
208  pfm = pf_map_new(&parameter);
209 
210  // Let's find something to bomb
211  pf_map_move_costs_iterate(pfm, ptile, move_cost, false)
212  {
213  if (move_cost >= punit->moves_left) {
214  // Too far!
215  break;
216  }
217 
218  if (has_handicap(pplayer, H_MAP) && !map_is_known(ptile, pplayer)) {
219  // The target tile is unknown
220  continue;
221  }
222 
223  if (has_handicap(pplayer, H_FOG)
224  && !map_is_known_and_seen(ptile, pplayer, V_MAIN)) {
225  // The tile is fogged
226  continue;
227  }
228 
229  if (is_enemy_unit_tile(ptile, pplayer)
230  && dai_should_we_air_attack_tile(ait, punit, ptile)
231  && can_unit_attack_tile(punit, ptile)) {
232  int new_best = dai_evaluate_tile_for_air_attack(punit, ptile);
233 
234  if (new_best > best) {
235  best_tile = ptile;
236  best = new_best;
237  log_debug("%s wants to attack tile (%d, %d)", unit_rule_name(punit),
238  TILE_XY(ptile));
239  }
240  }
241  }
243 
244  // Return the best values.
245  if (pptile) {
246  *pptile = best_tile;
247  }
248  if (path) {
249  *path = best_tile ? pf_map_path(pfm, best_tile) : PFPath();
250  }
251  pf_map_destroy(pfm);
252  return best;
253 }
254 
260 static struct tile *dai_find_strategic_airbase(struct ai_type *ait,
261  const struct unit *punit,
262  PFPath *path)
263 {
264  struct player *pplayer = unit_owner(punit);
265  struct pf_parameter parameter;
266  struct pf_map *pfm;
267  struct tile *best_tile = nullptr;
268  struct city *pcity;
269  struct unit *pvirtual = nullptr;
270  int best_worth = 0, target_worth;
271 
272  pft_fill_unit_parameter(&parameter, punit);
273  parameter.omniscience = !has_handicap(pplayer, H_MAP);
274  pfm = pf_map_new(&parameter);
275  pf_map_move_costs_iterate(pfm, ptile, move_cost, false)
276  {
277  if (move_cost >= punit->moves_left) {
278  break; // Too far!
279  }
280 
281  if (!is_airunit_refuel_point(ptile, pplayer, punit)) {
282  continue; // Cannot refuel here.
283  }
284 
285  if ((pcity = tile_city(ptile))
286  && def_ai_city_data(pcity, ait)->grave_danger != 0) {
287  best_tile = ptile;
288  break; // Fly there immediately!!
289  }
290 
291  if (!pvirtual) {
292  pvirtual = unit_virtual_create(
293  pplayer, player_city_by_number(pplayer, punit->homecity),
294  unit_type_get(punit), punit->veteran);
295  }
296 
297  unit_tile_set(pvirtual, ptile);
298  target_worth = find_something_to_bomb(ait, pvirtual, nullptr, nullptr);
299  if (target_worth > best_worth) {
300  // It's either a first find or it's better than the previous.
301  best_worth = target_worth;
302  best_tile = ptile;
303  // We can still look for something better.
304  }
305  }
307 
308  if (pvirtual) {
309  unit_virtual_destroy(pvirtual);
310  }
311 
312  if (path) {
313  // Stores the path.
314  *path = best_tile ? pf_map_path(pfm, best_tile) : PFPath();
315  }
316  pf_map_destroy(pfm);
317 
318  return best_tile;
319 }
320 
334 void dai_manage_airunit(struct ai_type *ait, struct player *pplayer,
335  struct unit *punit)
336 {
337  struct tile *dst_tile = unit_tile(punit);
338  // Loop prevention
339  int moves = punit->moves_left;
340  int id = punit->id;
341  struct pf_parameter parameter;
342  struct pf_map *pfm;
343  PFPath path;
344  CHECK_UNIT(punit);
345  pft_fill_unit_parameter(&parameter, punit);
346 
347  if (!is_unit_being_refueled(punit)) {
348  // We are out in the open, what shall we do?
349  if (punit->activity == ACTIVITY_GOTO
350  // We are on a GOTO. Check if it will get us anywhere
351  && nullptr != punit->goto_tile
352  && !same_pos(unit_tile(punit), punit->goto_tile)
353  && is_airunit_refuel_point(punit->goto_tile, pplayer, punit)) {
354  pfm = pf_map_new(&parameter);
355  path = pf_map_path(pfm, punit->goto_tile);
356  if (!path.empty()) {
357  bool alive = adv_follow_path(punit, path, punit->goto_tile);
358  pf_map_destroy(pfm);
359  if (alive && punit->moves_left > 0) {
360  // Maybe do something else.
361  dai_manage_airunit(ait, pplayer, punit);
362  }
363  return;
364  }
365  pf_map_destroy(pfm);
366  } else if ((dst_tile = find_nearest_airbase(punit, &path))) {
367  // Go refuelling
368  if (!adv_follow_path(punit, path, dst_tile)) {
369  return; // The unit died.
370  }
371  } else {
372  if (punit->fuel == 1) {
373  UNIT_LOG(LOG_DEBUG, punit, "Oops, fallin outta the sky");
374  }
375  def_ai_unit_data(punit, ait)->done = true; // Won't help trying again
376  return;
377  }
378 
379  } else if (punit->fuel == unit_type_get(punit)->fuel) {
380  // We only leave a refuel point when we are on full fuel
381 
382  if (find_something_to_bomb(ait, punit, &path, &dst_tile) > 0) {
383  /* Found target, coordinates are in punit's goto_dest.
384  * TODO: separate attacking into a function, check for the best
385  * tile to attack from */
386  fc_assert_ret(!path.empty() && dst_tile != nullptr);
387  if (!adv_follow_path(punit, path, dst_tile)) {
388  return; // The unit died.
389  }
390 
391  /* goto would be aborted: "Aborting GOTO for AI attack procedures"
392  * now actually need to attack */
393  // We could use ai_military_findvictim here, but I don't trust it...
394  unit_activity_handling(punit, ACTIVITY_IDLE);
395  if (is_tiles_adjacent(unit_tile(punit), dst_tile)) {
396  dai_unit_attack(ait, punit, dst_tile);
397  }
398  } else if ((dst_tile = dai_find_strategic_airbase(ait, punit, &path))) {
399  log_debug("%s will fly to (%i, %i) (%s) to fight there",
400  unit_rule_name(punit), TILE_XY(dst_tile),
401  tile_city(dst_tile) ? city_name_get(tile_city(dst_tile))
402  : "");
403  def_ai_unit_data(punit, ait)->done = true; // Wait for next turn
404  if (!adv_follow_path(punit, path, dst_tile)) {
405  return; // The unit died.
406  }
407  } else {
408  log_debug("%s cannot find anything to kill and is staying put",
409  unit_rule_name(punit));
410  def_ai_unit_data(punit, ait)->done = true;
411  unit_activity_handling(punit, ACTIVITY_IDLE);
412  }
413  }
414 
415  if ((punit = game_unit_by_number(id)) != nullptr && punit->moves_left > 0
416  && punit->moves_left != moves) {
417  /* We have moved this turn, might have ended up stuck out in the fields
418  * so, as a safety measure, let's manage again */
419  dai_manage_airunit(ait, pplayer, punit);
420  }
421 }
422 
429 bool dai_choose_attacker_air(struct ai_type *ait, struct player *pplayer,
430  struct city *pcity, struct adv_choice *choice,
431  bool allow_gold_upkeep)
432 {
433  bool want_something = false;
434 
435  // This AI doesn't know to build planes
436  if (has_handicap(pplayer, H_NOPLANES)) {
437  return false;
438  }
439 
440  /* military_advisor_choose_build does something idiotic,
441  * this function should not be called if there is danger... */
442  if (choice->want >= 100 && choice->type != CT_ATTACKER) {
443  return false;
444  }
445 
446  if (!player_knows_techs_with_flag(pplayer, TF_BUILD_AIRBORNE)) {
447  return false;
448  }
449 
450  unit_type_iterate(punittype)
451  {
452  struct unit_class *pclass = utype_class(punittype);
453 
454  if (pclass->adv.land_move == MOVE_NONE
455  || pclass->adv.sea_move == MOVE_NONE
456  || uclass_has_flag(pclass, UCF_TERRAIN_SPEED)
457  || unit_type_is_losing_hp(pplayer, punittype)) {
458  // We don't consider this a plane
459  continue;
460  }
461 
462  if (!allow_gold_upkeep
463  && utype_upkeep_cost(punittype, pplayer, O_GOLD) > 0) {
464  continue;
465  }
466 
467  // Temporary hack because pathfinding can't handle Fighters.
468  if (!utype_is_consumed_by_action_result(ACTRES_ATTACK, punittype)
469  && 1 == utype_fuel(punittype)) {
470  continue;
471  }
472 
473  if (can_city_build_unit_now(pcity, punittype)) {
474  struct unit *virtual_unit = unit_virtual_create(
475  pplayer, pcity, punittype,
476  city_production_unit_veteran_level(pcity, punittype));
477  int profit =
478  find_something_to_bomb(ait, virtual_unit, nullptr, nullptr);
479 
480  if (profit > choice->want) {
481  // Update choice
482  choice->want = profit;
483  choice->value.utype = punittype;
484  choice->type = CT_ATTACKER;
485  choice->need_boat = false;
486  adv_choice_set_use(choice, "offensive air");
487  want_something = true;
488  log_debug("%s wants to build %s (want=%d)", city_name_get(pcity),
489  utype_rule_name(punittype), profit);
490  } else {
491  log_debug("%s doesn't want to build %s (want=%d)",
492  city_name_get(pcity), utype_rule_name(punittype), profit);
493  }
494  unit_virtual_destroy(virtual_unit);
495  }
496  }
498 
499  return want_something;
500 }
struct action * action_by_number(action_id act_id)
Return the action with the given id.
Definition: actions.cpp:1149
#define TRADE_WEIGHTING
Definition: advbuilding.h:18
#define SHIELD_WEIGHTING
Definition: advbuilding.h:17
#define adv_choice_set_use(_choice, _use)
Definition: advchoice.h:69
@ CT_ATTACKER
Definition: advchoice.h:26
bool adv_follow_path(struct unit *punit, const PFPath &path, struct tile *ptile)
Move a unit along a path without disturbing its activity, role or assigned destination Return FALSE i...
Definition: advgoto.cpp:43
static struct tile * find_nearest_airbase(const struct unit *punit, PFPath *path)
Looks for nearest airbase for punit reachable imediatly.
Definition: aiair.cpp:53
static int find_something_to_bomb(struct ai_type *ait, struct unit *punit, PFPath *path, struct tile **pptile)
Find something to bomb Air-units specific victim search Returns the want for the best target.
Definition: aiair.cpp:197
static struct tile * dai_find_strategic_airbase(struct ai_type *ait, const struct unit *punit, PFPath *path)
Iterates through reachable cities and appraises them as a possible base for air operations by (air)un...
Definition: aiair.cpp:260
void dai_manage_airunit(struct ai_type *ait, struct player *pplayer, struct unit *punit)
Trying to manage bombers and stuff.
Definition: aiair.cpp:334
#define PROB_MULTIPLIER
bool dai_choose_attacker_air(struct ai_type *ait, struct player *pplayer, struct city *pcity, struct adv_choice *choice, bool allow_gold_upkeep)
Chooses the best available and usable air unit and records it in choice, if it's better than previous...
Definition: aiair.cpp:429
static bool dai_should_we_air_attack_tile(struct ai_type *ait, struct unit *punit, struct tile *ptile)
Very preliminary estimate for our intent to attack the tile (x, y).
Definition: aiair.cpp:87
static int dai_evaluate_tile_for_air_attack(struct unit *punit, struct tile *dst_tile)
Returns an estimate for the profit gained through attack.
Definition: aiair.cpp:113
static struct ai_city * def_ai_city_data(const struct city *pcity, struct ai_type *deftype)
Definition: aiplayer.h:35
static struct unit_ai * def_ai_unit_data(const struct unit *punit, struct ai_type *deftype)
Definition: aiplayer.h:41
int stack_cost(struct unit *pattacker, struct unit *pdefender)
Calculate the value of the target unit including the other units which will die in a successful attac...
Definition: aitools.cpp:1072
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
int military_amortize(struct player *pplayer, struct city *pcity, int value, int delay, int build_cost)
Amortize a want modified by the shields (build_cost) we risk losing.
Definition: aitools.cpp:132
int build_cost_balanced(const struct unit_type *punittype)
In the words of Syela: "Using funky fprime variable instead of f in the denom, so that def=1 units ar...
Definition: aiunit.cpp:240
int kill_desire(int benefit, int attack, int loss, int vuln, int victim_count)
Compute how much we want to kill certain victim we've chosen, counted in SHIELDs.
Definition: aiunit.cpp:334
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
const char * city_name_get(const struct city *pcity)
Return the name of the city.
Definition: city.cpp:1077
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
bool empty() const
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
@ 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
struct city * game_city_by_number(int id)
Often used function to get a city pointer from a city ID.
Definition: game.cpp:103
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_NOPLANES
Definition: handicaps.h:26
@ H_FOG
Definition: handicaps.h:25
constexpr auto LOG_DEBUG
Definition: log.h:27
#define fc_assert_ret(condition)
Definition: log.h:112
#define log_debug(message,...)
Definition: log.h:65
bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
Are two tiles adjacent to each other.
Definition: map.cpp:878
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Are (x1,y1) and (x2,y2) really the same when adjusted? This function might be necessary ALOT of place...
Definition: map.cpp:887
bool map_is_known(const struct tile *ptile, const struct player *pplayer)
Return whether the player knows the tile.
Definition: maphand.cpp:884
bool map_is_known_and_seen(const struct tile *ptile, const struct player *pplayer, enum vision_layer vlayer)
Returns whether the layer 'vlayer' of the tile 'ptile' is known and seen by the player 'pplayer'.
Definition: maphand.cpp:894
bool is_unit_being_refueled(const struct unit *punit)
Is unit being refueled in its current position.
Definition: movement.cpp:759
bool is_airunit_refuel_point(const struct tile *ptile, const struct player *pplayer, const struct unit *punit)
Can unit refuel on tile.
Definition: unittools.cpp:1635
#define MAX_MOVE_FRAGS
Definition: movement.h:20
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
bool player_knows_techs_with_flag(const struct player *pplayer, enum tech_flag_id flag)
Returns TRUE iff the player knows at least one tech which has the given flag.
Definition: player.cpp:1238
struct city * player_city_by_number(const struct player *pplayer, int city_id)
If the specified player owns the city with the specified id, return pointer to the city struct.
Definition: player.cpp:1113
#define UNIT_LOG(_, punit, msg,...)
Definition: srv_log.h:95
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
Definition: player.h:231
Definition: tile.h:42
bool done
Definition: aiunit.h:51
struct unit_class::@80 adv
enum move_level sea_move
Definition: unittype.h:136
enum move_level land_move
Definition: unittype.h:135
int hp
Definition: unittype.h:489
Definition: unit.h:134
enum unit_activity activity
Definition: unit.h:154
int moves_left
Definition: unit.h:147
int id
Definition: unit.h:141
int hp
Definition: unit.h:148
int fuel
Definition: unit.h:150
int homecity
Definition: unit.h:142
struct tile * goto_tile
Definition: unit.h:152
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_XY(ptile)
Definition: tile.h:36
const struct unit_type * utype
Definition: fc_types.h:585
bool unit_type_is_losing_hp(const struct player *pplayer, const struct unit_type *punittype)
Does unit lose hitpoints each turn?
Definition: unit.cpp:2003
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
void unit_tile_set(struct unit *punit, struct tile *ptile)
Set the tile location of the unit.
Definition: unit.cpp:1200
struct unit * is_enemy_unit_tile(const struct tile *ptile, const struct player *pplayer)
Is there an enemy unit on this tile? Returns the unit or nullptr if none.
Definition: unit.cpp:1235
#define unit_tile(_pu)
Definition: unit.h:371
#define CHECK_UNIT(punit)
Definition: unit.h:264
#define unit_owner(_pu)
Definition: unit.h:370
bool unit_activity_handling(struct unit *punit, enum unit_activity new_activity)
Handle request for changing activity.
Definition: unithand.cpp:5485
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
const char * utype_rule_name(const struct unit_type *punittype)
Return the (untranslated) rule name of the unit type.
Definition: unittype.cpp:1274
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_can_take_over(const struct unit *punit)
Return whether the unit can take over enemy cities.
Definition: unittype.cpp:203
int utype_pays_mp_for_action_estimate(const struct action *paction, const struct unit_type *putype, const struct player *act_player, const struct tile *act_tile, const struct tile *tgt_tile)
Returns an estimate of the amount of movement points successfully performing the specified action wil...
Definition: unittype.cpp:1104
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
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition: unittype.h:704
#define utype_class(_t_)
Definition: unittype.h:691
#define utype_fuel(ptype)
Definition: unittype.h:772
@ MOVE_NONE
Definition: unittype.h:115
#define unit_type_iterate(_p)
Definition: unittype.h:785
#define unit_type_iterate_end
Definition: unittype.h:791