webperimental: killstack decides stack protects.
[freeciv.git] / common / map.h
blobbd295f4287f69c523279278c0263bf24e62a4209
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.
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 #ifndef FC__MAP_H
14 #define FC__MAP_H
16 #ifdef __cplusplus
17 extern "C" {
18 #endif /* __cplusplus */
20 #include <math.h> /* sqrt */
22 /* utility */
23 #include "bitvector.h"
24 #include "iterator.h"
25 #include "log.h" /* fc_assert */
27 /* common */
28 #include "fc_types.h"
29 #include "game.h"
30 #include "map_types.h"
31 #include "tile.h"
32 #include "packets.h"
34 /* Parameters for terrain counting functions. */
35 static const bool C_ADJACENT = FALSE;
36 static const bool C_CARDINAL = TRUE;
37 static const bool C_NUMBER = FALSE;
38 static const bool C_PERCENT = TRUE;
40 #define MAP_IS_ISOMETRIC (CURRENT_TOPOLOGY & (TF_ISO + TF_HEX))
42 #define CURRENT_TOPOLOGY (wld.map.topology_id)
44 #define topo_has_flag(topo, flag) (((topo) & (flag)) != 0)
45 #define current_topo_has_flag(flag) topo_has_flag((CURRENT_TOPOLOGY), (flag))
47 #define ALL_DIRECTIONS_CARDINAL() topo_has_flag((CURRENT_TOPOLOGY), TF_HEX)
49 bool map_is_empty(void);
50 void map_init(struct civ_map *imap, bool server_side);
51 void map_init_topology(void);
52 void map_allocate(struct civ_map *amap);
53 void main_map_allocate(void);
54 void map_free(struct civ_map *fmap);
56 int map_vector_to_real_distance(int dx, int dy);
57 int map_vector_to_sq_distance(int dx, int dy);
58 int map_distance(const struct tile *tile0, const struct tile *tile1);
59 int real_map_distance(const struct tile *tile0, const struct tile *tile1);
60 int sq_map_distance(const struct tile *tile0,const struct tile *tile1);
62 bool same_pos(const struct tile *tile0, const struct tile *tile1);
63 bool base_get_direction_for_step(const struct civ_map *nmap,
64 const struct tile *src_tile,
65 const struct tile *dst_tile,
66 enum direction8 *dir);
67 int get_direction_for_step(const struct civ_map *nmap,
68 const struct tile *src_tile,
69 const struct tile *dst_tile);
72 /* Specific functions for start positions. */
73 struct startpos *map_startpos_by_number(int id);
74 int startpos_number(const struct startpos *psp);
76 bool startpos_allow(struct startpos *psp, struct nation_type *pnation);
77 bool startpos_disallow(struct startpos *psp, struct nation_type *pnation);
79 struct tile *startpos_tile(const struct startpos *psp);
80 bool startpos_nation_allowed(const struct startpos *psp,
81 const struct nation_type *pnation);
82 bool startpos_allows_all(const struct startpos *psp);
84 bool startpos_pack(const struct startpos *psp,
85 struct packet_edit_startpos_full *packet);
86 bool startpos_unpack(struct startpos *psp,
87 const struct packet_edit_startpos_full *packet);
89 /* See comment in "common/map.c". */
90 bool startpos_is_excluding(const struct startpos *psp);
91 const struct nation_hash *startpos_raw_nations(const struct startpos *psp);
93 /****************************************************************************
94 Iterate over all nations at the start position for which the function
95 startpos_nation_allowed() would return TRUE. This automatically takes into
96 account the value of startpos_is_excluding() and startpos_allows_all() to
97 iterate over the correct set of nations.
98 ****************************************************************************/
99 struct startpos_iter;
100 size_t startpos_iter_sizeof(void);
101 struct iterator *startpos_iter_init(struct startpos_iter *it,
102 const struct startpos *psp);
103 #define startpos_nations_iterate(ARG_psp, NAME_pnation) \
104 generic_iterate(struct startpos_iter, const struct nation_type *, \
105 NAME_pnation, startpos_iter_sizeof, \
106 startpos_iter_init, (ARG_psp))
107 #define startpos_nations_iterate_end generic_iterate_end
110 /* General map start positions functions. */
111 int map_startpos_count(void);
112 struct startpos *map_startpos_new(struct tile *ptile);
113 struct startpos *map_startpos_get(const struct tile *ptile);
114 bool map_startpos_remove(struct tile *ptile);
116 /****************************************************************************
117 Iterate over all start positions placed on the map.
118 ****************************************************************************/
119 struct map_startpos_iter;
120 size_t map_startpos_iter_sizeof(void);
121 struct iterator *map_startpos_iter_init(struct map_startpos_iter *iter);
123 #define map_startpos_iterate(NAME_psp) \
124 generic_iterate(struct map_startpos_iter, struct startpos *, \
125 NAME_psp, map_startpos_iter_sizeof, map_startpos_iter_init)
126 #define map_startpos_iterate_end generic_iterate_end
129 /* Number of index coordinates (for sanity checks and allocations) */
130 #define MAP_INDEX_SIZE (wld.map.xsize * wld.map.ysize)
132 #ifdef FREECIV_DEBUG
133 #define CHECK_MAP_POS(x,y) \
134 fc_assert(is_normal_map_pos((x),(y)))
135 #define CHECK_NATIVE_POS(x, y) \
136 fc_assert((x) >= 0 && (x) < wld.map.xsize && (y) >= 0 && (y) < wld.map.ysize)
137 #define CHECK_INDEX(mindex) \
138 fc_assert((mindex) >= 0 && (mindex) < MAP_INDEX_SIZE)
139 #else /* FREECIV_DEBUG */
140 #define CHECK_MAP_POS(x,y) ((void)0)
141 #define CHECK_NATIVE_POS(x, y) ((void)0)
142 #define CHECK_INDEX(mindex) ((void)0)
143 #endif /* FREECIV_DEBUG */
145 #define native_pos_to_index_nocheck(nat_x, nat_y) \
146 ((nat_x) + (nat_y) * wld.map.xsize)
147 #define native_pos_to_index(nat_x, nat_y) \
148 (CHECK_NATIVE_POS((nat_x), (nat_y)), \
149 native_pos_to_index_nocheck(nat_x, nat_y))
150 #define index_to_native_pos(pnat_x, pnat_y, mindex) \
151 (*(pnat_x) = index_to_native_pos_x(mindex), \
152 *(pnat_y) = index_to_native_pos_y(mindex))
153 #define index_to_native_pos_x(mindex) \
154 ((mindex) % wld.map.xsize)
155 #define index_to_native_pos_y(mindex) \
156 ((mindex) / wld.map.xsize)
158 /* Obscure math. See explanation in doc/HACKING. */
159 #define NATIVE_TO_MAP_POS(pmap_x, pmap_y, nat_x, nat_y) \
160 (MAP_IS_ISOMETRIC \
161 ? (*(pmap_x) = ((nat_y) + ((nat_y) & 1)) / 2 + (nat_x), \
162 *(pmap_y) = (nat_y) - *(pmap_x) + wld.map.xsize) \
163 : (*(pmap_x) = (nat_x), *(pmap_y) = (nat_y)))
165 #define MAP_TO_NATIVE_POS(pnat_x, pnat_y, map_x, map_y) \
166 (MAP_IS_ISOMETRIC \
167 ? (*(pnat_y) = (map_x) + (map_y) - wld.map.xsize, \
168 *(pnat_x) = (2 * (map_x) - *(pnat_y) - (*(pnat_y) & 1)) / 2) \
169 : (*(pnat_x) = (map_x), *(pnat_y) = (map_y)))
171 #define NATURAL_TO_MAP_POS(pmap_x, pmap_y, nat_x, nat_y) \
172 (MAP_IS_ISOMETRIC \
173 ? (*(pmap_x) = ((nat_y) + (nat_x)) / 2, \
174 *(pmap_y) = (nat_y) - *(pmap_x) + wld.map.xsize) \
175 : (*(pmap_x) = (nat_x), *(pmap_y) = (nat_y)))
177 #define MAP_TO_NATURAL_POS(pnat_x, pnat_y, map_x, map_y) \
178 (MAP_IS_ISOMETRIC \
179 ? (*(pnat_y) = (map_x) + (map_y) - wld.map.xsize, \
180 *(pnat_x) = 2 * (map_x) - *(pnat_y)) \
181 : (*(pnat_x) = (map_x), *(pnat_y) = (map_y)))
184 /* Provide a block to convert from map to native coordinates. This allows
185 * you to use a native version of the map position within the block. Note
186 * that the native position is declared as const and can't be changed
187 * inside the block. */
188 #define do_in_native_pos(nat_x, nat_y, map_x, map_y) \
190 int _nat_x, _nat_y; \
191 MAP_TO_NATIVE_POS(&_nat_x, &_nat_y, map_x, map_y); \
193 const int nat_x = _nat_x, nat_y = _nat_y;
195 #define do_in_native_pos_end \
199 /* Provide a block to convert from map to natural coordinates. This allows
200 * you to use a natural version of the map position within the block. Note
201 * that the natural position is declared as const and can't be changed
202 * inside the block. */
203 #define do_in_natural_pos(ntl_x, ntl_y, map_x, map_y) \
205 int _ntl_x, _ntl_y; \
206 MAP_TO_NATURAL_POS(&_ntl_x, &_ntl_y, map_x, map_y); \
208 const int ntl_x = _ntl_x, ntl_y = _ntl_y;
210 #define do_in_natural_pos_end \
214 /* Width and height of the map, in native coordinates. */
215 #define NATIVE_WIDTH wld.map.xsize
216 #define NATIVE_HEIGHT wld.map.ysize
218 /* Width and height of the map, in natural coordinates. */
219 #define NATURAL_WIDTH (MAP_IS_ISOMETRIC ? 2 * wld.map.xsize : wld.map.xsize)
220 #define NATURAL_HEIGHT wld.map.ysize
222 static inline int map_pos_to_index(struct civ_map *nmap,
223 int map_x, int map_y);
225 /* index_to_map_pos(int *, int *, int) inverts map_pos_to_index */
226 #define index_to_map_pos(pmap_x, pmap_y, mindex) \
227 (CHECK_INDEX(mindex), \
228 index_to_native_pos(pmap_x, pmap_y, mindex), \
229 NATIVE_TO_MAP_POS(pmap_x, pmap_y, *(pmap_x), *(pmap_y)))
230 static inline int index_to_map_pos_x(int mindex);
231 static inline int index_to_map_pos_y(int mindex);
233 #define DIRSTEP(dest_x, dest_y, dir) \
234 ( (dest_x) = DIR_DX[(dir)], \
235 (dest_y) = DIR_DY[(dir)])
238 * Steps from the tile in the given direction, yielding a new tile (or NULL).
240 * Direct calls to DIR_DXY should be avoided and DIRSTEP should be
241 * used. But to allow dest and src to be the same, as in
242 * MAPSTEP(x, y, x, y, dir)
243 * we bend this rule here.
245 struct tile *mapstep(const struct civ_map *nmap, const struct tile *ptile,
246 enum direction8 dir);
248 struct tile *map_pos_to_tile(const struct civ_map *nmap, int x, int y);
249 struct tile *native_pos_to_tile(const struct civ_map *nmap,
250 int nat_x, int nat_y);
251 struct tile *index_to_tile(const struct civ_map *imap, int mindex);
253 bool is_real_map_pos(const struct civ_map *nmap, int x, int y);
254 bool is_normal_map_pos(int x, int y);
256 bool is_singular_tile(const struct tile *ptile, int dist);
257 bool normalize_map_pos(const struct civ_map *nmap, int *x, int *y);
258 struct tile *nearest_real_tile(const struct civ_map *nmap, int x, int y);
259 void base_map_distance_vector(int *dx, int *dy,
260 int x0, int y0, int x1, int y1);
261 void map_distance_vector(int *dx, int *dy, const struct tile *ptile0,
262 const struct tile *ptile1);
263 int map_num_tiles(void);
264 #define map_size_checked() MAX(map_num_tiles() / 1000, 1)
266 struct tile *rand_neighbour(const struct civ_map *nmap,
267 const struct tile *ptile);
268 struct tile *rand_map_pos(const struct civ_map *nmap);
269 struct tile *rand_map_pos_filtered(const struct civ_map *nmap, void *data,
270 bool (*filter)(const struct tile *ptile,
271 const void *data));
273 bool can_be_irrigated(const struct tile *ptile,
274 const struct unit *punit);
275 bool is_tiles_adjacent(const struct tile *ptile0, const struct tile *ptile1);
276 bool is_move_cardinal(const struct civ_map *nmap,
277 const struct tile *src_tile,
278 const struct tile *dst_tile);
280 int tile_move_cost_ptrs(const struct civ_map *nmap,
281 const struct unit *punit,
282 const struct unit_type *punittype,
283 const struct player *pplayer,
284 const struct tile *t1, const struct tile *t2);
286 /***************************************************************
287 The cost to move punit from where it is to tile x,y.
288 It is assumed the move is a valid one, e.g. the tiles are adjacent.
289 ***************************************************************/
290 static inline int map_move_cost_unit(const struct civ_map *nmap,
291 struct unit *punit,
292 const struct tile *ptile)
294 return tile_move_cost_ptrs(nmap, punit,
295 unit_type_get(punit), unit_owner(punit),
296 unit_tile(punit), ptile);
299 /***************************************************************
300 Move cost between two tiles
301 ***************************************************************/
302 static inline int map_move_cost(const struct civ_map *nmap,
303 const struct player *pplayer,
304 const struct unit_type *punittype,
305 const struct tile *src_tile,
306 const struct tile *dst_tile)
308 return tile_move_cost_ptrs(nmap, NULL, punittype, pplayer,
309 src_tile, dst_tile);
312 bool is_safe_ocean(const struct civ_map *nmap, const struct tile *ptile);
313 bv_extras get_tile_infrastructure_set(const struct tile *ptile,
314 int *count);
316 bool can_channel_land(const struct tile *ptile);
317 bool can_reclaim_ocean(const struct tile *ptile);
318 bool can_thaw_terrain(const struct tile *ptile);
319 bool can_freeze_terrain(const struct tile *ptile);
320 bool terrain_surroundings_allow_change(const struct tile *ptile,
321 const struct terrain *pterrain);
323 extern struct terrain_misc terrain_control;
325 /* This iterates outwards from the starting point. Every tile within max_dist
326 * (including the starting tile) will show up exactly once, in an outward
327 * (based on real map distance) order. The returned values are always real
328 * and are normalized. The starting position must be normal.
330 * See also iterate_outward() */
331 #define iterate_outward_dxy(nmap, start_tile, max_dist, _tile, _x, _y) \
333 int _x, _y, _tile##_x, _tile##_y, _start##_x, _start##_y; \
334 struct tile *_tile; \
335 const struct tile *_tile##_start = (start_tile); \
336 int _tile##_max = (max_dist); \
337 int _tile##_index = 0; \
338 index_to_map_pos(&_start##_x, &_start##_y, tile_index(_tile##_start)); \
339 for (; \
340 _tile##_index < wld.map.num_iterate_outwards_indices; \
341 _tile##_index++) { \
342 if (wld.map.iterate_outwards_indices[_tile##_index].dist > _tile##_max) { \
343 break; \
345 _x = wld.map.iterate_outwards_indices[_tile##_index].dx; \
346 _y = wld.map.iterate_outwards_indices[_tile##_index].dy; \
347 _tile##_x = _x + _start##_x; \
348 _tile##_y = _y + _start##_y; \
349 _tile = map_pos_to_tile(nmap, _tile##_x, _tile##_y); \
350 if (NULL == _tile) { \
351 continue; \
354 #define iterate_outward_dxy_end \
358 /* See iterate_outward_dxy() */
359 #define iterate_outward(nmap, start_tile, max_dist, itr_tile) \
360 iterate_outward_dxy(nmap, start_tile, max_dist, itr_tile, _dx_itr, _dy_itr)
362 #define iterate_outward_end iterate_outward_dxy_end
365 * Iterate through all tiles in a square with given center and radius.
366 * The position (x_itr, y_itr) that is returned will be normalized;
367 * unreal positions will be automatically discarded. (dx_itr, dy_itr)
368 * is the standard distance vector between the position and the center
369 * position. Note that when the square is larger than the map the
370 * distance vector may not be the minimum distance vector.
372 #define square_dxy_iterate(nmap, center_tile, radius, tile_itr, dx_itr, dy_itr) \
373 iterate_outward_dxy(nmap, center_tile, radius, tile_itr, dx_itr, dy_itr)
375 #define square_dxy_iterate_end iterate_outward_dxy_end
378 * Iterate through all tiles in a square with given center and radius.
379 * Positions returned will have adjusted x, and positions with illegal
380 * y will be automatically discarded.
382 #define square_iterate(nmap, center_tile, radius, tile_itr) \
383 square_dxy_iterate(nmap, center_tile, radius, tile_itr, _dummy_x, dummy_y)
385 #define square_iterate_end square_dxy_iterate_end
388 * Iterate through all tiles in a circle with given center and squared
389 * radius. Positions returned will have adjusted (x, y); unreal
390 * positions will be automatically discarded.
392 #define circle_iterate(nmap, center_tile, sq_radius, tile_itr) \
393 circle_dxyr_iterate(nmap, center_tile, sq_radius, tile_itr, _dx, _dy, _dr)
395 #define circle_iterate_end \
396 circle_dxyr_iterate_end
398 /* dx, dy, dr are distance from center to tile in x, y and square distance;
399 * do not rely on x, y distance, since they do not work for hex topologies */
400 #define circle_dxyr_iterate(nmap, center_tile, sq_radius, \
401 _tile, dx, dy, dr) \
403 const int _tile##_sq_radius = (sq_radius); \
404 const int _tile##_cr_radius = (int)sqrt((double)MAX(_tile##_sq_radius, 0)); \
406 square_dxy_iterate(nmap, center_tile, _tile##_cr_radius, _tile, dx, dy) { \
407 const int dr = map_vector_to_sq_distance(dx, dy); \
409 if (dr <= _tile##_sq_radius) {
411 #define circle_dxyr_iterate_end \
413 } square_dxy_iterate_end; \
416 /* Iterate itr_tile through all map tiles adjacent to the given center map
417 * position, with normalization. Does not include the center position.
418 * The order of positions is unspecified. */
419 #define adjc_iterate(nmap, center_tile, itr_tile) \
421 /* Written as a wrapper to adjc_dir_iterate since it's the cleanest and \
422 * most efficient. */ \
423 adjc_dir_iterate(nmap, center_tile, itr_tile, ADJC_ITERATE_dir_itr##itr_tile) {
425 #define adjc_iterate_end \
426 } adjc_dir_iterate_end; \
429 /* As adjc_iterate() but also set direction8 iterator variable dir_itr */
430 #define adjc_dir_iterate(nmap, center_tile, itr_tile, dir_itr) \
431 adjc_dirlist_iterate(nmap, center_tile, itr_tile, dir_itr, \
432 wld.map.valid_dirs, wld.map.num_valid_dirs)
434 #define adjc_dir_iterate_end adjc_dirlist_iterate_end
436 /* Only set direction8 dir_itr (not tile) */
437 #define adjc_dir_base_iterate(nmap, center_tile, dir_itr) \
438 adjc_dirlist_base_iterate(nmap, center_tile, dir_itr, \
439 wld.map.valid_dirs, wld.map.num_valid_dirs)
441 #define adjc_dir_base_iterate_end \
442 adjc_dirlist_base_iterate_end
444 /* Iterate itr_tile through all map tiles cardinally adjacent to the given
445 * center map position, with normalization. Does not include the center
446 * position. The order of positions is unspecified. */
447 #define cardinal_adjc_iterate(nmap, center_tile, itr_tile) \
448 adjc_dirlist_iterate(nmap, center_tile, itr_tile, _dir_itr##center_tile, \
449 wld.map.cardinal_dirs, wld.map.num_cardinal_dirs)
451 #define cardinal_adjc_iterate_end adjc_dirlist_iterate_end
453 /* As cardinal_adjc_iterate but also set direction8 variable dir_itr */
454 #define cardinal_adjc_dir_iterate(nmap, center_tile, itr_tile, dir_itr) \
455 adjc_dirlist_iterate(nmap, center_tile, itr_tile, dir_itr, \
456 wld.map.cardinal_dirs, wld.map.num_cardinal_dirs)
458 #define cardinal_adjc_dir_iterate_end adjc_dirlist_iterate_end
460 /* Only set direction8 dir_itr (not tile) */
461 #define cardinal_adjc_dir_base_iterate(nmap, center_tile, dir_itr) \
462 adjc_dirlist_base_iterate(nmap, center_tile, dir_itr, \
463 wld.map.cardinal_dirs, wld.map.num_cardinal_dirs)
465 #define cardinal_adjc_dir_base_iterate_end \
466 adjc_dirlist_base_iterate_end
468 /* Iterate through all tiles cardinally adjacent to both tile1 and tile2 */
469 #define cardinal_between_iterate(nmap, tile1, tile2, between) \
470 cardinal_adjc_iterate(nmap, tile1, between) { \
471 cardinal_adjc_iterate(nmap, between, second) { \
472 if (same_pos(second, tile2)) {
474 #define cardinal_between_iterate_end \
476 } cardinal_adjc_iterate_end; \
477 } cardinal_adjc_iterate_end;
479 /* Iterate through all tiles adjacent to a tile using the given list of
480 * directions. _dir is the directional value, (center_x, center_y) is
481 * the center tile (which must be normalized). The center tile is not
482 * included in the iteration.
484 * This macro should not be used directly. Instead, use adjc_iterate,
485 * cardinal_adjc_iterate, or related iterators. */
486 #define adjc_dirlist_iterate(nmap, center_tile, _tile, _dir, \
487 dirlist, dircount) \
489 enum direction8 _dir; \
490 int _tile##_x, _tile##_y, _tile##_cx, _tile##_cy; \
491 struct tile *_tile; \
492 const struct tile *_tile##_center = (center_tile); \
493 int _tile##_index = 0; \
494 index_to_map_pos(&_tile##_cx, &_tile##_cy, tile_index(_tile##_center)); \
495 for (; \
496 _tile##_index < (dircount); \
497 _tile##_index++) { \
498 _dir = dirlist[_tile##_index]; \
499 DIRSTEP(_tile##_x, _tile##_y, _dir); \
500 _tile##_x += _tile##_cx; \
501 _tile##_y += _tile##_cy; \
502 _tile = map_pos_to_tile(nmap, _tile##_x, _tile##_y); \
503 if (NULL == _tile) { \
504 continue; \
507 #define adjc_dirlist_iterate_end \
511 /* Same as above but without setting the tile. */
512 #define adjc_dirlist_base_iterate(nmap, center_tile, _dir, dirlist, dircount) \
514 enum direction8 _dir; \
515 int _tile##_x, _tile##_y, _center##_x, _center##_y; \
516 const struct tile *_tile##_center = (center_tile); \
517 bool _tile##_is_border = is_border_tile(_tile##_center, 1); \
518 int _tile##_index = 0; \
519 index_to_map_pos(&_center##_x, &_center##_y, tile_index(_tile##_center)); \
520 for (; \
521 _tile##_index < (dircount); \
522 _tile##_index++) { \
523 _dir = dirlist[_tile##_index]; \
524 DIRSTEP(_tile##_x, _tile##_y, _dir); \
525 _tile##_x += _center##_x; \
526 _tile##_y += _center##_y; \
527 if (_tile##_is_border && !normalize_map_pos(nmap, &_tile##_x, &_tile##_y)) { \
528 continue; \
531 #define adjc_dirlist_base_iterate_end \
535 /* Iterate over all positions on the globe.
536 * Use index positions for cache efficiency. */
537 #define whole_map_iterate(_map, _tile) \
539 struct tile *_tile; \
540 int _tile##_index = 0; \
541 for (; \
542 _tile##_index < MAP_INDEX_SIZE; \
543 _tile##_index++) { \
544 _tile = (_map)->tiles + _tile##_index;
546 #define whole_map_iterate_end \
550 BV_DEFINE(dir_vector, 8);
552 /* return the reverse of the direction */
553 #define DIR_REVERSE(dir) (7 - (dir))
555 enum direction8 dir_cw(enum direction8 dir);
556 enum direction8 dir_ccw(enum direction8 dir);
557 const char* dir_get_name(enum direction8 dir);
558 bool map_untrusted_dir_is_valid(enum direction8 dir);
559 bool is_valid_dir(enum direction8 dir);
560 bool is_cardinal_dir(enum direction8 dir);
562 extern const int DIR_DX[8];
563 extern const int DIR_DY[8];
565 /* Used for network transmission; do not change. */
566 #define MAP_TILE_OWNER_NULL MAX_UINT8
568 #define MAP_DEFAULT_HUTS 15
569 #define MAP_MIN_HUTS 0
570 #define MAP_MAX_HUTS 500
572 #define MAP_DEFAULT_ANIMALS 20
573 #define MAP_MIN_ANIMALS 0
574 #define MAP_MAX_ANIMALS 500
576 #define MAP_DEFAULT_MAPSIZE MAPSIZE_FULLSIZE
578 /* Size of the map in thousands of tiles. If MAP_MAX_SIZE is increased,
579 * MAX_DBV_LENGTH in bitvector.c must be checked; see the static assertion
580 * below. */
581 #ifdef FREECIV_WEB
582 #define MAP_DEFAULT_SIZE 3
583 #define MAP_MIN_SIZE 0
584 #define MAP_MAX_SIZE 18
585 #else /* FREECIV_WEB */
586 #define MAP_DEFAULT_SIZE 4
587 #define MAP_MIN_SIZE 0
588 #define MAP_MAX_SIZE 2048
589 #endif /* FREECIV_WEB */
591 FC_STATIC_ASSERT(MAP_MAX_SIZE * 1000 <= MAX_DBV_LENGTH,
592 map_too_big_for_bitvector);
593 /* We communicate through the network with signed 32-bits integers. */
594 FC_STATIC_ASSERT((long unsigned) MAP_MAX_SIZE * 1000
595 < (long unsigned) 1 << 31,
596 map_too_big_for_network);
598 #define MAP_DEFAULT_TILESPERPLAYER 100
599 #define MAP_MIN_TILESPERPLAYER 1
600 #define MAP_MAX_TILESPERPLAYER 1000
602 /* This defines the maximum linear size in _native_ coordinates. */
603 #define MAP_DEFAULT_LINEAR_SIZE 64
604 #define MAP_MAX_LINEAR_SIZE (MAP_MAX_SIZE * 1000 / MAP_MIN_LINEAR_SIZE)
605 #define MAP_MIN_LINEAR_SIZE 16
607 /* The distance between two points at a map shouldn't be larger than this.
608 Adds MAP_MIN_LINEAR_SIZE because hex topologies forbids certain diagonal
609 moves. Includes MAP_MAX_LINEAR_SIZE because a map can be non wrapping. */
610 #define MAP_DISTANCE_MAX (MAP_MAX_LINEAR_SIZE + MAP_MIN_LINEAR_SIZE)
612 #define MAP_ORIGINAL_TOPO TF_WRAPX
613 #ifdef FREECIV_WEB
614 /* Freeciv-web doesn't support isometric maps yet. */
615 #define MAP_DEFAULT_TOPO TF_WRAPX
616 #else /* FREECIV_WEB */
617 #define MAP_DEFAULT_TOPO (TF_WRAPX|TF_ISO|TF_HEX)
618 #endif /* FREECIV_WEB */
620 #define MAP_DEFAULT_SEED 0
621 #define MAP_MIN_SEED 0
622 #define MAP_MAX_SEED (MAX_UINT32 >> 1)
624 #define MAP_DEFAULT_LANDMASS 30
625 #define MAP_MIN_LANDMASS 15
626 #define MAP_MAX_LANDMASS 85
628 #define MAP_DEFAULT_RICHES 250
629 #define MAP_MIN_RICHES 0
630 #define MAP_MAX_RICHES 1000
632 #define MAP_DEFAULT_STEEPNESS 30
633 #define MAP_MIN_STEEPNESS 0
634 #define MAP_MAX_STEEPNESS 100
636 #define MAP_DEFAULT_WETNESS 50
637 #define MAP_MIN_WETNESS 0
638 #define MAP_MAX_WETNESS 100
640 #define MAP_DEFAULT_GENERATOR MAPGEN_RANDOM
642 #define MAP_DEFAULT_STARTPOS MAPSTARTPOS_DEFAULT
644 #define MAP_DEFAULT_TINYISLES FALSE
645 #define MAP_MIN_TINYISLES FALSE
646 #define MAP_MAX_TINYISLES TRUE
648 #define MAP_DEFAULT_SEPARATE_POLES TRUE
649 #define MAP_MIN_SEPARATE_POLES FALSE
650 #define MAP_MAX_SEPARATE_POLES TRUE
652 #define MAP_DEFAULT_FLATPOLES 100
653 #define MAP_MIN_FLATPOLES 0
654 #define MAP_MAX_FLATPOLES 100
656 #define MAP_DEFAULT_SINGLE_POLE FALSE
657 #define MAP_MIN_SINGLE_POLE FALSE
658 #define MAP_MAX_SINGLE_POLE TRUE
660 #define MAP_DEFAULT_ALLTEMPERATE FALSE
661 #define MAP_MIN_ALLTEMPERATE FALSE
662 #define MAP_MAX_ALLTEMPERATE TRUE
664 #define MAP_DEFAULT_TEMPERATURE 50
665 #define MAP_MIN_TEMPERATURE 0
666 #define MAP_MAX_TEMPERATURE 100
668 #define MAP_DEFAULT_TEAM_PLACEMENT TEAM_PLACEMENT_CLOSEST
671 * Inline function definitions. These are at the bottom because they may use
672 * elements defined above.
675 static inline int map_pos_to_index(struct civ_map *nmap, int map_x, int map_y)
677 /* Note: writing this as a macro is hard; it needs temp variables. */
678 int nat_x, nat_y;
680 CHECK_MAP_POS(map_x, map_y);
681 MAP_TO_NATIVE_POS(&nat_x, &nat_y, map_x, map_y);
682 return native_pos_to_index(nat_x, nat_y);
685 static inline int index_to_map_pos_x(int mindex)
687 /* Note: writing this as a macro is hard; it needs temp variables. */
688 int map_x, map_y;
690 index_to_map_pos(&map_x, &map_y, mindex);
691 return map_x;
694 static inline int index_to_map_pos_y(int mindex)
696 /* Note: writing this as a macro is hard; it needs temp variables. */
697 int map_x, map_y;
699 index_to_map_pos(&map_x, &map_y, mindex);
700 return map_y;
703 /****************************************************************************
704 A "border position" is any map position that _may have_ positions within
705 real map distance dist that are non-normal. To see its correctness,
706 consider the case where dist is 1 or 0.
707 ****************************************************************************/
708 static inline bool is_border_tile(const struct tile *ptile, int dist)
710 /* HACK: An iso-map compresses the value in the X direction but not in
711 * the Y direction. Hence (x+1,y) is 1 tile away while (x,y+2) is also
712 * one tile away. */
713 int xdist = dist;
714 int ydist = (MAP_IS_ISOMETRIC ? (2 * dist) : dist);
715 int nat_x, nat_y;
717 index_to_native_pos(&nat_x, &nat_y, tile_index(ptile));
719 return (nat_x < xdist
720 || nat_y < ydist
721 || nat_x >= wld.map.xsize - xdist
722 || nat_y >= wld.map.ysize - ydist);
725 enum direction8 rand_direction(void);
726 enum direction8 opposite_direction(enum direction8 dir);
728 #ifdef __cplusplus
730 #endif /* __cplusplus */
732 #endif /* FC__MAP_H */