Freeciv-3.2
Loading...
Searching...
No Matches
daidata.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2002 - The Freeciv Project
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/* common */
19#include "game.h"
20#include "government.h"
21#include "map.h"
22#include "multipliers.h"
23#include "research.h"
24
25/* aicore */
26#include "aiactions.h"
27
28/* server */
29#include "cityturn.h"
30#include "plrhand.h"
31
32/* server/advisors */
33#include "advdata.h"
34
35/* ai/default */
36#include "aiferry.h"
37#include "daicity.h"
38#include "daidiplomacy.h"
39#include "daieffects.h"
40#include "daiplayer.h"
41#include "daisettler.h"
42#include "daiunit.h"
43
44#include "daidata.h"
45
46static void dai_diplomacy_new(struct ai_type *ait,
47 const struct player *plr1,
48 const struct player *plr2);
49static void dai_diplomacy_defaults(struct ai_type *ait,
50 const struct player *plr1,
51 const struct player *plr2);
52static void dai_diplomacy_destroy(struct ai_type *ait,
53 const struct player *plr1,
54 const struct player *plr2);
55
56/************************************************************************/
59void dai_data_init(struct ai_type *ait, struct player *pplayer)
60{
61 struct ai_plr *ai = def_ai_player_data(pplayer, ait);
62
64
65 ai->last_num_continents = -1;
66 ai->last_num_oceans = -1;
67
70 sizeof(*ai->diplomacy.player_intel_slots));
72 const struct ai_dip_intel **player_intel_slot
76
78 /* create ai diplomacy states for all other players */
79 dai_diplomacy_new(ait, pplayer, aplayer);
80 dai_diplomacy_defaults(ait, pplayer, aplayer);
81 /* create ai diplomacy state of this player */
82 if (aplayer != pplayer) {
83 dai_diplomacy_new(ait, aplayer, pplayer);
84 dai_diplomacy_defaults(ait, aplayer, pplayer);
85 }
87
89 ai->diplomacy.timer = 0;
90 ai->diplomacy.love_coeff = 4; /* 4% */
91 ai->diplomacy.love_incr = MAX_AI_LOVE * 3 / 100;
94
95 ai->settler = NULL;
96
97 /* Initialise autosettler. */
99}
100
101/************************************************************************/
104void dai_data_close(struct ai_type *ait, struct player *pplayer)
105{
106 struct ai_plr *ai = def_ai_player_data(pplayer, ait);
107
108 /* Finish the phase if it's open - free resources related to
109 * open/finish cycle */
110 dai_data_phase_finished(ait, pplayer);
111
112 /* Free autosettler. */
114
115 if (ai->diplomacy.player_intel_slots != NULL) {
117 /* destroy the ai diplomacy states of this player with others ... */
118 dai_diplomacy_destroy(ait, pplayer, aplayer);
119 /* and of others with this player. */
120 if (aplayer != pplayer) {
121 dai_diplomacy_destroy(ait, aplayer, pplayer);
122 }
125 }
126}
127
128/************************************************************************/
132bool is_ai_data_phase_open(struct ai_type *ait, struct player *pplayer)
133{
134 struct ai_plr *ai = def_ai_player_data(pplayer, ait);
135
136 return ai->phase_initialized;
137}
138
139/************************************************************************/
142void dai_data_phase_begin(struct ai_type *ait, struct player *pplayer,
143 bool is_new_phase)
144{
145 struct ai_plr *ai = def_ai_player_data(pplayer, ait);
146 bool caller_closes;
147
148 /* Note that this refreshes advisor data if needed. ai_plr_data_get()
149 is expected to refresh advisor data if needed, and ai_plr_data_get()
150 depends on this call
151 ai_plr_data_get()->ai_data_phase_begin()->adv_data_get() to do it.
152 If you change this, you may need to adjust ai_plr_data_get() also. */
153 struct adv_data *adv;
154
155 if (ai->phase_initialized) {
156 return;
157 }
158
160
161 adv = adv_data_get(pplayer, &caller_closes);
162
163 /* Store current number of known continents and oceans so we can compare
164 against it later in order to see if ai data needs refreshing. */
166 ai->last_num_oceans = adv->num_oceans;
167
168 /*** Diplomacy ***/
169 if (is_ai(pplayer) && !is_barbarian(pplayer) && is_new_phase) {
170 dai_diplomacy_begin_new_phase(ait, pplayer);
171 }
172
173 /* Set per-player variables. We must set all players, since players
174 * can be created during a turn, and we don't want those to have
175 * invalid values. */
177 struct ai_dip_intel *adip = dai_diplomacy_get(ait, pplayer, aplayer);
178
179 adip->is_allied_with_enemy = NULL;
180 adip->at_war_with_ally = NULL;
181 adip->is_allied_with_ally = NULL;
182
184 if (check_pl == pplayer
185 || check_pl == aplayer
186 || !check_pl->is_alive) {
187 continue;
188 }
190 && player_diplstate_get(pplayer, check_pl)->type == DS_WAR) {
191 adip->is_allied_with_enemy = check_pl;
192 }
193 if (pplayers_allied(pplayer, check_pl)
195 adip->at_war_with_ally = check_pl;
196 }
198 && pplayers_allied(pplayer, check_pl)) {
199 adip->is_allied_with_ally = check_pl;
200 }
203
204 /*** Statistics ***/
205
206 ai->stats.workers = fc_calloc(adv->num_continents + 1, sizeof(int));
207 ai->stats.ocean_workers = fc_calloc(adv->num_oceans + 1, sizeof(int));
208 unit_list_iterate(pplayer->units, punit) {
209 struct tile *ptile = unit_tile(punit);
210
212 Continent_id cont = tile_continent(ptile);
213
214 if (is_ocean_tile(ptile)) {
215 if (cont <= 0 && -cont <= adv->num_oceans) {
216 ai->stats.ocean_workers[(int)-cont]++;
217 } else {
218 /* Always fails */
219 fc_assert(cont <= 0 && -cont <= adv->num_oceans);
220 }
221 } else {
222 if (cont >= 0 && cont <= adv->num_continents) {
223 ai->stats.workers[(int)cont]++;
224 } else {
225 /* Always fails */
226 fc_assert(cont >= 0 && cont <= adv->num_continents);
227 }
228 }
229 }
231
233 unit_list_iterate(pplayer->units, punit) {
235 && def_ai_unit_data(punit, ait)->task == AIUNIT_ATTACK) {
236
237 fc_assert_msg(punit->goto_tile != NULL, "No target city for spy action");
238
239 if (punit->goto_tile != NULL) {
240 struct city *pcity = tile_city(punit->goto_tile);
241
242 if (pcity != NULL) {
243 /* Heading somewhere on a mission, reserve target. */
245 }
246 }
247 }
249
250 aiferry_init_stats(ait, pplayer);
251
252 /*** Interception engine ***/
253
254 /* We are tracking a unit if punit->server.ai->cur_pos is not NULL. If we
255 * are not tracking, start tracking by setting cur_pos. If we are,
256 * fill prev_pos with previous cur_pos. This way we get the
257 * necessary coordinates to calculate a probable trajectory. */
259 if (aplayer == pplayer) {
260 continue;
261 }
263 struct unit_ai *unit_data = def_ai_unit_data(punit, ait);
264
265 if (!unit_data->cur_pos) {
266 /* Start tracking */
267 unit_data->cur_pos = &unit_data->cur_struct;
268 unit_data->prev_pos = NULL;
269 } else {
270 unit_data->prev_struct = unit_data->cur_struct;
271 unit_data->prev_pos = &unit_data->prev_struct;
272 }
273 *unit_data->cur_pos = unit_tile(punit);
276
277 if (caller_closes) {
278 adv_data_phase_done(pplayer);
279 }
280}
281
282/************************************************************************/
285void dai_data_phase_finished(struct ai_type *ait, struct player *pplayer)
286{
287 struct ai_plr *ai = def_ai_player_data(pplayer, ait);
288
289 if (!ai->phase_initialized) {
290 return;
291 }
292
293 free(ai->stats.workers);
294 ai->stats.workers = NULL;
295
298
300}
301
302/************************************************************************/
308struct ai_plr *dai_plr_data_get(struct ai_type *ait, struct player *pplayer,
309 bool *caller_closes)
310{
311 struct ai_plr *ai = def_ai_player_data(pplayer, ait);
312
314
315 /* This assert really is required. See longer comment
316 in adv_data_get() for equivalent code. */
317#if defined(FREECIV_DEBUG) || defined(IS_DEVEL_VERSION)
319#endif
320
321 if (caller_closes != NULL) {
323 }
324
326 || ai->last_num_oceans != wld.map.num_oceans) {
327 /* We have discovered more continents, recalculate! */
328
329 /* See adv_data_get() */
330 if (ai->phase_initialized) {
331 dai_data_phase_finished(ait, pplayer);
332 dai_data_phase_begin(ait, pplayer, FALSE);
333 } else {
334 /* wrong order */
335 log_debug("%s ai data phase closed when dai_plr_data_get() called",
336 player_name(pplayer));
337 dai_data_phase_begin(ait, pplayer, FALSE);
338 if (caller_closes != NULL) {
340 } else {
341 dai_data_phase_finished(ait, pplayer);
342 }
343 }
344 } else {
345 if (!ai->phase_initialized && caller_closes != NULL) {
346 dai_data_phase_begin(ait, pplayer, FALSE);
348 }
349 }
350
351 return ai;
352}
353
354/************************************************************************/
357static void dai_diplomacy_new(struct ai_type *ait,
358 const struct player *plr1,
359 const struct player *plr2)
360{
362
363 fc_assert_ret(plr1 != NULL);
364 fc_assert_ret(plr2 != NULL);
365
366 const struct ai_dip_intel **player_intel_slot
368 + player_index(plr2);
369
371
372 player_intel = fc_calloc(1, sizeof(*player_intel));
374}
375
376/************************************************************************/
379static void dai_diplomacy_defaults(struct ai_type *ait,
380 const struct player *plr1,
381 const struct player *plr2)
382{
383 struct ai_dip_intel *player_intel = dai_diplomacy_get(ait, plr1, plr2);
384
386
387 /* pseudorandom value */
388 player_intel->spam = (player_index(plr1) + player_index(plr2)) % 5;
389 player_intel->countdown = -1;
390 player_intel->war_reason = DAI_WR_NONE;
391 player_intel->distance = 1;
392 player_intel->ally_patience = 0;
393 player_intel->asked_about_peace = 0;
394 player_intel->asked_about_alliance = 0;
395 player_intel->asked_about_ceasefire = 0;
396 player_intel->warned_about_space = 0;
397}
398
399/************************************************************************/
403 const struct player *plr1,
404 const struct player *plr2)
405{
406 fc_assert_ret_val(plr1 != NULL, NULL);
407 fc_assert_ret_val(plr2 != NULL, NULL);
408
409 const struct ai_dip_intel **player_intel_slot
411 + player_index(plr2);
412
414
415 return (struct ai_dip_intel *) *player_intel_slot;
416}
417
418/************************************************************************/
421static void dai_diplomacy_destroy(struct ai_type *ait,
422 const struct player *plr1,
423 const struct player *plr2)
424{
425 fc_assert_ret(plr1 != NULL);
426 fc_assert_ret(plr2 != NULL);
427
428 const struct ai_dip_intel **player_intel_slot
430 + player_index(plr2);
431
432 if (*player_intel_slot != NULL) {
433 free(dai_diplomacy_get(ait, plr1, plr2));
434 }
435
437}
438
439/************************************************************************/
442void dai_adjust_policies(struct ai_type *ait, struct player *pplayer)
443{
445 struct adv_data *adv;
446
447 adv = adv_data_get(pplayer, NULL);
448
450 if (multiplier_can_be_changed(ppol, pplayer)) {
451 int orig_value = 0;
452 int mp_val = player_multiplier_value(pplayer, ppol);
454 bool better_found = FALSE;
455
456 city_list_iterate(pplayer->cities, pcity) {
457 orig_value += dai_city_want(pplayer, pcity, adv, NULL);
459
460 /* Consider reducing policy value */
461 if (mp_val > ppol->start) {
462 int new_value = 0;
463
464 pplayer->multipliers[pidx].value = MAX(mp_val - ppol->step, ppol->start);
465
466 city_list_iterate(pplayer->cities, acity) {
469
470 city_list_iterate(pplayer->cities, pcity) {
471 new_value += dai_city_want(pplayer, pcity, adv, NULL);
473
474 if (new_value > orig_value) {
475 /* This is step to right direction, leave it in effect. */
476 pplayer->multipliers[pidx].target = pplayer->multipliers[pidx].value;
477
480 }
481 }
482
483 /* Consider increasing policy value */
484 if (!better_found && mp_val < ppol->stop) {
485 int new_value = 0;
486
487 pplayer->multipliers[pidx].value = MIN(mp_val + ppol->step, ppol->stop);
488
489 city_list_iterate(pplayer->cities, acity) {
492
493 city_list_iterate(pplayer->cities, pcity) {
494 new_value += dai_city_want(pplayer, pcity, adv, NULL);
496
497 if (new_value > orig_value) {
498 /* This is step to right direction, leave it in effect. */
499 pplayer->multipliers[pidx].target = pplayer->multipliers[pidx].value;
500
503 }
504 }
505
506 if (!better_found) {
507 /* Restore original multiplier value */
508 pplayer->multipliers[pidx].value = mp_val;
510 }
511 }
513
515 city_list_iterate(pplayer->cities, acity) {
518 }
519}
520
521/************************************************************************/
524void dai_gov_value(struct ai_type *ait, struct player *pplayer,
525 struct government *gov, adv_want *val, bool *override)
526{
527 int dist;
528 int bonus = 0; /* in percentage */
530 struct universal source = { .kind = VUT_GOVERNMENT, .value.govern = gov };
531 struct adv_data *adv;
532 int turns = 9999; /* TODO: Set to correct value */
533 int nplayers;
534 const struct research *presearch;
535
536 /* Use default handling of no-cities case */
537 if (city_list_size(pplayer->cities) == 0) {
538 *override = FALSE;
539 return;
540 }
541
542 adv = adv_data_get(pplayer, NULL);
543 nplayers = normal_player_count();
544 presearch = research_get(pplayer);
545
546 pplayer->government = gov;
547 /* Ideally we should change tax rates here, but since
548 * this is a rather big CPU operation, we'd rather not. */
549 check_player_max_rates(pplayer);
550 city_list_iterate(pplayer->cities, acity) {
553 city_list_iterate(pplayer->cities, pcity) {
554 bool capital;
555 const struct req_context context = { .player = pplayer, .city = pcity };
556
557 *val += dai_city_want(pplayer, pcity, adv, NULL);
558 capital = is_capital(pcity);
559
561 bool present = TRUE;
562 bool active = TRUE;
563
565 /* Check if all the requirements for the currently evaluated effect
566 * are met, except for having the tech that we are evaluating.
567 * TODO: Consider requirements that could be met later. */
568 if (VUT_GOVERNMENT == preq->source.kind
569 && preq->source.value.govern == gov) {
570 present = preq->present;
571 continue;
572 }
574 active = FALSE;
575 break; /* presence doesn't matter for inactive effects. */
576 }
577
579
580 if (active) {
581 adv_want v1;
582
583 v1 = dai_effect_value(pplayer, adv, pcity, capital,
584 turns, peffect, 1,
585 nplayers);
586
587 if (!present) {
588 /* Government removes the effect */
589 *val -= v1;
590 } else {
591 *val += v1;
592 }
593 }
596
597 bonus += adv_gov_action_immunity_want(gov);
598 bonus += adv_gov_player_bonus_want(pplayer);
599
601 if (revolution_turns > 0) {
602 bonus -= 6 / revolution_turns;
603 }
604
605 *val += (*val * bonus) / 100;
606
607 /* FIXME: handle reqs other than technologies. */
608 dist = 0;
610 if (VUT_ADVANCE == preq->source.kind) {
612 advance_number(preq->source.value.advance)));
613 }
615 *val = amortize(*val, dist);
616
617 *override = TRUE;
618}
adv_want adv_gov_player_bonus_want(struct player *pplayer)
Definition advdata.c:952
struct adv_data * adv_data_get(struct player *pplayer, bool *caller_closes)
Definition advdata.c:605
void adv_data_phase_done(struct player *pplayer)
Definition advdata.c:565
adv_want adv_gov_action_immunity_want(struct government *gov)
Definition advdata.c:824
adv_want amortize(adv_want benefit, int delay)
Definition advtools.c:29
bool aia_utype_is_considered_spy_vs_city(const struct unit_type *putype)
Definition aiactions.c:27
void aiferry_init_stats(struct ai_type *ait, struct player *pplayer)
Definition aiferry.c:92
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
#define BV_SET(bv, bit)
Definition bitvector.h:81
bool is_capital(const struct city *pcity)
Definition city.c:1579
#define city_list_iterate(citylist, pcity)
Definition city.h:508
#define city_list_iterate_end
Definition city.h:510
void auto_arrange_workers(struct city *pcity)
Definition cityturn.c:367
char * incite_cost
Definition comments.c:75
adv_want dai_city_want(struct player *pplayer, struct city *acity, struct adv_data *adv, struct impr_type *pimprove)
Definition daicity.c:1424
bool is_ai_data_phase_open(struct ai_type *ait, struct player *pplayer)
Definition daidata.c:132
void dai_gov_value(struct ai_type *ait, struct player *pplayer, struct government *gov, adv_want *val, bool *override)
Definition daidata.c:524
struct ai_plr * dai_plr_data_get(struct ai_type *ait, struct player *pplayer, bool *caller_closes)
Definition daidata.c:308
static void dai_diplomacy_destroy(struct ai_type *ait, const struct player *plr1, const struct player *plr2)
Definition daidata.c:421
void dai_adjust_policies(struct ai_type *ait, struct player *pplayer)
Definition daidata.c:442
static void dai_diplomacy_new(struct ai_type *ait, const struct player *plr1, const struct player *plr2)
Definition daidata.c:357
struct ai_dip_intel * dai_diplomacy_get(struct ai_type *ait, const struct player *plr1, const struct player *plr2)
Definition daidata.c:402
void dai_data_init(struct ai_type *ait, struct player *pplayer)
Definition daidata.c:59
void dai_data_phase_begin(struct ai_type *ait, struct player *pplayer, bool is_new_phase)
Definition daidata.c:142
static void dai_diplomacy_defaults(struct ai_type *ait, const struct player *plr1, const struct player *plr2)
Definition daidata.c:379
void dai_data_phase_finished(struct ai_type *ait, struct player *pplayer)
Definition daidata.c:285
void dai_data_close(struct ai_type *ait, struct player *pplayer)
Definition daidata.c:104
@ WIN_OPEN
Definition daidata.h:32
void dai_diplomacy_begin_new_phase(struct ai_type *ait, struct player *pplayer)
adv_want dai_effect_value(struct player *pplayer, const struct adv_data *adv, const struct city *pcity, const bool capital, int turns, const struct effect *peffect, const int c, const int nplayers)
Definition daieffects.c:138
static struct ai_plr * def_ai_player_data(const struct player *pplayer, struct ai_type *deftype)
Definition daiplayer.h:54
static struct unit_ai * def_ai_unit_data(const struct unit *punit, struct ai_type *deftype)
Definition daiplayer.h:48
void dai_auto_settler_init(struct ai_plr *ai)
void dai_auto_settler_free(struct ai_plr *ai)
@ AIUNIT_ATTACK
Definition daiunit.h:28
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 effect_list * get_req_source_effects(const struct universal *psource)
Definition effects.c:153
int get_player_bonus(const struct player *pplayer, enum effect_type effect_type)
Definition effects.c:828
#define effect_list_iterate_end
Definition effects.h:406
#define effect_list_iterate(effect_list, peffect)
Definition effects.h:404
float adv_want
Definition fc_types.h:1354
@ RPT_POSSIBLE
Definition fc_types.h:700
signed short Continent_id
Definition fc_types.h:372
struct world wld
Definition game.c:63
static GtkWidget * source
Definition gotodlg.c:58
GType type
Definition repodlgs.c:1313
#define fc_assert_msg(condition, message,...)
Definition log.h:181
#define fc_assert_ret(condition)
Definition log.h:191
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define log_debug(message,...)
Definition log.h:115
#define fc_calloc(n, esz)
Definition mem.h:38
bool multiplier_can_be_changed(struct multiplier *pmul, struct player *pplayer)
Multiplier_type_id multiplier_index(const struct multiplier *pmul)
Definition multipliers.c:80
#define multipliers_iterate(_mul_)
Definition multipliers.h:61
#define multipliers_iterate_end
Definition multipliers.h:67
int player_slot_count(void)
Definition player.c:418
int player_multiplier_value(const struct player *pplayer, const struct multiplier *pmul)
Definition player.c:1958
const char * player_name(const struct player *pplayer)
Definition player.c:895
int player_slot_index(const struct player_slot *pslot)
Definition player.c:426
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
bool pplayers_allied(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1405
#define players_iterate_end
Definition player.h:537
#define players_iterate(_pplayer)
Definition player.h:532
#define MAX_AI_LOVE
Definition player.h:561
static bool is_barbarian(const struct player *pplayer)
Definition player.h:489
#define player_slots_iterate(_pslot)
Definition player.h:523
#define is_ai(plr)
Definition player.h:230
#define players_iterate_alive_end
Definition player.h:547
#define player_slots_iterate_end
Definition player.h:527
#define players_iterate_alive(_pplayer)
Definition player.h:542
int normal_player_count(void)
Definition plrhand.c:3204
void check_player_max_rates(struct player *pplayer)
Definition plrhand.c:776
bool is_req_active(const struct req_context *context, const struct player *other_player, const struct requirement *req, const enum req_problem_type prob_type)
#define requirement_vector_iterate_end
#define requirement_vector_iterate(req_vec, preq)
int research_goal_unknown_techs(const struct research *presearch, Tech_type_id goal)
Definition research.c:750
struct research * research_get(const struct player *pplayer)
Definition research.c:128
#define MIN(x, y)
Definition shared.h:55
#define MAX(x, y)
Definition shared.h:54
adv_want val
Definition advdata.h:132
int num_oceans
Definition advdata.h:110
int num_continents
Definition advdata.h:109
struct government * gov
Definition advdata.h:131
int * ocean_workers
Definition daidata.h:83
int last_num_oceans
Definition daidata.h:75
int * workers
Definition daidata.h:82
int last_num_continents
Definition daidata.h:74
bool phase_initialized
Definition daidata.h:72
struct ai_plr::@253 stats
struct ai_settler * settler
Definition daidata.h:101
struct ai_plr::@254 diplomacy
int req_love_for_alliance
Definition daidata.h:96
int timer
Definition daidata.h:92
char love_incr
Definition daidata.h:94
char love_coeff
Definition daidata.h:93
bv_id diplomat_reservations
Definition daidata.h:85
const struct ai_dip_intel ** player_intel_slots
Definition daidata.h:90
int req_love_for_peace
Definition daidata.h:95
enum winning_strategy strategy
Definition daidata.h:91
Definition ai.h:50
Definition city.h:320
int id
Definition city.h:326
Continent_id num_continents
Definition map_types.h:81
Continent_id num_oceans
Definition map_types.h:82
struct requirement_vector reqs
Definition government.h:62
struct city_list * cities
Definition player.h:279
struct government * government
Definition player.h:256
struct unit_list * units
Definition player.h:280
bool is_alive
Definition player.h:266
struct multiplier_value multipliers[MAX_NUM_MULTIPLIERS]
Definition player.h:312
const struct player * player
Definition tile.h:50
struct tile * goto_tile
Definition unit.h:155
enum universals_n kind
Definition fc_types.h:902
struct civ_map map
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
Tech_type_id advance_number(const struct advance *padvance)
Definition tech.c:98
#define is_ocean_tile(ptile)
Definition terrain.h:303
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_continent(_tile)
Definition tile.h:92
#define unit_tile(_pu)
Definition unit.h:397
#define unit_list_iterate(unitlist, punit)
Definition unitlist.h:31
#define unit_list_iterate_end
Definition unitlist.h:33
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
bool unit_has_type_flag(const struct unit *punit, enum unit_type_flag_id flag)
Definition unittype.c:190