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/*******************************************************************/
691bool can_reclaim_ocean(const struct civ_map *nmap,
692 const struct tile *ptile)
693{
695 float pct = terrain_control.ocean_reclaim_requirement_pct/100.0;
699
701}
702
703/*******************************************************************/
708bool can_channel_land(const struct civ_map *nmap,
709 const struct tile *ptile)
710{
713
714 return ocean_tiles >= terrain_control.land_channel_requirement_pct;
715}
716
717/*******************************************************************/
722bool can_thaw_terrain(const struct civ_map *nmap,
723 const struct tile *ptile)
724{
726 FALSE, TRUE,
727 TER_FROZEN);
728
729 return unfrozen_tiles >= terrain_control.terrain_thaw_requirement_pct;
730}
731
732/*******************************************************************/
737bool can_freeze_terrain(const struct civ_map *nmap,
738 const struct tile *ptile)
739{
741 FALSE, TRUE,
742 TER_FROZEN);
743
744 return frozen_tiles >= terrain_control.terrain_freeze_requirement_pct;
745}
746
747/*******************************************************************/
752 const struct tile *ptile,
753 const struct terrain *pterrain)
754{
755 bool ret = TRUE;
756
757 if (is_ocean(tile_terrain(ptile))
758 && !is_ocean(pterrain) && !can_reclaim_ocean(nmap, ptile)) {
759 ret = FALSE;
760 } else if (!is_ocean(tile_terrain(ptile))
761 && is_ocean(pterrain) && !can_channel_land(nmap, ptile)) {
762 ret = FALSE;
763 }
764
765 if (ret) {
767 && !terrain_has_flag(pterrain, TER_FROZEN)
768 && !can_thaw_terrain(nmap, ptile)) {
769 ret = FALSE;
770 } else if (!terrain_has_flag(tile_terrain(ptile), TER_FROZEN)
771 && terrain_has_flag(pterrain, TER_FROZEN)
772 && !can_freeze_terrain(nmap, ptile)) {
773 ret = FALSE;
774 }
775 }
776
777 return ret;
778}
779
780/*******************************************************************/
790 const struct unit *punit,
791 const struct unit_type *punittype,
792 const struct player *pplayer,
793 const struct tile *t1, const struct tile *t2)
794{
795 const struct unit_class *pclass = utype_class(punittype);
796 int cost;
797 signed char cardinal_move = -1;
798 bool ri;
799
800 /* Try to exit early for detectable conditions */
802 /* units without UCF_TERRAIN_SPEED have a constant cost. */
803 return SINGLE_MOVE;
804
805 } else if (!is_native_tile_to_class(pclass, t2)) {
806 if (tile_city(t2) == NULL) {
807 /* Loading to transport. */
808
809 /* UTYF_IGTER units get move benefit. */
812 } else {
813 /* Entering port. (Could be "Conquer City") */
814
815 /* UTYF_IGTER units get move benefit. */
818 }
819
820 } else if (!is_native_tile_to_class(pclass, t1)) {
821 if (tile_city(t1) == NULL) {
822 /* Disembarking from transport. */
823
824 /* UTYF_IGTER units get move benefit. */
827 } else {
828 /* Leaving port. */
829
830 /* UTYF_IGTER units get move benefit. */
833 }
834 }
835
836 cost = tile_terrain(t2)->movement_cost * SINGLE_MOVE;
837 ri = restrict_infra(pplayer, t1, t2);
838
839 extra_type_list_iterate(pclass->cache.bonus_roads, pextra) {
840 struct road_type *proad = extra_road_get(pextra);
841
842 /* We check the destination tile first, as that's
843 * the end of move that determines the cost.
844 * If can avoid inner loop about integrating roads
845 * completely if the destination road has too high cost. */
846
847 if (cost > proad->move_cost
849 && tile_has_extra(t2, pextra)) {
850 extra_type_list_iterate(proad->integrators, iextra) {
851 /* We have no unrestricted infra related check here,
852 * destination road is the one that counts. */
853 if (tile_has_extra(t1, iextra)
855 if (proad->move_mode == RMM_FAST_ALWAYS) {
856 cost = proad->move_cost;
857 } else {
858 if (cardinal_move < 0) {
860 || is_move_cardinal(nmap, t1, t2)) ? 1 : 0;
861 }
862 if (cardinal_move > 0) {
863 cost = proad->move_cost;
864 } else {
865 switch (proad->move_mode) {
866 case RMM_CARDINAL:
867 break;
868 case RMM_RELAXED:
869 if (cost > proad->move_cost * 2) {
871 if (tile_has_extra(between, pextra)
872 || (pextra != iextra && tile_has_extra(between, iextra))) {
873 /* 'pextra != iextra' is there just to avoid tile_has_extra()
874 * in by far more common case that 'pextra == iextra' */
875 /* TODO: Should we restrict this more?
876 * Should we check against enemy cities on between tile?
877 * Should we check against non-native terrain on between tile?
878 */
879 cost = proad->move_cost * 2;
880 }
882 }
883 break;
884 case RMM_FAST_ALWAYS:
885 fc_assert(proad->move_mode != RMM_FAST_ALWAYS); /* Already handled above */
886 cost = proad->move_cost;
887 break;
888 }
889 }
890 }
891 }
893 }
895
896 /* UTYF_IGTER units have a maximum move cost per step. */
899 }
900
901 if (terrain_control.pythagorean_diagonal) {
902 if (cardinal_move < 0) {
904 || is_move_cardinal(nmap, t1, t2)) ? 1 : 0;
905 }
906 if (cardinal_move == 0) {
907 return cost * 181 >> 7; /* == (int) (cost * 1.41421356f) if cost < 99 */
908 }
909 }
910
911 return cost;
912}
913
914/*******************************************************************/
920static bool restrict_infra(const struct player *pplayer, const struct tile *t1,
921 const struct tile *t2)
922{
923 struct player *plr1 = tile_owner(t1), *plr2 = tile_owner(t2);
924
925 if (!pplayer || !game.info.restrictinfra) {
926 return FALSE;
927 }
928
929 if ((plr1 && pplayers_at_war(plr1, pplayer))
930 || (plr2 && pplayers_at_war(plr2, pplayer))) {
931 return TRUE;
932 }
933
934 return FALSE;
935}
936
937/*******************************************************************/
940bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
941{
942 return real_map_distance(tile0, tile1) == 1;
943}
944
945/*******************************************************************/
949bool same_pos(const struct tile *tile1, const struct tile *tile2)
950{
952
953 /* In case of virtual tile, tile1 can be different from tile2,
954 * but they have same index */
955 return (tile1->index == tile2->index);
956}
957
958/*******************************************************************/
961bool is_real_map_pos(const struct civ_map *nmap, int x, int y)
962{
963 return normalize_map_pos(nmap, &x, &y);
964}
965
966/*******************************************************************/
972bool is_normal_map_pos(int x, int y)
973{
974 int nat_x, nat_y;
975
977 return nat_x >= 0 && nat_x < wld.map.xsize && nat_y >= 0 && nat_y < wld.map.ysize;
978}
979
980/*******************************************************************/
988bool normalize_map_pos(const struct civ_map *nmap, int *x, int *y)
989{
990 struct tile *ptile = map_pos_to_tile(nmap, *x, *y);
991
992 if (ptile) {
993 index_to_map_pos(x, y, tile_index(ptile));
994 return TRUE;
995 } else {
996 return FALSE;
997 }
998}
999
1000/*******************************************************************/
1004struct tile *nearest_real_tile(const struct civ_map *nmap, int x, int y)
1005{
1006 int nat_x, nat_y;
1007
1010 nat_x = CLIP(0, nat_x, wld.map.xsize - 1);
1011 }
1013 nat_y = CLIP(0, nat_y, wld.map.ysize - 1);
1014 }
1016
1017 return map_pos_to_tile(nmap, x, y);
1018}
1019
1020/*******************************************************************/
1024{
1025 return wld.map.xsize * wld.map.ysize;
1026}
1027
1028/*******************************************************************/
1033void base_map_distance_vector(int *dx, int *dy,
1034 int x0dv, int y0dv, int x1dv, int y1dv)
1035{
1037 /* Wrapping is done in native coordinates. */
1040
1041 /* Find the "native" distance vector. This corresponds closely to the
1042 * map distance vector but is easier to wrap. */
1043 *dx = x1dv - x0dv;
1044 *dy = y1dv - y0dv;
1046 /* Wrap dx to be in [-map.xsize/2, map.xsize/2). */
1047 *dx = FC_WRAP(*dx + wld.map.xsize / 2, wld.map.xsize) - wld.map.xsize / 2;
1048 }
1050 /* Wrap dy to be in [-map.ysize/2, map.ysize/2). */
1051 *dy = FC_WRAP(*dy + wld.map.ysize / 2, wld.map.ysize) - wld.map.ysize / 2;
1052 }
1053
1054 /* Convert the native delta vector back to a pair of map positions. */
1055 x1dv = x0dv + *dx;
1056 y1dv = y0dv + *dy;
1059 }
1060
1061 /* Find the final (map) vector. */
1062 *dx = x1dv - x0dv;
1063 *dy = y1dv - y0dv;
1064}
1065
1066/*******************************************************************/
1082void map_distance_vector(int *dx, int *dy,
1083 const struct tile *tile0,
1084 const struct tile *tile1)
1085{
1086 int tx0, ty0, tx1, ty1;
1087
1091}
1092
1093/*******************************************************************/
1097struct tile *rand_map_pos(const struct civ_map *nmap)
1098{
1100
1102}
1103
1104/*******************************************************************/
1110struct tile *rand_map_pos_filtered(const struct civ_map *nmap, void *data,
1111 bool (*filter)(const struct tile *ptile,
1112 const void *data))
1113{
1114 struct tile *ptile;
1115 int tries = 0;
1117
1118 /* First do a few quick checks to find a spot. The limit on number of
1119 * tries could use some tweaking. */
1120 do {
1121 ptile = nmap->tiles + fc_rand(MAP_INDEX_SIZE);
1122 } while (filter != NULL && !filter(ptile, data) && ++tries < max_tries);
1123
1124 /* If that fails, count all available spots and pick one.
1125 * Slow but reliable. */
1126 if (filter == NULL) {
1127 ptile = NULL;
1128 } else if (tries == max_tries) {
1129 int count = 0, *positions;
1130
1131 positions = fc_calloc(MAP_INDEX_SIZE, sizeof(*positions));
1132
1134 if (filter(check_tile, data)) {
1135 positions[count] = tile_index(check_tile);
1136 count++;
1137 }
1139
1140 if (count == 0) {
1141 ptile = NULL;
1142 } else {
1143 ptile = wld.map.tiles + positions[fc_rand(count)];
1144 }
1145
1146 FC_FREE(positions);
1147 }
1148
1149 return ptile;
1150}
1151
1152/*******************************************************************/
1155const char *dir_get_name(enum direction8 dir)
1156{
1157 /* a switch statement is used so the ordering can be changed easily */
1158 switch (dir) {
1159 case DIR8_NORTH:
1160 return "N";
1161 case DIR8_NORTHEAST:
1162 return "NE";
1163 case DIR8_EAST:
1164 return "E";
1165 case DIR8_SOUTHEAST:
1166 return "SE";
1167 case DIR8_SOUTH:
1168 return "S";
1169 case DIR8_SOUTHWEST:
1170 return "SW";
1171 case DIR8_WEST:
1172 return "W";
1173 case DIR8_NORTHWEST:
1174 return "NW";
1175 default:
1176 return "[Undef]";
1177 }
1178}
1179
1180/*******************************************************************/
1184{
1185 /* a switch statement is used so the ordering can be changed easily */
1186 switch (dir) {
1187 case DIR8_NORTH:
1188 return DIR8_NORTHEAST;
1189 case DIR8_NORTHEAST:
1190 return DIR8_EAST;
1191 case DIR8_EAST:
1192 return DIR8_SOUTHEAST;
1193 case DIR8_SOUTHEAST:
1194 return DIR8_SOUTH;
1195 case DIR8_SOUTH:
1196 return DIR8_SOUTHWEST;
1197 case DIR8_SOUTHWEST:
1198 return DIR8_WEST;
1199 case DIR8_WEST:
1200 return DIR8_NORTHWEST;
1201 case DIR8_NORTHWEST:
1202 return DIR8_NORTH;
1203 default:
1205 return -1;
1206 }
1207}
1208
1209/*******************************************************************/
1213{
1214 /* a switch statement is used so the ordering can be changed easily */
1215 switch (dir) {
1216 case DIR8_NORTH:
1217 return DIR8_NORTHWEST;
1218 case DIR8_NORTHEAST:
1219 return DIR8_NORTH;
1220 case DIR8_EAST:
1221 return DIR8_NORTHEAST;
1222 case DIR8_SOUTHEAST:
1223 return DIR8_EAST;
1224 case DIR8_SOUTH:
1225 return DIR8_SOUTHEAST;
1226 case DIR8_SOUTHWEST:
1227 return DIR8_SOUTH;
1228 case DIR8_WEST:
1229 return DIR8_SOUTHWEST;
1230 case DIR8_NORTHWEST:
1231 return DIR8_WEST;
1232 default:
1234 return -1;
1235 }
1236}
1237
1238/*******************************************************************/
1243{
1244 switch (dir) {
1245 case DIR8_SOUTHEAST:
1246 case DIR8_NORTHWEST:
1247 /* These directions are invalid in hex topologies. */
1249 case DIR8_NORTHEAST:
1250 case DIR8_SOUTHWEST:
1251 /* These directions are invalid in iso-hex topologies. */
1253 case DIR8_NORTH:
1254 case DIR8_EAST:
1255 case DIR8_SOUTH:
1256 case DIR8_WEST:
1257 return TRUE;
1258 default:
1259 return FALSE;
1260 }
1261}
1262
1263/*******************************************************************/
1270{
1272
1273 return dir_validity[dir];
1274}
1275
1276/*******************************************************************/
1283{
1284 if (!direction8_is_valid(dir)) {
1285 /* Isn't even in range of direction8. */
1286 return FALSE;
1287 }
1288
1289 return is_valid_dir(dir);
1290}
1291
1292/*******************************************************************/
1300{
1301 switch (dir) {
1302 case DIR8_NORTH:
1303 case DIR8_SOUTH:
1304 case DIR8_EAST:
1305 case DIR8_WEST:
1306 return TRUE;
1307 case DIR8_SOUTHEAST:
1308 case DIR8_NORTHWEST:
1309 /* These directions are cardinal in iso-hex topologies. */
1311 case DIR8_NORTHEAST:
1312 case DIR8_SOUTHWEST:
1313 /* These directions are cardinal in hexagonal topologies. */
1315 }
1316 return FALSE;
1317}
1318
1319/*******************************************************************/
1326{
1328
1329 return dir_cardinality[dir];
1330}
1331
1332/*******************************************************************/
1338 const struct tile *start_tile,
1339 const struct tile *end_tile,
1340 enum direction8 *dir)
1341{
1342 adjc_dir_iterate(nmap, start_tile, test_tile, test_dir) {
1343 if (same_pos(end_tile, test_tile)) {
1344 *dir = test_dir;
1345 return TRUE;
1346 }
1348
1349 return FALSE;
1350}
1351
1352/*******************************************************************/
1357 const struct tile *start_tile,
1358 const struct tile *end_tile)
1359{
1360 enum direction8 dir;
1361
1362 if (base_get_direction_for_step(nmap, start_tile, end_tile, &dir)) {
1363 return dir;
1364 }
1365
1367 return -1;
1368}
1369
1370/*******************************************************************/
1374bool is_move_cardinal(const struct civ_map *nmap,
1375 const struct tile *start_tile,
1376 const struct tile *end_tile)
1377{
1379 if (same_pos(end_tile, test_tile)) {
1380 return TRUE;
1381 }
1383
1384 return FALSE;
1385}
1386
1387/************************************************************************/
1405static double map_relative_southness(const struct tile *ptile)
1406{
1407 int tile_x, tile_y;
1408 double x, y, toroid_rel_colatitude;
1409 bool toroid_flipped;
1410
1411 /* TODO: What should the fallback value be?
1412 * Since this is not public API, it shouldn't matter anyway. */
1413 fc_assert_ret_val(ptile != NULL, 0.5);
1414
1417 /* Compute natural coordinates relative to world size.
1418 * x and y are in the range [0.0, 1.0] */
1419 x = (double)ntl_x / (NATURAL_WIDTH - 1);
1420 y = (double)ntl_y / (NATURAL_HEIGHT - 1);
1422
1424 /* In an Earth-like topology, north and south are at the top and
1425 * bottom of the map.
1426 * This is equivalent to a Mercator projection. */
1427 return y;
1428 }
1429
1431 /* In a Uranus-like topology, north and south are at the left and
1432 * right side of the map.
1433 * This isn't really the way Uranus is; it's the way Earth would look
1434 * if you tilted your head sideways. It's still a Mercator
1435 * projection. */
1436 return x;
1437 }
1438
1439 /* Otherwise we have a torus topology. We set it up as an approximation
1440 * of a sphere with two circular polar zones and a square equatorial
1441 * zone. In this case north and south are not constant directions on the
1442 * map because we have to use a more complicated (custom) projection.
1443 *
1444 * Generators 2 and 5 work best if the center of the map is free. So
1445 * we want to set up the map with the poles (N,S) along the sides and the
1446 * equator (/,\‍) in between.
1447 *
1448 * ........
1449 * :\ NN /:
1450 * : \ / :
1451 * :S \/ S:
1452 * :S /\ S:
1453 * : / \ :
1454 * :/ NN \:
1455 * ''''''''
1456 */
1457
1458 /* First we will fold the map into fourths:
1459 *
1460 * ....
1461 * :\ N
1462 * : \
1463 * :S \
1464 *
1465 * and renormalize x and y to go from 0.0 to 1.0 again.
1466 */
1467 x = 2.0 * (x > 0.5 ? 1.0 - x : x);
1468 y = 2.0 * (y > 0.5 ? 1.0 - y : y);
1469
1470 /* Now flip it along the X direction to get this:
1471 *
1472 * ....
1473 * :N /
1474 * : /
1475 * :/ S
1476 */
1477 x = 1.0 - x;
1478
1479 /* To simplify the following computation, we can fold along the
1480 * diagonal. This leaves us with 1/8 of the map
1481 *
1482 * .....
1483 * :P /
1484 * : /
1485 * :/
1486 *
1487 * where P is the polar regions and / is the equator.
1488 * We must remember which hemisphere we are on for later. */
1489 if (x + y > 1.0) {
1490 /* This actually reflects the bottom-right half about the center point,
1491 * rather than about the diagonal, but that makes no difference. */
1492 x = 1.0 - x;
1493 y = 1.0 - y;
1495 } else {
1497 }
1498
1499 /* toroid_rel_colatitude is 0.0 at the poles and 1.0 at the equator.
1500 * This projection makes poles with a shape of a quarter-circle along
1501 * "P" and the equator as a straight line along "/".
1502 *
1503 * The formula is
1504 * lerp(1.5 (x^2 + y^2), (x+y)^2, x+y)
1505 * where
1506 * lerp(a,b,t) = a * (1-t) + b * t
1507 * is the linear interpolation between a and b, with
1508 * lerp(a,b,0) = a and lerp(a,b,1) = b
1509 *
1510 * I.e. the colatitude is computed as a linear interpolation between
1511 * - a = 1.5 (x^2 + y^2), proportional to the squared pythagorean
1512 * distance from the pole, which gives circular lines of latitude; and
1513 * - b = (x+y)^2, the squared manhattan distance from the pole, which
1514 * gives straight, diagonal lines of latitude parallel to the equator.
1515 *
1516 * These are interpolated with t = (x+y), the manhattan distance, which
1517 * ranges from 0 at the pole to 1 at the equator. So near the pole, the
1518 * (squared) pythagorean distance wins out, giving mostly circular lines,
1519 * and near the equator, the (squared) manhattan distance wins out,
1520 * giving mostly straight lines.
1521 *
1522 * Note that the colatitude growing with the square of the distance from
1523 * the pole keeps areas relatively the same as on non-toroidal maps:
1524 * On non-torus maps, the area closer to a pole than a given tile, and
1525 * the colatitude at that tile, both grow linearly with distance from the
1526 * pole. On torus maps, since the poles are singular points rather than
1527 * entire map edges, the area closer to a pole than a given tile grows
1528 * with the square of the distance to the pole - and so the colatitude
1529 * at that tile must also grow with the square in order to keep the size
1530 * of areas in a given range of colatitude relatively the same.
1531 *
1532 * See OSDN#43665, as well as the original discussion (via newsreader) at
1533 * news://news.gmane.io/gmane.games.freeciv.devel/42648 */
1534 toroid_rel_colatitude = (1.5 * (x * x * y + x * y * y)
1535 - 0.5 * (x * x * x + y * y * y)
1536 + 1.5 * (x * x + y * y));
1537
1538 /* Finally, convert from colatitude to latitude and add hemisphere
1539 * information back in:
1540 * - if we did not flip along the diagonal before, we are in the
1541 * northern hemisphere, with relative latitude in [0.0,0.5]
1542 * - if we _did_ flip, we are in the southern hemisphere, with
1543 * relative latitude in [0.5,1.0]
1544 */
1545 return ((toroid_flipped
1546 ? 2.0 - (toroid_rel_colatitude)
1548 / 2.0);
1549}
1550
1551/************************************************************************/
1559int map_signed_latitude(const struct tile *ptile)
1560{
1561 int north_latitude, south_latitude;
1562 double southness;
1563
1564 north_latitude = MAP_NORTH_LATITUDE(wld.map);
1565 south_latitude = MAP_SOUTH_LATITUDE(wld.map);
1566
1567 if (north_latitude == south_latitude) {
1568 /* Single-latitude / all-temperate map; no need to examine tile. */
1569 return south_latitude;
1570 }
1571
1572 fc_assert_ret_val(ptile != NULL, (north_latitude + south_latitude) / 2);
1573
1575
1576 /* Linear interpolation between northernmost and southernmost latitude.
1577 * Truncate / round towards zero so northern and southern hemisphere
1578 * are symmetrical when south_latitude = -north_latitude. */
1579 return north_latitude * (1.0 - southness) + south_latitude * southness;
1580}
1581
1582/*******************************************************************/
1590bool is_singular_tile(const struct tile *ptile, int dist)
1591{
1592 int tile_x, tile_y;
1593
1596 /* Iso-natural coordinates are doubled in scale. */
1597 dist *= MAP_IS_ISOMETRIC ? 2 : 1;
1598
1599 return ((!current_wrap_has_flag(WRAP_X)
1604}
1605
1606/*******************************************************************/
1609static struct startpos *startpos_new(struct tile *ptile)
1610{
1611 struct startpos *psp = fc_malloc(sizeof(*psp));
1612
1613 psp->location = ptile;
1614 psp->exclude = FALSE;
1615 psp->nations = nation_hash_new();
1616
1617 return psp;
1618}
1619
1620/*******************************************************************/
1623static void startpos_destroy(struct startpos *psp)
1624{
1625 fc_assert_ret(NULL != psp);
1627 free(psp);
1628}
1629
1630/*******************************************************************/
1634{
1635 return map_startpos_get(index_to_tile(&(wld.map), id));
1636}
1637
1638/*******************************************************************/
1642int startpos_number(const struct startpos *psp)
1643{
1644 fc_assert_ret_val(NULL != psp, -1);
1645 return tile_index(psp->location);
1646}
1647
1648/*******************************************************************/
1652bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
1653{
1654 fc_assert_ret_val(NULL != psp, FALSE);
1655 fc_assert_ret_val(NULL != pnation, FALSE);
1656
1657 if (0 == nation_hash_size(psp->nations) || !psp->exclude) {
1658 psp->exclude = FALSE; /* Disable "excluding" mode. */
1659 return nation_hash_insert(psp->nations, pnation, NULL);
1660 } else {
1661 return nation_hash_remove(psp->nations, pnation);
1662 }
1663}
1664
1665/*******************************************************************/
1669bool startpos_disallow(struct startpos *psp, struct nation_type *pnation)
1670{
1671 fc_assert_ret_val(NULL != psp, FALSE);
1672 fc_assert_ret_val(NULL != pnation, FALSE);
1673
1674 if (0 == nation_hash_size(psp->nations) || psp->exclude) {
1675 psp->exclude = TRUE; /* Enable "excluding" mode. */
1676 return nation_hash_remove(psp->nations, pnation);
1677 } else {
1678 return nation_hash_insert(psp->nations, pnation, NULL);
1679 }
1680}
1681
1682/*******************************************************************/
1685struct tile *startpos_tile(const struct startpos *psp)
1686{
1687 fc_assert_ret_val(NULL != psp, NULL);
1688 return psp->location;
1689}
1690
1691/*******************************************************************/
1694bool startpos_nation_allowed(const struct startpos *psp,
1695 const struct nation_type *pnation)
1696{
1697 fc_assert_ret_val(NULL != psp, FALSE);
1698 fc_assert_ret_val(NULL != pnation, FALSE);
1699 return XOR(psp->exclude, nation_hash_lookup(psp->nations, pnation, NULL));
1700}
1701
1702/*******************************************************************/
1705bool startpos_allows_all(const struct startpos *psp)
1706{
1707 fc_assert_ret_val(NULL != psp, FALSE);
1708 return (0 == nation_hash_size(psp->nations));
1709}
1710
1711/*******************************************************************/
1715bool startpos_pack(const struct startpos *psp,
1716 struct packet_edit_startpos_full *packet)
1717{
1718 fc_assert_ret_val(NULL != psp, FALSE);
1719 fc_assert_ret_val(NULL != packet, FALSE);
1720
1721 packet->id = startpos_number(psp);
1722 packet->exclude = psp->exclude;
1723 BV_CLR_ALL(packet->nations);
1724
1725 nation_hash_iterate(psp->nations, pnation) {
1726 BV_SET(packet->nations, nation_number(pnation));
1728 return TRUE;
1729}
1730
1731/*******************************************************************/
1735bool startpos_unpack(struct startpos *psp,
1736 const struct packet_edit_startpos_full *packet)
1737{
1738 fc_assert_ret_val(NULL != psp, FALSE);
1739 fc_assert_ret_val(NULL != packet, FALSE);
1740
1741 psp->exclude = packet->exclude;
1742
1744 if (!BV_ISSET_ANY(packet->nations)) {
1745 return TRUE;
1746 }
1747 nations_iterate(pnation) {
1748 if (BV_ISSET(packet->nations, nation_number(pnation))) {
1749 nation_hash_insert(psp->nations, pnation, NULL);
1750 }
1752 return TRUE;
1753}
1754
1755/*******************************************************************/
1762bool startpos_is_excluding(const struct startpos *psp)
1763{
1764 fc_assert_ret_val(NULL != psp, FALSE);
1765 return psp->exclude;
1766}
1767
1768/*******************************************************************/
1774const struct nation_hash *startpos_raw_nations(const struct startpos *psp)
1775{
1776 fc_assert_ret_val(NULL != psp, NULL);
1777 return psp->nations;
1778}
1779
1780/*******************************************************************/
1787{
1788 return MAX(sizeof(struct startpos_iter) + nation_iter_sizeof()
1789 - sizeof(struct iterator), nation_hash_iter_sizeof());
1790}
1791
1792/*******************************************************************/
1799{
1801
1802 do {
1803 iterator_next(&iter->nation_iter);
1804 } while (iterator_valid(&iter->nation_iter)
1805 || !nation_hash_lookup(iter->psp->nations,
1806 iterator_get(&iter->nation_iter), NULL));
1807}
1808
1809/*******************************************************************/
1817{
1819 return iterator_get(&iter->nation_iter);
1820}
1821
1822/*******************************************************************/
1826{
1828 return iterator_valid(&iter->nation_iter);
1829}
1830
1831/*******************************************************************/
1835 const struct startpos *psp)
1836{
1837 if (!psp) {
1839 }
1840
1841 if (startpos_allows_all(psp)) {
1842 return nation_iter_init((struct nation_iter *) iter);
1843 }
1844
1845 if (!psp->exclude) {
1847 psp->nations);
1848 }
1849
1850 iter->vtable.next = startpos_exclude_iter_next;
1851 iter->vtable.get = startpos_exclude_iter_get;
1852 iter->vtable.valid = startpos_exclude_iter_valid;
1853 iter->psp = psp;
1854 (void) nation_iter_init((struct nation_iter *) &iter->nation_iter);
1855
1856 return ITERATOR(iter);
1857}
1858
1859/*******************************************************************/
1863{
1864 if (NULL != wld.map.startpos_table) {
1866 } else {
1867 return 0;
1868 }
1869}
1870
1871/*******************************************************************/
1875struct startpos *map_startpos_new(struct tile *ptile)
1876{
1877 struct startpos *psp;
1878
1879 fc_assert_ret_val(NULL != ptile, NULL);
1881
1882 psp = startpos_new(ptile);
1884
1885 return psp;
1886}
1887
1888/*******************************************************************/
1892struct startpos *map_startpos_get(const struct tile *ptile)
1893{
1894 struct startpos *psp;
1895
1896 fc_assert_ret_val(NULL != ptile, NULL);
1898
1900
1901 return psp;
1902}
1903
1904/*******************************************************************/
1908bool map_startpos_remove(struct tile *ptile)
1909{
1910 fc_assert_ret_val(NULL != ptile, FALSE);
1912
1914}
1915
1916/*******************************************************************/
1921{
1923}
1924
1925/*******************************************************************/
1934
1935/*******************************************************************/
1942
1943/*******************************************************************/
1947{
1948 return direction8_max() - dir;
1949}
#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:708
struct startpos * map_startpos_get(const struct tile *ptile)
Definition map.c:1892
bool is_normal_map_pos(int x, int y)
Definition map.c:972
const int DIR_DY[8]
Definition map.c:87
int startpos_number(const struct startpos *psp)
Definition map.c:1642
bool can_reclaim_ocean(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:691
void map_free(struct civ_map *fmap)
Definition map.c:530
bool startpos_disallow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1669
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:1946
#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:1374
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:737
struct startpos * map_startpos_new(struct tile *ptile)
Definition map.c:1875
bool can_thaw_terrain(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:722
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:789
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:1694
#define STARTPOS_ITER(p)
Definition map.c:65
int map_num_tiles(void)
Definition map.c:1023
int get_direction_for_step(const struct civ_map *nmap, const struct tile *start_tile, const struct tile *end_tile)
Definition map.c:1356
struct tile * startpos_tile(const struct startpos *psp)
Definition map.c:1685
bool startpos_allows_all(const struct startpos *psp)
Definition map.c:1705
const struct nation_hash * startpos_raw_nations(const struct startpos *psp)
Definition map.c:1774
const int DIR_DX[8]
Definition map.c:86
struct tile * rand_map_pos(const struct civ_map *nmap)
Definition map.c:1097
static bool restrict_infra(const struct player *pplayer, const struct tile *t1, const struct tile *t2)
Definition map.c:920
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:1155
enum direction8 dir_ccw(enum direction8 dir)
Definition map.c:1212
struct iterator * map_startpos_iter_init(struct map_startpos_iter *iter)
Definition map.c:1929
bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
Definition map.c:940
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:1609
static double map_relative_southness(const struct tile *ptile)
Definition map.c:1405
bool startpos_pack(const struct startpos *psp, struct packet_edit_startpos_full *packet)
Definition map.c:1715
static bool is_valid_dir_calculate(enum direction8 dir)
Definition map.c:1242
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:1559
static bool is_cardinal_dir_calculate(enum direction8 dir)
Definition map.c:1299
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:1908
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:1110
int map_startpos_count(void)
Definition map.c:1862
size_t startpos_iter_sizeof(void)
Definition map.c:1786
bool is_cardinal_dir(enum direction8 dir)
Definition map.c:1325
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:949
bool map_untrusted_dir_is_valid(enum direction8 dir)
Definition map.c:1282
bool terrain_surroundings_allow_change(const struct civ_map *nmap, const struct tile *ptile, const struct terrain *pterrain)
Definition map.c:751
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:1735
bool is_valid_dir(enum direction8 dir)
Definition map.c:1269
void base_map_distance_vector(int *dx, int *dy, int x0dv, int y0dv, int x1dv, int y1dv)
Definition map.c:1033
enum direction8 dir_cw(enum direction8 dir)
Definition map.c:1183
enum direction8 rand_direction(void)
Definition map.c:1938
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:1623
struct terrain_misc terrain_control
Definition map.c:69
static void * startpos_exclude_iter_get(const struct iterator *startpos_iter)
Definition map.c:1816
struct tile * nearest_real_tile(const struct civ_map *nmap, int x, int y)
Definition map.c:1004
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:1337
static void startpos_exclude_iter_next(struct iterator *startpos_iter)
Definition map.c:1798
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:1082
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:1762
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:1633
bool map_is_empty(void)
Definition map.c:149
size_t map_startpos_iter_sizeof(void)
Definition map.c:1920
bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1652
bool normalize_map_pos(const struct civ_map *nmap, int *x, int *y)
Definition map.c:988
static bool startpos_exclude_iter_valid(const struct iterator *startpos_iter)
Definition map.c:1825
struct iterator * startpos_iter_init(struct startpos_iter *iter, const struct startpos *psp)
Definition map.c:1834
bool is_real_map_pos(const struct civ_map *nmap, int x, int y)
Definition map.c:961
bool is_singular_tile(const struct tile *ptile, int dist)
Definition map.c:1590
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:88
#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:169
#define tile_terrain(_tile)
Definition tile.h:114
#define tile_has_extra(ptile, pextra)
Definition tile.h:151
#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