32 #define SPECPQ_TAG map_index
33 #define SPECPQ_DATA_TYPE int
34 #define SPECPQ_PRIORITY_TYPE int
36 #define INITIAL_QUEUE_SIZE 100
106 return reinterpret_cast<const pf_map *
>(x);
246 "Wrong pf_map to pf_normal_map conversion.");
249 #define PF_NORMAL_MAP(pfm) pf_normal_map_check(pfm)
251 #define PF_NORMAL_MAP(pfm) ((struct pf_normal_map *) (pfm))
286 if (
nullptr != params->
get_TB) {
330 previous_scope, params);
360 if (
nullptr != params->
get_EC) {
381 "Unreached destination (%d, %d).",
TILE_XY(ptile));
398 if (node->
cost > 0) {
408 struct tile *dest_tile)
412 enum direction8 dir_next = direction8_invalid();
418 "Unreached destination (%d, %d).",
442 for (; i >= 0; i--) {
445 path[i].dir_to_next_pos = dir_next;
466 return MIN(cost, moves_left);
530 &cost1, &extra_cost1, params);
548 if (!map_index_pq_remove(pfnm->
queue, &tindex)) {
644 ACTION_SUICIDE_ATTACK))) {
670 if (
nullptr != params->
get_EC) {
686 map_index_pq_insert(pfnm->
queue, tindex1, -cost_of_path);
687 }
else if (cost_of_path
696 map_index_pq_replace(pfnm->
queue, tindex1, -cost_of_path);
703 if (!map_index_pq_remove(pfnm->
queue, &tindex)) {
819 map_index_pq_destroy(pfnm->
queue);
843 params = &base_map->
params;
846 base_map->mode = PF_NORMAL;
854 *params = *parameter;
960 "Wrong pf_map to pf_danger_map conversion.");
963 #define PF_DANGER_MAP(pfm) pf_danger_map_check(pfm)
965 #define PF_DANGER_MAP(pfm) ((struct pf_danger_map *) (pfm))
1000 if (
nullptr != params->
get_TB) {
1044 previous_scope, params);
1074 if (
nullptr != params->
get_EC) {
1099 "Unreached destination (%d, %d).",
TILE_XY(ptile));
1116 if (node->
cost > 0) {
1133 return cost + moves_left;
1146 enum direction8 dir_next = direction8_invalid();
1151 struct tile *iter_tile = ptile;
1159 "Unreached destination (%d, %d).",
TILE_XY(ptile));
1190 auto path =
PFPath(length);
1195 danger_seg =
nullptr;
1198 for (i = length - 1; i >= 0; i--) {
1199 bool old_waited =
false;
1207 path[i].tile = iter_tile;
1213 path[i].fuel_left = params->
fuel;
1214 path[i].total_MC = ((path[i].turn - 1) * params->
move_rate
1216 path[i].dir_to_next_pos = dir_next;
1228 path[i].tile = iter_tile;
1230 path[i].total_MC = node->
cost;
1235 path[i].total_MC = danger_seg->
cost;
1238 path[i].turn =
pf_turns(params, path[i].total_MC);
1239 path[i].moves_left =
pf_moves_left(params, path[i].total_MC);
1244 path[i].fuel_left = 1;
1247 path[i].dir_to_next_pos = (old_waited ? direction8_invalid() : dir_next);
1248 if (node->
cost > 0) {
1312 qCritical(
"Possible memory leak in pf_danger_map_create_segment().");
1318 && direction8_is_valid(direction8(node->
dir_to_here))) {
1332 for (i = 0, pos = node1->
danger_segment; i < length; i++, pos++) {
1337 if (i == length - 1) {
1350 || !direction8_is_valid(direction8(node->
dir_to_here)));
1359 bool to_danger,
int moves_left)
1367 if (to_danger && cost >= moves_left) {
1371 return MIN(cost, moves_left);
1426 if (!direction8_is_valid(direction8(node->
dir_to_here))
1448 loc_cost = node->
cost;
1501 ACTION_SUICIDE_ATTACK))) {
1529 if (
nullptr != params->
get_EC) {
1560 map_index_pq_insert(pfdm->
queue, tindex1, -cost_of_path);
1565 map_index_pq_replace(pfdm->
queue, tindex1, -cost_of_path);
1618 map_index_pq_insert(pfdm->
queue, tindex, -cc);
1623 if (map_index_pq_remove(pfdm->
danger_queue, &tindex)) {
1627 node = pfdm->
lattice + tindex;
1630 if (!map_index_pq_remove(pfdm->
queue, &tindex)) {
1642 node = pfdm->
lattice + tindex;
1668 qCritical(
"%s(): internal error.", __FUNCTION__);
1779 map_index_pq_destroy(pfdm->
queue);
1796 params = &base_map->
params;
1799 base_map->mode = PF_DANGER;
1817 *params = *parameter;
1928 "Wrong pf_map to pf_fuel_map conversion.");
1929 return reinterpret_cast<struct
pf_fuel_map *
>(pfm);
1931 #define PF_FUEL_MAP(pfm) pf_fuel_map_check(pfm)
1933 #define PF_FUEL_MAP(pfm) ((struct pf_fuel_map *) (pfm))
1942 int cost,
int extra,
int safety)
1985 if (
nullptr != params->
get_TB) {
2011 params->
get_action(ptile, node_known_type, params))) {
2042 previous_scope, params);
2084 if (
nullptr != params->
get_EC) {
2096 return (
nullptr == node->
pos
2122 while (
nullptr != pos && 0 == --pos->
ref_count) {
2137 if (
nullptr == pos) {
2154 pos->
prev =
nullptr;
2232 int cost,
int moves_left)
2237 return cost + moves_left % param->
move_rate;
2246 enum direction8 dir_next = direction8_invalid();
2250 struct tile *iter_tile = ptile;
2256 "Unreached destination (%d, %d).",
TILE_XY(ptile));
2262 while (direction8_is_valid(direction8(segment->
dir_to_here))) {
2265 if (segment != node->
segment) {
2279 segment = segment->
prev;
2290 auto path =
PFPath(length);
2297 for (i = length - 1; i >= 0; i--) {
2304 path[i].tile = iter_tile;
2307 path[i].total_MC = ((path[i].turn - 1) * params->
move_rate
2310 path[i].fuel_left = params->
fuel;
2311 path[i].dir_to_next_pos = dir_next;
2313 dir_next = direction8_invalid();
2316 if (
nullptr == segment) {
2328 path[i].tile = iter_tile;
2332 path[i].dir_to_next_pos = dir_next;
2348 segment = segment->
prev;
2391 if (
nullptr != pos) {
2405 && direction8_is_valid(direction8(node->
dir_to_here)));
2415 int remaining_moves = moves_left %
move_rate;
2417 if (remaining_moves == 0) {
2421 return MIN(cost, remaining_moves);
2423 return MIN(cost, moves_left);
2435 int moves_left,
int moves_left_req)
2450 return moves_left -
SINGLE_MOVE >= moves_left_req;
2498 bool waited =
false;
2504 if (!direction8_is_valid(direction8(node->
dir_to_here))
2523 int loc_cost = node->
cost;
2527 && 0 == loc_moves_left % params->
move_rate
2541 int cost, extra = 0;
2543 int cost_of_path, old_cost_of_path;
2587 ACTION_SUICIDE_ATTACK))) {
2626 if (moves_left < node1->moves_left_req
2645 if (
nullptr != params->
get_EC) {
2656 old_cost_of_path = 0;
2677 && cost_of_path < old_cost_of_path)) {
2692 map_index_pq_insert(pffm->
queue, tindex1, -cost_of_path);
2698 if (cost_of_path < old_cost_of_path) {
2699 map_index_pq_replace(pffm->
queue, tindex1, -cost_of_path);
2759 map_index_pq_insert(
2760 pffm->
queue, tindex,
2769 || (map_index_pq_priority(pffm->
waited_queue, &waited_priority)
2771 if (!map_index_pq_remove(pffm->
waited_queue, &tindex)) {
2779 node = pffm->
lattice + tindex;
2787 bool success = map_index_pq_remove(pffm->
queue, &tindex);
2791 map_index_pq_remove(pffm->
queue, &tindex);
2797 node = pffm->
lattice + tindex;
2835 qCritical(
"%s(): internal error.", __FUNCTION__);
2861 while (
nullptr == node->
segment) {
2946 map_index_pq_destroy(pffm->
queue);
2972 params = &base_map->
params;
2975 base_map->mode = PF_FUEL;
2984 *params = *parameter;
3035 qCritical(
"path finding code cannot deal with dangers "
3036 "and fuel together.");
3039 qCritical(
"jumbo callbacks for danger maps are not yet implemented.");
3044 qCritical(
"jumbo callbacks for fuel maps are not yet implemented.");
3094 if (!path.
empty()) {
3142 if (
nullptr == pfm->
tile) {
3150 pfm->
tile =
nullptr;
3270 for (i = 0;
positions[i].tile != ptile; i++) {
3277 std::vector<pf_position> new_positions(
length);
3278 for (
int j = 0; j <
length; j++) {
3315 if (!path.
empty()) {
3316 logger << QString::asprintf(
3317 "PF: path (at %p) consists of %d positions:\n", (
void *) &path,
3320 logger <<
"PF: path is empty";
3324 for (i = 0; i < path.
length(); i++) {
3326 logger << QString::asprintf(
3327 "PF: %2d/%2d: (%2d,%2d) dir=%-2s cost=%2d (%2d, %d) EC=%d\n",
3342 UTYF_IGTER, UTYF_CIVILIAN, UTYF_COAST_STRICT};
3371 for (i = 0; i < signifiant_flags_num; i++) {
3386 QHash<const pf_parameter *, struct pf_position *>
3402 pfrm->target_tile = target_tile;
3403 pfrm->max_turns = max_turns;
3407 param->
owner = pplayer;
3412 pfrm->hash =
new QHash<const pf_parameter *, struct pf_position *>;
3424 bool omniscient,
const struct civ_map *map)
3436 QHash<const pf_parameter *, pf_position *>::const_iterator it =
3437 pfrm->
hash->constBegin();
3438 while (it != pfrm->
hash->constEnd()) {
3458 struct tile *target_tile;
3463 if (pfrm->
hash->contains(param)) {
3464 pos = pfrm->
hash->value(param);
3477 }
else if (pfm->
tile == target_tile) {
3483 pfrm->
hash->insert(copy, pos);
3491 if (pfm->
tile == target_tile) {
3497 pfrm->
hash->insert(copy, pos);
3509 pfrm->
hash->insert(copy,
nullptr);
3519 const struct unit *punit)
3539 const struct unit *punit)
3550 const struct unit *punit,
3555 if (mypos !=
nullptr) {
struct tile * city_tile(const struct city *pcity)
Return the tile location of the city.
bool advance(struct tile *ptile)
Remove the part of a path leading up to a given tile.
pf_position & operator[](int i)
std::vector< pf_position > positions
#define fc_assert_msg(condition, message,...)
#define fc_assert_ret(condition)
#define fc_assert(condition)
#define fc_assert_ret_msg(condition, message,...)
#define fc_assert_ret_val(condition, val)
#define log_debug(message,...)
#define fc_assert_ret_val_msg(condition, val, message,...)
const char * dir_get_name(enum direction8 dir)
Return the debugging name of the direction.
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Return the tile for the given index position.
struct tile * mapstep(const struct civ_map *nmap, const struct tile *ptile, enum direction8 dir)
Step from the given tile in the given direction.
#define adjc_dir_iterate(nmap, center_tile, itr_tile, dir_itr)
#define adjc_dir_iterate_end
int unit_move_rate(const struct unit *punit)
This function calculates the move rate of the unit.
bool pf_reverse_map_unit_position(struct pf_reverse_map *pfrm, const struct unit *punit, struct pf_position *pos)
Fill the position.
static enum unit_type_flag_id signifiant_flags[3]
static void pf_danger_map_fill_position(const struct pf_danger_map *pfdm, struct tile *ptile, struct pf_position *pos)
Fill in the position which must be discovered already.
static struct pf_map * pf_fuel_map_new(const struct pf_parameter *parameter)
'pf_fuel_map' constructor.
static bool pf_fuel_map_iterate(struct pf_map *pfm)
Primary method for iterative path-finding for fuel units.
static struct pf_map * pf_danger_map_new(const struct pf_parameter *parameter)
'pf_danger_map' constructor.
#define PF_DANGER_MAP(pfm)
static bool pf_normal_node_init(struct pf_normal_map *pfnm, struct pf_normal_node *node, struct tile *ptile, enum pf_move_scope previous_scope)
Calculates cached values of the target node.
static PFPath pf_danger_map_construct_path(const struct pf_danger_map *pfdm, struct tile *ptile)
Read off the path to the node 'ptile', but with dangers.
static struct pf_fuel_pos * pf_fuel_pos_ref(struct pf_fuel_pos *pos)
Forget how we went to position.
static bool pf_danger_node_init(struct pf_danger_map *pfdm, struct pf_danger_node *node, struct tile *ptile, enum pf_move_scope previous_scope)
Calculates cached values of the target node.
static void pf_fuel_finalize_position_base(const struct pf_parameter *param, struct pf_position *pos, int cost, int moves_left)
Finalize the fuel position.
static int pf_normal_map_move_cost(struct pf_map *pfm, struct tile *ptile)
Return the move cost at ptile.
static int pf_fuel_map_fill_cost_for_full_moves(const struct pf_parameter *param, int cost, int moves_left)
This function returns the fill cost needed for a position, to get full moves at the next turn.
const struct pf_parameter * pf_map_parameter(const struct pf_map *pfm)
Return the pf_parameter for given pf_map.
pf_map * PF_MAP(void *x)
Casts to pf_map
static bool pf_fuel_map_position(struct pf_map *pfm, struct tile *ptile, struct pf_position *pos)
Get info about position at ptile and put it in pos.
static void pf_fuel_map_fill_position(const struct pf_fuel_map *pffm, struct tile *ptile, struct pf_position *pos)
Fill in the position which must be discovered already.
bool operator==(const pf_parameter &e1, const pf_parameter &e2)
bool pf_map_iterate(struct pf_map *pfm)
Iterates the path-finding algorithm one step further, to the next nearest position.
static void pf_fuel_map_create_segment(struct pf_fuel_map *pffm, struct tile *ptile, struct pf_fuel_node *node)
Creating path segment going back from node1 to a safe tile.
bool pf_map_position(struct pf_map *pfm, struct tile *ptile, struct pf_position *pos)
Get info about position at ptile and put it in pos.
static int pf_move_rate(const struct pf_parameter *param)
Return the "move rate".
void pf_map_iter_position(struct pf_map *pfm, struct pf_position *pos)
Read all info about the current position into pos.
struct pf_map * pf_map_new(const struct pf_parameter *parameter)
Factory function to create a new map according to the parameter.
static PFPath pf_danger_map_path(struct pf_map *pfm, struct tile *ptile)
Return the path to ptile.
int pf_map_iter_move_cost(struct pf_map *pfm)
Return the move cost at the current position.
static struct pf_map * pf_normal_map_new(const struct pf_parameter *parameter)
'pf_normal_map' constructor.
static bool pf_jumbo_map_iterate(struct pf_map *pfm)
Bare-bones PF iterator.
static PFPath pf_normal_map_path(struct pf_map *pfm, struct tile *ptile)
Return the path to ptile.
QDebug & operator<<(QDebug &logger, const PFPath &path)
Debug a path.
static int pf_normal_map_adjust_cost(int cost, int moves_left)
Adjust MC to reflect the move_rate.
static bool pf_normal_map_iterate_until(struct pf_normal_map *pfnm, struct tile *ptile)
Iterate the map until 'ptile' is reached.
static bool pf_fuel_node_init(struct pf_fuel_map *pffm, struct pf_fuel_node *node, struct tile *ptile, enum pf_move_scope previous_scope)
Calculates cached values of the target node.
struct pf_reverse_map * pf_reverse_map_new_for_city(const struct city *pcity, const struct player *attacker, int max_turns, bool omniscient, const struct civ_map *map)
'pf_reverse_map' constructor for city.
static bool pf_danger_map_position(struct pf_map *pfm, struct tile *ptile, struct pf_position *pos)
Get info about position at ptile and put it in pos .
static PFPath pf_fuel_map_path(struct pf_map *pfm, struct tile *ptile)
Return the path to ptile.
struct pf_reverse_map * pf_reverse_map_new(const struct player *pplayer, struct tile *target_tile, int max_turns, bool omniscient, const struct civ_map *map)
'pf_reverse_map' constructor.
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...
static const struct pf_position * pf_reverse_map_unit_pos(struct pf_reverse_map *pfrm, const struct unit *punit)
Returns the position for the unit.
static struct pf_fuel_pos * pf_fuel_pos_replace(struct pf_fuel_pos *pos, const struct pf_fuel_node *node)
Replace the position (unreferences it).
static int pf_moves_left_initially(const struct pf_parameter *param)
Return the number of "moves" started with.
static const struct pf_position * pf_reverse_map_pos(struct pf_reverse_map *pfrm, const struct pf_parameter *param)
Returns the map for the unit type.
static int pf_danger_map_move_cost(struct pf_map *pfm, struct tile *ptile)
Return the move cost at ptile.
static bool pf_fuel_map_attack_is_possible(const struct pf_parameter *param, int moves_left, int moves_left_req)
This function returns whether a unit with or without fuel can attack.
static void pf_finalize_position(const struct pf_parameter *param, struct pf_position *pos)
Take a position previously filled out (as by fill_position) and "finalize" it by reversing all fuel m...
void pf_reverse_map_destroy(struct pf_reverse_map *pfrm)
'pf_reverse_map' destructor.
static void pf_fuel_finalize_position(struct pf_position *pos, const struct pf_parameter *params, const struct pf_fuel_node *node, const struct pf_fuel_pos *head)
Finalize the fuel position.
static void pf_normal_map_fill_position(const struct pf_normal_map *pfnm, struct tile *ptile, struct pf_position *pos)
Fill in the position which must be discovered already.
static int pf_fuel_map_adjust_cost(int cost, int moves_left, int move_rate)
Adjust cost for move_rate and fuel usage.
static bool pf_danger_map_iterate(struct pf_map *pfm)
Primary method for iterative path-finding in presence of danger Notes:
static int pf_fuel_map_move_cost(struct pf_map *pfm, struct tile *ptile)
Return the move cost at ptile.
static void pf_position_fill_start_tile(struct pf_position *pos, const struct pf_parameter *param)
Fill the position for the start tile of a parameter.
static void pf_fuel_pos_unref(struct pf_fuel_pos *pos)
Forget how we went to position.
int pf_reverse_map_unit_move_cost(struct pf_reverse_map *pfrm, const struct unit *punit)
Get the move costs that a unit needs to reach the start tile.
static bool pf_normal_map_position(struct pf_map *pfm, struct tile *ptile, struct pf_position *pos)
Get info about position at ptile and put it in pos.
static bool pf_fuel_node_dangerous(const struct pf_fuel_node *node)
Returns whether this node is dangerous or not.
static void pf_danger_map_destroy(struct pf_map *pfm)
'pf_danger_map' destructor.
static bool pf_normal_map_iterate(struct pf_map *pfm)
Primary method for iterative path-finding.
static PFPath pf_fuel_map_construct_path(const struct pf_fuel_map *pffm, struct tile *ptile)
Read off the path to the node 'ptile', but with fuel danger.
void pf_map_destroy(struct pf_map *pfm)
After usage the map must be destroyed.
static int pf_moves_left(const struct pf_parameter *param, int cost)
Moves left after node is reached.
static int pf_danger_map_adjust_cost(const struct pf_parameter *params, int cost, bool to_danger, int moves_left)
Adjust cost taking into account possibility of making the move.
static bool pf_fuel_map_iterate_until(struct pf_fuel_map *pffm, struct tile *ptile)
Iterate the map until 'ptile' is reached.
struct tile * pf_map_iter(struct pf_map *pfm)
Return the current tile.
static void pf_normal_map_destroy(struct pf_map *pfm)
'pf_normal_map' destructor.
int pf_map_move_cost(struct pf_map *pfm, struct tile *ptile)
Tries to find the minimal move cost to reach ptile.
static int pf_fuel_total_CC(const struct pf_parameter *param, int cost, int extra, int safety)
Obtain cost-of-path from pure cost, extra cost and safety.
static void pf_fuel_map_destroy(struct pf_map *pfm)
'pf_fuel_map' destructor.
PFPath pf_map_iter_path(struct pf_map *pfm)
Return the path to our current position.This is equivalent to pf_map_path(pfm, pf_map_iter(pfm)).
static bool pf_danger_map_iterate_until(struct pf_danger_map *pfdm, struct tile *ptile)
Iterate the map until 'ptile' is reached.
#define INITIAL_QUEUE_SIZE
static int pf_danger_map_fill_cost_for_full_moves(const struct pf_parameter *param, int cost)
This function returns the fills the cost needed for a position, to get full moves at the next turn.
#define PF_NORMAL_MAP(pfm)
static int pf_turns(const struct pf_parameter *param, int cost)
Number of turns required to reach node.
static int pf_total_CC(const struct pf_parameter *param, int cost, int extra)
Obtain cost-of-path from pure cost and extra cost.
static PFPath pf_normal_map_construct_path(const struct pf_normal_map *pfnm, struct tile *dest_tile)
Read off the path to the node dest_tile, which must already be discovered.
static int pf_fuel_waited_total_CC(int cost, int safety)
Obtain cost-of-path for constant extra cost (used for node after waited).
static void pf_danger_map_create_segment(struct pf_danger_map *pfdm, struct pf_danger_node *node1)
Creating path segment going back from node1 to a safe tile.
bool player_can_invade_tile(const struct player *pplayer, const struct tile *ptile)
Return TRUE iff the player can invade a particular tile (linked with borders and diplomatic states).
SPECPQ_PRIORITY_TYPE priority
struct map_index_pq * danger_queue
struct pf_danger_node * lattice
struct map_index_pq * queue
struct pf_danger_node::pf_danger_pos * danger_segment
unsigned short extra_tile
struct map_index_pq * waited_queue
struct map_index_pq * queue
struct pf_fuel_node * lattice
struct pf_fuel_pos * segment
unsigned short cost_to_here[DIR8_MAGIC_MAX]
unsigned short extra_tile
struct pf_fuel_pos * prev
bool(* get_position)(struct pf_map *pfm, struct tile *ptile, struct pf_position *pos)
int(* get_move_cost)(struct pf_map *pfm, struct tile *ptile)
PFPath(* get_path)(struct pf_map *pfm, struct tile *ptile)
bool(* iterate)(struct pf_map *pfm)
void(* destroy)(struct pf_map *pfm)
struct pf_parameter params
struct pf_normal_node * lattice
struct map_index_pq * queue
unsigned short extra_tile
const struct unit_type * transported_by_initially
enum pf_action(* get_action)(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
enum pf_move_scope(* get_move_scope)(const struct tile *ptile, bool *can_disembark, enum pf_move_scope previous_scope, const struct pf_parameter *param)
const struct civ_map * map
enum tile_behavior(* get_TB)(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
int(* get_EC)(const struct tile *ptile, enum known_type known, const struct pf_parameter *param)
const struct player * owner
bool(* is_pos_dangerous)(const struct tile *ptile, enum known_type, const struct pf_parameter *param)
int(* get_moves_left_req)(const struct tile *ptile, enum known_type, const struct pf_parameter *param)
bool(* get_zoc)(const struct player *pplayer, const struct tile *ptile, const struct civ_map *zmap)
int(* get_MC)(const struct tile *from_tile, enum pf_move_scope src_move_scope, const struct tile *to_tile, enum pf_move_scope dst_move_scope, const struct pf_parameter *param)
int(* get_costs)(const struct tile *from_tile, enum direction8 dir, const struct tile *to_tile, int from_cost, int from_extra, int *to_cost, int *to_extra, const struct pf_parameter *param)
const struct unit_type * utype
bool(* is_action_possible)(const struct tile *from_tile, enum pf_move_scope src_move_scope, const struct tile *to_tile, enum pf_action action, const struct pf_parameter *param)
enum direction8 dir_to_here
enum direction8 dir_to_next_pos
struct pf_parameter template_params
struct tile * target_tile
QHash< const pf_parameter *, struct pf_position * > * hash
#define terrain_has_flag(terr, flag)
bool tile_has_native_base(const struct tile *ptile, const struct unit_type *punittype)
Check if tile contains base native for unit.
enum known_type tile_get_known(const struct tile *ptile, const struct player *pplayer)
Return a known_type enumeration value for the tile.
struct city * tile_city(const struct tile *ptile)
Return the city on this tile (or nullptr), checking for city center.
#define tile_terrain(_tile)
const struct unit_type * unit_type_get(const struct unit *punit)
Return the unit type for this unit.
bool utype_can_freely_unload(const struct unit_type *pcargotype, const struct unit_type *ptranstype)
Return TRUE iff the given cargo type has no restrictions on when it can unload from the given transpo...
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...
static bool utype_has_flag(const struct unit_type *punittype, int flag)