Freeciv-3.3: /fast/freeciv/nightly/main/common/map.c Source File

Freeciv-3.3

Loading...
Searching...
No Matches
map.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18/* utility */
19#include "fcintl.h"
20#include "iterator.h"
21#include "log.h"
22#include "mem.h"
23#include "rand.h"
24#include "shared.h"
25#include "support.h"
26
27/* common */
28#include "ai.h"
29#include "city.h"
30#include "game.h"
31#include "movement.h"
32#include "nation.h"
33#include "packets.h"
34#include "road.h"
35#include "unit.h"
36#include "unitlist.h"
37
38#include "map.h"
39
40 struct startpos {
41 struct tile *location;
42 bool exclude;
43 struct nation_hash *nations;
44};
45
46static struct startpos *startpos_new(struct tile *ptile);
47static void startpos_destroy(struct startpos *psp);
48
49/* struct startpos_hash and related functions. */
50#define SPECHASH_TAG startpos
51#define SPECHASH_IKEY_TYPE struct tile *
52#define SPECHASH_IDATA_TYPE struct startpos *
53#define SPECHASH_IDATA_FREE startpos_destroy
54#include "spechash.h"
55
56/* Srart position iterator. */
57 struct startpos_iter {
58 struct iterator vtable;
59 const struct startpos *psp;
60 /* 'struct nation_iter' really. See startpos_iter_sizeof(). */
61 struct iterator nation_iter;
62};
63
64#define STARTPOS_ITER(p) ((struct startpos_iter *) (p))
65
66
67/* These are initialized from the terrain ruleset */
68 struct terrain_misc terrain_control;
69
70/* Used to compute neighboring tiles.
71 *
72 * Using
73 * x1 = x + DIR_DX[dir];
74 * y1 = y + DIR_DY[dir];
75 * will give you the tile as shown below.
76 * -------
77 * |0|1|2|
78 * |-+-+-|
79 * |3| |4|
80 * |-+-+-|
81 * |5|6|7|
82 * -------
83 * Note that you must normalize x1 and y1 yourself.
84 */
85 const int DIR_DX[8] = { -1, 0, 1, -1, 1, -1, 0, 1 };
86 const int DIR_DY[8] = { -1, -1, -1, 0, 0, 1, 1, 1 };
87
88 static bool dir_cardinality[9]; /* Including invalid one */
89 static bool dir_validity[9]; /* Including invalid one */
90
91static bool is_valid_dir_calculate(enum direction8 dir);
92static bool is_cardinal_dir_calculate(enum direction8 dir);
93
94static bool restrict_infra(const struct player *pplayer, const struct tile *t1,
95 const struct tile *t2);
96
97/*******************************************************************/
100 bv_extras get_tile_infrastructure_set(const struct tile *ptile,
101 int *pcount)
102{
103 bv_extras pspresent;
104 int count = 0;
105
106 BV_CLR_ALL(pspresent);
107
108 extra_type_by_rmcause_iterate(ERM_PILLAGE, pextra) {
109 if (tile_has_extra(ptile, pextra)) {
110 struct tile *missingset = tile_virtual_new(ptile);
111 bool dependency = FALSE;
112
113 tile_remove_extra(missingset, pextra);
114 extra_type_iterate(pdependant) {
115 if (tile_has_extra(ptile, pdependant)) {
116 if (!are_reqs_active(&(const struct req_context) {
117 .tile = missingset,
118 },
119 nullptr, &pdependant->reqs, RPT_POSSIBLE)) {
120 dependency = TRUE;
121 break;
122 }
123 }
124 } extra_type_iterate_end;
125
126 tile_virtual_destroy(missingset);
127
128 if (!dependency) {
129 BV_SET(pspresent, extra_index(pextra));
130 count++;
131 }
132 }
133 } extra_type_by_rmcause_iterate_end;
134
135 if (pcount) {
136 *pcount = count;
137 }
138
139 return pspresent;
140}
141
142/*******************************************************************/
148 bool map_is_empty(void)
149{
150 return wld.map.tiles == nullptr;
151}
152
153/*******************************************************************/
156 void map_init(struct civ_map *imap, bool server_side)
157{
158 imap->topology_id = MAP_DEFAULT_TOPO;
159 imap->wrap_id = MAP_DEFAULT_WRAP;
160 imap->altitude_info = FALSE;
161 imap->num_continents = 0;
162 imap->num_oceans = 0;
163 imap->tiles = nullptr;
164 imap->startpos_table = nullptr;
165 imap->iterate_outwards_indices = nullptr;
166
167 /* The [xy]size values are set in map_init_topology. It is initialized
168 * to a non-zero value because some places erronously use these values
169 * before they're initialized. */
170 imap->xsize = MAP_DEFAULT_LINEAR_SIZE;
171 imap->ysize = MAP_DEFAULT_LINEAR_SIZE;
172
173 imap->north_latitude = MAP_DEFAULT_NORTH_LATITUDE;
174 imap->south_latitude = MAP_DEFAULT_SOUTH_LATITUDE;
175
176 if (server_side) {
177 imap->server.mapsize = MAP_DEFAULT_MAPSIZE;
178 imap->server.size = MAP_DEFAULT_SIZE;
179 imap->server.tilesperplayer = MAP_DEFAULT_TILESPERPLAYER;
180 imap->server.seed_setting = MAP_DEFAULT_SEED;
181 imap->server.seed = MAP_DEFAULT_SEED;
182 imap->server.riches = MAP_DEFAULT_RICHES;
183 imap->server.huts = MAP_DEFAULT_HUTS;
184 imap->server.huts_absolute = -1;
185 imap->server.animals = MAP_DEFAULT_ANIMALS;
186 imap->server.landpercent = MAP_DEFAULT_LANDMASS;
187 imap->server.wetness = MAP_DEFAULT_WETNESS;
188 imap->server.steepness = MAP_DEFAULT_STEEPNESS;
189 imap->server.generator = MAP_DEFAULT_GENERATOR;
190 imap->server.startpos = MAP_DEFAULT_STARTPOS;
191 imap->server.tinyisles = MAP_DEFAULT_TINYISLES;
192 imap->server.separatepoles = MAP_DEFAULT_SEPARATE_POLES;
193 imap->server.temperature = MAP_DEFAULT_TEMPERATURE;
194 imap->server.have_huts = FALSE;
195 imap->server.have_resources = FALSE;
196 imap->server.team_placement = MAP_DEFAULT_TEAM_PLACEMENT;
197 }
198}
199
200/*******************************************************************/
203 static void generate_map_indices(void)
204{
205 int i = 0, nat_x, nat_y, tiles;
206 int nat_center_x, nat_center_y, nat_min_x, nat_min_y, nat_max_x, nat_max_y;
207 int map_center_x, map_center_y;
208
209 /* These caluclations are done via tricky native math. We need to make
210 * sure that when "exploring" positions in the iterate_outward() we
211 * hit each position within the distance exactly once.
212 *
213 * To do this we pick a center position (at the center of the map, for
214 * convenience). Then we iterate over all of the positions around it,
215 * accounting for wrapping, in native coordinates. Note that some of
216 * the positions iterated over before will not even be real; the point
217 * is to use the native math so as to get the right behavior under
218 * different wrapping conditions.
219 *
220 * Thus the "center" position below is just an arbitrary point. We choose
221 * the center of the map to make the min/max values (below) simpler. */
222 nat_center_x = MAP_NATIVE_WIDTH / 2;
223 nat_center_y = MAP_NATIVE_HEIGHT / 2;
224 NATIVE_TO_MAP_POS(&map_center_x, &map_center_y,
225 nat_center_x, nat_center_y);
226
227 /* If we wrap in a particular direction (X or Y), we only need to explore a
228 * half of a map-width in that direction before we hit the wrap point.
229 * If not, we need to explore the full width since we have to account
230 * for the worst-case where we start at one edge of the map. Of course
231 * if we try to explore too far the extra steps will just be skipped by the
232 * normalize check later on. So the purpose at this point is just to
233 * get the right set of positions, relative to the start position, that
234 * may be needed for the iteration.
235 *
236 * If the map does wrap, we go map.Nsize / 2 in each direction.
237 * This gives a min value of 0 and a max value of Nsize-1, because of the
238 * center position chosen above. This also avoids any off-by-one errors.
239 *
240 * If the map doesn't wrap, we go map.Nsize-1 in each direction. In this
241 * case we're not concerned with going too far and wrapping around, so we
242 * just have to make sure we go far enough if we're at one edge of the
243 * map. */
244 nat_min_x = (current_wrap_has_flag(WRAP_X) ? 0
245 : (nat_center_x - MAP_NATIVE_WIDTH + 1));
246 nat_min_y = (current_wrap_has_flag(WRAP_Y) ? 0
247 : (nat_center_y - MAP_NATIVE_HEIGHT + 1));
248
249 nat_max_x = (current_wrap_has_flag(WRAP_X)
250 ? (MAP_NATIVE_WIDTH - 1)
251 : (nat_center_x + MAP_NATIVE_WIDTH - 1));
252 nat_max_y = (current_wrap_has_flag(WRAP_Y)
253 ? (MAP_NATIVE_HEIGHT - 1)
254 : (nat_center_y + MAP_NATIVE_HEIGHT - 1));
255 tiles = (nat_max_x - nat_min_x + 1) * (nat_max_y - nat_min_y + 1);
256
257 fc_assert(wld.map.iterate_outwards_indices == nullptr);
258 wld.map.iterate_outwards_indices =
259 fc_malloc(tiles * sizeof(*wld.map.iterate_outwards_indices));
260
261 for (nat_x = nat_min_x; nat_x <= nat_max_x; nat_x++) {
262 for (nat_y = nat_min_y; nat_y <= nat_max_y; nat_y++) {
263 int map_x, map_y, dx, dy;
264
265 /* Now for each position, we find the vector (in map coordinates) from
266 * the center position to that position. Then we calculate the
267 * distance between the two points. Wrapping is ignored at this
268 * point since the use of native positions means we should always have
269 * the shortest vector. */
270 NATIVE_TO_MAP_POS(&map_x, &map_y, nat_x, nat_y);
271 dx = map_x - map_center_x;
272 dy = map_y - map_center_y;
273
274 wld.map.iterate_outwards_indices[i].dx = dx;
275 wld.map.iterate_outwards_indices[i].dy = dy;
276 wld.map.iterate_outwards_indices[i].dist =
277 map_vector_to_real_distance(dx, dy);
278 i++;
279 }
280 }
281
282 fc_assert(i == tiles);
283
284 qsort(wld.map.iterate_outwards_indices, tiles,
285 sizeof(*wld.map.iterate_outwards_indices), compare_iter_index);
286
287#if 0
288 for (i = 0; i < tiles; i++) {
289 log_debug("%5d : (%3d,%3d) : %d", i,
290 wld.map.iterate_outwards_indices[i].dx,
291 wld.map.iterate_outwards_indices[i].dy,
292 wld.map.iterate_outwards_indices[i].dist);
293 }
294#endif /* FALSE */
295
296 wld.map.num_iterate_outwards_indices = tiles;
297}
298
299/*******************************************************************/
306 void map_init_topology(void)
307{
308 enum direction8 dir;
309
310 /* Sanity check for iso topologies */
311 fc_assert(!MAP_IS_ISOMETRIC || (MAP_NATIVE_HEIGHT % 2) == 0);
312
313 /* The size and ratio must satisfy the minimum and maximum *linear*
314 * restrictions on width */
315 fc_assert(MAP_NATIVE_WIDTH >= MAP_MIN_LINEAR_SIZE);
316 fc_assert(MAP_NATIVE_HEIGHT >= MAP_MIN_LINEAR_SIZE);
317 fc_assert(MAP_NATIVE_WIDTH <= MAP_MAX_LINEAR_SIZE);
318 fc_assert(MAP_NATIVE_HEIGHT <= MAP_MAX_LINEAR_SIZE);
319 fc_assert(map_num_tiles() >= MAP_MIN_SIZE * 1000);
320 fc_assert(map_num_tiles() <= MAP_MAX_SIZE * 1000);
321
322 wld.map.num_valid_dirs = wld.map.num_cardinal_dirs = 0;
323
324 /* Values for direction8_invalid() */
325 fc_assert(direction8_invalid() == 8);
326 dir_validity[8] = FALSE;
327 dir_cardinality[8] = FALSE;
328
329 /* Values for actual directions */
330 for (dir = 0; dir < 8; dir++) {
331 if (is_valid_dir_calculate(dir)) {
332 wld.map.valid_dirs[wld.map.num_valid_dirs] = dir;
333 wld.map.num_valid_dirs++;
334 dir_validity[dir] = TRUE;
335 } else {
336 dir_validity[dir] = FALSE;
337 }
338 if (is_cardinal_dir_calculate(dir)) {
339 wld.map.cardinal_dirs[wld.map.num_cardinal_dirs] = dir;
340 wld.map.num_cardinal_dirs++;
341 dir_cardinality[dir] = TRUE;
342 } else {
343 dir_cardinality[dir] = FALSE;
344 }
345 }
346 fc_assert(wld.map.num_valid_dirs > 0 && wld.map.num_valid_dirs <= 8);
347 fc_assert(wld.map.num_cardinal_dirs > 0
348 && wld.map.num_cardinal_dirs <= wld.map.num_valid_dirs);
349}
350
351/*******************************************************************/
354 static void tile_init(struct tile *ptile)
355{
356 ptile->continent = 0;
357
358 BV_CLR_ALL(ptile->extras);
359 ptile->resource = nullptr;
360 ptile->terrain = T_UNKNOWN;
361 ptile->units = unit_list_new();
362 ptile->owner = nullptr; /* Not claimed by any player. */
363 ptile->extras_owner = nullptr;
364 ptile->placing = nullptr;
365 ptile->claimer = nullptr;
366 ptile->worked = nullptr; /* No city working here. */
367 ptile->altitude = 0;
368 ptile->spec_sprite = nullptr;
369}
370
371/*******************************************************************/
375 struct tile *mapstep(const struct civ_map *nmap,
376 const struct tile *ptile, enum direction8 dir)
377{
378 int dx, dy, tile_x, tile_y;
379
380 if (!is_valid_dir(dir)) {
381 return nullptr;
382 }
383
384 index_to_map_pos(&tile_x, &tile_y, tile_index(ptile));
385 DIRSTEP(dx, dy, dir);
386
387 tile_x += dx;
388 tile_y += dy;
389
390 return map_pos_to_tile(&(wld.map), tile_x, tile_y);
391}
392
393/*******************************************************************/
401 static inline struct tile *base_native_pos_to_tile(const struct civ_map *nmap,
402 int nat_x, int nat_y)
403{
404 /* Wrap in X and Y directions, as needed. */
405 /* If the position is out of range in a non-wrapping direction, it is
406 * unreal. */
407 if (current_wrap_has_flag(WRAP_X)) {
408 nat_x = FC_WRAP(nat_x, MAP_NATIVE_WIDTH);
409 } else if (nat_x < 0 || nat_x >= MAP_NATIVE_WIDTH) {
410 return nullptr;
411 }
412 if (current_wrap_has_flag(WRAP_Y)) {
413 nat_y = FC_WRAP(nat_y, MAP_NATIVE_HEIGHT);
414 } else if (nat_y < 0 || nat_y >= MAP_NATIVE_HEIGHT) {
415 return nullptr;
416 }
417
418 /* We already checked legality of native pos above, don't repeat */
419 return nmap->tiles + native_pos_to_index_nocheck(nat_x, nat_y);
420}
421
422/*******************************************************************/
425 struct tile *map_pos_to_tile(const struct civ_map *nmap, int map_x, int map_y)
426{
427 /* Instead of introducing new variables for native coordinates,
428 * update the map coordinate variables = registers already in use.
429 * This is one of the most performance-critical functions we have,
430 * so taking measures like this makes sense. */
431#define nat_x map_x
432#define nat_y map_y
433
434 if (nmap->tiles == nullptr) {
435 return nullptr;
436 }
437
438 /* Normalization is best done in native coordinates. */
439 MAP_TO_NATIVE_POS(&nat_x, &nat_y, map_x, map_y);
440 return base_native_pos_to_tile(nmap, nat_x, nat_y);
441
442#undef nat_x
443#undef nat_y
444}
445
446/*******************************************************************/
449 struct tile *native_pos_to_tile(const struct civ_map *nmap,
450 int nat_x, int nat_y)
451{
452 if (nmap->tiles == nullptr) {
453 return nullptr;
454 }
455
456 return base_native_pos_to_tile(nmap, nat_x, nat_y);
457}
458
459/*******************************************************************/
462 struct tile *index_to_tile(const struct civ_map *imap, int mindex)
463{
464 if (imap->tiles == nullptr) {
465 return nullptr;
466 }
467
468 if (mindex >= 0 && mindex < MAP_INDEX_SIZE) {
469 return imap->tiles + mindex;
470 } else {
471 /* Unwrapped index coordinates are impossible, so the best we can do is
472 * return nullptr. */
473 return nullptr;
474 }
475}
476
477/*******************************************************************/
480 static void tile_free(struct tile *ptile)
481{
482 unit_list_destroy(ptile->units);
483
484 if (ptile->spec_sprite) {
485 free(ptile->spec_sprite);
486 ptile->spec_sprite = nullptr;
487 }
488
489 if (ptile->label) {
490 FC_FREE(ptile->label);
491 ptile->label = nullptr;
492 }
493}
494
495/*******************************************************************/
499 void map_allocate(struct civ_map *amap)
500{
501 log_debug("map_allocate (was %p) (%d,%d)",
502 (void *) amap->tiles, amap->xsize, amap->ysize);
503
504 fc_assert_ret(amap->tiles == nullptr);
505 amap->tiles = fc_calloc(MAP_INDEX_SIZE, sizeof(*amap->tiles));
506
507 /* Note this use of whole_map_iterate may be a bit sketchy, since the
508 * tile values (ptile->index, etc.) haven't been set yet. It might be
509 * better to do a manual loop here. */
510 whole_map_iterate(amap, ptile) {
511 ptile->index = ptile - amap->tiles;
512 CHECK_INDEX(tile_index(ptile));
513 tile_init(ptile);
514 } whole_map_iterate_end;
515
516 if (amap->startpos_table != nullptr) {
517 startpos_hash_destroy(amap->startpos_table);
518 }
519 amap->startpos_table = startpos_hash_new();
520}
521
522/*******************************************************************/
525 void main_map_allocate(void)
526{
527 map_allocate(&(wld.map));
528 generate_city_map_indices();
529 generate_map_indices();
530 CALL_FUNC_EACH_AI(map_alloc);
531}
532
533/*******************************************************************/
536 void map_free(struct civ_map *fmap)
537{
538 if (fmap->tiles) {
539 /* It is possible that map_init() was called but not map_allocate() */
540
541 whole_map_iterate(fmap, ptile) {
542 tile_free(ptile);
543 } whole_map_iterate_end;
544
545 free(fmap->tiles);
546 fmap->tiles = nullptr;
547
548 if (fmap->startpos_table) {
549 startpos_hash_destroy(fmap->startpos_table);
550 fmap->startpos_table = nullptr;
551 }
552
553 FC_FREE(fmap->iterate_outwards_indices);
554 }
555}
556
557/*******************************************************************/
560 void main_map_free(void)
561{
562 map_free(&(wld.map));
563 CALL_FUNC_EACH_AI(map_free);
564}
565
566/*******************************************************************/
570 static int map_vector_to_distance(int dx, int dy)
571{
572 if (current_topo_has_flag(TF_HEX)) {
573 /* Hex: all directions are cardinal so the distance is equivalent to
574 * the real distance. */
575 return map_vector_to_real_distance(dx, dy);
576 } else {
577 return abs(dx) + abs(dy);
578 }
579}
580
581/*******************************************************************/
584 int map_vector_to_real_distance(int dx, int dy)
585{
586 const int absdx = abs(dx), absdy = abs(dy);
587
588 if (current_topo_has_flag(TF_HEX)) {
589 if (current_topo_has_flag(TF_ISO)) {
590 /* Iso-hex: you can't move NE or SW. */
591 if ((dx < 0 && dy > 0)
592 || (dx > 0 && dy < 0)) {
593 /* Diagonal moves in this direction aren't allowed, so it will take
594 * the full number of moves. */
595 return absdx + absdy;
596 } else {
597 /* Diagonal moves in this direction *are* allowed. */
598 return MAX(absdx, absdy);
599 }
600 } else {
601 /* Hex: you can't move SE or NW. */
602 if ((dx > 0 && dy > 0)
603 || (dx < 0 && dy < 0)) {
604 /* Diagonal moves in this direction aren't allowed, so it will take
605 * the full number of moves. */
606 return absdx + absdy;
607 } else {
608 /* Diagonal moves in this direction *are* allowed. */
609 return MAX(absdx, absdy);
610 }
611 }
612 } else {
613 return MAX(absdx, absdy);
614 }
615}
616
617/*******************************************************************/
620 int map_vector_to_sq_distance(int dx, int dy)
621{
622 if (current_topo_has_flag(TF_HEX)) {
623 /* Hex: The square distance is just the square of the real distance; we
624 * don't worry about pythagorean calculations. */
625 int dist = map_vector_to_real_distance(dx, dy);
626
627 return dist * dist;
628 } else {
629 return dx * dx + dy * dy;
630 }
631}
632
633/*******************************************************************/
636 int real_map_distance(const struct tile *tile0, const struct tile *tile1)
637{
638 int dx, dy;
639
640 map_distance_vector(&dx, &dy, tile0, tile1);
641 return map_vector_to_real_distance(dx, dy);
642}
643
644/*******************************************************************/
647 int sq_map_distance(const struct tile *tile0, const struct tile *tile1)
648{
649 /* We assume map_distance_vector gives us the vector with the
650 minimum squared distance. Right now this is true. */
651 int dx, dy;
652
653 map_distance_vector(&dx, &dy, tile0, tile1);
654 return map_vector_to_sq_distance(dx, dy);
655}
656
657/*******************************************************************/
660 int map_distance(const struct tile *tile0, const struct tile *tile1)
661{
662 /* We assume map_distance_vector gives us the vector with the
663 minimum map distance. Right now this is true. */
664 int dx, dy;
665
666 map_distance_vector(&dx, &dy, tile0, tile1);
667 return map_vector_to_distance(dx, dy);
668}
669
670/*******************************************************************/
673 bool is_safe_ocean(const struct civ_map *nmap, const struct tile *ptile)
674{
675 adjc_iterate(nmap, ptile, adjc_tile) {
676 if (tile_terrain(adjc_tile) != T_UNKNOWN
677 && !terrain_has_flag(tile_terrain(adjc_tile), TER_UNSAFE_COAST)) {
678 return TRUE;
679 }
680 } adjc_iterate_end;
681
682 return FALSE;
683}
684
685/*******************************************************************/
690 bool can_reclaim_ocean(const struct civ_map *nmap,
691 const struct tile *ptile)
692{
693 int land_tiles = 100 - count_terrain_class_near_tile(nmap, ptile,
694 FALSE, TRUE,
695 TC_OCEAN);
696
697 return land_tiles >= terrain_control.ocean_reclaim_requirement_pct;
698}
699
700/*******************************************************************/
705 bool can_channel_land(const struct civ_map *nmap,
706 const struct tile *ptile)
707{
708 int ocean_tiles = count_terrain_class_near_tile(nmap, ptile,
709 FALSE, TRUE, TC_OCEAN);
710
711 return ocean_tiles >= terrain_control.land_channel_requirement_pct;
712}
713
714/*******************************************************************/
719 bool can_thaw_terrain(const struct civ_map *nmap,
720 const struct tile *ptile)
721{
722 int unfrozen_tiles = 100 - count_terrain_flag_near_tile(nmap, ptile,
723 FALSE, TRUE,
724 TER_FROZEN);
725
726 return unfrozen_tiles >= terrain_control.terrain_thaw_requirement_pct;
727}
728
729/*******************************************************************/
734 bool can_freeze_terrain(const struct civ_map *nmap,
735 const struct tile *ptile)
736{
737 int frozen_tiles = count_terrain_flag_near_tile(nmap, ptile,
738 FALSE, TRUE,
739 TER_FROZEN);
740
741 return frozen_tiles >= terrain_control.terrain_freeze_requirement_pct;
742}
743
744/*******************************************************************/
748 bool terrain_surroundings_allow_change(const struct civ_map *nmap,
749 const struct tile *ptile,
750 const struct terrain *pterrain)
751{
752 bool ret = TRUE;
753
754 if (is_ocean(tile_terrain(ptile))
755 && !is_ocean(pterrain) && !can_reclaim_ocean(nmap, ptile)) {
756 ret = FALSE;
757 } else if (!is_ocean(tile_terrain(ptile))
758 && is_ocean(pterrain) && !can_channel_land(nmap, ptile)) {
759 ret = FALSE;
760 }
761
762 if (ret) {
763 if (terrain_has_flag(tile_terrain(ptile), TER_FROZEN)
764 && !terrain_has_flag(pterrain, TER_FROZEN)
765 && !can_thaw_terrain(nmap, ptile)) {
766 ret = FALSE;
767 } else if (!terrain_has_flag(tile_terrain(ptile), TER_FROZEN)
768 && terrain_has_flag(pterrain, TER_FROZEN)
769 && !can_freeze_terrain(nmap, ptile)) {
770 ret = FALSE;
771 }
772 }
773
774 return ret;
775}
776
777/*******************************************************************/
786 int tile_move_cost_ptrs(const struct civ_map *nmap,
787 const struct unit *punit,
788 const struct unit_type *punittype,
789 const struct player *pplayer,
790 const struct tile *t1, const struct tile *t2)
791{
792 const struct unit_class *pclass = utype_class(punittype);
793 int cost;
794 signed char cardinal_move = -1;
795 bool ri;
796
797 /* Try to exit early for detectable conditions */
798 if (!uclass_has_flag(pclass, UCF_TERRAIN_SPEED)) {
799 /* Units without UCF_TERRAIN_SPEED have a constant cost. */
800 return SINGLE_MOVE;
801
802 } else if (!is_native_tile_to_class(pclass, t2)) {
803 if (tile_city(t2) == nullptr) {
804 /* Loading to transport. */
805
806 /* UTYF_IGTER units get move benefit. */
807 return (utype_has_flag(punittype, UTYF_IGTER)
808 ? MOVE_COST_IGTER : SINGLE_MOVE);
809 } else {
810 /* Entering port. (Could be "Conquer City") */
811
812 /* UTYF_IGTER units get move benefit. */
813 return (utype_has_flag(punittype, UTYF_IGTER)
814 ? MOVE_COST_IGTER : SINGLE_MOVE);
815 }
816
817 } else if (!is_native_tile_to_class(pclass, t1)) {
818 if (tile_city(t1) == nullptr) {
819 /* Disembarking from transport. */
820
821 /* UTYF_IGTER units get move benefit. */
822 return (utype_has_flag(punittype, UTYF_IGTER)
823 ? MOVE_COST_IGTER : SINGLE_MOVE);
824 } else {
825 /* Leaving port. */
826
827 /* UTYF_IGTER units get move benefit. */
828 return (utype_has_flag(punittype, UTYF_IGTER)
829 ? MOVE_COST_IGTER : SINGLE_MOVE);
830 }
831 }
832
833 cost = tile_terrain(t2)->movement_cost * SINGLE_MOVE;
834 ri = restrict_infra(pplayer, t1, t2);
835
836 extra_type_list_iterate(pclass->cache.bonus_roads, pextra) {
837 struct road_type *proad = extra_road_get(pextra);
838
839 /* We check the destination tile first, as that's
840 * the end of move that determines the cost.
841 * If can avoid inner loop about integrating roads
842 * completely if the destination road has too high cost. */
843
844 if (cost > proad->move_cost
845 && (!ri || road_has_flag(proad, RF_UNRESTRICTED_INFRA))
846 && tile_has_extra(t2, pextra)) {
847 extra_type_list_iterate(proad->integrators, iextra) {
848 /* We have no unrestricted infra related check here,
849 * destination road is the one that counts. */
850 if (tile_has_extra(t1, iextra)
851 && is_native_extra_to_uclass(iextra, pclass)) {
852 if (proad->move_mode == RMM_FAST_ALWAYS) {
853 cost = proad->move_cost;
854 } else {
855 if (cardinal_move < 0) {
856 cardinal_move = (ALL_DIRECTIONS_CARDINAL()
857 || is_move_cardinal(nmap, t1, t2)) ? 1 : 0;
858 }
859 if (cardinal_move > 0) {
860 cost = proad->move_cost;
861 } else {
862 switch (proad->move_mode) {
863 case RMM_CARDINAL:
864 break;
865 case RMM_RELAXED:
866 if (cost > proad->move_cost * 2) {
867 cardinal_between_iterate(nmap, t1, t2, between) {
868 if (tile_has_extra(between, pextra)
869 || (pextra != iextra && tile_has_extra(between, iextra))) {
870 /* 'pextra != iextra' is there just to avoid
871 * tile_has_extra() in by far more common case
872 * that 'pextra == iextra' */
873 /* TODO: Should we restrict this more?
874 * Should we check against enemy cities on between tile?
875 * Should we check against non-native terrain on between tile?
876 */
877 cost = proad->move_cost * 2;
878 }
879 } cardinal_between_iterate_end;
880 }
881 break;
882 case RMM_FAST_ALWAYS:
883
884 /* Already handled above */
885 fc_assert(proad->move_mode != RMM_FAST_ALWAYS);
886
887 cost = proad->move_cost;
888 break;
889 }
890 }
891 }
892 }
893 } extra_type_list_iterate_end;
894 }
895 } extra_type_list_iterate_end;
896
897 /* UTYF_IGTER units have a maximum move cost per step. */
898 if (utype_has_flag(punittype, UTYF_IGTER) && MOVE_COST_IGTER < cost) {
899 cost = MOVE_COST_IGTER;
900 }
901
902 if (terrain_control.pythagorean_diagonal) {
903 if (cardinal_move < 0) {
904 cardinal_move = (ALL_DIRECTIONS_CARDINAL()
905 || is_move_cardinal(nmap, t1, t2)) ? 1 : 0;
906 }
907 if (cardinal_move == 0) {
908 return cost * 181 >> 7; /* == (int) (cost * 1.41421356f) if cost < 99 */
909 }
910 }
911
912 return cost;
913}
914
915/*******************************************************************/
921 static bool restrict_infra(const struct player *pplayer, const struct tile *t1,
922 const struct tile *t2)
923{
924 struct player *plr1 = tile_owner(t1), *plr2 = tile_owner(t2);
925
926 if (!pplayer || !game.info.restrictinfra) {
927 return FALSE;
928 }
929
930 if ((plr1 && pplayers_at_war(plr1, pplayer))
931 || (plr2 && pplayers_at_war(plr2, pplayer))) {
932 return TRUE;
933 }
934
935 return FALSE;
936}
937
938/*******************************************************************/
941 bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
942{
943 return real_map_distance(tile0, tile1) == 1;
944}
945
946/*******************************************************************/
950 bool same_pos(const struct tile *tile1, const struct tile *tile2)
951{
952 fc_assert_ret_val(tile1 != nullptr && tile2 != nullptr, FALSE);
953
954 /* In case of virtual tile, tile1 can be different from tile2,
955 * but they have same index */
956 return (tile1->index == tile2->index);
957}
958
959/*******************************************************************/
962 bool is_real_map_pos(const struct civ_map *nmap, int x, int y)
963{
964 return normalize_map_pos(nmap, &x, &y);
965}
966
967/*******************************************************************/
973 bool is_normal_map_pos(int x, int y)
974{
975 int nat_x, nat_y;
976
977 MAP_TO_NATIVE_POS(&nat_x, &nat_y, x, y);
978
979 return nat_x >= 0 && nat_x < MAP_NATIVE_WIDTH
980 && nat_y >= 0 && nat_y < MAP_NATIVE_HEIGHT;
981}
982
983/*******************************************************************/
991 bool normalize_map_pos(const struct civ_map *nmap, int *x, int *y)
992{
993 struct tile *ptile = map_pos_to_tile(nmap, *x, *y);
994
995 if (ptile != nullptr) {
996 index_to_map_pos(x, y, tile_index(ptile));
997 return TRUE;
998 } else {
999 return FALSE;
1000 }
1001}
1002
1003/*******************************************************************/
1007 struct tile *nearest_real_tile(const struct civ_map *nmap, int x, int y)
1008{
1009 int nat_x, nat_y;
1010
1011 MAP_TO_NATIVE_POS(&nat_x, &nat_y, x, y);
1012 if (!current_wrap_has_flag(WRAP_X)) {
1013 nat_x = CLIP(0, nat_x, MAP_NATIVE_WIDTH - 1);
1014 }
1015 if (!current_wrap_has_flag(WRAP_Y)) {
1016 nat_y = CLIP(0, nat_y, MAP_NATIVE_HEIGHT - 1);
1017 }
1018 NATIVE_TO_MAP_POS(&x, &y, nat_x, nat_y);
1019
1020 return map_pos_to_tile(nmap, x, y);
1021}
1022
1023/*******************************************************************/
1026 int map_num_tiles(void)
1027{
1028 return MAP_NATIVE_WIDTH * MAP_NATIVE_HEIGHT;
1029}
1030
1031/*******************************************************************/
1036 void base_map_distance_vector(int *dx, int *dy,
1037 int x0dv, int y0dv, int x1dv, int y1dv)
1038{
1039 if (current_wrap_has_flag(WRAP_X) || current_wrap_has_flag(WRAP_Y)) {
1040 /* Wrapping is done in native coordinates. */
1041 MAP_TO_NATIVE_POS(&x0dv, &y0dv, x0dv, y0dv);
1042 MAP_TO_NATIVE_POS(&x1dv, &y1dv, x1dv, y1dv);
1043
1044 /* Find the "native" distance vector. This corresponds closely to the
1045 * map distance vector but is easier to wrap. */
1046 *dx = x1dv - x0dv;
1047 *dy = y1dv - y0dv;
1048 if (current_wrap_has_flag(WRAP_X)) {
1049 /* Wrap dx to be in [-map.xsize / 2, map.xsize / 2). */
1050 *dx = FC_WRAP(*dx + MAP_NATIVE_WIDTH / 2, MAP_NATIVE_WIDTH)
1051 - MAP_NATIVE_WIDTH / 2;
1052 }
1053 if (current_wrap_has_flag(WRAP_Y)) {
1054 /* Wrap dy to be in [-map.ysize / 2, map.ysize / 2). */
1055 *dy = FC_WRAP(*dy + MAP_NATIVE_HEIGHT / 2, MAP_NATIVE_HEIGHT)
1056 - MAP_NATIVE_HEIGHT / 2;
1057 }
1058
1059 /* Convert the native delta vector back to a pair of map positions. */
1060 x1dv = x0dv + *dx;
1061 y1dv = y0dv + *dy;
1062 NATIVE_TO_MAP_POS(&x0dv, &y0dv, x0dv, y0dv);
1063 NATIVE_TO_MAP_POS(&x1dv, &y1dv, x1dv, y1dv);
1064 }
1065
1066 /* Find the final (map) vector. */
1067 *dx = x1dv - x0dv;
1068 *dy = y1dv - y0dv;
1069}
1070
1071/*******************************************************************/
1087 void map_distance_vector(int *dx, int *dy,
1088 const struct tile *tile0,
1089 const struct tile *tile1)
1090{
1091 int tx0, ty0, tx1, ty1;
1092
1093 index_to_map_pos(&tx0, &ty0, tile_index(tile0));
1094 index_to_map_pos(&tx1, &ty1, tile_index(tile1));
1095 base_map_distance_vector(dx, dy, tx0, ty0, tx1, ty1);
1096}
1097
1098/*******************************************************************/
1102 struct tile *rand_map_pos(const struct civ_map *nmap)
1103{
1104 int nat_x = fc_rand(MAP_NATIVE_WIDTH);
1105 int nat_y = fc_rand(MAP_NATIVE_HEIGHT);
1106
1107 return native_pos_to_tile(nmap, nat_x, nat_y);
1108}
1109
1110/*******************************************************************/
1116 struct tile *rand_map_pos_filtered(const struct civ_map *nmap, void *data,
1117 bool (*filter)(const struct tile *ptile,
1118 const void *data))
1119{
1120 struct tile *ptile;
1121 int tries = 0;
1122 const int max_tries = MAP_INDEX_SIZE / ACTIVITY_FACTOR;
1123
1124 /* First do a few quick checks to find a spot. The limit on number of
1125 * tries could use some tweaking. */
1126 do {
1127 ptile = nmap->tiles + fc_rand(MAP_INDEX_SIZE);
1128 } while (filter != nullptr && !filter(ptile, data) && ++tries < max_tries);
1129
1130 /* If that fails, count all available spots and pick one.
1131 * Slow but reliable. */
1132 if (filter == nullptr) {
1133 ptile = nullptr;
1134 } else if (tries == max_tries) {
1135 int count = 0, *positions;
1136
1137 positions = fc_calloc(MAP_INDEX_SIZE, sizeof(*positions));
1138
1139 whole_map_iterate(nmap, check_tile) {
1140 if (filter(check_tile, data)) {
1141 positions[count] = tile_index(check_tile);
1142 count++;
1143 }
1144 } whole_map_iterate_end;
1145
1146 if (count == 0) {
1147 ptile = nullptr;
1148 } else {
1149 ptile = wld.map.tiles + positions[fc_rand(count)];
1150 }
1151
1152 FC_FREE(positions);
1153 }
1154
1155 return ptile;
1156}
1157
1158/*******************************************************************/
1161 const char *dir_get_name(enum direction8 dir)
1162{
1163 /* A switch statement is used so the ordering can be changed easily */
1164 switch (dir) {
1165 case DIR8_NORTH:
1166 return "N";
1167 case DIR8_NORTHEAST:
1168 return "NE";
1169 case DIR8_EAST:
1170 return "E";
1171 case DIR8_SOUTHEAST:
1172 return "SE";
1173 case DIR8_SOUTH:
1174 return "S";
1175 case DIR8_SOUTHWEST:
1176 return "SW";
1177 case DIR8_WEST:
1178 return "W";
1179 case DIR8_NORTHWEST:
1180 return "NW";
1181 default:
1182 return "[Undef]";
1183 }
1184}
1185
1186/*******************************************************************/
1189 enum direction8 dir_cw(enum direction8 dir)
1190{
1191 /* A switch statement is used so the ordering can be changed easily */
1192 switch (dir) {
1193 case DIR8_NORTH:
1194 return DIR8_NORTHEAST;
1195 case DIR8_NORTHEAST:
1196 return DIR8_EAST;
1197 case DIR8_EAST:
1198 return DIR8_SOUTHEAST;
1199 case DIR8_SOUTHEAST:
1200 return DIR8_SOUTH;
1201 case DIR8_SOUTH:
1202 return DIR8_SOUTHWEST;
1203 case DIR8_SOUTHWEST:
1204 return DIR8_WEST;
1205 case DIR8_WEST:
1206 return DIR8_NORTHWEST;
1207 case DIR8_NORTHWEST:
1208 return DIR8_NORTH;
1209 default:
1210 fc_assert(FALSE);
1211 return -1;
1212 }
1213}
1214
1215/*******************************************************************/
1218 enum direction8 dir_ccw(enum direction8 dir)
1219{
1220 /* A switch statement is used so the ordering can be changed easily */
1221 switch (dir) {
1222 case DIR8_NORTH:
1223 return DIR8_NORTHWEST;
1224 case DIR8_NORTHEAST:
1225 return DIR8_NORTH;
1226 case DIR8_EAST:
1227 return DIR8_NORTHEAST;
1228 case DIR8_SOUTHEAST:
1229 return DIR8_EAST;
1230 case DIR8_SOUTH:
1231 return DIR8_SOUTHEAST;
1232 case DIR8_SOUTHWEST:
1233 return DIR8_SOUTH;
1234 case DIR8_WEST:
1235 return DIR8_SOUTHWEST;
1236 case DIR8_NORTHWEST:
1237 return DIR8_WEST;
1238 default:
1239 fc_assert(FALSE);
1240 return -1;
1241 }
1242}
1243
1244/*******************************************************************/
1248 static bool is_valid_dir_calculate(enum direction8 dir)
1249{
1250 switch (dir) {
1251 case DIR8_SOUTHEAST:
1252 case DIR8_NORTHWEST:
1253 /* These directions are invalid in hex topologies. */
1254 return !(current_topo_has_flag(TF_HEX) && !current_topo_has_flag(TF_ISO));
1255 case DIR8_NORTHEAST:
1256 case DIR8_SOUTHWEST:
1257 /* These directions are invalid in iso-hex topologies. */
1258 return !(current_topo_has_flag(TF_HEX) && current_topo_has_flag(TF_ISO));
1259 case DIR8_NORTH:
1260 case DIR8_EAST:
1261 case DIR8_SOUTH:
1262 case DIR8_WEST:
1263 return TRUE;
1264 default:
1265 return FALSE;
1266 }
1267}
1268
1269/*******************************************************************/
1275 bool is_valid_dir(enum direction8 dir)
1276{
1277 fc_assert_ret_val(dir <= direction8_invalid(), FALSE);
1278
1279 return dir_validity[dir];
1280}
1281
1282/*******************************************************************/
1288 bool map_untrusted_dir_is_valid(enum direction8 dir)
1289{
1290 if (!direction8_is_valid(dir)) {
1291 /* Isn't even in range of direction8. */
1292 return FALSE;
1293 }
1294
1295 return is_valid_dir(dir);
1296}
1297
1298/*******************************************************************/
1305 static bool is_cardinal_dir_calculate(enum direction8 dir)
1306{
1307 switch (dir) {
1308 case DIR8_NORTH:
1309 case DIR8_SOUTH:
1310 case DIR8_EAST:
1311 case DIR8_WEST:
1312 return TRUE;
1313 case DIR8_SOUTHEAST:
1314 case DIR8_NORTHWEST:
1315 /* These directions are cardinal in iso-hex topologies. */
1316 return current_topo_has_flag(TF_HEX) && current_topo_has_flag(TF_ISO);
1317 case DIR8_NORTHEAST:
1318 case DIR8_SOUTHWEST:
1319 /* These directions are cardinal in hexagonal topologies. */
1320 return current_topo_has_flag(TF_HEX) && !current_topo_has_flag(TF_ISO);
1321 }
1322 return FALSE;
1323}
1324
1325/*******************************************************************/
1331 bool is_cardinal_dir(enum direction8 dir)
1332{
1333 fc_assert_ret_val(dir <= direction8_invalid(), FALSE);
1334
1335 return dir_cardinality[dir];
1336}
1337
1338/*******************************************************************/
1343 bool base_get_direction_for_step(const struct civ_map *nmap,
1344 const struct tile *start_tile,
1345 const struct tile *end_tile,
1346 enum direction8 *dir)
1347{
1348 adjc_dir_iterate(nmap, start_tile, test_tile, test_dir) {
1349 if (same_pos(end_tile, test_tile)) {
1350 *dir = test_dir;
1351 return TRUE;
1352 }
1353 } adjc_dir_iterate_end;
1354
1355 return FALSE;
1356}
1357
1358/*******************************************************************/
1362 int get_direction_for_step(const struct civ_map *nmap,
1363 const struct tile *start_tile,
1364 const struct tile *end_tile)
1365{
1366 enum direction8 dir;
1367
1368 if (base_get_direction_for_step(nmap, start_tile, end_tile, &dir)) {
1369 return dir;
1370 }
1371
1372 fc_assert(FALSE);
1373
1374 return -1;
1375}
1376
1377/*******************************************************************/
1381 bool is_move_cardinal(const struct civ_map *nmap,
1382 const struct tile *start_tile,
1383 const struct tile *end_tile)
1384{
1385 cardinal_adjc_dir_iterate(nmap, start_tile, test_tile, test_dir) {
1386 if (same_pos(end_tile, test_tile)) {
1387 return TRUE;
1388 }
1389 } cardinal_adjc_dir_iterate_end;
1390
1391 return FALSE;
1392}
1393
1394/************************************************************************/
1412 static double map_relative_southness(const struct tile *ptile)
1413{
1414 int tile_x, tile_y;
1415 double x, y, toroid_rel_colatitude;
1416 bool toroid_flipped;
1417
1418 /* TODO: What should the fallback value be?
1419 * Since this is not public API, it shouldn't matter anyway. */
1420 fc_assert_ret_val(ptile != nullptr, 0.5);
1421
1422 index_to_map_pos(&tile_x, &tile_y, tile_index(ptile));
1423 do_in_natural_pos(ntl_x, ntl_y, tile_x, tile_y) {
1424 /* Compute natural coordinates relative to world size.
1425 * x and y are in the range [0.0, 1.0] */
1426 x = (double)ntl_x / (MAP_NATURAL_WIDTH - 1);
1427 y = (double)ntl_y / (MAP_NATURAL_HEIGHT - 1);
1428 } do_in_natural_pos_end;
1429
1430 if (!current_wrap_has_flag(WRAP_Y)) {
1431 /* In an Earth-like topology, north and south are at the top and
1432 * bottom of the map.
1433 * This is equivalent to a Mercator projection. */
1434 return y;
1435 }
1436
1437 if (!current_wrap_has_flag(WRAP_X) && current_wrap_has_flag(WRAP_Y)) {
1438 /* In a Uranus-like topology, north and south are at the left and
1439 * right side of the map.
1440 * This isn't really the way Uranus is; it's the way Earth would look
1441 * if you tilted your head sideways. It's still a Mercator
1442 * projection. */
1443 return x;
1444 }
1445
1446 /* Otherwise we have a torus topology. We set it up as an approximation
1447 * of a sphere with two circular polar zones and a square equatorial
1448 * zone. In this case north and south are not constant directions on the
1449 * map because we have to use a more complicated (custom) projection.
1450 *
1451 * Generators 2 and 5 work best if the center of the map is free.
1452 * So we want to set up the map with the poles (N,S) along the sides and
1453 * the equator (/,\‍) in between.
1454 *
1455 * ........
1456 * :\ NN /:
1457 * : \ / :
1458 * :S \/ S:
1459 * :S /\ S:
1460 * : / \ :
1461 * :/ NN \:
1462 * ''''''''
1463 */
1464
1465 /* First we will fold the map into fourths:
1466 *
1467 * ....
1468 * :\ N
1469 * : \
1470 * :S \
1471 *
1472 * and renormalize x and y to go from 0.0 to 1.0 again.
1473 */
1474 x = 2.0 * (x > 0.5 ? 1.0 - x : x);
1475 y = 2.0 * (y > 0.5 ? 1.0 - y : y);
1476
1477 /* Now flip it along the X direction to get this:
1478 *
1479 * ....
1480 * :N /
1481 * : /
1482 * :/ S
1483 */
1484 x = 1.0 - x;
1485
1486 /* To simplify the following computation, we can fold along the
1487 * diagonal. This leaves us with 1/8 of the map
1488 *
1489 * .....
1490 * :P /
1491 * : /
1492 * :/
1493 *
1494 * where P is the polar regions and / is the equator.
1495 * We must remember which hemisphere we are on for later. */
1496 if (x + y > 1.0) {
1497 /* This actually reflects the bottom-right half about the center point,
1498 * rather than about the diagonal, but that makes no difference. */
1499 x = 1.0 - x;
1500 y = 1.0 - y;
1501 toroid_flipped = TRUE;
1502 } else {
1503 toroid_flipped = FALSE;
1504 }
1505
1506 /* toroid_rel_colatitude is 0.0 at the poles and 1.0 at the equator.
1507 * This projection makes poles with a shape of a quarter-circle along
1508 * "P" and the equator as a straight line along "/".
1509 *
1510 * The formula is
1511 * lerp(1.5 (x^2 + y^2), (x+y)^2, x+y)
1512 * where
1513 * lerp(a,b,t) = a * (1-t) + b * t
1514 * is the linear interpolation between a and b, with
1515 * lerp(a,b,0) = a and lerp(a,b,1) = b
1516 *
1517 * I.e. the colatitude is computed as a linear interpolation between
1518 * - a = 1.5 (x^2 + y^2), proportional to the squared pythagorean
1519 * distance from the pole, which gives circular lines of latitude; and
1520 * - b = (x+y)^2, the squared manhattan distance from the pole, which
1521 * gives straight, diagonal lines of latitude parallel to the equator.
1522 *
1523 * These are interpolated with t = (x+y), the manhattan distance, which
1524 * ranges from 0 at the pole to 1 at the equator. So near the pole, the
1525 * (squared) pythagorean distance wins out, giving mostly circular lines,
1526 * and near the equator, the (squared) manhattan distance wins out,
1527 * giving mostly straight lines.
1528 *
1529 * Note that the colatitude growing with the square of the distance from
1530 * the pole keeps areas relatively the same as on non-toroidal maps:
1531 * On non-torus maps, the area closer to a pole than a given tile, and
1532 * the colatitude at that tile, both grow linearly with distance from the
1533 * pole. On torus maps, since the poles are singular points rather than
1534 * entire map edges, the area closer to a pole than a given tile grows
1535 * with the square of the distance to the pole - and so the colatitude
1536 * at that tile must also grow with the square in order to keep the size
1537 * of areas in a given range of colatitude relatively the same.
1538 *
1539 * See OSDN#43665, as well as the original discussion (via newsreader) at
1540 * news://news.gmane.io/gmane.games.freeciv.devel/42648 */
1541 toroid_rel_colatitude = (1.5 * (x * x * y + x * y * y)
1542 - 0.5 * (x * x * x + y * y * y)
1543 + 1.5 * (x * x + y * y));
1544
1545 /* Finally, convert from colatitude to latitude and add hemisphere
1546 * information back in:
1547 * - if we did not flip along the diagonal before, we are in the
1548 * northern hemisphere, with relative latitude in [0.0,0.5]
1549 * - if we _did_ flip, we are in the southern hemisphere, with
1550 * relative latitude in [0.5,1.0]
1551 */
1552 return ((toroid_flipped
1553 ? 2.0 - (toroid_rel_colatitude)
1554 : (toroid_rel_colatitude))
1555 / 2.0);
1556}
1557
1558/************************************************************************/
1566 int map_signed_latitude(const struct tile *ptile)
1567{
1568 int north_latitude, south_latitude;
1569 double southness;
1570
1571 north_latitude = MAP_NORTH_LATITUDE(wld.map);
1572 south_latitude = MAP_SOUTH_LATITUDE(wld.map);
1573
1574 if (north_latitude == south_latitude) {
1575 /* Single-latitude / all-temperate map; no need to examine tile. */
1576 return south_latitude;
1577 }
1578
1579 fc_assert_ret_val(ptile != nullptr, (north_latitude + south_latitude) / 2);
1580
1581 southness = map_relative_southness(ptile);
1582
1583 /* Linear interpolation between northernmost and southernmost latitude.
1584 * Truncate / round towards zero so northern and southern hemisphere
1585 * are symmetrical when south_latitude = -north_latitude. */
1586 return north_latitude * (1.0 - southness) + south_latitude * southness;
1587}
1588
1589/*******************************************************************/
1597 bool is_singular_tile(const struct tile *ptile, int dist)
1598{
1599 int tile_x, tile_y;
1600
1601 index_to_map_pos(&tile_x, &tile_y, tile_index(ptile));
1602 do_in_natural_pos(ntl_x, ntl_y, tile_x, tile_y) {
1603 /* Iso-natural coordinates are doubled in scale. */
1604 dist *= MAP_IS_ISOMETRIC ? 2 : 1;
1605
1606 return ((!current_wrap_has_flag(WRAP_X)
1607 && (ntl_x < dist || ntl_x >= MAP_NATURAL_WIDTH - dist))
1608 || (!current_wrap_has_flag(WRAP_Y)
1609 && (ntl_y < dist || ntl_y >= MAP_NATURAL_HEIGHT - dist)));
1610 } do_in_natural_pos_end;
1611}
1612
1613/*******************************************************************/
1616 static struct startpos *startpos_new(struct tile *ptile)
1617{
1618 struct startpos *psp = fc_malloc(sizeof(*psp));
1619
1620 psp->location = ptile;
1621 psp->exclude = FALSE;
1622 psp->nations = nation_hash_new();
1623
1624 return psp;
1625}
1626
1627/*******************************************************************/
1630 static void startpos_destroy(struct startpos *psp)
1631{
1632 fc_assert_ret(psp != nullptr);
1633
1634 nation_hash_destroy(psp->nations);
1635 free(psp);
1636}
1637
1638/*******************************************************************/
1641 struct startpos *map_startpos_by_number(int id)
1642{
1643 return map_startpos_get(index_to_tile(&(wld.map), id));
1644}
1645
1646/*******************************************************************/
1650 int startpos_number(const struct startpos *psp)
1651{
1652 fc_assert_ret_val(psp != nullptr, -1);
1653
1654 return tile_index(psp->location);
1655}
1656
1657/*******************************************************************/
1661 bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
1662{
1663 fc_assert_ret_val(psp != nullptr, FALSE);
1664 fc_assert_ret_val(pnation != nullptr, FALSE);
1665
1666 if (0 == nation_hash_size(psp->nations) || !psp->exclude) {
1667 psp->exclude = FALSE; /* Disable "excluding" mode. */
1668 return nation_hash_insert(psp->nations, pnation, nullptr);
1669 } else {
1670 return nation_hash_remove(psp->nations, pnation);
1671 }
1672}
1673
1674/*******************************************************************/
1678 bool startpos_disallow(struct startpos *psp, struct nation_type *pnation)
1679{
1680 fc_assert_ret_val(psp != nullptr, FALSE);
1681 fc_assert_ret_val(pnation != nullptr, FALSE);
1682
1683 if (0 == nation_hash_size(psp->nations) || psp->exclude) {
1684 psp->exclude = TRUE; /* Enable "excluding" mode. */
1685 return nation_hash_remove(psp->nations, pnation);
1686 } else {
1687 return nation_hash_insert(psp->nations, pnation, nullptr);
1688 }
1689}
1690
1691/*******************************************************************/
1694 struct tile *startpos_tile(const struct startpos *psp)
1695{
1696 fc_assert_ret_val(psp != nullptr, nullptr);
1697
1698 return psp->location;
1699}
1700
1701/*******************************************************************/
1704 bool startpos_nation_allowed(const struct startpos *psp,
1705 const struct nation_type *pnation)
1706{
1707 fc_assert_ret_val(psp != nullptr, FALSE);
1708 fc_assert_ret_val(pnation != nullptr, FALSE);
1709
1710 return XOR(psp->exclude, nation_hash_lookup(psp->nations, pnation,
1711 nullptr));
1712}
1713
1714/*******************************************************************/
1717 bool startpos_allows_all(const struct startpos *psp)
1718{
1719 fc_assert_ret_val(psp != nullptr, FALSE);
1720
1721 return (0 == nation_hash_size(psp->nations));
1722}
1723
1724/*******************************************************************/
1728 bool startpos_pack(const struct startpos *psp,
1729 struct packet_edit_startpos_full *packet)
1730{
1731 fc_assert_ret_val(psp != nullptr, FALSE);
1732 fc_assert_ret_val(packet != nullptr, FALSE);
1733
1734 packet->id = startpos_number(psp);
1735 packet->exclude = psp->exclude;
1736 BV_CLR_ALL(packet->nations);
1737
1738 nation_hash_iterate(psp->nations, pnation) {
1739 BV_SET(packet->nations, nation_number(pnation));
1740 } nation_hash_iterate_end;
1741
1742 return TRUE;
1743}
1744
1745/*******************************************************************/
1749 bool startpos_unpack(struct startpos *psp,
1750 const struct packet_edit_startpos_full *packet)
1751{
1752 fc_assert_ret_val(psp != nullptr, FALSE);
1753 fc_assert_ret_val(packet != nullptr, FALSE);
1754
1755 psp->exclude = packet->exclude;
1756
1757 nation_hash_clear(psp->nations);
1758 if (!BV_ISSET_ANY(packet->nations)) {
1759 return TRUE;
1760 }
1761 nations_iterate(pnation) {
1762 if (BV_ISSET(packet->nations, nation_number(pnation))) {
1763 nation_hash_insert(psp->nations, pnation, nullptr);
1764 }
1765 } nations_iterate_end;
1766
1767 return TRUE;
1768}
1769
1770/*******************************************************************/
1777 bool startpos_is_excluding(const struct startpos *psp)
1778{
1779 fc_assert_ret_val(psp != nullptr, FALSE);
1780
1781 return psp->exclude;
1782}
1783
1784/*******************************************************************/
1790 const struct nation_hash *startpos_raw_nations(const struct startpos *psp)
1791{
1792 fc_assert_ret_val(psp != nullptr, nullptr);
1793
1794 return psp->nations;
1795}
1796
1797/*******************************************************************/
1803 size_t startpos_iter_sizeof(void)
1804{
1805 return MAX(sizeof(struct startpos_iter) + nation_iter_sizeof()
1806 - sizeof(struct iterator), nation_hash_iter_sizeof());
1807}
1808
1809/*******************************************************************/
1815 static void startpos_exclude_iter_next(struct iterator *startpos_iter)
1816{
1817 struct startpos_iter *iter = STARTPOS_ITER(startpos_iter);
1818
1819 do {
1820 iterator_next(&iter->nation_iter);
1821 } while (iterator_valid(&iter->nation_iter)
1822 || !nation_hash_lookup(iter->psp->nations,
1823 iterator_get(&iter->nation_iter),
1824 nullptr));
1825}
1826
1827/*******************************************************************/
1834 static void *startpos_exclude_iter_get(const struct iterator *startpos_iter)
1835{
1836 struct startpos_iter *iter = STARTPOS_ITER(startpos_iter);
1837
1838 return iterator_get(&iter->nation_iter);
1839}
1840
1841/*******************************************************************/
1844 static bool startpos_exclude_iter_valid(const struct iterator *startpos_iter)
1845{
1846 struct startpos_iter *iter = STARTPOS_ITER(startpos_iter);
1847
1848 return iterator_valid(&iter->nation_iter);
1849}
1850
1851/*******************************************************************/
1854 struct iterator *startpos_iter_init(struct startpos_iter *iter,
1855 const struct startpos *psp)
1856{
1857 if (psp == nullptr) {
1858 return invalid_iter_init(ITERATOR(iter));
1859 }
1860
1861 if (startpos_allows_all(psp)) {
1862 return nation_iter_init((struct nation_iter *) iter);
1863 }
1864
1865 if (!psp->exclude) {
1866 return nation_hash_key_iter_init((struct nation_hash_iter *) iter,
1867 psp->nations);
1868 }
1869
1870 iter->vtable.next = startpos_exclude_iter_next;
1871 iter->vtable.get = startpos_exclude_iter_get;
1872 iter->vtable.valid = startpos_exclude_iter_valid;
1873 iter->psp = psp;
1874 (void) nation_iter_init((struct nation_iter *) &iter->nation_iter);
1875
1876 return ITERATOR(iter);
1877}
1878
1879/*******************************************************************/
1882 int map_startpos_count(void)
1883{
1884 if (wld.map.startpos_table != nullptr) {
1885 return startpos_hash_size(wld.map.startpos_table);
1886 } else {
1887 return 0;
1888 }
1889}
1890
1891/*******************************************************************/
1895 struct startpos *map_startpos_new(struct tile *ptile)
1896{
1897 struct startpos *psp;
1898
1899 fc_assert_ret_val(ptile != nullptr, nullptr);
1900 fc_assert_ret_val(wld.map.startpos_table != nullptr, nullptr);
1901
1902 psp = startpos_new(ptile);
1903 startpos_hash_replace(wld.map.startpos_table, tile_hash_key(ptile), psp);
1904
1905 return psp;
1906}
1907
1908/*******************************************************************/
1912 struct startpos *map_startpos_get(const struct tile *ptile)
1913{
1914 struct startpos *psp;
1915
1916 fc_assert_ret_val(ptile != nullptr, nullptr);
1917 fc_assert_ret_val(wld.map.startpos_table != nullptr, nullptr);
1918
1919 startpos_hash_lookup(wld.map.startpos_table, tile_hash_key(ptile), &psp);
1920
1921 return psp;
1922}
1923
1924/*******************************************************************/
1928 bool map_startpos_remove(struct tile *ptile)
1929{
1930 fc_assert_ret_val(ptile != nullptr, FALSE);
1931 fc_assert_ret_val(wld.map.startpos_table != nullptr, FALSE);
1932
1933 return startpos_hash_remove(wld.map.startpos_table, tile_hash_key(ptile));
1934}
1935
1936/*******************************************************************/
1940 size_t map_startpos_iter_sizeof(void)
1941{
1942 return startpos_hash_iter_sizeof();
1943}
1944
1945/*******************************************************************/
1949 struct iterator *map_startpos_iter_init(struct map_startpos_iter *iter)
1950{
1951 return startpos_hash_value_iter_init((struct startpos_hash_iter *) iter,
1952 wld.map.startpos_table);
1953}
1954
1955/*******************************************************************/
1958 enum direction8 rand_direction(void)
1959{
1960 return MAP_VALID_DIRS[fc_rand(MAP_NUM_VALID_DIRS)];
1961}
1962
1963/*******************************************************************/
1966 enum direction8 opposite_direction(enum direction8 dir)
1967{
1968 return direction8_max() - dir;
1969}
ai.h
CALL_FUNC_EACH_AI
#define CALL_FUNC_EACH_AI(_func,...)
Definition ai.h:387
BV_CLR_ALL
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
BV_SET
#define BV_SET(bv, bit)
Definition bitvector.h:81
BV_ISSET
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
BV_ISSET_ANY
#define BV_ISSET_ANY(vec)
Definition bitvector.h:109
generate_city_map_indices
void generate_city_map_indices(void)
Definition city.c:526
compare_iter_index
int compare_iter_index(const void *a, const void *b)
Definition city.c:342
city.h
incite_cost
char * incite_cost
Definition comments.c:74
punit
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
cost
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 int cost
Definition dialogs_g.h:74
is_native_extra_to_uclass
bool is_native_extra_to_uclass(const struct extra_type *pextra, const struct unit_class *pclass)
Definition extras.c:843
extra_type_iterate
#define extra_type_iterate(_p)
Definition extras.h:315
extra_type_list_iterate
#define extra_type_list_iterate(extralist, pextra)
Definition extras.h:165
extra_type_iterate_end
#define extra_type_iterate_end
Definition extras.h:321
extra_type_by_rmcause_iterate_end
#define extra_type_by_rmcause_iterate_end
Definition extras.h:358
extra_index
#define extra_index(_e_)
Definition extras.h:183
extra_type_by_rmcause_iterate
#define extra_type_by_rmcause_iterate(_rmcause, _extra)
Definition extras.h:353
extra_type_list_iterate_end
#define extra_type_list_iterate_end
Definition extras.h:167
extra_road_get
#define extra_road_get(_e_)
Definition extras.h:191
RPT_POSSIBLE
@ RPT_POSSIBLE
Definition fc_types.h:707
fcintl.h
game
struct civ_game game
Definition game.c:62
wld
struct world wld
Definition game.c:63
game.h
invalid_iter_init
struct iterator * invalid_iter_init(struct iterator *it)
Definition iterator.c:51
iterator.h
iterator_get
static void * iterator_get(const struct iterator *it)
Definition iterator.h:53
iterator_valid
static bool iterator_valid(const struct iterator *it)
Definition iterator.h:61
ITERATOR
#define ITERATOR(p)
Definition iterator.h:37
iterator_next
static void iterator_next(struct iterator *it)
Definition iterator.h:42
log.h
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
fc_assert
#define fc_assert(condition)
Definition log.h:176
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
log_debug
#define log_debug(message,...)
Definition log.h:115
get_tile_infrastructure_set
bv_extras get_tile_infrastructure_set(const struct tile *ptile, int *pcount)
Definition map.c:100
can_channel_land
bool can_channel_land(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:705
map_startpos_get
struct startpos * map_startpos_get(const struct tile *ptile)
Definition map.c:1912
is_normal_map_pos
bool is_normal_map_pos(int x, int y)
Definition map.c:973
DIR_DY
const int DIR_DY[8]
Definition map.c:86
startpos_number
int startpos_number(const struct startpos *psp)
Definition map.c:1650
can_reclaim_ocean
bool can_reclaim_ocean(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:690
map_free
void map_free(struct civ_map *fmap)
Definition map.c:536
startpos_disallow
bool startpos_disallow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1678
main_map_free
void main_map_free(void)
Definition map.c:560
nat_x
#define nat_x
map_vector_to_distance
static int map_vector_to_distance(int dx, int dy)
Definition map.c:570
opposite_direction
enum direction8 opposite_direction(enum direction8 dir)
Definition map.c:1966
nat_y
#define nat_y
is_move_cardinal
bool is_move_cardinal(const struct civ_map *nmap, const struct tile *start_tile, const struct tile *end_tile)
Definition map.c:1381
sq_map_distance
int sq_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:647
can_freeze_terrain
bool can_freeze_terrain(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:734
map_startpos_new
struct startpos * map_startpos_new(struct tile *ptile)
Definition map.c:1895
can_thaw_terrain
bool can_thaw_terrain(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:719
tile_move_cost_ptrs
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:786
tile_free
static void tile_free(struct tile *ptile)
Definition map.c:480
startpos_nation_allowed
bool startpos_nation_allowed(const struct startpos *psp, const struct nation_type *pnation)
Definition map.c:1704
STARTPOS_ITER
#define STARTPOS_ITER(p)
Definition map.c:64
map_num_tiles
int map_num_tiles(void)
Definition map.c:1026
get_direction_for_step
int get_direction_for_step(const struct civ_map *nmap, const struct tile *start_tile, const struct tile *end_tile)
Definition map.c:1362
startpos_tile
struct tile * startpos_tile(const struct startpos *psp)
Definition map.c:1694
startpos_allows_all
bool startpos_allows_all(const struct startpos *psp)
Definition map.c:1717
startpos_raw_nations
const struct nation_hash * startpos_raw_nations(const struct startpos *psp)
Definition map.c:1790
DIR_DX
const int DIR_DX[8]
Definition map.c:85
rand_map_pos
struct tile * rand_map_pos(const struct civ_map *nmap)
Definition map.c:1102
restrict_infra
static bool restrict_infra(const struct player *pplayer, const struct tile *t1, const struct tile *t2)
Definition map.c:921
base_native_pos_to_tile
static struct tile * base_native_pos_to_tile(const struct civ_map *nmap, int nat_x, int nat_y)
Definition map.c:401
generate_map_indices
static void generate_map_indices(void)
Definition map.c:203
dir_get_name
const char * dir_get_name(enum direction8 dir)
Definition map.c:1161
dir_ccw
enum direction8 dir_ccw(enum direction8 dir)
Definition map.c:1218
map_startpos_iter_init
struct iterator * map_startpos_iter_init(struct map_startpos_iter *iter)
Definition map.c:1949
is_tiles_adjacent
bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
Definition map.c:941
map_allocate
void map_allocate(struct civ_map *amap)
Definition map.c:499
main_map_allocate
void main_map_allocate(void)
Definition map.c:525
dir_validity
static bool dir_validity[9]
Definition map.c:89
is_safe_ocean
bool is_safe_ocean(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:673
startpos_new
static struct startpos * startpos_new(struct tile *ptile)
Definition map.c:1616
map_relative_southness
static double map_relative_southness(const struct tile *ptile)
Definition map.c:1412
startpos_pack
bool startpos_pack(const struct startpos *psp, struct packet_edit_startpos_full *packet)
Definition map.c:1728
is_valid_dir_calculate
static bool is_valid_dir_calculate(enum direction8 dir)
Definition map.c:1248
index_to_tile
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:462
map_signed_latitude
int map_signed_latitude(const struct tile *ptile)
Definition map.c:1566
is_cardinal_dir_calculate
static bool is_cardinal_dir_calculate(enum direction8 dir)
Definition map.c:1305
map_pos_to_tile
struct tile * map_pos_to_tile(const struct civ_map *nmap, int map_x, int map_y)
Definition map.c:425
map_vector_to_sq_distance
int map_vector_to_sq_distance(int dx, int dy)
Definition map.c:620
map_startpos_remove
bool map_startpos_remove(struct tile *ptile)
Definition map.c:1928
rand_map_pos_filtered
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:1116
map_startpos_count
int map_startpos_count(void)
Definition map.c:1882
startpos_iter_sizeof
size_t startpos_iter_sizeof(void)
Definition map.c:1803
is_cardinal_dir
bool is_cardinal_dir(enum direction8 dir)
Definition map.c:1331
tile_init
static void tile_init(struct tile *ptile)
Definition map.c:354
same_pos
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:950
map_untrusted_dir_is_valid
bool map_untrusted_dir_is_valid(enum direction8 dir)
Definition map.c:1288
terrain_surroundings_allow_change
bool terrain_surroundings_allow_change(const struct civ_map *nmap, const struct tile *ptile, const struct terrain *pterrain)
Definition map.c:748
real_map_distance
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:636
startpos_unpack
bool startpos_unpack(struct startpos *psp, const struct packet_edit_startpos_full *packet)
Definition map.c:1749
is_valid_dir
bool is_valid_dir(enum direction8 dir)
Definition map.c:1275
base_map_distance_vector
void base_map_distance_vector(int *dx, int *dy, int x0dv, int y0dv, int x1dv, int y1dv)
Definition map.c:1036
dir_cw
enum direction8 dir_cw(enum direction8 dir)
Definition map.c:1189
rand_direction
enum direction8 rand_direction(void)
Definition map.c:1958
mapstep
struct tile * mapstep(const struct civ_map *nmap, const struct tile *ptile, enum direction8 dir)
Definition map.c:375
startpos_destroy
static void startpos_destroy(struct startpos *psp)
Definition map.c:1630
terrain_control
struct terrain_misc terrain_control
Definition map.c:68
startpos_exclude_iter_get
static void * startpos_exclude_iter_get(const struct iterator *startpos_iter)
Definition map.c:1834
nearest_real_tile
struct tile * nearest_real_tile(const struct civ_map *nmap, int x, int y)
Definition map.c:1007
base_get_direction_for_step
bool base_get_direction_for_step(const struct civ_map *nmap, const struct tile *start_tile, const struct tile *end_tile, enum direction8 *dir)
Definition map.c:1343
startpos_exclude_iter_next
static void startpos_exclude_iter_next(struct iterator *startpos_iter)
Definition map.c:1815
native_pos_to_tile
struct tile * native_pos_to_tile(const struct civ_map *nmap, int nat_x, int nat_y)
Definition map.c:449
map_distance_vector
void map_distance_vector(int *dx, int *dy, const struct tile *tile0, const struct tile *tile1)
Definition map.c:1087
dir_cardinality
static bool dir_cardinality[9]
Definition map.c:88
map_init
void map_init(struct civ_map *imap, bool server_side)
Definition map.c:156
startpos_is_excluding
bool startpos_is_excluding(const struct startpos *psp)
Definition map.c:1777
map_distance
int map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:660
map_startpos_by_number
struct startpos * map_startpos_by_number(int id)
Definition map.c:1641
map_is_empty
bool map_is_empty(void)
Definition map.c:148
map_startpos_iter_sizeof
size_t map_startpos_iter_sizeof(void)
Definition map.c:1940
startpos_allow
bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1661
normalize_map_pos
bool normalize_map_pos(const struct civ_map *nmap, int *x, int *y)
Definition map.c:991
startpos_exclude_iter_valid
static bool startpos_exclude_iter_valid(const struct iterator *startpos_iter)
Definition map.c:1844
startpos_iter_init
struct iterator * startpos_iter_init(struct startpos_iter *iter, const struct startpos *psp)
Definition map.c:1854
is_real_map_pos
bool is_real_map_pos(const struct civ_map *nmap, int x, int y)
Definition map.c:962
map_init_topology
void map_init_topology(void)
Definition map.c:306
is_singular_tile
bool is_singular_tile(const struct tile *ptile, int dist)
Definition map.c:1597
map_vector_to_real_distance
int map_vector_to_real_distance(int dx, int dy)
Definition map.c:584
map.h
MAP_MAX_SIZE
#define MAP_MAX_SIZE
Definition map.h:610
current_topo_has_flag
#define current_topo_has_flag(flag)
Definition map.h:43
MAP_DEFAULT_SIZE
#define MAP_DEFAULT_SIZE
Definition map.h:608
MAP_MAX_LINEAR_SIZE
#define MAP_MAX_LINEAR_SIZE
Definition map.h:626
adjc_dir_iterate
#define adjc_dir_iterate(nmap, center_tile, itr_tile, dir_itr)
Definition map.h:424
MAP_DEFAULT_HUTS
#define MAP_DEFAULT_HUTS
Definition map.h:590
adjc_iterate_end
#define adjc_iterate_end
Definition map.h:419
do_in_natural_pos
#define do_in_natural_pos(ntl_x, ntl_y, map_x, map_y)
Definition map.h:203
MAP_DEFAULT_LINEAR_SIZE
#define MAP_DEFAULT_LINEAR_SIZE
Definition map.h:625
MAP_DEFAULT_STARTPOS
#define MAP_DEFAULT_STARTPOS
Definition map.h:666
MAP_DEFAULT_ANIMALS
#define MAP_DEFAULT_ANIMALS
Definition map.h:594
MAP_DEFAULT_TEAM_PLACEMENT
#define MAP_DEFAULT_TEAM_PLACEMENT
Definition map.h:684
MAP_DEFAULT_TOPO
#define MAP_DEFAULT_TOPO
Definition map.h:640
MAP_DEFAULT_SEED
#define MAP_DEFAULT_SEED
Definition map.h:644
CHECK_INDEX
#define CHECK_INDEX(mindex)
Definition map.h:142
cardinal_between_iterate
#define cardinal_between_iterate(nmap, tile1, tile2, between)
Definition map.h:463
MAP_DEFAULT_MAPSIZE
#define MAP_DEFAULT_MAPSIZE
Definition map.h:598
MAP_MIN_LINEAR_SIZE
#define MAP_MIN_LINEAR_SIZE
Definition map.h:627
MAP_DEFAULT_LANDMASS
#define MAP_DEFAULT_LANDMASS
Definition map.h:648
adjc_iterate
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:414
MAP_SOUTH_LATITUDE
#define MAP_SOUTH_LATITUDE(_nmap)
Definition map.h:569
MAP_TO_NATIVE_POS
#define MAP_TO_NATIVE_POS(pnat_x, pnat_y, map_x, map_y)
Definition map.h:165
ALL_DIRECTIONS_CARDINAL
#define ALL_DIRECTIONS_CARDINAL()
Definition map.h:48
NATIVE_TO_MAP_POS
#define NATIVE_TO_MAP_POS(pmap_x, pmap_y, nat_x, nat_y)
Definition map.h:159
cardinal_adjc_dir_iterate_end
#define cardinal_adjc_dir_iterate_end
Definition map.h:452
MAP_DEFAULT_WRAP
#define MAP_DEFAULT_WRAP
Definition map.h:641
MAP_MIN_SIZE
#define MAP_MIN_SIZE
Definition map.h:609
MAP_DEFAULT_NORTH_LATITUDE
#define MAP_DEFAULT_NORTH_LATITUDE
Definition map.h:564
MAP_DEFAULT_SEPARATE_POLES
#define MAP_DEFAULT_SEPARATE_POLES
Definition map.h:672
MAP_DEFAULT_RICHES
#define MAP_DEFAULT_RICHES
Definition map.h:652
MAP_DEFAULT_TINYISLES
#define MAP_DEFAULT_TINYISLES
Definition map.h:668
whole_map_iterate
#define whole_map_iterate(_map, _tile)
Definition map.h:531
MAP_NORTH_LATITUDE
#define MAP_NORTH_LATITUDE(_nmap)
Definition map.h:568
MAP_DEFAULT_TILESPERPLAYER
#define MAP_DEFAULT_TILESPERPLAYER
Definition map.h:620
adjc_dir_iterate_end
#define adjc_dir_iterate_end
Definition map.h:428
MAP_DEFAULT_TEMPERATURE
#define MAP_DEFAULT_TEMPERATURE
Definition map.h:680
cardinal_between_iterate_end
#define cardinal_between_iterate_end
Definition map.h:468
MAP_DEFAULT_SOUTH_LATITUDE
#define MAP_DEFAULT_SOUTH_LATITUDE
Definition map.h:565
current_wrap_has_flag
#define current_wrap_has_flag(flag)
Definition map.h:46
MAP_DEFAULT_GENERATOR
#define MAP_DEFAULT_GENERATOR
Definition map.h:664
do_in_natural_pos_end
#define do_in_natural_pos_end
Definition map.h:210
MAP_DEFAULT_WETNESS
#define MAP_DEFAULT_WETNESS
Definition map.h:660
native_pos_to_index_nocheck
#define native_pos_to_index_nocheck(nat_x, nat_y)
Definition map.h:145
cardinal_adjc_dir_iterate
#define cardinal_adjc_dir_iterate(nmap, center_tile, itr_tile, dir_itr)
Definition map.h:448
whole_map_iterate_end
#define whole_map_iterate_end
Definition map.h:540
index_to_map_pos
#define index_to_map_pos(pmap_x, pmap_y, mindex)
Definition map.h:218
MAP_DEFAULT_STEEPNESS
#define MAP_DEFAULT_STEEPNESS
Definition map.h:656
DIRSTEP
#define DIRSTEP(dest_x, dest_y, dir)
Definition map.h:225
terrain_misc
#define terrain_misc
Definition map_types.h:29
mem.h
fc_calloc
#define fc_calloc(n, esz)
Definition mem.h:38
FC_FREE
#define FC_FREE(ptr)
Definition mem.h:41
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
movement.h
SINGLE_MOVE
#define SINGLE_MOVE
Definition movement.h:26
is_native_tile_to_class
static bool is_native_tile_to_class(const struct unit_class *punitclass, const struct tile *ptile)
Definition movement.h:84
MOVE_COST_IGTER
#define MOVE_COST_IGTER
Definition movement.h:27
nation_number
Nation_type_id nation_number(const struct nation_type *pnation)
Definition nation.c:486
nation_iter_init
struct iterator * nation_iter_init(struct nation_iter *it)
Definition nation.c:557
nation_iter_sizeof
size_t nation_iter_sizeof(void)
Definition nation.c:524
nation.h
nation_hash_iterate
#define nation_hash_iterate(nationhash, pnation)
Definition nation.h:93
nations_iterate_end
#define nations_iterate_end
Definition nation.h:336
nations_iterate
#define nations_iterate(NAME_pnation)
Definition nation.h:333
nation_hash_iterate_end
#define nation_hash_iterate_end
Definition nation.h:95
packets.h
pplayers_at_war
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1388
rand.h
fc_rand
#define fc_rand(_size)
Definition rand.h:56
are_reqs_active
bool are_reqs_active(const struct req_context *context, const struct player *other_player, const struct requirement_vector *reqs, const enum req_problem_type prob_type)
Definition requirements.c:5705
road_has_flag
bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
Definition road.c:410
road.h
shared.h
CLIP
#define CLIP(lower, current, upper)
Definition shared.h:57
FC_WRAP
#define FC_WRAP(value, range)
Definition shared.h:65
MAX
#define MAX(x, y)
Definition shared.h:54
XOR
#define XOR(p, q)
Definition shared.h:71
spechash.h
y
struct sprite int int y
Definition sprite_g.h:31
x
struct sprite int x
Definition sprite_g.h:31
civ_game::info
struct packet_game_info info
Definition game.h:89
civ_map
Definition map_types.h:71
civ_map::startpos_table
struct startpos_hash * startpos_table
Definition map_types.h:85
civ_map::tiles
struct tile * tiles
Definition map_types.h:84
civ_map::valid_dirs
enum direction8 valid_dirs[8]
Definition map_types.h:75
civ_map::num_iterate_outwards_indices
int num_iterate_outwards_indices
Definition map_types.h:78
civ_map::num_cardinal_dirs
int num_cardinal_dirs
Definition map_types.h:76
civ_map::num_valid_dirs
int num_valid_dirs
Definition map_types.h:76
civ_map::iterate_outwards_indices
struct iter_index * iterate_outwards_indices
Definition map_types.h:77
civ_map::cardinal_dirs
enum direction8 cardinal_dirs[8]
Definition map_types.h:75
iter_index::dist
int dist
Definition city.h:110
iter_index::dx
int dx
Definition city.h:110
iter_index::dy
int dy
Definition city.h:110
iterator
Definition iterator.h:31
nation_iter
Definition nation.c:515
nation_type
Definition nation.h:98
packet_edit_startpos_full
Definition packets_gen.h:1703
packet_edit_startpos_full::id
int id
Definition packets_gen.h:1704
packet_edit_startpos_full::exclude
bool exclude
Definition packets_gen.h:1705
packet_edit_startpos_full::nations
bv_startpos_nations nations
Definition packets_gen.h:1706
packet_game_info::restrictinfra
bool restrictinfra
Definition packets_gen.h:224
player
Definition player.h:249
req_context
Definition requirements.h:100
road_type
Definition road.h:71
startpos_iter
Definition map.c:57
startpos_iter::psp
const struct startpos * psp
Definition map.c:59
startpos_iter::vtable
struct iterator vtable
Definition map.c:58
startpos
Definition map.c:40
startpos::exclude
bool exclude
Definition map.c:42
startpos::location
struct tile * location
Definition map.c:41
startpos::nations
struct nation_hash * nations
Definition map.c:43
terrain
Definition terrain.h:75
tile
Definition tile.h:50
tile::spec_sprite
char * spec_sprite
Definition tile.h:67
tile::label
char * label
Definition tile.h:66
tile::altitude
int altitude
Definition tile.h:65
tile::extras
bv_extras extras
Definition tile.h:55
tile::resource
struct extra_type * resource
Definition tile.h:56
tile::units
struct unit_list * units
Definition tile.h:58
tile::extras_owner
struct player * extras_owner
Definition tile.h:63
tile::terrain
struct terrain * terrain
Definition tile.h:57
tile::placing
struct extra_type * placing
Definition tile.h:61
tile::worked
struct city * worked
Definition tile.h:59
tile::owner
struct player * owner
Definition tile.h:60
tile::continent
Continent_id continent
Definition tile.h:54
tile::claimer
struct tile * claimer
Definition tile.h:64
unit_class
Definition unittype.h:149
unit_type
Definition unittype.h:507
unit
Definition unit.h:140
world::map
struct civ_map map
Definition world_object.h:38
support.h
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
count_terrain_class_near_tile
int count_terrain_class_near_tile(const struct civ_map *nmap, const struct tile *ptile, bool cardinal_only, bool percentage, enum terrain_class tclass)
Definition terrain.c:633
count_terrain_flag_near_tile
int count_terrain_flag_near_tile(const struct civ_map *nmap, const struct tile *ptile, bool cardinal_only, bool percentage, enum terrain_flag_id flag)
Definition terrain.c:478
T_UNKNOWN
#define T_UNKNOWN
Definition terrain.h:62
is_ocean
#define is_ocean(pterrain)
Definition terrain.h:194
terrain_has_flag
#define terrain_has_flag(terr, flag)
Definition terrain.h:176
tile_virtual_destroy
void tile_virtual_destroy(struct tile *vtile)
Definition tile.c:1035
tile_remove_extra
void tile_remove_extra(struct tile *ptile, const struct extra_type *pextra)
Definition tile.c:965
tile_virtual_new
struct tile * tile_virtual_new(const struct tile *ptile)
Definition tile.c:981
tile_hash_key
void * tile_hash_key(const struct tile *ptile)
Definition tile.c:1085
tile_city
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
tile_index
#define tile_index(_pt_)
Definition tile.h:89
ACTIVITY_FACTOR
#define ACTIVITY_FACTOR
Definition tile.h:166
tile_terrain
#define tile_terrain(_tile)
Definition tile.h:111
tile_has_extra
#define tile_has_extra(ptile, pextra)
Definition tile.h:148
tile_owner
#define tile_owner(_tile)
Definition tile.h:97
unit.h
unitlist.h
uclass_has_flag
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:773
utype_class
#define utype_class(_t_)
Definition unittype.h:756
utype_has_flag
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:624
MAP_NATIVE_WIDTH
#define MAP_NATIVE_WIDTH
Definition world_object.h:55
MAP_NUM_VALID_DIRS
#define MAP_NUM_VALID_DIRS
Definition world_object.h:65
MAP_INDEX_SIZE
#define MAP_INDEX_SIZE
Definition world_object.h:52
MAP_IS_ISOMETRIC
#define MAP_IS_ISOMETRIC
Definition world_object.h:46
MAP_NATURAL_HEIGHT
#define MAP_NATURAL_HEIGHT
Definition world_object.h:60
MAP_NATURAL_WIDTH
#define MAP_NATURAL_WIDTH
Definition world_object.h:59
MAP_NATIVE_HEIGHT
#define MAP_NATIVE_HEIGHT
Definition world_object.h:56
MAP_VALID_DIRS
#define MAP_VALID_DIRS
Definition world_object.h:64