Freeciv-3.3
Loading...
Searching...
No Matches
map.h
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#ifndef FC__MAP_H
14#define FC__MAP_H
15
16#ifdef __cplusplus
17extern "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 "packets.h"
32#include "world_object.h"
33
34struct tile;
35
36/* Parameters for terrain counting functions. */
37static const bool C_ADJACENT = FALSE;
38static const bool C_CARDINAL = TRUE;
39static const bool C_NUMBER = FALSE;
40static const bool C_PERCENT = TRUE;
41
42#define topo_has_flag(topo, flag) (((topo) & (flag)) != 0)
43#define current_topo_has_flag(flag) topo_has_flag((CURRENT_TOPOLOGY), (flag))
44
45#define wrap_has_flag(wrap, flag) (((wrap) & (flag)) != 0)
46#define current_wrap_has_flag(flag) wrap_has_flag((CURRENT_WRAP), (flag))
47
48#define ALL_DIRECTIONS_CARDINAL() topo_has_flag((CURRENT_TOPOLOGY), TF_HEX)
49
50bool map_is_empty(void);
51void map_init(struct civ_map *imap, bool server_side);
52void map_init_topology(struct civ_map *nmap);
53void map_allocate(struct civ_map *amap);
54void main_map_allocate(void);
55void map_free(struct civ_map *fmap, bool server_side);
56void main_map_free(void);
57
58int map_vector_to_real_distance(int dx, int dy);
59int map_vector_to_sq_distance(int dx, int dy);
60int map_distance(const struct tile *tile0, const struct tile *tile1);
61int real_map_distance(const struct tile *tile0, const struct tile *tile1);
62int sq_map_distance(const struct tile *tile0,const struct tile *tile1);
63
64bool same_pos(const struct tile *tile0, const struct tile *tile1);
66 const struct tile *src_tile,
67 const struct tile *dst_tile,
68 enum direction8 *dir);
69int get_direction_for_step(const struct civ_map *nmap,
70 const struct tile *src_tile,
71 const struct tile *dst_tile);
72
77
78#define is_whole_continent_known(cont) \
79 (is_server() || wld.map.client.adj_matrix[cont][0] == 0)
80
81/* Use positive ocean ID */
82#define is_whole_ocean_known(ocean) \
83 (is_server() || wld.map.client.adj_matrix[0][ocean] == 0)
84
85/* Specific functions for start positions. */
86struct startpos *map_startpos_by_number(int id);
87int startpos_number(const struct startpos *psp);
88
89bool startpos_allow(struct startpos *psp, struct nation_type *pnation);
90bool startpos_disallow(struct startpos *psp, struct nation_type *pnation);
91
92struct tile *startpos_tile(const struct startpos *psp);
93bool startpos_nation_allowed(const struct startpos *psp,
94 const struct nation_type *pnation);
95bool startpos_allows_all(const struct startpos *psp);
96
97bool startpos_pack(const struct startpos *psp,
98 struct packet_edit_startpos_full *packet);
99bool startpos_unpack(struct startpos *psp,
100 const struct packet_edit_startpos_full *packet);
101
102/* See comment in "common/map.c". */
103bool startpos_is_excluding(const struct startpos *psp);
104const struct nation_hash *startpos_raw_nations(const struct startpos *psp);
105
106/****************************************************************************
107 Iterate over all nations at the start position for which the function
108 startpos_nation_allowed() would return TRUE. This automatically takes into
109 account the value of startpos_is_excluding() and startpos_allows_all() to
110 iterate over the correct set of nations.
111****************************************************************************/
112struct startpos_iter;
113size_t startpos_iter_sizeof(void);
114struct iterator *startpos_iter_init(struct startpos_iter *it,
115 const struct startpos *psp);
116#define startpos_nations_iterate(ARG_psp, NAME_pnation) \
117 generic_iterate(struct startpos_iter, const struct nation_type *, \
118 NAME_pnation, startpos_iter_sizeof, \
119 startpos_iter_init, (ARG_psp))
120#define startpos_nations_iterate_end generic_iterate_end
121
122
123/* General map start positions functions. */
124int map_startpos_count(void);
125struct startpos *map_startpos_new(struct tile *ptile);
126struct startpos *map_startpos_get(const struct tile *ptile);
127bool map_startpos_remove(struct tile *ptile);
128
129/****************************************************************************
130 Iterate over all start positions placed on the map.
131****************************************************************************/
132struct map_startpos_iter;
133size_t map_startpos_iter_sizeof(void);
135
136#define map_startpos_iterate(NAME_psp) \
137 generic_iterate(struct map_startpos_iter, struct startpos *, \
138 NAME_psp, map_startpos_iter_sizeof, map_startpos_iter_init)
139#define map_startpos_iterate_end generic_iterate_end
140
141
142#ifdef FREECIV_DEBUG
143#define CHECK_MAP_POS(x,y) \
144 fc_assert(is_normal_map_pos((x),(y)))
145#define CHECK_NATIVE_POS(x, y) \
146 fc_assert((x) >= 0 && (x) < MAP_NATIVE_WIDTH && \
147 (y) >= 0 && (y) < MAP_NATIVE_HEIGHT)
148#define CHECK_INDEX(mindex) \
149 fc_assert((mindex) >= 0 && (mindex) < MAP_INDEX_SIZE)
150#else /* FREECIV_DEBUG */
151#define CHECK_MAP_POS(x,y) ((void)0)
152#define CHECK_NATIVE_POS(x, y) ((void)0)
153#define CHECK_INDEX(mindex) ((void)0)
154#endif /* FREECIV_DEBUG */
155
156#define native_pos_to_index_nocheck(nat_x, nat_y) \
157 ((nat_x) + (nat_y) * MAP_NATIVE_WIDTH)
158#define native_pos_to_index(nat_x, nat_y) \
159 (CHECK_NATIVE_POS((nat_x), (nat_y)), \
160 native_pos_to_index_nocheck(nat_x, nat_y))
161#define index_to_native_pos(pnat_x, pnat_y, mindex) \
162 (*(pnat_x) = index_to_native_pos_x(mindex), \
163 *(pnat_y) = index_to_native_pos_y(mindex))
164#define index_to_native_pos_x(mindex) \
165 ((mindex) % MAP_NATIVE_WIDTH)
166#define index_to_native_pos_y(mindex) \
167 ((mindex) / MAP_NATIVE_WIDTH)
168
169/* Obscure math. See explanation in doc/HACKING. */
170#define NATIVE_TO_MAP_POS(pmap_x, pmap_y, nat_x, nat_y) \
171 (MAP_IS_ISOMETRIC \
172 ? (*(pmap_x) = ((nat_y) + ((nat_y) & 1)) / 2 + (nat_x), \
173 *(pmap_y) = (nat_y) - *(pmap_x) + MAP_NATIVE_WIDTH) \
174 : (*(pmap_x) = (nat_x), *(pmap_y) = (nat_y)))
175
176#define MAP_TO_NATIVE_POS(pnat_x, pnat_y, map_x, map_y) \
177 (MAP_IS_ISOMETRIC \
178 ? (*(pnat_y) = (map_x) + (map_y) - MAP_NATIVE_WIDTH, \
179 *(pnat_x) = (2 * (map_x) - *(pnat_y) - (*(pnat_y) & 1)) / 2) \
180 : (*(pnat_x) = (map_x), *(pnat_y) = (map_y)))
181
182#define NATURAL_TO_MAP_POS(pmap_x, pmap_y, nat_x, nat_y) \
183 (MAP_IS_ISOMETRIC \
184 ? (*(pmap_x) = ((nat_y) + (nat_x)) / 2, \
185 *(pmap_y) = (nat_y) - *(pmap_x) + MAP_NATIVE_WIDTH) \
186 : (*(pmap_x) = (nat_x), *(pmap_y) = (nat_y)))
187
188#define MAP_TO_NATURAL_POS(pnat_x, pnat_y, map_x, map_y) \
189 (MAP_IS_ISOMETRIC \
190 ? (*(pnat_y) = (map_x) + (map_y) - MAP_NATIVE_WIDTH, \
191 *(pnat_x) = 2 * (map_x) - *(pnat_y)) \
192 : (*(pnat_x) = (map_x), *(pnat_y) = (map_y)))
193
194
195/* Provide a block to convert from map to native coordinates. This allows
196 * you to use a native version of the map position within the block.
197 * Note that the native position is declared as const and can't be changed
198 * inside the block. */
199#define do_in_native_pos(nat_x, nat_y, map_x, map_y) \
200{ \
201 int _nat_x, _nat_y; \
202 MAP_TO_NATIVE_POS(&_nat_x, &_nat_y, map_x, map_y); \
203 { \
204 const int nat_x = _nat_x, nat_y = _nat_y;
205
206#define do_in_native_pos_end \
207 } \
208}
209
210/* Provide a block to convert from map to natural coordinates. This allows
211 * you to use a natural version of the map position within the block.
212 * Note that the natural position is declared as const and can't be changed
213 * inside the block. */
214#define do_in_natural_pos(ntl_x, ntl_y, map_x, map_y) \
215{ \
216 int _ntl_x, _ntl_y; \
217 MAP_TO_NATURAL_POS(&_ntl_x, &_ntl_y, map_x, map_y); \
218 { \
219 const int ntl_x = _ntl_x, ntl_y = _ntl_y;
220
221#define do_in_natural_pos_end \
222 } \
223}
224
225static inline int map_pos_to_index(struct civ_map *nmap,
226 int map_x, int map_y);
227
228/* index_to_map_pos(int *, int *, int) inverts map_pos_to_index */
229#define index_to_map_pos(pmap_x, pmap_y, mindex) \
230 (CHECK_INDEX(mindex), \
231 index_to_native_pos(pmap_x, pmap_y, mindex), \
232 NATIVE_TO_MAP_POS(pmap_x, pmap_y, *(pmap_x), *(pmap_y)))
233static inline int index_to_map_pos_x(int mindex);
234static inline int index_to_map_pos_y(int mindex);
235
236#define DIRSTEP(dest_x, dest_y, dir) \
237( (dest_x) = DIR_DX[(dir)], \
238 (dest_y) = DIR_DY[(dir)])
239
240/*
241 * Steps from the tile in the given direction, yielding a new tile
242 * (or nullptr).
243 *
244 * Direct calls to DIR_DXY should be avoided and DIRSTEP should be
245 * used. But to allow dest and src to be the same, as in
246 * MAPSTEP(x, y, x, y, dir)
247 * we bend this rule here.
248 */
249struct tile *mapstep(const struct civ_map *nmap, const struct tile *ptile,
250 enum direction8 dir);
251
252struct tile *map_pos_to_tile(const struct civ_map *nmap, int x, int y);
253struct tile *native_pos_to_tile(const struct civ_map *nmap,
254 int nat_x, int nat_y);
255struct tile *index_to_tile(const struct civ_map *imap, int mindex);
256
257bool is_real_map_pos(const struct civ_map *nmap, int x, int y);
258bool is_normal_map_pos(int x, int y);
259
260bool is_singular_tile(const struct tile *ptile, int dist);
261bool normalize_map_pos(const struct civ_map *nmap, int *x, int *y);
262struct tile *nearest_real_tile(const struct civ_map *nmap, int x, int y);
263void base_map_distance_vector(int *dx, int *dy,
264 int x0, int y0, int x1, int y1);
265void map_distance_vector(int *dx, int *dy, const struct tile *ptile0,
266 const struct tile *ptile1);
267int map_num_tiles(void);
268#define map_size_checked() MAX(map_num_tiles() / 1000, 1)
269
270struct tile *rand_map_pos(const struct civ_map *nmap);
271struct tile *rand_map_pos_filtered(const struct civ_map *nmap, void *data,
272 bool (*filter)(const struct tile *ptile,
273 const void *data));
274
275bool is_tiles_adjacent(const struct tile *ptile0, const struct tile *ptile1);
276bool is_move_cardinal(const struct civ_map *nmap,
277 const struct tile *src_tile,
278 const struct tile *dst_tile);
279
280int 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);
285
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***************************************************************/
290static inline int map_move_cost_unit(const struct civ_map *nmap,
291 struct unit *punit,
292 const struct tile *ptile)
293{
296 unit_tile(punit), ptile);
297}
298
299/***************************************************************
300 Move cost between two tiles
301***************************************************************/
302static 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)
307{
308 return tile_move_cost_ptrs(nmap, nullptr, punittype, pplayer,
309 src_tile, dst_tile);
310}
311
312bool is_safe_ocean(const struct civ_map *nmap, const struct tile *ptile);
313bv_extras get_tile_infrastructure_set(const struct tile *ptile,
314 int *count);
315
316bool can_channel_land(const struct civ_map *nmap,
317 const struct tile *ptile);
318bool can_reclaim_ocean(const struct civ_map *nmap,
319 const struct tile *ptile);
320bool can_thaw_terrain(const struct civ_map *nmap,
321 const struct tile *ptile);
322bool can_freeze_terrain(const struct civ_map *nmap,
323 const struct tile *ptile);
325 const struct tile *ptile,
326 const struct terrain *pterrain);
327
328extern struct terrain_misc terrain_control;
329
330/* This iterates outwards from the starting point. Every tile within max_dist
331 * (including the starting tile) will show up exactly once, in an outward
332 * (based on real map distance) order. The returned values are always real
333 * and are normalized. The starting position must be normal.
334 *
335 * See also iterate_outward() */
336#define iterate_outward_dxy(nmap, start_tile, max_dist, _tile, _x, _y) \
337{ \
338 int _x, _y, _tile##_x, _tile##_y, _start##_x, _start##_y; \
339 struct tile *_tile; \
340 const struct tile *_tile##_start = (start_tile); \
341 int _tile##_max = (max_dist); \
342 int _tile##_index = 0; \
343 index_to_map_pos(&_start##_x, &_start##_y, tile_index(_tile##_start)); \
344 for (; \
345 _tile##_index < MAP_NUM_ITERATE_OUTWARDS_INDICES; \
346 _tile##_index++) { \
347 if (MAP_ITERATE_OUTWARDS_INDICES[_tile##_index].dist > _tile##_max) { \
348 break; \
349 } \
350 _x = MAP_ITERATE_OUTWARDS_INDICES[_tile##_index].dx; \
351 _y = MAP_ITERATE_OUTWARDS_INDICES[_tile##_index].dy; \
352 _tile##_x = _x + _start##_x; \
353 _tile##_y = _y + _start##_y; \
354 _tile = map_pos_to_tile(nmap, _tile##_x, _tile##_y); \
355 if (_tile == nullptr) { \
356 continue; \
357 }
358
359#define iterate_outward_dxy_end \
360 } \
361}
362
363/* See iterate_outward_dxy() */
364#define iterate_outward(nmap, start_tile, max_dist, itr_tile) \
365 iterate_outward_dxy(nmap, start_tile, max_dist, itr_tile, \
366 _dx_itr##itr_tile, _dy_itr##itr_tile)
367
368#define iterate_outward_end iterate_outward_dxy_end
369
370/*
371 * Iterate through all tiles in a square with given center and radius.
372 * The position (x_itr, y_itr) that is returned will be normalized;
373 * unreal positions will be automatically discarded. (dx_itr, dy_itr)
374 * is the standard distance vector between the position and the center
375 * position. Note that when the square is larger than the map the
376 * distance vector may not be the minimum distance vector.
377 */
378#define square_dxy_iterate(nmap, center_tile, radius, tile_itr, dx_itr, dy_itr) \
379 iterate_outward_dxy(nmap, center_tile, radius, tile_itr, dx_itr, dy_itr)
380
381#define square_dxy_iterate_end iterate_outward_dxy_end
382
383/*
384 * Iterate through all tiles in a square with given center and radius.
385 * Positions returned will have adjusted x, and positions with illegal
386 * y will be automatically discarded.
387 */
388#define square_iterate(nmap, center_tile, radius, tile_itr) \
389 square_dxy_iterate(nmap, center_tile, radius, tile_itr, _dummy_x, dummy_y)
390
391#define square_iterate_end square_dxy_iterate_end
392
393/*
394 * Iterate through all tiles in a circle with given center and squared
395 * radius. Positions returned will have adjusted (x, y); unreal
396 * positions will be automatically discarded.
397 */
398#define circle_iterate(nmap, center_tile, sq_radius, tile_itr) \
399 circle_dxyr_iterate(nmap, center_tile, sq_radius, tile_itr, _dx, _dy, _dr)
400
401#define circle_iterate_end \
402 circle_dxyr_iterate_end
403
404/* dx, dy, dr are distance from center to tile in x, y and square distance;
405 * do not rely on x, y distance, since they do not work for hex topologies. */
406#define circle_dxyr_iterate(nmap, center_tile, sq_radius, \
407 _tile, dx, dy, dr) \
408{ \
409 const int _tile##_sq_radius = (sq_radius); \
410 const int _tile##_cr_radius = (int)sqrt((double)MAX(_tile##_sq_radius, 0)); \
411 \
412 square_dxy_iterate(nmap, center_tile, _tile##_cr_radius, _tile, dx, dy) { \
413 const int dr = map_vector_to_sq_distance(dx, dy); \
414 \
415 if (dr <= _tile##_sq_radius) {
416
417#define circle_dxyr_iterate_end \
418 } \
419 } square_dxy_iterate_end; \
420}
421
422/* Iterate itr_tile through all map tiles adjacent to the given center map
423 * position, with normalization. Does not include the center position.
424 * The order of positions is unspecified. */
425#define adjc_iterate(nmap, center_tile, itr_tile) \
426{ \
427 /* Written as a wrapper to adjc_dir_iterate since it's the cleanest and \
428 * most efficient. */ \
429 adjc_dir_iterate(nmap, center_tile, itr_tile, ADJC_ITERATE_dir_itr##itr_tile) {
431#define adjc_iterate_end \
432 } adjc_dir_iterate_end; \
433}
434
435/* As adjc_iterate() but also set direction8 iterator variable dir_itr */
436#define adjc_dir_iterate(nmap, center_tile, itr_tile, dir_itr) \
437 adjc_dirlist_iterate(nmap, center_tile, itr_tile, dir_itr, \
438 (nmap)->valid_dirs, (nmap)->num_valid_dirs)
440#define adjc_dir_iterate_end adjc_dirlist_iterate_end
441
442/* Only set direction8 dir_itr (not tile) */
443#define adjc_dir_base_iterate(nmap, center_tile, dir_itr) \
444 adjc_dirlist_base_iterate(nmap, center_tile, dir_itr, \
445 (nmap)->valid_dirs, (nmap)->num_valid_dirs)
447#define adjc_dir_base_iterate_end \
448 adjc_dirlist_base_iterate_end
449
450/* Iterate itr_tile through all map tiles cardinally adjacent to the given
451 * center map position, with normalization. Does not include the center
452 * position. The order of positions is unspecified. */
453#define cardinal_adjc_iterate(nmap, center_tile, itr_tile) \
454 adjc_dirlist_iterate(nmap, center_tile, itr_tile, _dir_itr##itr_tile, \
455 (nmap)->cardinal_dirs, (nmap)->num_cardinal_dirs)
457#define cardinal_adjc_iterate_end adjc_dirlist_iterate_end
458
459/* As cardinal_adjc_iterate but also set direction8 variable dir_itr */
460#define cardinal_adjc_dir_iterate(nmap, center_tile, itr_tile, dir_itr) \
461 adjc_dirlist_iterate(nmap, center_tile, itr_tile, dir_itr, \
462 (nmap)->cardinal_dirs, (nmap)->num_cardinal_dirs)
464#define cardinal_adjc_dir_iterate_end adjc_dirlist_iterate_end
465
466/* Only set direction8 dir_itr (not tile) */
467#define cardinal_adjc_dir_base_iterate(nmap, center_tile, dir_itr) \
468 adjc_dirlist_base_iterate(nmap, center_tile, dir_itr, \
469 (nmap)->cardinal_dirs, (nmap)->num_cardinal_dirs)
471#define cardinal_adjc_dir_base_iterate_end \
472 adjc_dirlist_base_iterate_end
473
474/* Iterate through all tiles cardinally adjacent to both tile1 and tile2 */
475#define cardinal_between_iterate(nmap, tile1, tile2, between) \
476 cardinal_adjc_iterate(nmap, tile1, between) { \
477 cardinal_adjc_iterate(nmap, between, second) { \
478 if (same_pos(second, tile2)) {
480#define cardinal_between_iterate_end \
481 } \
482 } cardinal_adjc_iterate_end; \
483 } cardinal_adjc_iterate_end;
484
485/* Helper for range_adjc_*_iterate */
486#define _RANGE_DIRLIST(_range, _nmap) \
487 ((_range) == REQ_RANGE_ADJACENT ? (_nmap)->valid_dirs \
488 : (_range) == REQ_RANGE_CADJACENT ? (_nmap)->cardinal_dirs \
489 : nullptr)
491#define _RANGE_DIRCOUNT(_range, _nmap) \
492 ((_range) == REQ_RANGE_ADJACENT ? (_nmap)->num_valid_dirs \
493 : (_range) == REQ_RANGE_CADJACENT ? (_nmap)->num_cardinal_dirs \
494 : 0)
495
496/* Iterate through either adjacent or cardinally adjacent tiles (or none)
497 * depending on the given requirement range. The range must not change
498 * during iteration. */
499#define range_adjc_iterate(nmap, center_tile, range, itr_tile) \
500 range_adjc_dir_iterate(nmap, center_tile, range, itr_tile, _dir_itr##itr_tile)
502#define range_adjc_iterate_end range_adjc_dir_iterate_end
504#define range_adjc_dir_iterate(nmap, center_tile, range, itr_tile, dir_itr) \
505 adjc_dirlist_iterate(nmap, center_tile, itr_tile, dir_itr, \
506 _RANGE_DIRLIST(range, nmap), _RANGE_DIRCOUNT(range, nmap))
508#define range_adjc_dir_iterate_end adjc_dirlist_iterate_end
510#define range_adjc_dir_base_iterate(nmap, center_tile, range, dir_itr) \
511 adjc_dirlist_base_iterate(nmap, center_tile, dir_itr, \
512 _RANGE_DIRLIST(range, nmap), _RANGE_DIRCOUNT(range, nmap))
514#define range_adjc_dir_base_iterate_end adjc_dirlist_base_iterate_end
515
516/* Iterate through all tiles adjacent to a tile using the given list of
517 * directions. _dir is the directional value, (center_x, center_y) is
518 * the center tile (which must be normalized). The center tile is not
519 * included in the iteration.
520 *
521 * This macro should not be used directly. Instead, use adjc_iterate,
522 * cardinal_adjc_iterate, range_adjc_iterate, or related iterators. */
523#define adjc_dirlist_iterate(nmap, center_tile, _tile, _dir, \
524 dirlist, dircount) \
525{ \
526 enum direction8 _dir; \
527 int _tile##_x, _tile##_y, _tile##_cx, _tile##_cy; \
528 struct tile *_tile; \
529 const struct tile *_tile##_center = (center_tile); \
530 int _tile##_index = 0; \
531 index_to_map_pos(&_tile##_cx, &_tile##_cy, tile_index(_tile##_center)); \
532 for (; \
533 _tile##_index < (dircount); \
534 _tile##_index++) { \
535 _dir = (dirlist)[_tile##_index]; \
536 DIRSTEP(_tile##_x, _tile##_y, _dir); \
537 _tile##_x += _tile##_cx; \
538 _tile##_y += _tile##_cy; \
539 _tile = map_pos_to_tile(nmap, _tile##_x, _tile##_y); \
540 if (_tile == nullptr) { \
541 continue; \
542 }
544#define adjc_dirlist_iterate_end \
545 } \
546}
547
548/* Same as above but without setting the tile. */
549#define adjc_dirlist_base_iterate(nmap, center_tile, _dir, dirlist, dircount) \
550{ \
551 enum direction8 _dir; \
552 int _tile##_x, _tile##_y, _center##_x, _center##_y; \
553 const struct tile *_tile##_center = (center_tile); \
554 bool _tile##_is_border = is_border_tile(_tile##_center, 1); \
555 int _tile##_index = 0; \
556 index_to_map_pos(&_center##_x, &_center##_y, tile_index(_tile##_center)); \
557 for (; \
558 _tile##_index < (dircount); \
559 _tile##_index++) { \
560 _dir = (dirlist)[_tile##_index]; \
561 DIRSTEP(_tile##_x, _tile##_y, _dir); \
562 _tile##_x += _center##_x; \
563 _tile##_y += _center##_y; \
564 if (_tile##_is_border && !normalize_map_pos(nmap, &_tile##_x, &_tile##_y)) { \
565 continue; \
566 }
568#define adjc_dirlist_base_iterate_end \
569 } \
570}
571
572/* Iterate over all positions on the globe.
573 * Use index positions for cache efficiency. */
574#define whole_map_iterate(_map, _tile) \
575{ \
576 struct tile *_tile; \
577 int _tile##_index = 0; \
578 for (; \
579 _tile##_index < MAP_INDEX_SIZE; \
580 _tile##_index++) { \
581 _tile = (_map)->tiles + _tile##_index;
583#define whole_map_iterate_end \
584 } \
585}
588
589/* Return the reverse of the direction */
590#define DIR_REVERSE(dir) (7 - (dir))
591
592enum direction8 dir_cw(enum direction8 dir);
593enum direction8 dir_ccw(enum direction8 dir);
594const char *dir_get_name(enum direction8 dir);
596bool is_valid_dir(enum direction8 dir);
597bool is_cardinal_dir(enum direction8 dir);
598
599extern const int DIR_DX[8];
600extern const int DIR_DY[8];
601
602/* Latitude granularity, irrespective of map/generator settings */
603#define MAP_MAX_LATITUDE 1000
605#define MAP_MAX_LATITUDE_BOUND (MAP_MAX_LATITUDE)
606#define MAP_MIN_LATITUDE_BOUND (-MAP_MAX_LATITUDE)
607#define MAP_DEFAULT_NORTH_LATITUDE MAP_MAX_LATITUDE_BOUND
608#define MAP_DEFAULT_SOUTH_LATITUDE MAP_MIN_LATITUDE_BOUND
609
610/* Northernmost and southernmost latitude for the given map */
611#define MAP_NORTH_LATITUDE(_nmap) ((_nmap).north_latitude)
612#define MAP_SOUTH_LATITUDE(_nmap) ((_nmap).south_latitude)
613
614/* Maximum and minimum latitude present in the given map */
615#define MAP_MAX_REAL_LATITUDE(_nmap) \
616 MAX(MAP_NORTH_LATITUDE(_nmap), MAP_SOUTH_LATITUDE(_nmap))
617#define MAP_MIN_REAL_LATITUDE(_nmap) \
618 MIN(MAP_NORTH_LATITUDE(_nmap), MAP_SOUTH_LATITUDE(_nmap))
619#define MAP_REAL_LATITUDE_RANGE(_nmap) \
620 (MAP_MAX_REAL_LATITUDE(_nmap) - MAP_MIN_REAL_LATITUDE(_nmap))
621
622/* Maximum and minimum absolute latitude */
623#define MAP_MAX_ABS_LATITUDE(_nmap) \
624 MAX(MAP_MAX_REAL_LATITUDE(_nmap), -MAP_MIN_REAL_LATITUDE(_nmap))
625#define MAP_MIN_ABS_LATITUDE(_nmap) \
626 MAX(0, MAX(MAP_MIN_REAL_LATITUDE(_nmap), -MAP_MAX_REAL_LATITUDE(_nmap)))
627
628int map_signed_latitude(const struct tile *ptile);
629
630/* Used for network protocol; do not change. */
631#define MAP_TILE_OWNER_NULL MAX_UINT8
633#define MAP_DEFAULT_HUTS 15
634#define MAP_MIN_HUTS 0
635#define MAP_MAX_HUTS 500
637#define MAP_DEFAULT_ANIMALS 20
638#define MAP_MIN_ANIMALS 0
639#define MAP_MAX_ANIMALS 500
641#define MAP_DEFAULT_MAPSIZE MAPSIZE_FULLSIZE
642
643/* Size of the map in thousands of tiles. If MAP_MAX_SIZE is increased,
644 * MAX_DBV_LENGTH in bitvector.c must be checked; see the static assertion
645 * below. */
646#ifdef FREECIV_WEB
647#define MAP_DEFAULT_SIZE 3
648#define MAP_MIN_SIZE 0
649#define MAP_MAX_SIZE 38
650#else /* FREECIV_WEB */
651#define MAP_DEFAULT_SIZE 4
652#define MAP_MIN_SIZE 0
653#define MAP_MAX_SIZE 2048
654#endif /* FREECIV_WEB */
658/* We communicate through the network with signed 32-bits integers. */
659FC_STATIC_ASSERT((long unsigned) MAP_MAX_SIZE * 1000
660 < (long unsigned) 1 << 31,
663#define MAP_DEFAULT_TILESPERPLAYER 100
664#define MAP_MIN_TILESPERPLAYER 1
665#define MAP_MAX_TILESPERPLAYER 1000
666
667/* This defines the maximum linear size in _native_ coordinates. */
668#define MAP_DEFAULT_LINEAR_SIZE 64
669#define MAP_MAX_LINEAR_SIZE (MAP_MAX_SIZE * 1000 / MAP_MIN_LINEAR_SIZE)
670#define MAP_MIN_LINEAR_SIZE 16
671
672/* The distance between two points at a map shouldn't be larger than this.
673Adds MAP_MIN_LINEAR_SIZE because hex topologies forbids certain diagonal
674moves. Includes MAP_MAX_LINEAR_SIZE because a map can be non wrapping. */
675#define MAP_DISTANCE_MAX (MAP_MAX_LINEAR_SIZE + MAP_MIN_LINEAR_SIZE)
677#define MAP_ORIGINAL_TOPO TF_WRAPX
678#ifdef FREECIV_WEB
679/* Freeciv-web doesn't support isometric maps yet. */
680#define MAP_DEFAULT_TOPO 0
681#define MAP_DEFAULT_WRAP WRAP_X
682#else /* FREECIV_WEB */
683#define MAP_DEFAULT_TOPO (TF_ISO|TF_HEX)
684#define MAP_DEFAULT_WRAP (WRAP_X)
685#endif /* FREECIV_WEB */
687#define MAP_DEFAULT_SEED 0
688#define MAP_MIN_SEED 0
689#define MAP_MAX_SEED (MAX_UINT32 >> 1)
691#define MAP_DEFAULT_LANDMASS 30
692#define MAP_MIN_LANDMASS 15
693#define MAP_MAX_LANDMASS 85
695#define MAP_DEFAULT_RICHES 250
696#define MAP_MIN_RICHES 0
697#define MAP_MAX_RICHES 1000
699#define MAP_DEFAULT_STEEPNESS 30
700#define MAP_MIN_STEEPNESS 0
701#define MAP_MAX_STEEPNESS 100
703#define MAP_DEFAULT_WETNESS 50
704#define MAP_MIN_WETNESS 0
705#define MAP_MAX_WETNESS 100
707#define MAP_DEFAULT_GENERATOR MAPGEN_RANDOM
709#define MAP_DEFAULT_STARTPOS MAPSTARTPOS_DEFAULT
711#define MAP_DEFAULT_TINYISLES FALSE
712#define MAP_MIN_TINYISLES FALSE
713#define MAP_MAX_TINYISLES TRUE
715#define MAP_DEFAULT_SEPARATE_POLES TRUE
716#define MAP_MIN_SEPARATE_POLES FALSE
717#define MAP_MAX_SEPARATE_POLES TRUE
719#define MAP_DEFAULT_FLATPOLES 100
720#define MAP_MIN_FLATPOLES 0
721#define MAP_MAX_FLATPOLES 100
723#define MAP_DEFAULT_TEMPERATURE 50
724#define MAP_MIN_TEMPERATURE 0
725#define MAP_MAX_TEMPERATURE 100
727#define MAP_DEFAULT_TEAM_PLACEMENT TEAM_PLACEMENT_CLOSEST
728
729/*
730 * Inline function definitions. These are at the bottom because they may use
731 * elements defined above.
732 */
734static inline int map_pos_to_index(struct civ_map *nmap, int map_x, int map_y)
735{
736 /* Note: writing this as a macro is hard; it needs temp variables. */
737 int nat_x, nat_y;
738
742}
744static inline int index_to_map_pos_x(int mindex)
745{
746 /* Note: writing this as a macro is hard; it needs temp variables. */
747 int map_x, map_y;
748
750 return map_x;
751}
753static inline int index_to_map_pos_y(int mindex)
754{
755 /* Note: writing this as a macro is hard; it needs temp variables. */
756 int map_x, map_y;
757
759 return map_y;
760}
761
762/****************************************************************************
763 A "border position" is any map position that _may have_ positions within
764 real map distance dist that are non-normal. To see its correctness,
765 consider the case where dist is 1 or 0.
766****************************************************************************/
767static inline bool is_border_tile(const struct tile *ptile, int dist)
768{
769 /* HACK: An iso-map compresses the value in the X direction but not in
770 * the Y direction. Hence (x+1,y) is 1 tile away while (x,y+2) is also
771 * one tile away. */
772 int xdist = dist;
773 int ydist = (MAP_IS_ISOMETRIC ? (2 * dist) : dist);
774 int nat_x, nat_y;
775
777
778 return (nat_x < xdist
779 || nat_y < ydist
782}
783
784enum direction8 rand_direction(void);
786
787#ifdef __cplusplus
788}
789#endif /* __cplusplus */
790
791#endif /* FC__MAP_H */
#define MAX_DBV_LENGTH
Definition bitvector.h:71
#define BV_DEFINE(name, bits)
Definition bitvector.h:140
char * incite_cost
Definition comments.c:76
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
signed short Continent_id
Definition fc_types.h:231
#define nat_x
#define nat_y
#define MAP_MAX_SIZE
Definition map.h:652
bool can_channel_land(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:744
#define native_pos_to_index(nat_x, nat_y)
Definition map.h:158
struct startpos * map_startpos_get(const struct tile *ptile)
Definition map.c:2038
bool is_normal_map_pos(int x, int y)
Definition map.c:1099
int get_continent_size(Continent_id id)
Definition map.c:819
const int DIR_DY[8]
Definition map.c:86
int startpos_number(const struct startpos *psp)
Definition map.c:1776
bool can_reclaim_ocean(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:729
bool startpos_disallow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1804
void main_map_free(void)
Definition map.c:599
enum direction8 opposite_direction(enum direction8 dir)
Definition map.c:2092
int sq_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:686
bool can_freeze_terrain(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:773
static int index_to_map_pos_y(int mindex)
Definition map.h:752
struct startpos * map_startpos_new(struct tile *ptile)
Definition map.c:2021
void map_distance_vector(int *dx, int *dy, const struct tile *ptile0, const struct tile *ptile1)
Definition map.c:1213
bool can_thaw_terrain(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:758
int tile_move_cost_ptrs(const struct civ_map *nmap, const struct unit *punit, const struct unit_type *punittype, const struct player *pplayer, const struct tile *t1, const struct tile *t2)
Definition map.c:912
bool base_get_direction_for_step(const struct civ_map *nmap, const struct tile *src_tile, const struct tile *dst_tile, enum direction8 *dir)
Definition map.c:1469
bool startpos_nation_allowed(const struct startpos *psp, const struct nation_type *pnation)
Definition map.c:1830
int map_num_tiles(void)
Definition map.c:1152
static const bool C_PERCENT
Definition map.h:40
static const bool C_NUMBER
Definition map.h:39
struct tile * startpos_tile(const struct startpos *psp)
Definition map.c:1820
bool startpos_allows_all(const struct startpos *psp)
Definition map.c:1843
const struct nation_hash * startpos_raw_nations(const struct startpos *psp)
Definition map.c:1916
FC_STATIC_ASSERT((long unsigned) MAP_MAX_SIZE *1000<(long unsigned) 1<< 31, map_too_big_for_network)
const int DIR_DX[8]
Definition map.c:85
#define CHECK_MAP_POS(x, y)
Definition map.h:151
struct tile * rand_map_pos(const struct civ_map *nmap)
Definition map.c:1228
const char * dir_get_name(enum direction8 dir)
Definition map.c:1287
enum direction8 dir_ccw(enum direction8 dir)
Definition map.c:1344
struct iterator * map_startpos_iter_init(struct map_startpos_iter *iter)
Definition map.c:2075
void map_allocate(struct civ_map *amap)
Definition map.c:508
void map_init_topology(struct civ_map *nmap)
Definition map.c:315
#define MAP_TO_NATIVE_POS(pnat_x, pnat_y, map_x, map_y)
Definition map.h:176
bool same_pos(const struct tile *tile0, const struct tile *tile1)
Definition map.c:1076
static const bool C_ADJACENT
Definition map.h:37
void main_map_allocate(void)
Definition map.c:534
bool is_safe_ocean(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:712
bool startpos_pack(const struct startpos *psp, struct packet_edit_startpos_full *packet)
Definition map.c:1854
static int map_pos_to_index(struct civ_map *nmap, int map_x, int map_y)
Definition map.h:733
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:471
int map_signed_latitude(const struct tile *ptile)
Definition map.c:1692
void base_map_distance_vector(int *dx, int *dy, int x0, int y0, int x1, int y1)
Definition map.c:1162
int map_vector_to_sq_distance(int dx, int dy)
Definition map.c:659
bool map_startpos_remove(struct tile *ptile)
Definition map.c:2054
static int map_move_cost_unit(const struct civ_map *nmap, struct unit *punit, const struct tile *ptile)
Definition map.h:290
bool is_move_cardinal(const struct civ_map *nmap, const struct tile *src_tile, const struct tile *dst_tile)
Definition map.c:1507
struct tile * rand_map_pos_filtered(const struct civ_map *nmap, void *data, bool(*filter)(const struct tile *ptile, const void *data))
Definition map.c:1242
int map_startpos_count(void)
Definition map.c:2008
bv_extras get_tile_infrastructure_set(const struct tile *ptile, int *count)
Definition map.c:100
size_t startpos_iter_sizeof(void)
Definition map.c:1929
int get_direction_for_step(const struct civ_map *nmap, const struct tile *src_tile, const struct tile *dst_tile)
Definition map.c:1488
static int index_to_map_pos_x(int mindex)
Definition map.h:743
bool is_cardinal_dir(enum direction8 dir)
Definition map.c:1457
static const bool C_CARDINAL
Definition map.h:38
bool map_untrusted_dir_is_valid(enum direction8 dir)
Definition map.c:1414
bool terrain_surroundings_allow_change(const struct civ_map *nmap, const struct tile *ptile, const struct terrain *pterrain)
Definition map.c:787
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:675
bool startpos_unpack(struct startpos *psp, const struct packet_edit_startpos_full *packet)
Definition map.c:1875
struct iterator * startpos_iter_init(struct startpos_iter *it, const struct startpos *psp)
Definition map.c:1980
int get_ocean_size(Continent_id id)
Definition map.c:830
static bool is_border_tile(const struct tile *ptile, int dist)
Definition map.h:766
bool is_valid_dir(enum direction8 dir)
Definition map.c:1401
enum direction8 dir_cw(enum direction8 dir)
Definition map.c:1315
int get_island_surrounder(Continent_id id)
Definition map.c:842
enum direction8 rand_direction(void)
Definition map.c:2084
struct tile * mapstep(const struct civ_map *nmap, const struct tile *ptile, enum direction8 dir)
Definition map.c:384
void map_free(struct civ_map *fmap, bool server_side)
Definition map.c:545
struct terrain_misc terrain_control
Definition map.c:68
bool is_tiles_adjacent(const struct tile *ptile0, const struct tile *ptile1)
Definition map.c:1067
struct tile * nearest_real_tile(const struct civ_map *nmap, int x, int y)
Definition map.c:1133
struct tile * native_pos_to_tile(const struct civ_map *nmap, int nat_x, int nat_y)
Definition map.c:458
struct tile * map_pos_to_tile(const struct civ_map *nmap, int x, int y)
Definition map.c:434
int get_lake_surrounder(Continent_id id)
Definition map.c:875
#define index_to_native_pos(pnat_x, pnat_y, mindex)
Definition map.h:161
void map_init(struct civ_map *imap, bool server_side)
Definition map.c:156
bool startpos_is_excluding(const struct startpos *psp)
Definition map.c:1903
static int map_move_cost(const struct civ_map *nmap, const struct player *pplayer, const struct unit_type *punittype, const struct tile *src_tile, const struct tile *dst_tile)
Definition map.h:302
int map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:699
struct startpos * map_startpos_by_number(int id)
Definition map.c:1767
bool map_is_empty(void)
Definition map.c:148
size_t map_startpos_iter_sizeof(void)
Definition map.c:2066
bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1787
bool normalize_map_pos(const struct civ_map *nmap, int *x, int *y)
Definition map.c:1117
bool is_real_map_pos(const struct civ_map *nmap, int x, int y)
Definition map.c:1088
#define index_to_map_pos(pmap_x, pmap_y, mindex)
Definition map.h:229
bool is_singular_tile(const struct tile *ptile, int dist)
Definition map.c:1723
int map_vector_to_real_distance(int dx, int dy)
Definition map.c:623
#define terrain_misc
Definition map_types.h:29
struct sprite int int y
Definition sprite_g.h:31
struct sprite int x
Definition sprite_g.h:31
Definition map.c:40
Definition tile.h:50
Definition unit.h:140
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define tile_index(_pt_)
Definition tile.h:89
#define unit_tile(_pu)
Definition unit.h:404
#define unit_owner(_pu)
Definition unit.h:403
const struct unit_type * unit_type_get(const struct unit *punit)
Definition unittype.c:123
#define MAP_NATIVE_WIDTH
#define MAP_IS_ISOMETRIC
#define MAP_NATIVE_HEIGHT