Freeciv-3.3: /fast/freeciv/nightly/main/server/advisors/infracache.c Source File

Freeciv-3.3

Loading...
Searching...
No Matches
infracache.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
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 "city.h"
20#include "game.h"
21#include "map.h"
22#include "player.h"
23#include "tile.h"
24
25/* server */
26#include "maphand.h"
27
28/* server/advisors */
29#include "advbuilding.h"
30#include "autoworkers.h"
31
32#include "infracache.h"
33
34/* Cache activities within the city map */
35 struct worker_activity_cache {
36 adv_want act[ACTIVITY_LAST];
37 adv_want extra[MAX_EXTRA_TYPES];
38 adv_want rmextra[MAX_EXTRA_TYPES];
39};
40
41static adv_want adv_calc_cultivate(const struct city *pcity,
42 const struct tile *ptile);
43static adv_want adv_calc_plant(const struct city *pcity,
44 const struct tile *ptile);
45static adv_want adv_calc_transform(const struct city *pcity,
46 const struct tile *ptile);
47static adv_want adv_calc_extra(const struct city *pcity,
48 const struct tile *ptile,
49 const struct extra_type *pextra);
50static adv_want adv_calc_rmextra(const struct city *pcity,
51 const struct tile *ptile,
52 const struct extra_type *pextra);
53
54/**********************************************************************/
62 static adv_want adv_calc_cultivate(const struct city *pcity,
63 const struct tile *ptile)
64{
65 adv_want goodness;
66 struct terrain *old_terrain, *new_terrain;
67
68 fc_assert_ret_val(ptile != NULL, -1);
69
70 old_terrain = tile_terrain(ptile);
71 new_terrain = old_terrain->cultivate_result;
72
73 if (new_terrain != old_terrain && new_terrain != T_NONE) {
74 struct tile *vtile;
75
76 if (tile_city(ptile) && terrain_has_flag(new_terrain, TER_NO_CITIES)) {
77 /* Not a valid activity. */
78 return -1;
79 }
80 /* Irrigation would change the terrain type, clearing conflicting
81 * extras in the process. Calculate the benefit of doing so. */
82 vtile = tile_virtual_new(ptile);
83
84 tile_change_terrain(vtile, new_terrain);
85 goodness = city_tile_value(pcity, vtile, 0, 0);
86 tile_virtual_destroy(vtile);
87
88 return goodness;
89 } else {
90 return -1;
91 }
92}
93
94/**********************************************************************/
102 static adv_want adv_calc_plant(const struct city *pcity,
103 const struct tile *ptile)
104{
105 adv_want goodness;
106 struct terrain *old_terrain, *new_terrain;
107
108 fc_assert_ret_val(ptile != NULL, -1);
109
110 old_terrain = tile_terrain(ptile);
111 new_terrain = old_terrain->plant_result;
112
113 if (old_terrain != new_terrain && new_terrain != T_NONE) {
114 struct tile *vtile;
115
116 if (tile_city(ptile) && terrain_has_flag(new_terrain, TER_NO_CITIES)) {
117 /* Not a valid activity. */
118 return -1;
119 }
120 /* Mining would change the terrain type, clearing conflicting
121 * extras in the process. Calculate the benefit of doing so. */
122 vtile = tile_virtual_new(ptile);
123
124 tile_change_terrain(vtile, new_terrain);
125 goodness = city_tile_value(pcity, vtile, 0, 0);
126 tile_virtual_destroy(vtile);
127
128 return goodness;
129 } else {
130 return -1;
131 }
132}
133
134/**********************************************************************/
142 static adv_want adv_calc_transform(const struct city *pcity,
143 const struct tile *ptile)
144{
145 adv_want goodness;
146 struct tile *vtile;
147 struct terrain *old_terrain, *new_terrain;
148 const struct civ_map *nmap = &(wld.map);
149
150 fc_assert_ret_val(ptile != NULL, -1);
151
152 old_terrain = tile_terrain(ptile);
153 new_terrain = old_terrain->transform_result;
154
155 if (old_terrain == new_terrain || new_terrain == T_NONE) {
156 return -1;
157 }
158
159 if (!terrain_surroundings_allow_change(nmap, ptile, new_terrain)) {
160 /* Can't do this terrain conversion here. */
161 return -1;
162 }
163
164 if (tile_city(ptile) && terrain_has_flag(new_terrain, TER_NO_CITIES)) {
165 return -1;
166 }
167
168 vtile = tile_virtual_new(ptile);
169 tile_change_terrain(vtile, new_terrain);
170 goodness = city_tile_value(pcity, vtile, 0, 0);
171 tile_virtual_destroy(vtile);
172
173 return goodness;
174}
175
176/**********************************************************************/
188 static adv_want adv_calc_extra(const struct city *pcity,
189 const struct tile *ptile,
190 const struct extra_type *pextra)
191{
192 adv_want goodness = -1;
193
194 fc_assert_ret_val(ptile != NULL, -1);
195
196 if (player_can_build_extra(pextra, city_owner(pcity), ptile)) {
197 struct tile *vtile = tile_virtual_new(ptile);
198
199 tile_add_extra(vtile, pextra);
200
201 extra_type_iterate(cextra) {
202 if (tile_has_extra(vtile, cextra)
203 && !can_extras_coexist(pextra, cextra)) {
204 tile_remove_extra(vtile, cextra);
205 }
206 } extra_type_iterate_end;
207
208 goodness = city_tile_value(pcity, vtile, 0, 0);
209 tile_virtual_destroy(vtile);
210 }
211
212 return goodness;
213}
214
215/**********************************************************************/
223 static adv_want adv_calc_rmextra(const struct city *pcity,
224 const struct tile *ptile,
225 const struct extra_type *pextra)
226{
227 adv_want goodness = -1;
228
229 fc_assert_ret_val(ptile != NULL, -1);
230
231 if (player_can_remove_extra(pextra, city_owner(pcity), ptile)) {
232 struct tile *vtile = tile_virtual_new(ptile);
233
234 tile_remove_extra(vtile, pextra);
235
236 goodness = city_tile_value(pcity, vtile, 0, 0);
237 tile_virtual_destroy(vtile);
238 }
239
240 return goodness;
241}
242
243/**********************************************************************/
250 void initialize_infrastructure_cache(struct player *pplayer)
251{
252 const struct civ_map *nmap = &(wld.map);
253
254 city_list_iterate(pplayer->cities, pcity) {
255 struct tile *pcenter = city_tile(pcity);
256 int radius_sq = city_map_radius_sq_get(pcity);
257
258 city_map_iterate(radius_sq, city_index, city_x, city_y) {
259 aw_transform_action_iterate(act) {
260 adv_city_worker_act_set(pcity, city_index, action_id_get_activity(act),
261 -1);
262 } aw_transform_action_iterate_end;
263 } city_map_iterate_end;
264
265 city_tile_iterate_index(nmap, radius_sq, pcenter, ptile, cindex) {
266 adv_city_worker_act_set(pcity, cindex, ACTIVITY_MINE,
267 adv_calc_plant(pcity, ptile));
268 adv_city_worker_act_set(pcity, cindex, ACTIVITY_IRRIGATE,
269 adv_calc_cultivate(pcity, ptile));
270 adv_city_worker_act_set(pcity, cindex, ACTIVITY_TRANSFORM,
271 adv_calc_transform(pcity, ptile));
272
273 /* road_bonus() is handled dynamically later; it takes into
274 * account settlers that have already been assigned to building
275 * roads this turn. */
276 extra_type_iterate(pextra) {
277 /* We have no use for extra value, if workers cannot be assigned
278 * to build it, so don't use time to calculate values otherwise */
279 if (pextra->buildable
280 && is_extra_caused_by_worker_action(pextra)) {
281 adv_city_worker_extra_set(pcity, cindex, pextra,
282 adv_calc_extra(pcity, ptile, pextra));
283 } else {
284 adv_city_worker_extra_set(pcity, cindex, pextra, 0);
285 }
286 if (tile_has_extra(ptile, pextra)
287 && is_extra_removed_by_worker_action(pextra)) {
288 adv_city_worker_rmextra_set(pcity, cindex, pextra,
289 adv_calc_rmextra(pcity, ptile, pextra));
290 } else {
291 adv_city_worker_rmextra_set(pcity, cindex, pextra, 0);
292 }
293 } extra_type_iterate_end;
294 } city_tile_iterate_index_end;
295 } city_list_iterate_end;
296}
297
298/**********************************************************************/
303 adv_want city_tile_value(const struct city *pcity, const struct tile *ptile,
304 int foodneed, int prodneed)
305{
306 int food = city_tile_output_now(pcity, ptile, O_FOOD);
307 int shield = city_tile_output_now(pcity, ptile, O_SHIELD);
308 int trade = city_tile_output_now(pcity, ptile, O_TRADE);
309 adv_want value = 0;
310
311 /* Each food, trade, and shield gets a certain weighting. We also benefit
312 * tiles that have at least one of an item - this promotes balance and
313 * also accounts for INC_TILE effects. */
314 value += food * FOOD_WEIGHTING;
315 if (food > 0) {
316 value += FOOD_WEIGHTING / 2;
317 }
318 value += shield * SHIELD_WEIGHTING;
319 if (shield > 0) {
320 value += SHIELD_WEIGHTING / 2;
321 }
322 value += trade * TRADE_WEIGHTING;
323 if (trade > 0) {
324 value += TRADE_WEIGHTING / 2;
325 }
326
327 return value;
328}
329
330/**********************************************************************/
334 void adv_city_worker_act_set(struct city *pcity, int city_tile_index,
335 enum unit_activity act_id, adv_want value)
336{
337 if (pcity->server.adv->act_cache_radius_sq
338 != city_map_radius_sq_get(pcity)) {
339 log_debug("update activity cache for %s: radius_sq changed from "
340 "%d to %d", city_name_get(pcity),
341 pcity->server.adv->act_cache_radius_sq,
342 city_map_radius_sq_get(pcity));
343 adv_city_update(pcity);
344 }
345
346 fc_assert_ret(NULL != pcity);
347 fc_assert_ret(NULL != pcity->server.adv);
348 fc_assert_ret(NULL != pcity->server.adv->act_cache);
349 fc_assert_ret(pcity->server.adv->act_cache_radius_sq
350 == city_map_radius_sq_get(pcity));
351 fc_assert_ret(city_tile_index < city_map_tiles_from_city(pcity));
352
353 (pcity->server.adv->act_cache[city_tile_index]).act[act_id] = value;
354}
355
356/**********************************************************************/
360 adv_want adv_city_worker_act_get(const struct city *pcity,
361 int city_tile_index,
362 enum unit_activity act_id)
363{
364 fc_assert_ret_val(NULL != pcity, 0);
365 fc_assert_ret_val(NULL != pcity->server.adv, 0);
366 fc_assert_ret_val(NULL != pcity->server.adv->act_cache, 0);
367 fc_assert_ret_val(pcity->server.adv->act_cache_radius_sq
368 == city_map_radius_sq_get(pcity), 0);
369 fc_assert_ret_val(city_tile_index < city_map_tiles_from_city(pcity), 0);
370
371 return (pcity->server.adv->act_cache[city_tile_index]).act[act_id];
372}
373
374/**********************************************************************/
378 void adv_city_worker_extra_set(struct city *pcity, int city_tile_index,
379 const struct extra_type *pextra, int value)
380{
381 if (pcity->server.adv->act_cache_radius_sq
382 != city_map_radius_sq_get(pcity)) {
383 log_debug("update activity cache for %s: radius_sq changed from "
384 "%d to %d", city_name_get(pcity),
385 pcity->server.adv->act_cache_radius_sq,
386 city_map_radius_sq_get(pcity));
387 adv_city_update(pcity);
388 }
389
390 fc_assert_ret(NULL != pcity);
391 fc_assert_ret(NULL != pcity->server.adv);
392 fc_assert_ret(NULL != pcity->server.adv->act_cache);
393 fc_assert_ret(pcity->server.adv->act_cache_radius_sq
394 == city_map_radius_sq_get(pcity));
395 fc_assert_ret(city_tile_index < city_map_tiles_from_city(pcity));
396
397 (pcity->server.adv->act_cache[city_tile_index]).extra[extra_index(pextra)] = value;
398}
399
400/**********************************************************************/
404 void adv_city_worker_rmextra_set(struct city *pcity, int city_tile_index,
405 const struct extra_type *pextra, int value)
406{
407 if (pcity->server.adv->act_cache_radius_sq
408 != city_map_radius_sq_get(pcity)) {
409 log_debug("update activity cache for %s: radius_sq changed from "
410 "%d to %d", city_name_get(pcity),
411 pcity->server.adv->act_cache_radius_sq,
412 city_map_radius_sq_get(pcity));
413 adv_city_update(pcity);
414 }
415
416 fc_assert_ret(NULL != pcity);
417 fc_assert_ret(NULL != pcity->server.adv);
418 fc_assert_ret(NULL != pcity->server.adv->act_cache);
419 fc_assert_ret(pcity->server.adv->act_cache_radius_sq
420 == city_map_radius_sq_get(pcity));
421 fc_assert_ret(city_tile_index < city_map_tiles_from_city(pcity));
422
423 (pcity->server.adv->act_cache[city_tile_index]).rmextra[extra_index(pextra)] = value;
424}
425
426/**********************************************************************/
430 int adv_city_worker_extra_get(const struct city *pcity, int city_tile_index,
431 const struct extra_type *pextra)
432{
433 fc_assert_ret_val(NULL != pcity, 0);
434 fc_assert_ret_val(NULL != pcity->server.adv, 0);
435 fc_assert_ret_val(NULL != pcity->server.adv->act_cache, 0);
436 fc_assert_ret_val(pcity->server.adv->act_cache_radius_sq
437 == city_map_radius_sq_get(pcity), 0);
438 fc_assert_ret_val(city_tile_index < city_map_tiles_from_city(pcity), 0);
439
440 return (pcity->server.adv->act_cache[city_tile_index]).extra[extra_index(pextra)];
441}
442
443/**********************************************************************/
447 int adv_city_worker_rmextra_get(const struct city *pcity, int city_tile_index,
448 const struct extra_type *pextra)
449{
450 fc_assert_ret_val(NULL != pcity, 0);
451 fc_assert_ret_val(NULL != pcity->server.adv, 0);
452 fc_assert_ret_val(NULL != pcity->server.adv->act_cache, 0);
453 fc_assert_ret_val(pcity->server.adv->act_cache_radius_sq
454 == city_map_radius_sq_get(pcity), 0);
455 fc_assert_ret_val(city_tile_index < city_map_tiles_from_city(pcity), 0);
456
457 return (pcity->server.adv->act_cache[city_tile_index]).rmextra[extra_index(pextra)];
458}
459
460/**********************************************************************/
463 void adv_city_update(struct city *pcity)
464{
465 int radius_sq = city_map_radius_sq_get(pcity);
466
467 fc_assert_ret(NULL != pcity);
468 fc_assert_ret(NULL != pcity->server.adv);
469
470 /* initialize act_cache if needed */
471 if (pcity->server.adv->act_cache == NULL
472 || pcity->server.adv->act_cache_radius_sq == -1
473 || pcity->server.adv->act_cache_radius_sq != radius_sq) {
474 pcity->server.adv->act_cache
475 = fc_realloc(pcity->server.adv->act_cache,
476 city_map_tiles(radius_sq)
477 * sizeof(*(pcity->server.adv->act_cache)));
478 /* initialize with 0 */
479 memset(pcity->server.adv->act_cache, 0,
480 city_map_tiles(radius_sq)
481 * sizeof(*(pcity->server.adv->act_cache)));
482 pcity->server.adv->act_cache_radius_sq = radius_sq;
483 }
484}
485
486/**********************************************************************/
489 void adv_city_alloc(struct city *pcity)
490{
491 pcity->server.adv = fc_calloc(1, sizeof(*pcity->server.adv));
492
493 pcity->server.adv->act_cache = NULL;
494 pcity->server.adv->act_cache_radius_sq = -1;
495 /* Allocate memory for pcity->ai->act_cache */
496 adv_city_update(pcity);
497}
498
499/**********************************************************************/
502 void adv_city_free(struct city *pcity)
503{
504 fc_assert_ret(NULL != pcity);
505
506 if (pcity->server.adv) {
507 if (pcity->server.adv->act_cache) {
508 FC_FREE(pcity->server.adv->act_cache);
509 }
510 FC_FREE(pcity->server.adv);
511 }
512}
action_id_get_activity
#define action_id_get_activity(act_id)
Definition actions.h:456
advbuilding.h
TRADE_WEIGHTING
#define TRADE_WEIGHTING
Definition advbuilding.h:21
FOOD_WEIGHTING
#define FOOD_WEIGHTING
Definition advbuilding.h:19
SHIELD_WEIGHTING
#define SHIELD_WEIGHTING
Definition advbuilding.h:20
autoworkers.h
aw_transform_action_iterate
#define aw_transform_action_iterate(_act_)
Definition autoworkers.h:74
aw_transform_action_iterate_end
#define aw_transform_action_iterate_end
Definition autoworkers.h:78
city_name_get
const char * city_name_get(const struct city *pcity)
Definition city.c:1133
city_tile_output_now
int city_tile_output_now(const struct city *pcity, const struct tile *ptile, Output_type_id otype)
Definition city.c:1380
city_map_radius_sq_get
int city_map_radius_sq_get(const struct city *pcity)
Definition city.c:137
city_map_tiles
int city_map_tiles(int city_radius_sq)
Definition city.c:171
city.h
city_list_iterate
#define city_list_iterate(citylist, pcity)
Definition city.h:508
city_tile
#define city_tile(_pcity_)
Definition city.h:564
city_tile_iterate_index
#define city_tile_iterate_index(_nmap, _radius_sq, _city_tile, _tile, _index)
Definition city.h:201
city_tile_iterate_index_end
#define city_tile_iterate_index_end
Definition city.h:209
city_owner
#define city_owner(_pcity_)
Definition city.h:563
city_list_iterate_end
#define city_list_iterate_end
Definition city.h:510
city_map_iterate_end
#define city_map_iterate_end
Definition city.h:177
city_map_iterate
#define city_map_iterate(_radius_sq, _index, _x, _y)
Definition city.h:173
city_map_tiles_from_city
#define city_map_tiles_from_city(_pcity)
Definition city.h:127
incite_cost
char * incite_cost
Definition comments.c:74
is_extra_removed_by_worker_action
bool is_extra_removed_by_worker_action(const struct extra_type *pextra)
Definition extras.c:1059
is_extra_caused_by_worker_action
bool is_extra_caused_by_worker_action(const struct extra_type *pextra)
Definition extras.c:1046
player_can_build_extra
bool player_can_build_extra(const struct extra_type *pextra, const struct player *pplayer, const struct tile *ptile)
Definition extras.c:468
can_extras_coexist
bool can_extras_coexist(const struct extra_type *pextra1, const struct extra_type *pextra2)
Definition extras.c:1017
player_can_remove_extra
bool player_can_remove_extra(const struct extra_type *pextra, const struct player *pplayer, const struct tile *ptile)
Definition extras.c:595
extra_type_iterate
#define extra_type_iterate(_p)
Definition extras.h:315
extra_type_iterate_end
#define extra_type_iterate_end
Definition extras.h:321
extra_index
#define extra_index(_e_)
Definition extras.h:183
adv_want
float adv_want
Definition fc_types.h:1335
MAX_EXTRA_TYPES
#define MAX_EXTRA_TYPES
Definition fc_types.h:50
O_SHIELD
@ O_SHIELD
Definition fc_types.h:101
O_FOOD
@ O_FOOD
Definition fc_types.h:101
O_TRADE
@ O_TRADE
Definition fc_types.h:101
wld
struct world wld
Definition game.c:62
game.h
adv_calc_transform
static adv_want adv_calc_transform(const struct city *pcity, const struct tile *ptile)
Definition infracache.c:142
adv_city_worker_act_get
adv_want adv_city_worker_act_get(const struct city *pcity, int city_tile_index, enum unit_activity act_id)
Definition infracache.c:360
adv_city_free
void adv_city_free(struct city *pcity)
Definition infracache.c:502
adv_calc_extra
static adv_want adv_calc_extra(const struct city *pcity, const struct tile *ptile, const struct extra_type *pextra)
Definition infracache.c:188
adv_calc_rmextra
static adv_want adv_calc_rmextra(const struct city *pcity, const struct tile *ptile, const struct extra_type *pextra)
Definition infracache.c:223
adv_city_worker_extra_set
void adv_city_worker_extra_set(struct city *pcity, int city_tile_index, const struct extra_type *pextra, int value)
Definition infracache.c:378
adv_city_update
void adv_city_update(struct city *pcity)
Definition infracache.c:463
adv_city_worker_act_set
void adv_city_worker_act_set(struct city *pcity, int city_tile_index, enum unit_activity act_id, adv_want value)
Definition infracache.c:334
adv_city_worker_extra_get
int adv_city_worker_extra_get(const struct city *pcity, int city_tile_index, const struct extra_type *pextra)
Definition infracache.c:430
initialize_infrastructure_cache
void initialize_infrastructure_cache(struct player *pplayer)
Definition infracache.c:250
adv_city_worker_rmextra_set
void adv_city_worker_rmextra_set(struct city *pcity, int city_tile_index, const struct extra_type *pextra, int value)
Definition infracache.c:404
adv_city_worker_rmextra_get
int adv_city_worker_rmextra_get(const struct city *pcity, int city_tile_index, const struct extra_type *pextra)
Definition infracache.c:447
adv_calc_cultivate
static adv_want adv_calc_cultivate(const struct city *pcity, const struct tile *ptile)
Definition infracache.c:62
adv_calc_plant
static adv_want adv_calc_plant(const struct city *pcity, const struct tile *ptile)
Definition infracache.c:102
adv_city_alloc
void adv_city_alloc(struct city *pcity)
Definition infracache.c:489
city_tile_value
adv_want city_tile_value(const struct city *pcity, const struct tile *ptile, int foodneed, int prodneed)
Definition infracache.c:303
infracache.h
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
log_debug
#define log_debug(message,...)
Definition log.h:115
terrain_surroundings_allow_change
bool terrain_surroundings_allow_change(const struct civ_map *nmap, const struct tile *ptile, const struct terrain *pterrain)
Definition map.c:748
map.h
maphand.h
fc_calloc
#define fc_calloc(n, esz)
Definition mem.h:38
FC_FREE
#define FC_FREE(ptr)
Definition mem.h:41
fc_realloc
#define fc_realloc(ptr, sz)
Definition mem.h:36
player.h
adv_city::act_cache_radius_sq
int act_cache_radius_sq
Definition infracache.h:25
adv_city::act_cache
struct worker_activity_cache * act_cache
Definition infracache.h:24
city
Definition city.h:320
city::adv
struct adv_city * adv
Definition city.h:452
city::server
struct city::@17::@19 server
civ_map
Definition map_types.h:71
extra_type
Definition extras.h:88
player
Definition player.h:249
player::cities
struct city_list * cities
Definition player.h:281
terrain
Definition terrain.h:75
tile
Definition tile.h:50
worker_activity_cache
Definition infracache.c:35
worker_activity_cache::extra
adv_want extra[MAX_EXTRA_TYPES]
Definition infracache.c:37
worker_activity_cache::rmextra
adv_want rmextra[MAX_EXTRA_TYPES]
Definition infracache.c:38
worker_activity_cache::act
adv_want act[ACTIVITY_LAST]
Definition infracache.c:36
world::map
struct civ_map map
Definition world_object.h:38
T_NONE
#define T_NONE
Definition terrain.h:61
terrain_has_flag
#define terrain_has_flag(terr, flag)
Definition terrain.h:176
tile_add_extra
void tile_add_extra(struct tile *ptile, const struct extra_type *pextra)
Definition tile.c:955
tile_virtual_destroy
void tile_virtual_destroy(struct tile *vtile)
Definition tile.c:1035
tile_remove_extra
void tile_remove_extra(struct tile *ptile, const struct extra_type *pextra)
Definition tile.c:965
tile_change_terrain
void tile_change_terrain(struct tile *ptile, struct terrain *pterrain)
Definition tile.c:496
tile_virtual_new
struct tile * tile_virtual_new(const struct tile *ptile)
Definition tile.c:981
tile_city
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
tile.h
tile_terrain
#define tile_terrain(_tile)
Definition tile.h:111
tile_has_extra
#define tile_has_extra(ptile, pextra)
Definition tile.h:148