Freeciv-3.2: /fast/freeciv/nightly/S3_2/common/map.c Source File

Freeciv-3.2

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