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