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