Freeciv-3.2
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#include <string.h> /* strlen */
18
19/* utility */
20#include "fcintl.h"
21#include "iterator.h"
22#include "log.h"
23#include "mem.h"
24#include "rand.h"
25#include "shared.h"
26#include "support.h"
27
28/* common */
29#include "ai.h"
30#include "city.h"
31#include "game.h"
32#include "movement.h"
33#include "nation.h"
34#include "packets.h"
35#include "road.h"
36#include "unit.h"
37#include "unitlist.h"
38
39#include "map.h"
40
41struct startpos {
42 struct tile *location;
43 bool exclude;
45};
46
47static struct startpos *startpos_new(struct tile *ptile);
48static void startpos_destroy(struct startpos *psp);
49
50/* struct startpos_hash and related functions. */
51#define SPECHASH_TAG startpos
52#define SPECHASH_IKEY_TYPE struct tile *
53#define SPECHASH_IDATA_TYPE struct startpos *
54#define SPECHASH_IDATA_FREE startpos_destroy
55#include "spechash.h"
56
57/* Srart position iterator. */
60 const struct startpos *psp;
61 /* 'struct nation_iter' really. See startpos_iter_sizeof(). */
63};
64
65#define STARTPOS_ITER(p) ((struct startpos_iter *) (p))
66
67
68/* these are initialized from the terrain ruleset */
70
71/* used to compute neighboring tiles.
72 *
73 * using
74 * x1 = x + DIR_DX[dir];
75 * y1 = y + DIR_DY[dir];
76 * will give you the tile as shown below.
77 * -------
78 * |0|1|2|
79 * |-+-+-|
80 * |3| |4|
81 * |-+-+-|
82 * |5|6|7|
83 * -------
84 * Note that you must normalize x1 and y1 yourself.
85 */
86const int DIR_DX[8] = { -1, 0, 1, -1, 1, -1, 0, 1 };
87const int DIR_DY[8] = { -1, -1, -1, 0, 0, 1, 1, 1 };
88
89static bool dir_cardinality[9]; /* Including invalid one */
90static bool dir_validity[9]; /* Including invalid one */
91
92static bool is_valid_dir_calculate(enum direction8 dir);
93static bool is_cardinal_dir_calculate(enum direction8 dir);
94
95static bool restrict_infra(const struct player *pplayer, const struct tile *t1,
96 const struct tile *t2);
97
98/*******************************************************************/
102 int *pcount)
103{
105 int count = 0;
106
108
110 if (tile_has_extra(ptile, pextra)) {
111 struct tile *missingset = tile_virtual_new(ptile);
112 bool dependency = FALSE;
113
116 if (tile_has_extra(ptile, pdependant)) {
117 if (!are_reqs_active(&(const struct req_context) {
118 .tile = missingset,
119 },
120 NULL, &pdependant->reqs, RPT_POSSIBLE)) {
122 break;
123 }
124 }
126
128
129 if (!dependency) {
130 BV_SET(pspresent, extra_index(pextra));
131 count++;
132 }
133 }
135
136 if (pcount) {
137 *pcount = count;
138 }
139
140 return pspresent;
141}
142
143/*******************************************************************/
149bool map_is_empty(void)
150{
151 return wld.map.tiles == NULL;
152}
153
154/*******************************************************************/
157void map_init(struct civ_map *imap, bool server_side)
158{
159 imap->topology_id = MAP_DEFAULT_TOPO;
160 imap->wrap_id = MAP_DEFAULT_WRAP;
161 imap->num_continents = 0;
162 imap->num_oceans = 0;
163 imap->tiles = NULL;
164 imap->startpos_table = NULL;
165 imap->iterate_outwards_indices = NULL;
166
167 /* The [xy]size values are set in map_init_topology(). It is initialized
168 * to a non-zero value because some places erroneously use these values
169 * before they're initialized. */
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/*******************************************************************/
203static void generate_map_indices(void)
204{
205 int i = 0, nat_x, nat_y, tiles;
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 hit each
211 * 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 the
216 * positions iterated over before will not even be real; the point is to
217 * use the native math so as to get the right behavior under different
218 * 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. */
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. If
229 * not we need to explore the full width since we have to account for the
230 * worst-case where we start at one edge of the map. Of course if we try
231 * 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. This
237 * 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. */
246
248 ? (wld.map.xsize - 1)
249 : (nat_center_x + wld.map.xsize - 1));
251 ? (wld.map.ysize - 1)
252 : (nat_center_y + wld.map.ysize - 1));
253 tiles = (nat_max_x - nat_min_x + 1) * (nat_max_y - nat_min_y + 1);
254
257 fc_malloc(tiles * sizeof(*wld.map.iterate_outwards_indices));
258
259 for (nat_x = nat_min_x; nat_x <= nat_max_x; nat_x++) {
260 for (nat_y = nat_min_y; nat_y <= nat_max_y; nat_y++) {
261 int map_x, map_y, dx, dy;
262
263 /* Now for each position, we find the vector (in map coordinates) from
264 * the center position to that position. Then we calculate the
265 * distance between the two points. Wrapping is ignored at this
266 * point since the use of native positions means we should always have
267 * the shortest vector. */
269 dx = map_x - map_center_x;
270 dy = map_y - map_center_y;
271
276 i++;
277 }
278 }
279 fc_assert(i == tiles);
280
283
284#if 0
285 for (i = 0; i < tiles; i++) {
286 log_debug("%5d : (%3d,%3d) : %d", i,
290 }
291#endif
292
294}
295
296/*******************************************************************/
304{
305 enum direction8 dir;
306
307 /* sanity check for iso topologies*/
308 fc_assert(!MAP_IS_ISOMETRIC || (wld.map.ysize % 2) == 0);
309
310 /* The size and ratio must satisfy the minimum and maximum *linear*
311 * restrictions on width */
318
319 nmap->num_valid_dirs = nmap->num_cardinal_dirs = 0;
320
321 /* Values for direction8_invalid() */
323 dir_validity[8] = FALSE;
325
326 /* Values for actual directions */
327 for (dir = 0; dir < 8; dir++) {
328 if (is_valid_dir_calculate(dir)) {
329 nmap->valid_dirs[nmap->num_valid_dirs] = dir;
330 nmap->num_valid_dirs++;
331 dir_validity[dir] = TRUE;
332 } else {
333 dir_validity[dir] = FALSE;
334 }
335 if (is_cardinal_dir_calculate(dir)) {
336 nmap->cardinal_dirs[nmap->num_cardinal_dirs] = dir;
337 nmap->num_cardinal_dirs++;
338 dir_cardinality[dir] = TRUE;
339 } else {
340 dir_cardinality[dir] = FALSE;
341 }
342 }
343 fc_assert(nmap->num_valid_dirs > 0 && nmap->num_valid_dirs <= 8);
344 fc_assert(nmap->num_cardinal_dirs > 0
345 && nmap->num_cardinal_dirs <= nmap->num_valid_dirs);
346}
347
348/*******************************************************************/
351static void tile_init(struct tile *ptile)
352{
353 ptile->continent = 0;
354
355 BV_CLR_ALL(ptile->extras);
356 ptile->resource = NULL;
357 ptile->terrain = T_UNKNOWN;
358 ptile->units = unit_list_new();
359 ptile->owner = NULL; /* Not claimed by any player. */
360 ptile->extras_owner = NULL;
361 ptile->placing = NULL;
362 ptile->claimer = NULL;
363 ptile->worked = NULL; /* No city working here. */
364 ptile->spec_sprite = NULL;
365}
366
367/*******************************************************************/
371struct tile *mapstep(const struct civ_map *nmap,
372 const struct tile *ptile, enum direction8 dir)
373{
374 int dx, dy, tile_x, tile_y;
375
376 if (!is_valid_dir(dir)) {
377 return NULL;
378 }
379
381 DIRSTEP(dx, dy, dir);
382
383 tile_x += dx;
384 tile_y += dy;
385
386 return map_pos_to_tile(&(wld.map), tile_x, tile_y);
387}
388
389/*******************************************************************/
395static inline struct tile *base_native_pos_to_tile(const struct civ_map *nmap,
396 int nat_x, int nat_y)
397{
398 /* Wrap in X and Y directions, as needed. */
399 /* If the position is out of range in a non-wrapping direction, it is
400 * unreal. */
403 } else if (nat_x < 0 || nat_x >= wld.map.xsize) {
404 return NULL;
405 }
408 } else if (nat_y < 0 || nat_y >= wld.map.ysize) {
409 return NULL;
410 }
411
412 /* We already checked legality of native pos above, don't repeat */
414}
415
416/*******************************************************************/
419struct tile *map_pos_to_tile(const struct civ_map *nmap, int map_x, int map_y)
420{
421 /* Instead of introducing new variables for native coordinates,
422 * update the map coordinate variables = registers already in use.
423 * This is one of the most performance-critical functions we have,
424 * so taking measures like this makes sense. */
425#define nat_x map_x
426#define nat_y map_y
427
428 if (nmap->tiles == NULL) {
429 return NULL;
430 }
431
432 /* Normalization is best done in native coordinates. */
435
436#undef nat_x
437#undef nat_y
438}
439
440/*******************************************************************/
443struct tile *native_pos_to_tile(const struct civ_map *nmap,
444 int nat_x, int nat_y)
445{
446 if (nmap->tiles == NULL) {
447 return NULL;
448 }
449
451}
452
453/*******************************************************************/
456struct tile *index_to_tile(const struct civ_map *imap, int mindex)
457{
458 if (!imap->tiles) {
459 return NULL;
460 }
461
462 if (mindex >= 0 && mindex < MAP_INDEX_SIZE) {
463 return imap->tiles + mindex;
464 } else {
465 /* Unwrapped index coordinates are impossible, so the best we can do is
466 * return NULL. */
467 return NULL;
468 }
469}
470
471/*******************************************************************/
474static void tile_free(struct tile *ptile)
475{
476 unit_list_destroy(ptile->units);
477
478 if (ptile->spec_sprite) {
479 free(ptile->spec_sprite);
480 ptile->spec_sprite = NULL;
481 }
482
483 if (ptile->label) {
484 FC_FREE(ptile->label);
485 ptile->label = NULL;
486 }
487}
488
489/*******************************************************************/
494{
495 log_debug("map_allocate (was %p) (%d,%d)",
496 (void *) amap->tiles, amap->xsize, amap->ysize);
497
498 fc_assert_ret(NULL == amap->tiles);
499 amap->tiles = fc_calloc(MAP_INDEX_SIZE, sizeof(*amap->tiles));
500
501 /* Note this use of whole_map_iterate may be a bit sketchy, since the
502 * tile values (ptile->index, etc.) haven't been set yet. It might be
503 * better to do a manual loop here. */
504 whole_map_iterate(amap, ptile) {
505 ptile->index = ptile - amap->tiles;
506 CHECK_INDEX(tile_index(ptile));
507 tile_init(ptile);
509
510 if (amap->startpos_table != NULL) {
511 startpos_hash_destroy(amap->startpos_table);
512 }
513 amap->startpos_table = startpos_hash_new();
514}
515
516/*******************************************************************/
526
527/*******************************************************************/
530void map_free(struct civ_map *fmap)
531{
532 if (fmap->tiles) {
533 /* it is possible that map_init was called but not map_allocate */
534
535 whole_map_iterate(fmap, ptile) {
536 tile_free(ptile);
538
539 free(fmap->tiles);
540 fmap->tiles = NULL;
541
542 if (fmap->startpos_table) {
543 startpos_hash_destroy(fmap->startpos_table);
544 fmap->startpos_table = NULL;
545 }
546
547 FC_FREE(fmap->iterate_outwards_indices);
548 }
549}
550
551/*******************************************************************/
555{
556 map_free(&(wld.map));
558}
559
560/*******************************************************************/
564static int map_vector_to_distance(int dx, int dy)
565{
567 /* Hex: all directions are cardinal so the distance is equivalent to
568 * the real distance. */
569 return map_vector_to_real_distance(dx, dy);
570 } else {
571 return abs(dx) + abs(dy);
572 }
573}
574
575/*******************************************************************/
579{
580 const int absdx = abs(dx), absdy = abs(dy);
581
584 /* Iso-hex: you can't move NE or SW. */
585 if ((dx < 0 && dy > 0)
586 || (dx > 0 && dy < 0)) {
587 /* Diagonal moves in this direction aren't allowed, so it will take
588 * the full number of moves. */
589 return absdx + absdy;
590 } else {
591 /* Diagonal moves in this direction *are* allowed. */
592 return MAX(absdx, absdy);
593 }
594 } else {
595 /* Hex: you can't move SE or NW. */
596 if ((dx > 0 && dy > 0)
597 || (dx < 0 && dy < 0)) {
598 /* Diagonal moves in this direction aren't allowed, so it will take
599 * the full number of moves. */
600 return absdx + absdy;
601 } else {
602 /* Diagonal moves in this direction *are* allowed. */
603 return MAX(absdx, absdy);
604 }
605 }
606 } else {
607 return MAX(absdx, absdy);
608 }
609}
610
611/*******************************************************************/
614int map_vector_to_sq_distance(int dx, int dy)
615{
617 /* Hex: The square distance is just the square of the real distance; we
618 * don't worry about pythagorean calculations. */
619 int dist = map_vector_to_real_distance(dx, dy);
620
621 return dist * dist;
622 } else {
623 return dx * dx + dy * dy;
624 }
625}
626
627/*******************************************************************/
630int real_map_distance(const struct tile *tile0, const struct tile *tile1)
631{
632 int dx, dy;
633
634 map_distance_vector(&dx, &dy, tile0, tile1);
635 return map_vector_to_real_distance(dx, dy);
636}
637
638/*******************************************************************/
641int sq_map_distance(const struct tile *tile0, const struct tile *tile1)
642{
643 /* We assume map_distance_vector gives us the vector with the
644 minimum squared distance. Right now this is true. */
645 int dx, dy;
646
647 map_distance_vector(&dx, &dy, tile0, tile1);
648 return map_vector_to_sq_distance(dx, dy);
649}
650
651/*******************************************************************/
654int map_distance(const struct tile *tile0, const struct tile *tile1)
655{
656 /* We assume map_distance_vector gives us the vector with the
657 minimum map distance. Right now this is true. */
658 int dx, dy;
659
660 map_distance_vector(&dx, &dy, tile0, tile1);
661 return map_vector_to_distance(dx, dy);
662}
663
664/*******************************************************************/
667bool is_safe_ocean(const struct civ_map *nmap, const struct tile *ptile)
668{
669 adjc_iterate(nmap, ptile, adjc_tile) {
672 return TRUE;
673 }
675
676 return FALSE;
677}
678
679/*******************************************************************/
684bool can_reclaim_ocean(const struct civ_map *nmap,
685 const struct tile *ptile)
686{
688 FALSE, TRUE,
689 TC_OCEAN);
690
691 return land_tiles >= terrain_control.ocean_reclaim_requirement_pct;
692}
693
694/*******************************************************************/
699bool can_channel_land(const struct civ_map *nmap,
700 const struct tile *ptile)
701{
704
705 return ocean_tiles >= terrain_control.land_channel_requirement_pct;
706}
707
708/*******************************************************************/
713bool can_thaw_terrain(const struct civ_map *nmap,
714 const struct tile *ptile)
715{
717 FALSE, TRUE,
718 TER_FROZEN);
719
720 return unfrozen_tiles >= terrain_control.terrain_thaw_requirement_pct;
721}
722
723/*******************************************************************/
728bool can_freeze_terrain(const struct civ_map *nmap,
729 const struct tile *ptile)
730{
732 FALSE, TRUE,
733 TER_FROZEN);
734
735 return frozen_tiles >= terrain_control.terrain_freeze_requirement_pct;
736}
737
738/*******************************************************************/
743 const struct tile *ptile,
744 const struct terrain *pterrain)
745{
746 bool ret = TRUE;
747
748 if (is_ocean(tile_terrain(ptile))
749 && !is_ocean(pterrain) && !can_reclaim_ocean(nmap, ptile)) {
750 ret = FALSE;
751 } else if (!is_ocean(tile_terrain(ptile))
752 && is_ocean(pterrain) && !can_channel_land(nmap, ptile)) {
753 ret = FALSE;
754 }
755
756 if (ret) {
758 && !terrain_has_flag(pterrain, TER_FROZEN)
759 && !can_thaw_terrain(nmap, ptile)) {
760 ret = FALSE;
761 } else if (!terrain_has_flag(tile_terrain(ptile), TER_FROZEN)
762 && terrain_has_flag(pterrain, TER_FROZEN)
763 && !can_freeze_terrain(nmap, ptile)) {
764 ret = FALSE;
765 }
766 }
767
768 return ret;
769}
770
771/*******************************************************************/
781 const struct unit *punit,
782 const struct unit_type *punittype,
783 const struct player *pplayer,
784 const struct tile *t1, const struct tile *t2)
785{
786 const struct unit_class *pclass = utype_class(punittype);
787 int cost;
788 signed char cardinal_move = -1;
789 bool ri;
790
791 /* Try to exit early for detectable conditions */
793 /* units without UCF_TERRAIN_SPEED have a constant cost. */
794 return SINGLE_MOVE;
795
796 } else if (!is_native_tile_to_class(pclass, t2)) {
797 if (tile_city(t2) == NULL) {
798 /* Loading to transport. */
799
800 /* UTYF_IGTER units get move benefit. */
803 } else {
804 /* Entering port. (Could be "Conquer City") */
805
806 /* UTYF_IGTER units get move benefit. */
809 }
810
811 } else if (!is_native_tile_to_class(pclass, t1)) {
812 if (tile_city(t1) == NULL) {
813 /* Disembarking from transport. */
814
815 /* UTYF_IGTER units get move benefit. */
818 } else {
819 /* Leaving port. */
820
821 /* UTYF_IGTER units get move benefit. */
824 }
825 }
826
827 cost = tile_terrain(t2)->movement_cost * SINGLE_MOVE;
828 ri = restrict_infra(pplayer, t1, t2);
829
830 extra_type_list_iterate(pclass->cache.bonus_roads, pextra) {
831 struct road_type *proad = extra_road_get(pextra);
832
833 /* We check the destination tile first, as that's
834 * the end of move that determines the cost.
835 * If can avoid inner loop about integrating roads
836 * completely if the destination road has too high cost. */
837
838 if (cost > proad->move_cost
840 && tile_has_extra(t2, pextra)) {
841 extra_type_list_iterate(proad->integrators, iextra) {
842 /* We have no unrestricted infra related check here,
843 * destination road is the one that counts. */
844 if (tile_has_extra(t1, iextra)
846 if (proad->move_mode == RMM_FAST_ALWAYS) {
847 cost = proad->move_cost;
848 } else {
849 if (cardinal_move < 0) {
851 || is_move_cardinal(nmap, t1, t2)) ? 1 : 0;
852 }
853 if (cardinal_move > 0) {
854 cost = proad->move_cost;
855 } else {
856 switch (proad->move_mode) {
857 case RMM_CARDINAL:
858 break;
859 case RMM_RELAXED:
860 if (cost > proad->move_cost * 2) {
862 if (tile_has_extra(between, pextra)
863 || (pextra != iextra && tile_has_extra(between, iextra))) {
864 /* 'pextra != iextra' is there just to avoid tile_has_extra()
865 * in by far more common case that 'pextra == iextra' */
866 /* TODO: Should we restrict this more?
867 * Should we check against enemy cities on between tile?
868 * Should we check against non-native terrain on between tile?
869 */
870 cost = proad->move_cost * 2;
871 }
873 }
874 break;
875 case RMM_FAST_ALWAYS:
876 fc_assert(proad->move_mode != RMM_FAST_ALWAYS); /* Already handled above */
877 cost = proad->move_cost;
878 break;
879 }
880 }
881 }
882 }
884 }
886
887 /* UTYF_IGTER units have a maximum move cost per step. */
890 }
891
892 if (terrain_control.pythagorean_diagonal) {
893 if (cardinal_move < 0) {
895 || is_move_cardinal(nmap, t1, t2)) ? 1 : 0;
896 }
897 if (cardinal_move == 0) {
898 return cost * 181 >> 7; /* == (int) (cost * 1.41421356f) if cost < 99 */
899 }
900 }
901
902 return cost;
903}
904
905/*******************************************************************/
911static bool restrict_infra(const struct player *pplayer, const struct tile *t1,
912 const struct tile *t2)
913{
914 struct player *plr1 = tile_owner(t1), *plr2 = tile_owner(t2);
915
916 if (!pplayer || !game.info.restrictinfra) {
917 return FALSE;
918 }
919
920 if ((plr1 && pplayers_at_war(plr1, pplayer))
921 || (plr2 && pplayers_at_war(plr2, pplayer))) {
922 return TRUE;
923 }
924
925 return FALSE;
926}
927
928/*******************************************************************/
931bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
932{
933 return real_map_distance(tile0, tile1) == 1;
934}
935
936/*******************************************************************/
940bool same_pos(const struct tile *tile1, const struct tile *tile2)
941{
943
944 /* In case of virtual tile, tile1 can be different from tile2,
945 * but they have same index */
946 return (tile1->index == tile2->index);
947}
948
949/*******************************************************************/
952bool is_real_map_pos(const struct civ_map *nmap, int x, int y)
953{
954 return normalize_map_pos(nmap, &x, &y);
955}
956
957/*******************************************************************/
963bool is_normal_map_pos(int x, int y)
964{
965 int nat_x, nat_y;
966
968 return nat_x >= 0 && nat_x < wld.map.xsize && nat_y >= 0 && nat_y < wld.map.ysize;
969}
970
971/*******************************************************************/
979bool normalize_map_pos(const struct civ_map *nmap, int *x, int *y)
980{
981 struct tile *ptile = map_pos_to_tile(nmap, *x, *y);
982
983 if (ptile) {
984 index_to_map_pos(x, y, tile_index(ptile));
985 return TRUE;
986 } else {
987 return FALSE;
988 }
989}
990
991/*******************************************************************/
995struct tile *nearest_real_tile(const struct civ_map *nmap, int x, int y)
996{
997 int nat_x, nat_y;
998
1001 nat_x = CLIP(0, nat_x, wld.map.xsize - 1);
1002 }
1004 nat_y = CLIP(0, nat_y, wld.map.ysize - 1);
1005 }
1007
1008 return map_pos_to_tile(nmap, x, y);
1009}
1010
1011/*******************************************************************/
1015{
1016 return wld.map.xsize * wld.map.ysize;
1017}
1018
1019/*******************************************************************/
1024void base_map_distance_vector(int *dx, int *dy,
1025 int x0dv, int y0dv, int x1dv, int y1dv)
1026{
1028 /* Wrapping is done in native coordinates. */
1031
1032 /* Find the "native" distance vector. This corresponds closely to the
1033 * map distance vector but is easier to wrap. */
1034 *dx = x1dv - x0dv;
1035 *dy = y1dv - y0dv;
1037 /* Wrap dx to be in [-map.xsize/2, map.xsize/2). */
1038 *dx = FC_WRAP(*dx + wld.map.xsize / 2, wld.map.xsize) - wld.map.xsize / 2;
1039 }
1041 /* Wrap dy to be in [-map.ysize/2, map.ysize/2). */
1042 *dy = FC_WRAP(*dy + wld.map.ysize / 2, wld.map.ysize) - wld.map.ysize / 2;
1043 }
1044
1045 /* Convert the native delta vector back to a pair of map positions. */
1046 x1dv = x0dv + *dx;
1047 y1dv = y0dv + *dy;
1050 }
1051
1052 /* Find the final (map) vector. */
1053 *dx = x1dv - x0dv;
1054 *dy = y1dv - y0dv;
1055}
1056
1057/*******************************************************************/
1073void map_distance_vector(int *dx, int *dy,
1074 const struct tile *tile0,
1075 const struct tile *tile1)
1076{
1077 int tx0, ty0, tx1, ty1;
1078
1082}
1083
1084/*******************************************************************/
1088struct tile *rand_map_pos(const struct civ_map *nmap)
1089{
1091
1093}
1094
1095/*******************************************************************/
1101struct tile *rand_map_pos_filtered(const struct civ_map *nmap, void *data,
1102 bool (*filter)(const struct tile *ptile,
1103 const void *data))
1104{
1105 struct tile *ptile;
1106 int tries = 0;
1108
1109 /* First do a few quick checks to find a spot. The limit on number of
1110 * tries could use some tweaking. */
1111 do {
1112 ptile = nmap->tiles + fc_rand(MAP_INDEX_SIZE);
1113 } while (filter != NULL && !filter(ptile, data) && ++tries < max_tries);
1114
1115 /* If that fails, count all available spots and pick one.
1116 * Slow but reliable. */
1117 if (filter == NULL) {
1118 ptile = NULL;
1119 } else if (tries == max_tries) {
1120 int count = 0, *positions;
1121
1122 positions = fc_calloc(MAP_INDEX_SIZE, sizeof(*positions));
1123
1125 if (filter(check_tile, data)) {
1126 positions[count] = tile_index(check_tile);
1127 count++;
1128 }
1130
1131 if (count == 0) {
1132 ptile = NULL;
1133 } else {
1134 ptile = wld.map.tiles + positions[fc_rand(count)];
1135 }
1136
1137 FC_FREE(positions);
1138 }
1139
1140 return ptile;
1141}
1142
1143/*******************************************************************/
1146const char *dir_get_name(enum direction8 dir)
1147{
1148 /* a switch statement is used so the ordering can be changed easily */
1149 switch (dir) {
1150 case DIR8_NORTH:
1151 return "N";
1152 case DIR8_NORTHEAST:
1153 return "NE";
1154 case DIR8_EAST:
1155 return "E";
1156 case DIR8_SOUTHEAST:
1157 return "SE";
1158 case DIR8_SOUTH:
1159 return "S";
1160 case DIR8_SOUTHWEST:
1161 return "SW";
1162 case DIR8_WEST:
1163 return "W";
1164 case DIR8_NORTHWEST:
1165 return "NW";
1166 default:
1167 return "[Undef]";
1168 }
1169}
1170
1171/*******************************************************************/
1175{
1176 /* a switch statement is used so the ordering can be changed easily */
1177 switch (dir) {
1178 case DIR8_NORTH:
1179 return DIR8_NORTHEAST;
1180 case DIR8_NORTHEAST:
1181 return DIR8_EAST;
1182 case DIR8_EAST:
1183 return DIR8_SOUTHEAST;
1184 case DIR8_SOUTHEAST:
1185 return DIR8_SOUTH;
1186 case DIR8_SOUTH:
1187 return DIR8_SOUTHWEST;
1188 case DIR8_SOUTHWEST:
1189 return DIR8_WEST;
1190 case DIR8_WEST:
1191 return DIR8_NORTHWEST;
1192 case DIR8_NORTHWEST:
1193 return DIR8_NORTH;
1194 default:
1196 return -1;
1197 }
1198}
1199
1200/*******************************************************************/
1204{
1205 /* a switch statement is used so the ordering can be changed easily */
1206 switch (dir) {
1207 case DIR8_NORTH:
1208 return DIR8_NORTHWEST;
1209 case DIR8_NORTHEAST:
1210 return DIR8_NORTH;
1211 case DIR8_EAST:
1212 return DIR8_NORTHEAST;
1213 case DIR8_SOUTHEAST:
1214 return DIR8_EAST;
1215 case DIR8_SOUTH:
1216 return DIR8_SOUTHEAST;
1217 case DIR8_SOUTHWEST:
1218 return DIR8_SOUTH;
1219 case DIR8_WEST:
1220 return DIR8_SOUTHWEST;
1221 case DIR8_NORTHWEST:
1222 return DIR8_WEST;
1223 default:
1225 return -1;
1226 }
1227}
1228
1229/*******************************************************************/
1234{
1235 switch (dir) {
1236 case DIR8_SOUTHEAST:
1237 case DIR8_NORTHWEST:
1238 /* These directions are invalid in hex topologies. */
1240 case DIR8_NORTHEAST:
1241 case DIR8_SOUTHWEST:
1242 /* These directions are invalid in iso-hex topologies. */
1244 case DIR8_NORTH:
1245 case DIR8_EAST:
1246 case DIR8_SOUTH:
1247 case DIR8_WEST:
1248 return TRUE;
1249 default:
1250 return FALSE;
1251 }
1252}
1253
1254/*******************************************************************/
1261{
1263
1264 return dir_validity[dir];
1265}
1266
1267/*******************************************************************/
1274{
1275 if (!direction8_is_valid(dir)) {
1276 /* Isn't even in range of direction8. */
1277 return FALSE;
1278 }
1279
1280 return is_valid_dir(dir);
1281}
1282
1283/*******************************************************************/
1291{
1292 switch (dir) {
1293 case DIR8_NORTH:
1294 case DIR8_SOUTH:
1295 case DIR8_EAST:
1296 case DIR8_WEST:
1297 return TRUE;
1298 case DIR8_SOUTHEAST:
1299 case DIR8_NORTHWEST:
1300 /* These directions are cardinal in iso-hex topologies. */
1302 case DIR8_NORTHEAST:
1303 case DIR8_SOUTHWEST:
1304 /* These directions are cardinal in hexagonal topologies. */
1306 }
1307 return FALSE;
1308}
1309
1310/*******************************************************************/
1317{
1319
1320 return dir_cardinality[dir];
1321}
1322
1323/*******************************************************************/
1329 const struct tile *start_tile,
1330 const struct tile *end_tile,
1331 enum direction8 *dir)
1332{
1333 adjc_dir_iterate(nmap, start_tile, test_tile, test_dir) {
1334 if (same_pos(end_tile, test_tile)) {
1335 *dir = test_dir;
1336 return TRUE;
1337 }
1339
1340 return FALSE;
1341}
1342
1343/*******************************************************************/
1348 const struct tile *start_tile,
1349 const struct tile *end_tile)
1350{
1351 enum direction8 dir;
1352
1353 if (base_get_direction_for_step(nmap, start_tile, end_tile, &dir)) {
1354 return dir;
1355 }
1356
1358 return -1;
1359}
1360
1361/*******************************************************************/
1365bool is_move_cardinal(const struct civ_map *nmap,
1366 const struct tile *start_tile,
1367 const struct tile *end_tile)
1368{
1370 if (same_pos(end_tile, test_tile)) {
1371 return TRUE;
1372 }
1374
1375 return FALSE;
1376}
1377
1378/************************************************************************/
1396static double map_relative_southness(const struct tile *ptile)
1397{
1398 int tile_x, tile_y;
1399 double x, y, toroid_rel_colatitude;
1400 bool toroid_flipped;
1401
1402 /* TODO: What should the fallback value be?
1403 * Since this is not public API, it shouldn't matter anyway. */
1404 fc_assert_ret_val(ptile != NULL, 0.5);
1405
1408 /* Compute natural coordinates relative to world size.
1409 * x and y are in the range [0.0, 1.0] */
1410 x = (double)ntl_x / (NATURAL_WIDTH - 1);
1411 y = (double)ntl_y / (NATURAL_HEIGHT - 1);
1413
1415 /* In an Earth-like topology, north and south are at the top and
1416 * bottom of the map.
1417 * This is equivalent to a Mercator projection. */
1418 return y;
1419 }
1420
1422 /* In a Uranus-like topology, north and south are at the left and
1423 * right side of the map.
1424 * This isn't really the way Uranus is; it's the way Earth would look
1425 * if you tilted your head sideways. It's still a Mercator
1426 * projection. */
1427 return x;
1428 }
1429
1430 /* Otherwise we have a torus topology. We set it up as an approximation
1431 * of a sphere with two circular polar zones and a square equatorial
1432 * zone. In this case north and south are not constant directions on the
1433 * map because we have to use a more complicated (custom) projection.
1434 *
1435 * Generators 2 and 5 work best if the center of the map is free. So
1436 * we want to set up the map with the poles (N,S) along the sides and the
1437 * equator (/,\‍) in between.
1438 *
1439 * ........
1440 * :\ NN /:
1441 * : \ / :
1442 * :S \/ S:
1443 * :S /\ S:
1444 * : / \ :
1445 * :/ NN \:
1446 * ''''''''
1447 */
1448
1449 /* First we will fold the map into fourths:
1450 *
1451 * ....
1452 * :\ N
1453 * : \
1454 * :S \
1455 *
1456 * and renormalize x and y to go from 0.0 to 1.0 again.
1457 */
1458 x = 2.0 * (x > 0.5 ? 1.0 - x : x);
1459 y = 2.0 * (y > 0.5 ? 1.0 - y : y);
1460
1461 /* Now flip it along the X direction to get this:
1462 *
1463 * ....
1464 * :N /
1465 * : /
1466 * :/ S
1467 */
1468 x = 1.0 - x;
1469
1470 /* To simplify the following computation, we can fold along the
1471 * diagonal. This leaves us with 1/8 of the map
1472 *
1473 * .....
1474 * :P /
1475 * : /
1476 * :/
1477 *
1478 * where P is the polar regions and / is the equator.
1479 * We must remember which hemisphere we are on for later. */
1480 if (x + y > 1.0) {
1481 /* This actually reflects the bottom-right half about the center point,
1482 * rather than about the diagonal, but that makes no difference. */
1483 x = 1.0 - x;
1484 y = 1.0 - y;
1486 } else {
1488 }
1489
1490 /* toroid_rel_colatitude is 0.0 at the poles and 1.0 at the equator.
1491 * This projection makes poles with a shape of a quarter-circle along
1492 * "P" and the equator as a straight line along "/".
1493 *
1494 * The formula is
1495 * lerp(1.5 (x^2 + y^2), (x+y)^2, x+y)
1496 * where
1497 * lerp(a,b,t) = a * (1-t) + b * t
1498 * is the linear interpolation between a and b, with
1499 * lerp(a,b,0) = a and lerp(a,b,1) = b
1500 *
1501 * I.e. the colatitude is computed as a linear interpolation between
1502 * - a = 1.5 (x^2 + y^2), proportional to the squared pythagorean
1503 * distance from the pole, which gives circular lines of latitude; and
1504 * - b = (x+y)^2, the squared manhattan distance from the pole, which
1505 * gives straight, diagonal lines of latitude parallel to the equator.
1506 *
1507 * These are interpolated with t = (x+y), the manhattan distance, which
1508 * ranges from 0 at the pole to 1 at the equator. So near the pole, the
1509 * (squared) pythagorean distance wins out, giving mostly circular lines,
1510 * and near the equator, the (squared) manhattan distance wins out,
1511 * giving mostly straight lines.
1512 *
1513 * Note that the colatitude growing with the square of the distance from
1514 * the pole keeps areas relatively the same as on non-toroidal maps:
1515 * On non-torus maps, the area closer to a pole than a given tile, and
1516 * the colatitude at that tile, both grow linearly with distance from the
1517 * pole. On torus maps, since the poles are singular points rather than
1518 * entire map edges, the area closer to a pole than a given tile grows
1519 * with the square of the distance to the pole - and so the colatitude
1520 * at that tile must also grow with the square in order to keep the size
1521 * of areas in a given range of colatitude relatively the same.
1522 *
1523 * See OSDN#43665, as well as the original discussion (via newsreader) at
1524 * news://news.gmane.io/gmane.games.freeciv.devel/42648 */
1525 toroid_rel_colatitude = (1.5 * (x * x * y + x * y * y)
1526 - 0.5 * (x * x * x + y * y * y)
1527 + 1.5 * (x * x + y * y));
1528
1529 /* Finally, convert from colatitude to latitude and add hemisphere
1530 * information back in:
1531 * - if we did not flip along the diagonal before, we are in the
1532 * northern hemisphere, with relative latitude in [0.0,0.5]
1533 * - if we _did_ flip, we are in the southern hemisphere, with
1534 * relative latitude in [0.5,1.0]
1535 */
1536 return ((toroid_flipped
1537 ? 2.0 - (toroid_rel_colatitude)
1539 / 2.0);
1540}
1541
1542/************************************************************************/
1550int map_signed_latitude(const struct tile *ptile)
1551{
1552 int north_latitude, south_latitude;
1553 double southness;
1554
1555 north_latitude = MAP_NORTH_LATITUDE(wld.map);
1556 south_latitude = MAP_SOUTH_LATITUDE(wld.map);
1557
1558 if (north_latitude == south_latitude) {
1559 /* Single-latitude / all-temperate map; no need to examine tile. */
1560 return south_latitude;
1561 }
1562
1563 fc_assert_ret_val(ptile != NULL, (north_latitude + south_latitude) / 2);
1564
1566
1567 /* Linear interpolation between northernmost and southernmost latitude.
1568 * Truncate / round towards zero so northern and southern hemisphere
1569 * are symmetrical when south_latitude = -north_latitude. */
1570 return north_latitude * (1.0 - southness) + south_latitude * southness;
1571}
1572
1573/*******************************************************************/
1581bool is_singular_tile(const struct tile *ptile, int dist)
1582{
1583 int tile_x, tile_y;
1584
1587 /* Iso-natural coordinates are doubled in scale. */
1588 dist *= MAP_IS_ISOMETRIC ? 2 : 1;
1589
1590 return ((!current_wrap_has_flag(WRAP_X)
1595}
1596
1597/*******************************************************************/
1600static struct startpos *startpos_new(struct tile *ptile)
1601{
1602 struct startpos *psp = fc_malloc(sizeof(*psp));
1603
1604 psp->location = ptile;
1605 psp->exclude = FALSE;
1606 psp->nations = nation_hash_new();
1607
1608 return psp;
1609}
1610
1611/*******************************************************************/
1614static void startpos_destroy(struct startpos *psp)
1615{
1616 fc_assert_ret(NULL != psp);
1618 free(psp);
1619}
1620
1621/*******************************************************************/
1625{
1626 return map_startpos_get(index_to_tile(&(wld.map), id));
1627}
1628
1629/*******************************************************************/
1633int startpos_number(const struct startpos *psp)
1634{
1635 fc_assert_ret_val(NULL != psp, -1);
1636 return tile_index(psp->location);
1637}
1638
1639/*******************************************************************/
1643bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
1644{
1645 fc_assert_ret_val(NULL != psp, FALSE);
1646 fc_assert_ret_val(NULL != pnation, FALSE);
1647
1648 if (0 == nation_hash_size(psp->nations) || !psp->exclude) {
1649 psp->exclude = FALSE; /* Disable "excluding" mode. */
1650 return nation_hash_insert(psp->nations, pnation, NULL);
1651 } else {
1652 return nation_hash_remove(psp->nations, pnation);
1653 }
1654}
1655
1656/*******************************************************************/
1660bool startpos_disallow(struct startpos *psp, struct nation_type *pnation)
1661{
1662 fc_assert_ret_val(NULL != psp, FALSE);
1663 fc_assert_ret_val(NULL != pnation, FALSE);
1664
1665 if (0 == nation_hash_size(psp->nations) || psp->exclude) {
1666 psp->exclude = TRUE; /* Enable "excluding" mode. */
1667 return nation_hash_remove(psp->nations, pnation);
1668 } else {
1669 return nation_hash_insert(psp->nations, pnation, NULL);
1670 }
1671}
1672
1673/*******************************************************************/
1676struct tile *startpos_tile(const struct startpos *psp)
1677{
1678 fc_assert_ret_val(NULL != psp, NULL);
1679 return psp->location;
1680}
1681
1682/*******************************************************************/
1685bool startpos_nation_allowed(const struct startpos *psp,
1686 const struct nation_type *pnation)
1687{
1688 fc_assert_ret_val(NULL != psp, FALSE);
1689 fc_assert_ret_val(NULL != pnation, FALSE);
1690 return XOR(psp->exclude, nation_hash_lookup(psp->nations, pnation, NULL));
1691}
1692
1693/*******************************************************************/
1696bool startpos_allows_all(const struct startpos *psp)
1697{
1698 fc_assert_ret_val(NULL != psp, FALSE);
1699 return (0 == nation_hash_size(psp->nations));
1700}
1701
1702/*******************************************************************/
1706bool startpos_pack(const struct startpos *psp,
1707 struct packet_edit_startpos_full *packet)
1708{
1709 fc_assert_ret_val(NULL != psp, FALSE);
1710 fc_assert_ret_val(NULL != packet, FALSE);
1711
1712 packet->id = startpos_number(psp);
1713 packet->exclude = psp->exclude;
1714 BV_CLR_ALL(packet->nations);
1715
1716 nation_hash_iterate(psp->nations, pnation) {
1717 BV_SET(packet->nations, nation_number(pnation));
1719 return TRUE;
1720}
1721
1722/*******************************************************************/
1726bool startpos_unpack(struct startpos *psp,
1727 const struct packet_edit_startpos_full *packet)
1728{
1729 fc_assert_ret_val(NULL != psp, FALSE);
1730 fc_assert_ret_val(NULL != packet, FALSE);
1731
1732 psp->exclude = packet->exclude;
1733
1735 if (!BV_ISSET_ANY(packet->nations)) {
1736 return TRUE;
1737 }
1738 nations_iterate(pnation) {
1739 if (BV_ISSET(packet->nations, nation_number(pnation))) {
1740 nation_hash_insert(psp->nations, pnation, NULL);
1741 }
1743 return TRUE;
1744}
1745
1746/*******************************************************************/
1753bool startpos_is_excluding(const struct startpos *psp)
1754{
1755 fc_assert_ret_val(NULL != psp, FALSE);
1756 return psp->exclude;
1757}
1758
1759/*******************************************************************/
1765const struct nation_hash *startpos_raw_nations(const struct startpos *psp)
1766{
1767 fc_assert_ret_val(NULL != psp, NULL);
1768 return psp->nations;
1769}
1770
1771/*******************************************************************/
1778{
1779 return MAX(sizeof(struct startpos_iter) + nation_iter_sizeof()
1780 - sizeof(struct iterator), nation_hash_iter_sizeof());
1781}
1782
1783/*******************************************************************/
1790{
1792
1793 do {
1794 iterator_next(&iter->nation_iter);
1795 } while (iterator_valid(&iter->nation_iter)
1796 || !nation_hash_lookup(iter->psp->nations,
1797 iterator_get(&iter->nation_iter), NULL));
1798}
1799
1800/*******************************************************************/
1808{
1810 return iterator_get(&iter->nation_iter);
1811}
1812
1813/*******************************************************************/
1817{
1819 return iterator_valid(&iter->nation_iter);
1820}
1821
1822/*******************************************************************/
1826 const struct startpos *psp)
1827{
1828 if (!psp) {
1830 }
1831
1832 if (startpos_allows_all(psp)) {
1833 return nation_iter_init((struct nation_iter *) iter);
1834 }
1835
1836 if (!psp->exclude) {
1838 psp->nations);
1839 }
1840
1841 iter->vtable.next = startpos_exclude_iter_next;
1842 iter->vtable.get = startpos_exclude_iter_get;
1843 iter->vtable.valid = startpos_exclude_iter_valid;
1844 iter->psp = psp;
1845 (void) nation_iter_init((struct nation_iter *) &iter->nation_iter);
1846
1847 return ITERATOR(iter);
1848}
1849
1850/*******************************************************************/
1854{
1855 if (NULL != wld.map.startpos_table) {
1857 } else {
1858 return 0;
1859 }
1860}
1861
1862/*******************************************************************/
1866struct startpos *map_startpos_new(struct tile *ptile)
1867{
1868 struct startpos *psp;
1869
1870 fc_assert_ret_val(NULL != ptile, NULL);
1872
1873 psp = startpos_new(ptile);
1875
1876 return psp;
1877}
1878
1879/*******************************************************************/
1883struct startpos *map_startpos_get(const struct tile *ptile)
1884{
1885 struct startpos *psp;
1886
1887 fc_assert_ret_val(NULL != ptile, NULL);
1889
1891
1892 return psp;
1893}
1894
1895/*******************************************************************/
1899bool map_startpos_remove(struct tile *ptile)
1900{
1901 fc_assert_ret_val(NULL != ptile, FALSE);
1903
1905}
1906
1907/*******************************************************************/
1912{
1914}
1915
1916/*******************************************************************/
1925
1926/*******************************************************************/
1933
1934/*******************************************************************/
1938{
1939 return direction8_max() - dir;
1940}
#define CALL_FUNC_EACH_AI(_func,...)
Definition ai.h:387
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
#define BV_ISSET_ANY(vec)
Definition bitvector.h:109
void generate_city_map_indices(void)
Definition city.c:527
int compare_iter_index(const void *a, const void *b)
Definition city.c:343
char * incite_cost
Definition comments.c:75
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
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
bool is_native_extra_to_uclass(const struct extra_type *pextra, const struct unit_class *pclass)
Definition extras.c:843
#define extra_type_iterate(_p)
Definition extras.h:315
#define extra_type_list_iterate(extralist, pextra)
Definition extras.h:165
#define extra_type_iterate_end
Definition extras.h:321
#define extra_type_by_rmcause_iterate_end
Definition extras.h:358
#define extra_index(_e_)
Definition extras.h:183
#define extra_type_by_rmcause_iterate(_rmcause, _extra)
Definition extras.h:353
#define extra_type_list_iterate_end
Definition extras.h:167
#define extra_road_get(_e_)
Definition extras.h:191
@ RPT_POSSIBLE
Definition fc_types.h:700
struct civ_game game
Definition game.c:62
struct world wld
Definition game.c:63
struct iterator * invalid_iter_init(struct iterator *it)
Definition iterator.c:51
static void * iterator_get(const struct iterator *it)
Definition iterator.h:53
static bool iterator_valid(const struct iterator *it)
Definition iterator.h:61
#define ITERATOR(p)
Definition iterator.h:37
static void iterator_next(struct iterator *it)
Definition iterator.h:42
#define fc_assert_ret(condition)
Definition log.h:191
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define log_debug(message,...)
Definition log.h:115
bv_extras get_tile_infrastructure_set(const struct tile *ptile, int *pcount)
Definition map.c:101
bool can_channel_land(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:699
struct startpos * map_startpos_get(const struct tile *ptile)
Definition map.c:1883
bool is_normal_map_pos(int x, int y)
Definition map.c:963
const int DIR_DY[8]
Definition map.c:87
int startpos_number(const struct startpos *psp)
Definition map.c:1633
bool can_reclaim_ocean(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:684
void map_free(struct civ_map *fmap)
Definition map.c:530
bool startpos_disallow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1660
void main_map_free(void)
Definition map.c:554
#define nat_x
static int map_vector_to_distance(int dx, int dy)
Definition map.c:564
enum direction8 opposite_direction(enum direction8 dir)
Definition map.c:1937
#define nat_y
bool is_move_cardinal(const struct civ_map *nmap, const struct tile *start_tile, const struct tile *end_tile)
Definition map.c:1365
int sq_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:641
bool can_freeze_terrain(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:728
struct startpos * map_startpos_new(struct tile *ptile)
Definition map.c:1866
bool can_thaw_terrain(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:713
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:780
static void tile_free(struct tile *ptile)
Definition map.c:474
bool startpos_nation_allowed(const struct startpos *psp, const struct nation_type *pnation)
Definition map.c:1685
#define STARTPOS_ITER(p)
Definition map.c:65
int map_num_tiles(void)
Definition map.c:1014
int get_direction_for_step(const struct civ_map *nmap, const struct tile *start_tile, const struct tile *end_tile)
Definition map.c:1347
struct tile * startpos_tile(const struct startpos *psp)
Definition map.c:1676
bool startpos_allows_all(const struct startpos *psp)
Definition map.c:1696
const struct nation_hash * startpos_raw_nations(const struct startpos *psp)
Definition map.c:1765
const int DIR_DX[8]
Definition map.c:86
struct tile * rand_map_pos(const struct civ_map *nmap)
Definition map.c:1088
static bool restrict_infra(const struct player *pplayer, const struct tile *t1, const struct tile *t2)
Definition map.c:911
static struct tile * base_native_pos_to_tile(const struct civ_map *nmap, int nat_x, int nat_y)
Definition map.c:395
static void generate_map_indices(void)
Definition map.c:203
const char * dir_get_name(enum direction8 dir)
Definition map.c:1146
enum direction8 dir_ccw(enum direction8 dir)
Definition map.c:1203
struct iterator * map_startpos_iter_init(struct map_startpos_iter *iter)
Definition map.c:1920
bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
Definition map.c:931
void map_allocate(struct civ_map *amap)
Definition map.c:493
void map_init_topology(struct civ_map *nmap)
Definition map.c:303
void main_map_allocate(void)
Definition map.c:519
static bool dir_validity[9]
Definition map.c:90
bool is_safe_ocean(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:667
static struct startpos * startpos_new(struct tile *ptile)
Definition map.c:1600
static double map_relative_southness(const struct tile *ptile)
Definition map.c:1396
bool startpos_pack(const struct startpos *psp, struct packet_edit_startpos_full *packet)
Definition map.c:1706
static bool is_valid_dir_calculate(enum direction8 dir)
Definition map.c:1233
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:456
int map_signed_latitude(const struct tile *ptile)
Definition map.c:1550
static bool is_cardinal_dir_calculate(enum direction8 dir)
Definition map.c:1290
struct tile * map_pos_to_tile(const struct civ_map *nmap, int map_x, int map_y)
Definition map.c:419
int map_vector_to_sq_distance(int dx, int dy)
Definition map.c:614
bool map_startpos_remove(struct tile *ptile)
Definition map.c:1899
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:1101
int map_startpos_count(void)
Definition map.c:1853
size_t startpos_iter_sizeof(void)
Definition map.c:1777
bool is_cardinal_dir(enum direction8 dir)
Definition map.c:1316
static void tile_init(struct tile *ptile)
Definition map.c:351
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:940
bool map_untrusted_dir_is_valid(enum direction8 dir)
Definition map.c:1273
bool terrain_surroundings_allow_change(const struct civ_map *nmap, const struct tile *ptile, const struct terrain *pterrain)
Definition map.c:742
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:630
bool startpos_unpack(struct startpos *psp, const struct packet_edit_startpos_full *packet)
Definition map.c:1726
bool is_valid_dir(enum direction8 dir)
Definition map.c:1260
void base_map_distance_vector(int *dx, int *dy, int x0dv, int y0dv, int x1dv, int y1dv)
Definition map.c:1024
enum direction8 dir_cw(enum direction8 dir)
Definition map.c:1174
enum direction8 rand_direction(void)
Definition map.c:1929
struct tile * mapstep(const struct civ_map *nmap, const struct tile *ptile, enum direction8 dir)
Definition map.c:371
static void startpos_destroy(struct startpos *psp)
Definition map.c:1614
struct terrain_misc terrain_control
Definition map.c:69
static void * startpos_exclude_iter_get(const struct iterator *startpos_iter)
Definition map.c:1807
struct tile * nearest_real_tile(const struct civ_map *nmap, int x, int y)
Definition map.c:995
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:1328
static void startpos_exclude_iter_next(struct iterator *startpos_iter)
Definition map.c:1789
struct tile * native_pos_to_tile(const struct civ_map *nmap, int nat_x, int nat_y)
Definition map.c:443
void map_distance_vector(int *dx, int *dy, const struct tile *tile0, const struct tile *tile1)
Definition map.c:1073
static bool dir_cardinality[9]
Definition map.c:89
void map_init(struct civ_map *imap, bool server_side)
Definition map.c:157
bool startpos_is_excluding(const struct startpos *psp)
Definition map.c:1753
int map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:654
struct startpos * map_startpos_by_number(int id)
Definition map.c:1624
bool map_is_empty(void)
Definition map.c:149
size_t map_startpos_iter_sizeof(void)
Definition map.c:1911
bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1643
bool normalize_map_pos(const struct civ_map *nmap, int *x, int *y)
Definition map.c:979
static bool startpos_exclude_iter_valid(const struct iterator *startpos_iter)
Definition map.c:1816
struct iterator * startpos_iter_init(struct startpos_iter *iter, const struct startpos *psp)
Definition map.c:1825
bool is_real_map_pos(const struct civ_map *nmap, int x, int y)
Definition map.c:952
bool is_singular_tile(const struct tile *ptile, int dist)
Definition map.c:1581
int map_vector_to_real_distance(int dx, int dy)
Definition map.c:578
#define MAP_MAX_SIZE
Definition map.h:624
#define current_topo_has_flag(flag)
Definition map.h:48
#define MAP_DEFAULT_SIZE
Definition map.h:622
#define MAP_MAX_LINEAR_SIZE
Definition map.h:640
#define adjc_dir_iterate(nmap, center_tile, itr_tile, dir_itr)
Definition map.h:438
#define MAP_DEFAULT_HUTS
Definition map.h:604
#define adjc_iterate_end
Definition map.h:433
#define do_in_natural_pos(ntl_x, ntl_y, map_x, map_y)
Definition map.h:210
#define MAP_INDEX_SIZE
Definition map.h:137
#define MAP_DEFAULT_LINEAR_SIZE
Definition map.h:639
#define MAP_DEFAULT_STARTPOS
Definition map.h:680
#define NATURAL_HEIGHT
Definition map.h:227
#define MAP_DEFAULT_ANIMALS
Definition map.h:608
#define MAP_DEFAULT_TEAM_PLACEMENT
Definition map.h:698
#define MAP_DEFAULT_TOPO
Definition map.h:654
#define MAP_DEFAULT_SEED
Definition map.h:658
#define MAP_IS_ISOMETRIC
Definition map.h:42
#define CHECK_INDEX(mindex)
Definition map.h:149
#define cardinal_between_iterate(nmap, tile1, tile2, between)
Definition map.h:477
#define MAP_DEFAULT_MAPSIZE
Definition map.h:612
#define MAP_MIN_LINEAR_SIZE
Definition map.h:641
#define MAP_DEFAULT_LANDMASS
Definition map.h:662
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:428
#define MAP_SOUTH_LATITUDE(_nmap)
Definition map.h:583
#define MAP_TO_NATIVE_POS(pnat_x, pnat_y, map_x, map_y)
Definition map.h:172
#define ALL_DIRECTIONS_CARDINAL()
Definition map.h:53
#define NATIVE_TO_MAP_POS(pmap_x, pmap_y, nat_x, nat_y)
Definition map.h:166
#define cardinal_adjc_dir_iterate_end
Definition map.h:466
#define MAP_DEFAULT_WRAP
Definition map.h:655
#define MAP_MIN_SIZE
Definition map.h:623
#define MAP_DEFAULT_NORTH_LATITUDE
Definition map.h:578
#define MAP_DEFAULT_SEPARATE_POLES
Definition map.h:686
#define MAP_DEFAULT_RICHES
Definition map.h:666
#define MAP_DEFAULT_TINYISLES
Definition map.h:682
#define whole_map_iterate(_map, _tile)
Definition map.h:545
#define MAP_NORTH_LATITUDE(_nmap)
Definition map.h:582
#define MAP_DEFAULT_TILESPERPLAYER
Definition map.h:634
#define adjc_dir_iterate_end
Definition map.h:442
#define MAP_DEFAULT_TEMPERATURE
Definition map.h:694
#define cardinal_between_iterate_end
Definition map.h:482
#define MAP_DEFAULT_SOUTH_LATITUDE
Definition map.h:579
#define current_wrap_has_flag(flag)
Definition map.h:51
#define MAP_DEFAULT_GENERATOR
Definition map.h:678
#define NATURAL_WIDTH
Definition map.h:226
#define do_in_natural_pos_end
Definition map.h:217
#define MAP_DEFAULT_WETNESS
Definition map.h:674
#define native_pos_to_index_nocheck(nat_x, nat_y)
Definition map.h:152
#define cardinal_adjc_dir_iterate(nmap, center_tile, itr_tile, dir_itr)
Definition map.h:462
#define whole_map_iterate_end
Definition map.h:554
#define index_to_map_pos(pmap_x, pmap_y, mindex)
Definition map.h:233
#define MAP_DEFAULT_STEEPNESS
Definition map.h:670
#define DIRSTEP(dest_x, dest_y, dir)
Definition map.h:240
#define terrain_misc
Definition map_types.h:29
#define fc_calloc(n, esz)
Definition mem.h:38
#define FC_FREE(ptr)
Definition mem.h:41
#define fc_malloc(sz)
Definition mem.h:34
#define SINGLE_MOVE
Definition movement.h:26
static bool is_native_tile_to_class(const struct unit_class *punitclass, const struct tile *ptile)
Definition movement.h:84
#define MOVE_COST_IGTER
Definition movement.h:27
Nation_type_id nation_number(const struct nation_type *pnation)
Definition nation.c:486
struct iterator * nation_iter_init(struct nation_iter *it)
Definition nation.c:557
size_t nation_iter_sizeof(void)
Definition nation.c:524
#define nation_hash_iterate(nationhash, pnation)
Definition nation.h:93
#define nations_iterate_end
Definition nation.h:336
#define nations_iterate(NAME_pnation)
Definition nation.h:333
#define nation_hash_iterate_end
Definition nation.h:95
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1388
#define fc_rand(_size)
Definition rand.h:56
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)
bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
Definition road.c:410
#define CLIP(lower, current, upper)
Definition shared.h:57
#define FC_WRAP(value, range)
Definition shared.h:65
#define MAX(x, y)
Definition shared.h:54
#define XOR(p, q)
Definition shared.h:71
struct sprite int int y
Definition sprite_g.h:31
struct sprite int x
Definition sprite_g.h:31
struct packet_game_info info
Definition game.h:89
struct startpos_hash * startpos_table
Definition map_types.h:84
struct tile * tiles
Definition map_types.h:83
int xsize
Definition map_types.h:78
int ysize
Definition map_types.h:78
enum direction8 valid_dirs[8]
Definition map_types.h:74
int num_iterate_outwards_indices
Definition map_types.h:77
int num_valid_dirs
Definition map_types.h:75
struct iter_index * iterate_outwards_indices
Definition map_types.h:76
int dist
Definition city.h:110
int dx
Definition city.h:110
int dy
Definition city.h:110
bv_startpos_nations nations
const struct startpos * psp
Definition map.c:60
struct iterator vtable
Definition map.c:59
Definition map.c:41
bool exclude
Definition map.c:43
struct tile * location
Definition map.c:42
struct nation_hash * nations
Definition map.c:44
Definition tile.h:50
char * spec_sprite
Definition tile.h:66
char * label
Definition tile.h:65
bv_extras extras
Definition tile.h:55
struct extra_type * resource
Definition tile.h:56
struct unit_list * units
Definition tile.h:58
struct player * extras_owner
Definition tile.h:63
struct terrain * terrain
Definition tile.h:57
struct extra_type * placing
Definition tile.h:61
struct city * worked
Definition tile.h:59
struct player * owner
Definition tile.h:60
Continent_id continent
Definition tile.h:54
struct tile * claimer
Definition tile.h:64
Definition unit.h:138
struct civ_map map
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
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
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
#define T_UNKNOWN
Definition terrain.h:57
#define is_ocean(pterrain)
Definition terrain.h:301
#define terrain_has_flag(terr, flag)
Definition terrain.h:283
void tile_virtual_destroy(struct tile *vtile)
Definition tile.c:1033
void tile_remove_extra(struct tile *ptile, const struct extra_type *pextra)
Definition tile.c:965
struct tile * tile_virtual_new(const struct tile *ptile)
Definition tile.c:981
void * tile_hash_key(const struct tile *ptile)
Definition tile.c:1083
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_index(_pt_)
Definition tile.h:88
#define ACTIVITY_FACTOR
Definition tile.h:165
#define tile_terrain(_tile)
Definition tile.h:110
#define tile_has_extra(ptile, pextra)
Definition tile.h:147
#define tile_owner(_tile)
Definition tile.h:96
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:766
#define utype_class(_t_)
Definition unittype.h:749
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:617