Freeciv-3.1
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;
44 struct nation_hash *nations;
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/*******************************************************************/
101bv_extras get_tile_infrastructure_set(const struct tile *ptile,
102 int *pcount)
103{
104 bv_extras pspresent;
105 int count = 0;
106
107 BV_CLR_ALL(pspresent);
108
109 extra_type_by_rmcause_iterate(ERM_PILLAGE, pextra) {
110 if (tile_has_extra(ptile, pextra)) {
111 struct tile *missingset = tile_virtual_new(ptile);
112 bool dependency = FALSE;
113
114 tile_remove_extra(missingset, pextra);
115 extra_type_iterate(pdependant) {
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)) {
121 dependency = TRUE;
122 break;
123 }
124 }
126
127 tile_virtual_destroy(missingset);
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{
160 imap->num_continents = 0;
161 imap->num_oceans = 0;
162 imap->tiles = NULL;
163 imap->startpos_table = NULL;
164 imap->iterate_outwards_indices = NULL;
165
166 /* The [xy]size values are set in map_init_topology(). It is initialized
167 * to a non-zero value because some places erroneously use these values
168 * before they're initialized. */
171
172 if (server_side) {
180 imap->server.huts_absolute = -1;
192 imap->server.have_huts = FALSE;
195 }
196}
197
198/*******************************************************************/
201static void generate_map_indices(void)
202{
203 int i = 0, nat_x, nat_y, tiles;
204 int nat_center_x, nat_center_y, nat_min_x, nat_min_y, nat_max_x, nat_max_y;
205 int map_center_x, map_center_y;
206
207 /* These caluclations are done via tricky native math. We need to make
208 * sure that when "exploring" positions in the iterate_outward we hit each
209 * position within the distance exactly once.
210 *
211 * To do this we pick a center position (at the center of the map, for
212 * convenience). Then we iterate over all of the positions around it,
213 * accounting for wrapping, in native coordinates. Note that some of the
214 * positions iterated over before will not even be real; the point is to
215 * use the native math so as to get the right behavior under different
216 * wrapping conditions.
217 *
218 * Thus the "center" position below is just an arbitrary point. We choose
219 * the center of the map to make the min/max values (below) simpler. */
220 nat_center_x = wld.map.xsize / 2;
221 nat_center_y = wld.map.ysize / 2;
222 NATIVE_TO_MAP_POS(&map_center_x, &map_center_y,
223 nat_center_x, nat_center_y);
224
225 /* If we wrap in a particular direction (X or Y) we only need to explore a
226 * half of a map-width in that direction before we hit the wrap point. If
227 * not we need to explore the full width since we have to account for the
228 * worst-case where we start at one edge of the map. Of course if we try
229 * to explore too far the extra steps will just be skipped by the
230 * normalize check later on. So the purpose at this point is just to
231 * get the right set of positions, relative to the start position, that
232 * may be needed for the iteration.
233 *
234 * If the map does wrap, we go map.Nsize / 2 in each direction. This
235 * gives a min value of 0 and a max value of Nsize-1, because of the
236 * center position chosen above. This also avoids any off-by-one errors.
237 *
238 * If the map doesn't wrap, we go map.Nsize-1 in each direction. In this
239 * case we're not concerned with going too far and wrapping around, so we
240 * just have to make sure we go far enough if we're at one edge of the
241 * map. */
242 nat_min_x = (current_topo_has_flag(TF_WRAPX) ? 0 : (nat_center_x - wld.map.xsize + 1));
243 nat_min_y = (current_topo_has_flag(TF_WRAPY) ? 0 : (nat_center_y - wld.map.ysize + 1));
244
245 nat_max_x = (current_topo_has_flag(TF_WRAPX)
246 ? (wld.map.xsize - 1)
247 : (nat_center_x + wld.map.xsize - 1));
248 nat_max_y = (current_topo_has_flag(TF_WRAPY)
249 ? (wld.map.ysize - 1)
250 : (nat_center_y + wld.map.ysize - 1));
251 tiles = (nat_max_x - nat_min_x + 1) * (nat_max_y - nat_min_y + 1);
252
255 fc_malloc(tiles * sizeof(*wld.map.iterate_outwards_indices));
256
257 for (nat_x = nat_min_x; nat_x <= nat_max_x; nat_x++) {
258 for (nat_y = nat_min_y; nat_y <= nat_max_y; nat_y++) {
259 int map_x, map_y, dx, dy;
260
261 /* Now for each position, we find the vector (in map coordinates) from
262 * the center position to that position. Then we calculate the
263 * distance between the two points. Wrapping is ignored at this
264 * point since the use of native positions means we should always have
265 * the shortest vector. */
266 NATIVE_TO_MAP_POS(&map_x, &map_y, nat_x, nat_y);
267 dx = map_x - map_center_x;
268 dy = map_y - map_center_y;
269
274 i++;
275 }
276 }
277 fc_assert(i == tiles);
278
279 qsort(wld.map.iterate_outwards_indices, tiles,
281
282#if 0
283 for (i = 0; i < tiles; i++) {
284 log_debug("%5d : (%3d,%3d) : %d", i,
288 }
289#endif
290
292}
293
294/*******************************************************************/
301void map_init_topology(struct civ_map *nmap)
302{
303 enum direction8 dir;
304
305 /* sanity check for iso topologies*/
306 fc_assert(!MAP_IS_ISOMETRIC || (wld.map.ysize % 2) == 0);
307
308 /* The size and ratio must satisfy the minimum and maximum *linear*
309 * restrictions on width */
316
317 nmap->num_valid_dirs = nmap->num_cardinal_dirs = 0;
318
319 /* Values for direction8_invalid() */
320 fc_assert(direction8_invalid() == 8);
321 dir_validity[8] = FALSE;
323
324 /* Values for actual directions */
325 for (dir = 0; dir < 8; dir++) {
326 if (is_valid_dir_calculate(dir)) {
327 nmap->valid_dirs[nmap->num_valid_dirs] = dir;
328 nmap->num_valid_dirs++;
329 dir_validity[dir] = TRUE;
330 } else {
331 dir_validity[dir] = FALSE;
332 }
333 if (is_cardinal_dir_calculate(dir)) {
334 nmap->cardinal_dirs[nmap->num_cardinal_dirs] = dir;
335 nmap->num_cardinal_dirs++;
336 dir_cardinality[dir] = TRUE;
337 } else {
338 dir_cardinality[dir] = FALSE;
339 }
340 }
341 fc_assert(nmap->num_valid_dirs > 0 && nmap->num_valid_dirs <= 8);
343 && nmap->num_cardinal_dirs <= nmap->num_valid_dirs);
344}
345
346/*******************************************************************/
349static void tile_init(struct tile *ptile)
350{
351 ptile->continent = 0;
352
353 BV_CLR_ALL(ptile->extras);
354 ptile->resource = NULL;
355 ptile->terrain = T_UNKNOWN;
356 ptile->units = unit_list_new();
357 ptile->owner = NULL; /* Not claimed by any player. */
358 ptile->extras_owner = NULL;
359 ptile->placing = NULL;
360 ptile->claimer = NULL;
361 ptile->worked = NULL; /* No city working here. */
362 ptile->spec_sprite = NULL;
363}
364
365/*******************************************************************/
369struct tile *mapstep(const struct civ_map *nmap,
370 const struct tile *ptile, enum direction8 dir)
371{
372 int dx, dy, tile_x, tile_y;
373
374 if (!is_valid_dir(dir)) {
375 return NULL;
376 }
377
378 index_to_map_pos(&tile_x, &tile_y, tile_index(ptile));
379 DIRSTEP(dx, dy, dir);
380
381 tile_x += dx;
382 tile_y += dy;
383
384 return map_pos_to_tile(&(wld.map), tile_x, tile_y);
385}
386
387/*******************************************************************/
393static inline struct tile *base_native_pos_to_tile(const struct civ_map *nmap,
394 int nat_x, int nat_y)
395{
396 /* Wrap in X and Y directions, as needed. */
397 /* If the position is out of range in a non-wrapping direction, it is
398 * unreal. */
399 if (current_topo_has_flag(TF_WRAPX)) {
401 } else if (nat_x < 0 || nat_x >= wld.map.xsize) {
402 return NULL;
403 }
404 if (current_topo_has_flag(TF_WRAPY)) {
406 } else if (nat_y < 0 || nat_y >= wld.map.ysize) {
407 return NULL;
408 }
409
410 /* We already checked legality of native pos above, don't repeat */
412}
413
414/*******************************************************************/
417struct tile *map_pos_to_tile(const struct civ_map *nmap, int map_x, int map_y)
418{
419 /* Instead of introducing new variables for native coordinates,
420 * update the map coordinate variables = registers already in use.
421 * This is one of the most performance-critical functions we have,
422 * so taking measures like this makes sense. */
423#define nat_x map_x
424#define nat_y map_y
425
426 if (nmap->tiles == NULL) {
427 return NULL;
428 }
429
430 /* Normalization is best done in native coordinates. */
431 MAP_TO_NATIVE_POS(&nat_x, &nat_y, map_x, map_y);
432 return base_native_pos_to_tile(nmap, nat_x, nat_y);
433
434#undef nat_x
435#undef nat_y
436}
437
438/*******************************************************************/
441struct tile *native_pos_to_tile(const struct civ_map *nmap,
442 int nat_x, int nat_y)
443{
444 if (nmap->tiles == NULL) {
445 return NULL;
446 }
447
448 return base_native_pos_to_tile(nmap, nat_x, nat_y);
449}
450
451/*******************************************************************/
454struct tile *index_to_tile(const struct civ_map *imap, int mindex)
455{
456 if (!imap->tiles) {
457 return NULL;
458 }
459
460 if (mindex >= 0 && mindex < MAP_INDEX_SIZE) {
461 return imap->tiles + mindex;
462 } else {
463 /* Unwrapped index coordinates are impossible, so the best we can do is
464 * return NULL. */
465 return NULL;
466 }
467}
468
469/*******************************************************************/
472static void tile_free(struct tile *ptile)
473{
474 unit_list_destroy(ptile->units);
475
476 if (ptile->spec_sprite) {
477 free(ptile->spec_sprite);
478 ptile->spec_sprite = NULL;
479 }
480
481 if (ptile->label) {
482 FC_FREE(ptile->label);
483 ptile->label = NULL;
484 }
485}
486
487/*******************************************************************/
491void map_allocate(struct civ_map *amap)
492{
493 log_debug("map_allocate (was %p) (%d,%d)",
494 (void *) amap->tiles, amap->xsize, amap->ysize);
495
496 fc_assert_ret(NULL == amap->tiles);
497 amap->tiles = fc_calloc(MAP_INDEX_SIZE, sizeof(*amap->tiles));
498
499 /* Note this use of whole_map_iterate may be a bit sketchy, since the
500 * tile values (ptile->index, etc.) haven't been set yet. It might be
501 * better to do a manual loop here. */
502 whole_map_iterate(amap, ptile) {
503 ptile->index = ptile - amap->tiles;
504 CHECK_INDEX(tile_index(ptile));
505 tile_init(ptile);
507
508 if (amap->startpos_table != NULL) {
509 startpos_hash_destroy(amap->startpos_table);
510 }
511 amap->startpos_table = startpos_hash_new();
512}
513
514/*******************************************************************/
524
525/*******************************************************************/
528void map_free(struct civ_map *fmap)
529{
530 if (fmap->tiles) {
531 /* it is possible that map_init was called but not map_allocate */
532
533 whole_map_iterate(fmap, ptile) {
534 tile_free(ptile);
536
537 free(fmap->tiles);
538 fmap->tiles = NULL;
539
540 if (fmap->startpos_table) {
541 startpos_hash_destroy(fmap->startpos_table);
542 fmap->startpos_table = NULL;
543 }
544
546 }
547}
548
549/*******************************************************************/
553{
554 map_free(&(wld.map));
556}
557
558/*******************************************************************/
562static int map_vector_to_distance(int dx, int dy)
563{
564 if (current_topo_has_flag(TF_HEX)) {
565 /* Hex: all directions are cardinal so the distance is equivalent to
566 * the real distance. */
567 return map_vector_to_real_distance(dx, dy);
568 } else {
569 return abs(dx) + abs(dy);
570 }
571}
572
573/*******************************************************************/
577{
578 const int absdx = abs(dx), absdy = abs(dy);
579
580 if (current_topo_has_flag(TF_HEX)) {
581 if (current_topo_has_flag(TF_ISO)) {
582 /* Iso-hex: you can't move NE or SW. */
583 if ((dx < 0 && dy > 0)
584 || (dx > 0 && dy < 0)) {
585 /* Diagonal moves in this direction aren't allowed, so it will take
586 * the full number of moves. */
587 return absdx + absdy;
588 } else {
589 /* Diagonal moves in this direction *are* allowed. */
590 return MAX(absdx, absdy);
591 }
592 } else {
593 /* Hex: you can't move SE or NW. */
594 if ((dx > 0 && dy > 0)
595 || (dx < 0 && dy < 0)) {
596 /* Diagonal moves in this direction aren't allowed, so it will take
597 * the full number of moves. */
598 return absdx + absdy;
599 } else {
600 /* Diagonal moves in this direction *are* allowed. */
601 return MAX(absdx, absdy);
602 }
603 }
604 } else {
605 return MAX(absdx, absdy);
606 }
607}
608
609/*******************************************************************/
612int map_vector_to_sq_distance(int dx, int dy)
613{
614 if (current_topo_has_flag(TF_HEX)) {
615 /* Hex: The square distance is just the square of the real distance; we
616 * don't worry about pythagorean calculations. */
617 int dist = map_vector_to_real_distance(dx, dy);
618
619 return dist * dist;
620 } else {
621 return dx * dx + dy * dy;
622 }
623}
624
625/*******************************************************************/
628int real_map_distance(const struct tile *tile0, const struct tile *tile1)
629{
630 int dx, dy;
631
632 map_distance_vector(&dx, &dy, tile0, tile1);
633 return map_vector_to_real_distance(dx, dy);
634}
635
636/*******************************************************************/
639int sq_map_distance(const struct tile *tile0, const struct tile *tile1)
640{
641 /* We assume map_distance_vector gives us the vector with the
642 minimum squared distance. Right now this is true. */
643 int dx, dy;
644
645 map_distance_vector(&dx, &dy, tile0, tile1);
646 return map_vector_to_sq_distance(dx, dy);
647}
648
649/*******************************************************************/
652int map_distance(const struct tile *tile0, const struct tile *tile1)
653{
654 /* We assume map_distance_vector gives us the vector with the
655 minimum map distance. Right now this is true. */
656 int dx, dy;
657
658 map_distance_vector(&dx, &dy, tile0, tile1);
659 return map_vector_to_distance(dx, dy);
660}
661
662/*******************************************************************/
665bool is_safe_ocean(const struct civ_map *nmap, const struct tile *ptile)
666{
667 adjc_iterate(nmap, ptile, adjc_tile) {
668 if (tile_terrain(adjc_tile) != T_UNKNOWN
669 && !terrain_has_flag(tile_terrain(adjc_tile), TER_UNSAFE_COAST)) {
670 return TRUE;
671 }
673
674 return FALSE;
675}
676
677/*******************************************************************/
682bool can_reclaim_ocean(const struct civ_map *nmap,
683 const struct tile *ptile)
684{
685 int land_tiles = 100 - count_terrain_class_near_tile(nmap, ptile,
686 FALSE, TRUE,
687 TC_OCEAN);
688
689 return land_tiles >= terrain_control.ocean_reclaim_requirement_pct;
690}
691
692/*******************************************************************/
697bool can_channel_land(const struct civ_map *nmap,
698 const struct tile *ptile)
699{
700 int ocean_tiles = count_terrain_class_near_tile(nmap, ptile,
701 FALSE, TRUE, TC_OCEAN);
702
703 return ocean_tiles >= terrain_control.land_channel_requirement_pct;
704}
705
706/*******************************************************************/
711bool can_thaw_terrain(const struct civ_map *nmap,
712 const struct tile *ptile)
713{
714 int unfrozen_tiles = 100 - count_terrain_flag_near_tile(nmap, ptile,
715 FALSE, TRUE,
716 TER_FROZEN);
717
718 return unfrozen_tiles >= terrain_control.terrain_thaw_requirement_pct;
719}
720
721/*******************************************************************/
726bool can_freeze_terrain(const struct civ_map *nmap,
727 const struct tile *ptile)
728{
729 int frozen_tiles = count_terrain_flag_near_tile(nmap, ptile,
730 FALSE, TRUE,
731 TER_FROZEN);
732
733 return frozen_tiles >= terrain_control.terrain_freeze_requirement_pct;
734}
735
736/*******************************************************************/
741 const struct tile *ptile,
742 const struct terrain *pterrain)
743{
744 bool ret = TRUE;
745
746 if (is_ocean(tile_terrain(ptile))
747 && !is_ocean(pterrain) && !can_reclaim_ocean(nmap, ptile)) {
748 ret = FALSE;
749 } else if (!is_ocean(tile_terrain(ptile))
750 && is_ocean(pterrain) && !can_channel_land(nmap, ptile)) {
751 ret = FALSE;
752 }
753
754 if (ret) {
755 if (terrain_has_flag(tile_terrain(ptile), TER_FROZEN)
756 && !terrain_has_flag(pterrain, TER_FROZEN)
757 && !can_thaw_terrain(nmap, ptile)) {
758 ret = FALSE;
759 } else if (!terrain_has_flag(tile_terrain(ptile), TER_FROZEN)
760 && terrain_has_flag(pterrain, TER_FROZEN)
761 && !can_freeze_terrain(nmap, ptile)) {
762 ret = FALSE;
763 }
764 }
765
766 return ret;
767}
768
769/*******************************************************************/
778int tile_move_cost_ptrs(const struct civ_map *nmap,
779 const struct unit *punit,
780 const struct unit_type *punittype,
781 const struct player *pplayer,
782 const struct tile *t1, const struct tile *t2)
783{
784 const struct unit_class *pclass = utype_class(punittype);
785 int cost;
786 signed char cardinal_move = -1;
787 bool ri;
788
789 /* Try to exit early for detectable conditions */
790 if (!uclass_has_flag(pclass, UCF_TERRAIN_SPEED)) {
791 /* units without UCF_TERRAIN_SPEED have a constant cost. */
792 return SINGLE_MOVE;
793
794 } else if (!is_native_tile_to_class(pclass, t2)) {
795 if (tile_city(t2) == NULL) {
796 /* Loading to transport. */
797
798 /* UTYF_IGTER units get move benefit. */
799 return (utype_has_flag(punittype, UTYF_IGTER)
801 } else {
802 /* Entering port. (Could be "Conquer City") */
803
804 /* UTYF_IGTER units get move benefit. */
805 return (utype_has_flag(punittype, UTYF_IGTER)
807 }
808
809 } else if (!is_native_tile_to_class(pclass, t1)) {
810 if (tile_city(t1) == NULL) {
811 /* Disembarking from transport. */
812
813 /* UTYF_IGTER units get move benefit. */
814 return (utype_has_flag(punittype, UTYF_IGTER)
816 } else {
817 /* Leaving port. */
818
819 /* UTYF_IGTER units get move benefit. */
820 return (utype_has_flag(punittype, UTYF_IGTER)
822 }
823 }
824
825 cost = tile_terrain(t2)->movement_cost * SINGLE_MOVE;
826 ri = restrict_infra(pplayer, t1, t2);
827
828 extra_type_list_iterate(pclass->cache.bonus_roads, pextra) {
829 struct road_type *proad = extra_road_get(pextra);
830
831 /* We check the destination tile first, as that's
832 * the end of move that determines the cost.
833 * If can avoid inner loop about integrating roads
834 * completely if the destination road has too high cost. */
835
836 if (cost > proad->move_cost
837 && (!ri || road_has_flag(proad, RF_UNRESTRICTED_INFRA))
838 && tile_has_extra(t2, pextra)) {
839 extra_type_list_iterate(proad->integrators, iextra) {
840 /* We have no unrestricted infra related check here,
841 * destination road is the one that counts. */
842 if (tile_has_extra(t1, iextra)
843 && is_native_extra_to_uclass(iextra, pclass)) {
844 if (proad->move_mode == RMM_FAST_ALWAYS) {
845 cost = proad->move_cost;
846 } else {
847 if (cardinal_move < 0) {
848 cardinal_move = (ALL_DIRECTIONS_CARDINAL()
849 || is_move_cardinal(nmap, t1, t2)) ? 1 : 0;
850 }
851 if (cardinal_move > 0) {
852 cost = proad->move_cost;
853 } else {
854 switch (proad->move_mode) {
855 case RMM_CARDINAL:
856 break;
857 case RMM_RELAXED:
858 if (cost > proad->move_cost * 2) {
859 cardinal_between_iterate(nmap, t1, t2, between) {
860 if (tile_has_extra(between, pextra)
861 || (pextra != iextra && tile_has_extra(between, iextra))) {
862 /* 'pextra != iextra' is there just to avoid tile_has_extra()
863 * in by far more common case that 'pextra == iextra' */
864 /* TODO: Should we restrict this more?
865 * Should we check against enemy cities on between tile?
866 * Should we check against non-native terrain on between tile?
867 */
868 cost = proad->move_cost * 2;
869 }
871 }
872 break;
873 case RMM_FAST_ALWAYS:
874 fc_assert(proad->move_mode != RMM_FAST_ALWAYS); /* Already handled above */
875 cost = proad->move_cost;
876 break;
877 }
878 }
879 }
880 }
882 }
884
885 /* UTYF_IGTER units have a maximum move cost per step. */
886 if (utype_has_flag(punittype, UTYF_IGTER) && MOVE_COST_IGTER < cost) {
888 }
889
890 if (terrain_control.pythagorean_diagonal) {
891 if (cardinal_move < 0) {
892 cardinal_move = (ALL_DIRECTIONS_CARDINAL()
893 || is_move_cardinal(nmap, t1, t2)) ? 1 : 0;
894 }
895 if (cardinal_move == 0) {
896 return cost * 181 >> 7; /* == (int) (cost * 1.41421356f) if cost < 99 */
897 }
898 }
899
900 return cost;
901}
902
903/*******************************************************************/
909static bool restrict_infra(const struct player *pplayer, const struct tile *t1,
910 const struct tile *t2)
911{
912 struct player *plr1 = tile_owner(t1), *plr2 = tile_owner(t2);
913
914 if (!pplayer || !game.info.restrictinfra) {
915 return FALSE;
916 }
917
918 if ((plr1 && pplayers_at_war(plr1, pplayer))
919 || (plr2 && pplayers_at_war(plr2, pplayer))) {
920 return TRUE;
921 }
922
923 return FALSE;
924}
925
926/*******************************************************************/
929bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
930{
931 return real_map_distance(tile0, tile1) == 1;
932}
933
934/*******************************************************************/
938bool same_pos(const struct tile *tile1, const struct tile *tile2)
939{
940 fc_assert_ret_val(tile1 != NULL && tile2 != NULL, FALSE);
941
942 /* In case of virtual tile, tile1 can be different from tile2,
943 * but they have same index */
944 return (tile1->index == tile2->index);
945}
946
947/*******************************************************************/
950bool is_real_map_pos(const struct civ_map *nmap, int x, int y)
951{
952 return normalize_map_pos(nmap, &x, &y);
953}
954
955/*******************************************************************/
961bool is_normal_map_pos(int x, int y)
962{
963 int nat_x, nat_y;
964
965 MAP_TO_NATIVE_POS(&nat_x, &nat_y, x, y);
966 return nat_x >= 0 && nat_x < wld.map.xsize && nat_y >= 0 && nat_y < wld.map.ysize;
967}
968
969/*******************************************************************/
977bool normalize_map_pos(const struct civ_map *nmap, int *x, int *y)
978{
979 struct tile *ptile = map_pos_to_tile(nmap, *x, *y);
980
981 if (ptile) {
982 index_to_map_pos(x, y, tile_index(ptile));
983 return TRUE;
984 } else {
985 return FALSE;
986 }
987}
988
989/*******************************************************************/
993struct tile *nearest_real_tile(const struct civ_map *nmap, int x, int y)
994{
995 int nat_x, nat_y;
996
997 MAP_TO_NATIVE_POS(&nat_x, &nat_y, x, y);
998 if (!current_topo_has_flag(TF_WRAPX)) {
999 nat_x = CLIP(0, nat_x, wld.map.xsize - 1);
1000 }
1001 if (!current_topo_has_flag(TF_WRAPY)) {
1002 nat_y = CLIP(0, nat_y, wld.map.ysize - 1);
1003 }
1004 NATIVE_TO_MAP_POS(&x, &y, nat_x, nat_y);
1005
1006 return map_pos_to_tile(nmap, x, y);
1007}
1008
1009/*******************************************************************/
1013{
1014 return wld.map.xsize * wld.map.ysize;
1015}
1016
1017/*******************************************************************/
1022void base_map_distance_vector(int *dx, int *dy,
1023 int x0dv, int y0dv, int x1dv, int y1dv)
1024{
1025 if (current_topo_has_flag(TF_WRAPX) || current_topo_has_flag(TF_WRAPY)) {
1026 /* Wrapping is done in native coordinates. */
1027 MAP_TO_NATIVE_POS(&x0dv, &y0dv, x0dv, y0dv);
1028 MAP_TO_NATIVE_POS(&x1dv, &y1dv, x1dv, y1dv);
1029
1030 /* Find the "native" distance vector. This corresponds closely to the
1031 * map distance vector but is easier to wrap. */
1032 *dx = x1dv - x0dv;
1033 *dy = y1dv - y0dv;
1034 if (current_topo_has_flag(TF_WRAPX)) {
1035 /* Wrap dx to be in [-map.xsize/2, map.xsize/2). */
1036 *dx = FC_WRAP(*dx + wld.map.xsize / 2, wld.map.xsize) - wld.map.xsize / 2;
1037 }
1038 if (current_topo_has_flag(TF_WRAPY)) {
1039 /* Wrap dy to be in [-map.ysize/2, map.ysize/2). */
1040 *dy = FC_WRAP(*dy + wld.map.ysize / 2, wld.map.ysize) - wld.map.ysize / 2;
1041 }
1042
1043 /* Convert the native delta vector back to a pair of map positions. */
1044 x1dv = x0dv + *dx;
1045 y1dv = y0dv + *dy;
1046 NATIVE_TO_MAP_POS(&x0dv, &y0dv, x0dv, y0dv);
1047 NATIVE_TO_MAP_POS(&x1dv, &y1dv, x1dv, y1dv);
1048 }
1049
1050 /* Find the final (map) vector. */
1051 *dx = x1dv - x0dv;
1052 *dy = y1dv - y0dv;
1053}
1054
1055/*******************************************************************/
1071void map_distance_vector(int *dx, int *dy,
1072 const struct tile *tile0,
1073 const struct tile *tile1)
1074{
1075 int tx0, ty0, tx1, ty1;
1076
1077 index_to_map_pos(&tx0, &ty0, tile_index(tile0));
1078 index_to_map_pos(&tx1, &ty1, tile_index(tile1));
1079 base_map_distance_vector(dx, dy, tx0, ty0, tx1, ty1);
1080}
1081
1082/*******************************************************************/
1086struct tile *rand_map_pos(const struct civ_map *nmap)
1087{
1089
1090 return native_pos_to_tile(nmap, nat_x, nat_y);
1091}
1092
1093/*******************************************************************/
1099struct tile *rand_map_pos_filtered(const struct civ_map *nmap, void *data,
1100 bool (*filter)(const struct tile *ptile,
1101 const void *data))
1102{
1103 struct tile *ptile;
1104 int tries = 0;
1105 const int max_tries = MAP_INDEX_SIZE / ACTIVITY_FACTOR;
1106
1107 /* First do a few quick checks to find a spot. The limit on number of
1108 * tries could use some tweaking. */
1109 do {
1110 ptile = nmap->tiles + fc_rand(MAP_INDEX_SIZE);
1111 } while (filter != NULL && !filter(ptile, data) && ++tries < max_tries);
1112
1113 /* If that fails, count all available spots and pick one.
1114 * Slow but reliable. */
1115 if (filter == NULL) {
1116 ptile = NULL;
1117 } else if (tries == max_tries) {
1118 int count = 0, *positions;
1119
1120 positions = fc_calloc(MAP_INDEX_SIZE, sizeof(*positions));
1121
1122 whole_map_iterate(nmap, check_tile) {
1123 if (filter(check_tile, data)) {
1124 positions[count] = tile_index(check_tile);
1125 count++;
1126 }
1128
1129 if (count == 0) {
1130 ptile = NULL;
1131 } else {
1132 ptile = wld.map.tiles + positions[fc_rand(count)];
1133 }
1134
1135 FC_FREE(positions);
1136 }
1137
1138 return ptile;
1139}
1140
1141/*******************************************************************/
1144const char *dir_get_name(enum direction8 dir)
1145{
1146 /* a switch statement is used so the ordering can be changed easily */
1147 switch (dir) {
1148 case DIR8_NORTH:
1149 return "N";
1150 case DIR8_NORTHEAST:
1151 return "NE";
1152 case DIR8_EAST:
1153 return "E";
1154 case DIR8_SOUTHEAST:
1155 return "SE";
1156 case DIR8_SOUTH:
1157 return "S";
1158 case DIR8_SOUTHWEST:
1159 return "SW";
1160 case DIR8_WEST:
1161 return "W";
1162 case DIR8_NORTHWEST:
1163 return "NW";
1164 default:
1165 return "[Undef]";
1166 }
1167}
1168
1169/*******************************************************************/
1172enum direction8 dir_cw(enum direction8 dir)
1173{
1174 /* a switch statement is used so the ordering can be changed easily */
1175 switch (dir) {
1176 case DIR8_NORTH:
1177 return DIR8_NORTHEAST;
1178 case DIR8_NORTHEAST:
1179 return DIR8_EAST;
1180 case DIR8_EAST:
1181 return DIR8_SOUTHEAST;
1182 case DIR8_SOUTHEAST:
1183 return DIR8_SOUTH;
1184 case DIR8_SOUTH:
1185 return DIR8_SOUTHWEST;
1186 case DIR8_SOUTHWEST:
1187 return DIR8_WEST;
1188 case DIR8_WEST:
1189 return DIR8_NORTHWEST;
1190 case DIR8_NORTHWEST:
1191 return DIR8_NORTH;
1192 default:
1194 return -1;
1195 }
1196}
1197
1198/*******************************************************************/
1201enum direction8 dir_ccw(enum direction8 dir)
1202{
1203 /* a switch statement is used so the ordering can be changed easily */
1204 switch (dir) {
1205 case DIR8_NORTH:
1206 return DIR8_NORTHWEST;
1207 case DIR8_NORTHEAST:
1208 return DIR8_NORTH;
1209 case DIR8_EAST:
1210 return DIR8_NORTHEAST;
1211 case DIR8_SOUTHEAST:
1212 return DIR8_EAST;
1213 case DIR8_SOUTH:
1214 return DIR8_SOUTHEAST;
1215 case DIR8_SOUTHWEST:
1216 return DIR8_SOUTH;
1217 case DIR8_WEST:
1218 return DIR8_SOUTHWEST;
1219 case DIR8_NORTHWEST:
1220 return DIR8_WEST;
1221 default:
1223 return -1;
1224 }
1225}
1226
1227/*******************************************************************/
1231static bool is_valid_dir_calculate(enum direction8 dir)
1232{
1233 switch (dir) {
1234 case DIR8_SOUTHEAST:
1235 case DIR8_NORTHWEST:
1236 /* These directions are invalid in hex topologies. */
1237 return !(current_topo_has_flag(TF_HEX) && !current_topo_has_flag(TF_ISO));
1238 case DIR8_NORTHEAST:
1239 case DIR8_SOUTHWEST:
1240 /* These directions are invalid in iso-hex topologies. */
1241 return !(current_topo_has_flag(TF_HEX) && current_topo_has_flag(TF_ISO));
1242 case DIR8_NORTH:
1243 case DIR8_EAST:
1244 case DIR8_SOUTH:
1245 case DIR8_WEST:
1246 return TRUE;
1247 default:
1248 return FALSE;
1249 }
1250}
1251
1252/*******************************************************************/
1258bool is_valid_dir(enum direction8 dir)
1259{
1260 fc_assert_ret_val(dir <= direction8_invalid(), FALSE);
1261
1262 return dir_validity[dir];
1263}
1264
1265/*******************************************************************/
1271bool map_untrusted_dir_is_valid(enum direction8 dir)
1272{
1273 if (!direction8_is_valid(dir)) {
1274 /* Isn't even in range of direction8. */
1275 return FALSE;
1276 }
1277
1278 return is_valid_dir(dir);
1279}
1280
1281/*******************************************************************/
1288static bool is_cardinal_dir_calculate(enum direction8 dir)
1289{
1290 switch (dir) {
1291 case DIR8_NORTH:
1292 case DIR8_SOUTH:
1293 case DIR8_EAST:
1294 case DIR8_WEST:
1295 return TRUE;
1296 case DIR8_SOUTHEAST:
1297 case DIR8_NORTHWEST:
1298 /* These directions are cardinal in iso-hex topologies. */
1299 return current_topo_has_flag(TF_HEX) && current_topo_has_flag(TF_ISO);
1300 case DIR8_NORTHEAST:
1301 case DIR8_SOUTHWEST:
1302 /* These directions are cardinal in hexagonal topologies. */
1303 return current_topo_has_flag(TF_HEX) && !current_topo_has_flag(TF_ISO);
1304 }
1305 return FALSE;
1306}
1307
1308/*******************************************************************/
1314bool is_cardinal_dir(enum direction8 dir)
1315{
1316 fc_assert_ret_val(dir <= direction8_invalid(), FALSE);
1317
1318 return dir_cardinality[dir];
1319}
1320
1321/*******************************************************************/
1326bool base_get_direction_for_step(const struct civ_map *nmap,
1327 const struct tile *start_tile,
1328 const struct tile *end_tile,
1329 enum direction8 *dir)
1330{
1331 adjc_dir_iterate(nmap, start_tile, test_tile, test_dir) {
1332 if (same_pos(end_tile, test_tile)) {
1333 *dir = test_dir;
1334 return TRUE;
1335 }
1337
1338 return FALSE;
1339}
1340
1341/*******************************************************************/
1345int get_direction_for_step(const struct civ_map *nmap,
1346 const struct tile *start_tile,
1347 const struct tile *end_tile)
1348{
1349 enum direction8 dir;
1350
1351 if (base_get_direction_for_step(nmap, start_tile, end_tile, &dir)) {
1352 return dir;
1353 }
1354
1356 return -1;
1357}
1358
1359/*******************************************************************/
1363bool is_move_cardinal(const struct civ_map *nmap,
1364 const struct tile *start_tile,
1365 const struct tile *end_tile)
1366{
1367 cardinal_adjc_dir_iterate(nmap, start_tile, test_tile, test_dir) {
1368 if (same_pos(end_tile, test_tile)) {
1369 return TRUE;
1370 }
1372
1373 return FALSE;
1374}
1375
1376/*******************************************************************/
1384bool is_singular_tile(const struct tile *ptile, int dist)
1385{
1386 int tile_x, tile_y;
1387
1388 index_to_map_pos(&tile_x, &tile_y, tile_index(ptile));
1389 do_in_natural_pos(ntl_x, ntl_y, tile_x, tile_y) {
1390 /* Iso-natural coordinates are doubled in scale. */
1391 dist *= MAP_IS_ISOMETRIC ? 2 : 1;
1392
1393 return ((!current_topo_has_flag(TF_WRAPX)
1394 && (ntl_x < dist || ntl_x >= NATURAL_WIDTH - dist))
1395 || (!current_topo_has_flag(TF_WRAPY)
1396 && (ntl_y < dist || ntl_y >= NATURAL_HEIGHT - dist)));
1398}
1399
1400/*******************************************************************/
1403static struct startpos *startpos_new(struct tile *ptile)
1404{
1405 struct startpos *psp = fc_malloc(sizeof(*psp));
1406
1407 psp->location = ptile;
1408 psp->exclude = FALSE;
1409 psp->nations = nation_hash_new();
1410
1411 return psp;
1412}
1413
1414/*******************************************************************/
1417static void startpos_destroy(struct startpos *psp)
1418{
1419 fc_assert_ret(NULL != psp);
1420 nation_hash_destroy(psp->nations);
1421 free(psp);
1422}
1423
1424/*******************************************************************/
1428{
1429 return map_startpos_get(index_to_tile(&(wld.map), id));
1430}
1431
1432/*******************************************************************/
1436int startpos_number(const struct startpos *psp)
1437{
1438 fc_assert_ret_val(NULL != psp, -1);
1439 return tile_index(psp->location);
1440}
1441
1442/*******************************************************************/
1446bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
1447{
1448 fc_assert_ret_val(NULL != psp, FALSE);
1449 fc_assert_ret_val(NULL != pnation, FALSE);
1450
1451 if (0 == nation_hash_size(psp->nations) || !psp->exclude) {
1452 psp->exclude = FALSE; /* Disable "excluding" mode. */
1453 return nation_hash_insert(psp->nations, pnation, NULL);
1454 } else {
1455 return nation_hash_remove(psp->nations, pnation);
1456 }
1457}
1458
1459/*******************************************************************/
1463bool startpos_disallow(struct startpos *psp, struct nation_type *pnation)
1464{
1465 fc_assert_ret_val(NULL != psp, FALSE);
1466 fc_assert_ret_val(NULL != pnation, FALSE);
1467
1468 if (0 == nation_hash_size(psp->nations) || psp->exclude) {
1469 psp->exclude = TRUE; /* Enable "excluding" mode. */
1470 return nation_hash_remove(psp->nations, pnation);
1471 } else {
1472 return nation_hash_insert(psp->nations, pnation, NULL);
1473 }
1474}
1475
1476/*******************************************************************/
1479struct tile *startpos_tile(const struct startpos *psp)
1480{
1481 fc_assert_ret_val(NULL != psp, NULL);
1482 return psp->location;
1483}
1484
1485/*******************************************************************/
1488bool startpos_nation_allowed(const struct startpos *psp,
1489 const struct nation_type *pnation)
1490{
1491 fc_assert_ret_val(NULL != psp, FALSE);
1492 fc_assert_ret_val(NULL != pnation, FALSE);
1493 return XOR(psp->exclude, nation_hash_lookup(psp->nations, pnation, NULL));
1494}
1495
1496/*******************************************************************/
1499bool startpos_allows_all(const struct startpos *psp)
1500{
1501 fc_assert_ret_val(NULL != psp, FALSE);
1502 return (0 == nation_hash_size(psp->nations));
1503}
1504
1505/*******************************************************************/
1509bool startpos_pack(const struct startpos *psp,
1510 struct packet_edit_startpos_full *packet)
1511{
1512 fc_assert_ret_val(NULL != psp, FALSE);
1513 fc_assert_ret_val(NULL != packet, FALSE);
1514
1515 packet->id = startpos_number(psp);
1516 packet->exclude = psp->exclude;
1517 BV_CLR_ALL(packet->nations);
1518
1519 nation_hash_iterate(psp->nations, pnation) {
1520 BV_SET(packet->nations, nation_number(pnation));
1522 return TRUE;
1523}
1524
1525/*******************************************************************/
1529bool startpos_unpack(struct startpos *psp,
1530 const struct packet_edit_startpos_full *packet)
1531{
1532 fc_assert_ret_val(NULL != psp, FALSE);
1533 fc_assert_ret_val(NULL != packet, FALSE);
1534
1535 psp->exclude = packet->exclude;
1536
1537 nation_hash_clear(psp->nations);
1538 if (!BV_ISSET_ANY(packet->nations)) {
1539 return TRUE;
1540 }
1541 nations_iterate(pnation) {
1542 if (BV_ISSET(packet->nations, nation_number(pnation))) {
1543 nation_hash_insert(psp->nations, pnation, NULL);
1544 }
1546 return TRUE;
1547}
1548
1549/*******************************************************************/
1556bool startpos_is_excluding(const struct startpos *psp)
1557{
1558 fc_assert_ret_val(NULL != psp, FALSE);
1559 return psp->exclude;
1560}
1561
1562/*******************************************************************/
1568const struct nation_hash *startpos_raw_nations(const struct startpos *psp)
1569{
1570 fc_assert_ret_val(NULL != psp, NULL);
1571 return psp->nations;
1572}
1573
1574/*******************************************************************/
1581{
1582 return MAX(sizeof(struct startpos_iter) + nation_iter_sizeof()
1583 - sizeof(struct iterator), nation_hash_iter_sizeof());
1584}
1585
1586/*******************************************************************/
1593{
1595
1596 do {
1597 iterator_next(&iter->nation_iter);
1598 } while (iterator_valid(&iter->nation_iter)
1599 || !nation_hash_lookup(iter->psp->nations,
1600 iterator_get(&iter->nation_iter), NULL));
1601}
1602
1603/*******************************************************************/
1611{
1613 return iterator_get(&iter->nation_iter);
1614}
1615
1616/*******************************************************************/
1620{
1622 return iterator_valid(&iter->nation_iter);
1623}
1624
1625/*******************************************************************/
1629 const struct startpos *psp)
1630{
1631 if (!psp) {
1632 return invalid_iter_init(ITERATOR(iter));
1633 }
1634
1635 if (startpos_allows_all(psp)) {
1636 return nation_iter_init((struct nation_iter *) iter);
1637 }
1638
1639 if (!psp->exclude) {
1640 return nation_hash_key_iter_init((struct nation_hash_iter *) iter,
1641 psp->nations);
1642 }
1643
1647 iter->psp = psp;
1648 (void) nation_iter_init((struct nation_iter *) &iter->nation_iter);
1649
1650 return ITERATOR(iter);
1651}
1652
1653/*******************************************************************/
1657{
1658 if (NULL != wld.map.startpos_table) {
1659 return startpos_hash_size(wld.map.startpos_table);
1660 } else {
1661 return 0;
1662 }
1663}
1664
1665/*******************************************************************/
1669struct startpos *map_startpos_new(struct tile *ptile)
1670{
1671 struct startpos *psp;
1672
1673 fc_assert_ret_val(NULL != ptile, NULL);
1674 fc_assert_ret_val(NULL != wld.map.startpos_table, NULL);
1675
1676 psp = startpos_new(ptile);
1677 startpos_hash_replace(wld.map.startpos_table, tile_hash_key(ptile), psp);
1678
1679 return psp;
1680}
1681
1682/*******************************************************************/
1686struct startpos *map_startpos_get(const struct tile *ptile)
1687{
1688 struct startpos *psp;
1689
1690 fc_assert_ret_val(NULL != ptile, NULL);
1691 fc_assert_ret_val(NULL != wld.map.startpos_table, NULL);
1692
1693 startpos_hash_lookup(wld.map.startpos_table, tile_hash_key(ptile), &psp);
1694
1695 return psp;
1696}
1697
1698/*******************************************************************/
1702bool map_startpos_remove(struct tile *ptile)
1703{
1704 fc_assert_ret_val(NULL != ptile, FALSE);
1706
1707 return startpos_hash_remove(wld.map.startpos_table, tile_hash_key(ptile));
1708}
1709
1710/*******************************************************************/
1715{
1716 return startpos_hash_iter_sizeof();
1717}
1718
1719/*******************************************************************/
1723struct iterator *map_startpos_iter_init(struct map_startpos_iter *iter)
1724{
1725 return startpos_hash_value_iter_init((struct startpos_hash_iter *) iter,
1727}
1728
1729/*******************************************************************/
1732enum direction8 rand_direction(void)
1733{
1735}
1736
1737/*******************************************************************/
1740enum direction8 opposite_direction(enum direction8 dir)
1741{
1742 return direction8_max() - dir;
1743}
#define CALL_FUNC_EACH_AI(_func,...)
Definition ai.h:384
#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:522
int compare_iter_index(const void *a, const void *b)
Definition city.c:338
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:73
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:73
bool is_native_extra_to_uclass(const struct extra_type *pextra, const struct unit_class *pclass)
Definition extras.c:792
#define extra_type_iterate(_p)
Definition extras.h:291
#define extra_type_list_iterate(extralist, pextra)
Definition extras.h:159
#define extra_type_iterate_end
Definition extras.h:297
#define extra_type_by_rmcause_iterate_end
Definition extras.h:334
#define extra_index(_e_)
Definition extras.h:177
#define extra_type_by_rmcause_iterate(_rmcause, _extra)
Definition extras.h:329
#define extra_type_list_iterate_end
Definition extras.h:161
#define extra_road_get(_e_)
Definition extras.h:185
@ RPT_POSSIBLE
Definition fc_types.h:585
struct civ_game game
Definition game.c:57
struct world wld
Definition game.c:58
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:697
struct startpos * map_startpos_get(const struct tile *ptile)
Definition map.c:1686
bool is_normal_map_pos(int x, int y)
Definition map.c:961
const int DIR_DY[8]
Definition map.c:87
int startpos_number(const struct startpos *psp)
Definition map.c:1436
bool can_reclaim_ocean(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:682
void map_free(struct civ_map *fmap)
Definition map.c:528
bool startpos_disallow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1463
void main_map_free(void)
Definition map.c:552
#define nat_x
static int map_vector_to_distance(int dx, int dy)
Definition map.c:562
enum direction8 opposite_direction(enum direction8 dir)
Definition map.c:1740
#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:1363
int sq_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:639
bool can_freeze_terrain(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:726
struct startpos * map_startpos_new(struct tile *ptile)
Definition map.c:1669
bool can_thaw_terrain(const struct civ_map *nmap, const struct tile *ptile)
Definition map.c:711
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:778
static void tile_free(struct tile *ptile)
Definition map.c:472
bool startpos_nation_allowed(const struct startpos *psp, const struct nation_type *pnation)
Definition map.c:1488
#define STARTPOS_ITER(p)
Definition map.c:65
int map_num_tiles(void)
Definition map.c:1012
int get_direction_for_step(const struct civ_map *nmap, const struct tile *start_tile, const struct tile *end_tile)
Definition map.c:1345
struct tile * startpos_tile(const struct startpos *psp)
Definition map.c:1479
bool startpos_allows_all(const struct startpos *psp)
Definition map.c:1499
const struct nation_hash * startpos_raw_nations(const struct startpos *psp)
Definition map.c:1568
const int DIR_DX[8]
Definition map.c:86
struct tile * rand_map_pos(const struct civ_map *nmap)
Definition map.c:1086
static bool restrict_infra(const struct player *pplayer, const struct tile *t1, const struct tile *t2)
Definition map.c:909
static struct tile * base_native_pos_to_tile(const struct civ_map *nmap, int nat_x, int nat_y)
Definition map.c:393
static void generate_map_indices(void)
Definition map.c:201
const char * dir_get_name(enum direction8 dir)
Definition map.c:1144
enum direction8 dir_ccw(enum direction8 dir)
Definition map.c:1201
struct iterator * map_startpos_iter_init(struct map_startpos_iter *iter)
Definition map.c:1723
bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
Definition map.c:929
void map_allocate(struct civ_map *amap)
Definition map.c:491
void map_init_topology(struct civ_map *nmap)
Definition map.c:301
void main_map_allocate(void)
Definition map.c:517
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:665
static struct startpos * startpos_new(struct tile *ptile)
Definition map.c:1403
bool startpos_pack(const struct startpos *psp, struct packet_edit_startpos_full *packet)
Definition map.c:1509
static bool is_valid_dir_calculate(enum direction8 dir)
Definition map.c:1231
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:454
static bool is_cardinal_dir_calculate(enum direction8 dir)
Definition map.c:1288
struct tile * map_pos_to_tile(const struct civ_map *nmap, int map_x, int map_y)
Definition map.c:417
int map_vector_to_sq_distance(int dx, int dy)
Definition map.c:612
bool map_startpos_remove(struct tile *ptile)
Definition map.c:1702
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:1099
int map_startpos_count(void)
Definition map.c:1656
size_t startpos_iter_sizeof(void)
Definition map.c:1580
bool is_cardinal_dir(enum direction8 dir)
Definition map.c:1314
static void tile_init(struct tile *ptile)
Definition map.c:349
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Definition map.c:938
bool map_untrusted_dir_is_valid(enum direction8 dir)
Definition map.c:1271
bool terrain_surroundings_allow_change(const struct civ_map *nmap, const struct tile *ptile, const struct terrain *pterrain)
Definition map.c:740
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:628
bool startpos_unpack(struct startpos *psp, const struct packet_edit_startpos_full *packet)
Definition map.c:1529
bool is_valid_dir(enum direction8 dir)
Definition map.c:1258
void base_map_distance_vector(int *dx, int *dy, int x0dv, int y0dv, int x1dv, int y1dv)
Definition map.c:1022
enum direction8 dir_cw(enum direction8 dir)
Definition map.c:1172
enum direction8 rand_direction(void)
Definition map.c:1732
struct tile * mapstep(const struct civ_map *nmap, const struct tile *ptile, enum direction8 dir)
Definition map.c:369
static void startpos_destroy(struct startpos *psp)
Definition map.c:1417
struct terrain_misc terrain_control
Definition map.c:69
static void * startpos_exclude_iter_get(const struct iterator *startpos_iter)
Definition map.c:1610
struct tile * nearest_real_tile(const struct civ_map *nmap, int x, int y)
Definition map.c:993
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:1326
static void startpos_exclude_iter_next(struct iterator *startpos_iter)
Definition map.c:1592
struct tile * native_pos_to_tile(const struct civ_map *nmap, int nat_x, int nat_y)
Definition map.c:441
void map_distance_vector(int *dx, int *dy, const struct tile *tile0, const struct tile *tile1)
Definition map.c:1071
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:1556
int map_distance(const struct tile *tile0, const struct tile *tile1)
Definition map.c:652
struct startpos * map_startpos_by_number(int id)
Definition map.c:1427
bool map_is_empty(void)
Definition map.c:149
size_t map_startpos_iter_sizeof(void)
Definition map.c:1714
bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1446
bool normalize_map_pos(const struct civ_map *nmap, int *x, int *y)
Definition map.c:977
static bool startpos_exclude_iter_valid(const struct iterator *startpos_iter)
Definition map.c:1619
struct iterator * startpos_iter_init(struct startpos_iter *iter, const struct startpos *psp)
Definition map.c:1628
bool is_real_map_pos(const struct civ_map *nmap, int x, int y)
Definition map.c:950
bool is_singular_tile(const struct tile *ptile, int dist)
Definition map.c:1384
int map_vector_to_real_distance(int dx, int dy)
Definition map.c:576
#define MAP_MAX_SIZE
Definition map.h:590
#define current_topo_has_flag(flag)
Definition map.h:45
#define MAP_DEFAULT_SIZE
Definition map.h:588
#define MAP_MAX_LINEAR_SIZE
Definition map.h:606
#define adjc_dir_iterate(nmap, center_tile, itr_tile, dir_itr)
Definition map.h:432
#define MAP_DEFAULT_HUTS
Definition map.h:570
#define adjc_iterate_end
Definition map.h:427
#define do_in_natural_pos(ntl_x, ntl_y, map_x, map_y)
Definition map.h:204
#define MAP_INDEX_SIZE
Definition map.h:131
#define MAP_DEFAULT_LINEAR_SIZE
Definition map.h:605
#define MAP_DEFAULT_STARTPOS
Definition map.h:644
#define NATURAL_HEIGHT
Definition map.h:221
#define MAP_DEFAULT_ANIMALS
Definition map.h:574
#define MAP_DEFAULT_TEAM_PLACEMENT
Definition map.h:670
#define MAP_DEFAULT_TOPO
Definition map.h:619
#define MAP_DEFAULT_SEED
Definition map.h:622
#define MAP_IS_ISOMETRIC
Definition map.h:40
#define CHECK_INDEX(mindex)
Definition map.h:143
#define cardinal_between_iterate(nmap, tile1, tile2, between)
Definition map.h:471
#define MAP_DEFAULT_MAPSIZE
Definition map.h:578
#define MAP_MIN_LINEAR_SIZE
Definition map.h:607
#define MAP_DEFAULT_LANDMASS
Definition map.h:626
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:422
#define MAP_TO_NATIVE_POS(pnat_x, pnat_y, map_x, map_y)
Definition map.h:166
#define ALL_DIRECTIONS_CARDINAL()
Definition map.h:47
#define NATIVE_TO_MAP_POS(pmap_x, pmap_y, nat_x, nat_y)
Definition map.h:160
#define cardinal_adjc_dir_iterate_end
Definition map.h:460
#define MAP_MIN_SIZE
Definition map.h:589
#define MAP_DEFAULT_SINGLE_POLE
Definition map.h:658
#define MAP_DEFAULT_SEPARATE_POLES
Definition map.h:650
#define MAP_DEFAULT_RICHES
Definition map.h:630
#define MAP_DEFAULT_TINYISLES
Definition map.h:646
#define whole_map_iterate(_map, _tile)
Definition map.h:539
#define MAP_DEFAULT_TILESPERPLAYER
Definition map.h:600
#define adjc_dir_iterate_end
Definition map.h:436
#define MAP_DEFAULT_TEMPERATURE
Definition map.h:666
#define MAP_DEFAULT_ALLTEMPERATE
Definition map.h:662
#define cardinal_between_iterate_end
Definition map.h:476
#define MAP_DEFAULT_GENERATOR
Definition map.h:642
#define NATURAL_WIDTH
Definition map.h:220
#define do_in_natural_pos_end
Definition map.h:211
#define MAP_DEFAULT_WETNESS
Definition map.h:638
#define native_pos_to_index_nocheck(nat_x, nat_y)
Definition map.h:146
#define cardinal_adjc_dir_iterate(nmap, center_tile, itr_tile, dir_itr)
Definition map.h:456
#define whole_map_iterate_end
Definition map.h:548
#define index_to_map_pos(pmap_x, pmap_y, mindex)
Definition map.h:227
#define MAP_DEFAULT_STEEPNESS
Definition map.h:634
#define DIRSTEP(dest_x, dest_y, dir)
Definition map.h:234
#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:24
static bool is_native_tile_to_class(const struct unit_class *punitclass, const struct tile *ptile)
Definition movement.h:80
#define MOVE_COST_IGTER
Definition movement.h:25
Nation_type_id nation_number(const struct nation_type *pnation)
Definition nation.c:485
struct iterator * nation_iter_init(struct nation_iter *it)
Definition nation.c:556
size_t nation_iter_sizeof(void)
Definition nation.c:523
#define nation_hash_iterate(nationhash, pnation)
Definition nation.h:92
#define nations_iterate_end
Definition nation.h:335
#define nations_iterate(NAME_pnation)
Definition nation.h:332
#define nation_hash_iterate_end
Definition nation.h:94
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Definition player.c:1364
#define fc_rand(_size)
Definition rand.h:34
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 packet_game_info info
Definition game.h:89
struct startpos_hash * startpos_table
Definition map_types.h:81
struct tile * tiles
Definition map_types.h:80
int animals
Definition map_types.h:93
int xsize
Definition map_types.h:77
randseed seed
Definition map_types.h:89
bool tinyisles
Definition map_types.h:97
int ysize
Definition map_types.h:77
int num_continents
Definition map_types.h:78
enum direction8 valid_dirs[8]
Definition map_types.h:73
int riches
Definition map_types.h:90
bool alltemperate
Definition map_types.h:101
int num_iterate_outwards_indices
Definition map_types.h:76
int num_cardinal_dirs
Definition map_types.h:74
enum mapsize_type mapsize
Definition map_types.h:85
int num_valid_dirs
Definition map_types.h:74
enum map_startpos startpos
Definition map_types.h:96
int num_oceans
Definition map_types.h:79
bool have_resources
Definition map_types.h:107
int steepness
Definition map_types.h:104
int wetness
Definition map_types.h:103
int size
Definition map_types.h:86
int tilesperplayer
Definition map_types.h:87
randseed seed_setting
Definition map_types.h:88
struct iter_index * iterate_outwards_indices
Definition map_types.h:75
int landpercent
Definition map_types.h:94
struct civ_map::@41::@43 server
enum team_placement team_placement
Definition map_types.h:108
int topology_id
Definition map_types.h:72
enum direction8 cardinal_dirs[8]
Definition map_types.h:73
int huts
Definition map_types.h:91
bool have_huts
Definition map_types.h:106
bool single_pole
Definition map_types.h:100
enum map_generator generator
Definition map_types.h:95
bool separatepoles
Definition map_types.h:98
int temperature
Definition map_types.h:102
int huts_absolute
Definition map_types.h:92
int dist
Definition city.h:102
int dx
Definition city.h:102
int dy
Definition city.h:102
bool(* valid)(const struct iterator *it)
Definition iterator.h:34
void *(* get)(const struct iterator *it)
Definition iterator.h:33
void(* next)(struct iterator *it)
Definition iterator.h:32
bv_startpos_nations nations
enum road_move_mode move_mode
Definition road.h:79
struct extra_type_list * integrators
Definition road.h:93
int move_cost
Definition road.h:78
const struct startpos * psp
Definition map.c:60
struct iterator vtable
Definition map.c:59
struct iterator nation_iter
Definition map.c:62
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:49
char * spec_sprite
Definition tile.h:65
char * label
Definition tile.h:64
int index
Definition tile.h:50
bv_extras extras
Definition tile.h:54
struct extra_type * resource
Definition tile.h:55
struct unit_list * units
Definition tile.h:57
struct player * extras_owner
Definition tile.h:62
struct terrain * terrain
Definition tile.h:56
struct extra_type * placing
Definition tile.h:60
struct city * worked
Definition tile.h:58
struct player * owner
Definition tile.h:59
Continent_id continent
Definition tile.h:53
struct tile * claimer
Definition tile.h:63
struct unit_class::@85 cache
struct extra_type_list * bonus_roads
Definition unittype.h:158
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:621
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:466
#define T_UNKNOWN
Definition terrain.h:57
#define is_ocean(pterrain)
Definition terrain.h:287
#define terrain_has_flag(terr, flag)
Definition terrain.h:269
void tile_virtual_destroy(struct tile *vtile)
Definition tile.c:1018
void tile_remove_extra(struct tile *ptile, const struct extra_type *pextra)
Definition tile.c:950
struct tile * tile_virtual_new(const struct tile *ptile)
Definition tile.c:966
void * tile_hash_key(const struct tile *ptile)
Definition tile.c:1068
struct city * tile_city(const struct tile *ptile)
Definition tile.c:83
#define tile_index(_pt_)
Definition tile.h:87
#define ACTIVITY_FACTOR
Definition tile.h:164
#define tile_terrain(_tile)
Definition tile.h:109
#define tile_has_extra(ptile, pextra)
Definition tile.h:146
#define tile_owner(_tile)
Definition tile.h:95
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition unittype.h:753
#define utype_class(_t_)
Definition unittype.h:736
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition unittype.h:604