Freeciv21
Develop your civilization from humble roots to a global empire
map.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2020 Freeciv21 and Freeciv
3 \_ \ / __/ contributors. This file is part of Freeciv21.
4  _\ \ / /__ Freeciv21 is free software: you can redistribute it
5  \___ \____/ __/ and/or modify it under the terms of the GNU General
6  \_ _/ Public License as published by the Free Software
7  | @ @ \_ Foundation, either version 3 of the License,
8  | or (at your option) any later version.
9  _/ /\ You should have received a copy of the GNU
10  /o) (o/\ \_ General Public License along with Freeciv21.
11  \_____/ / If not, see https://www.gnu.org/licenses/.
12  \____/ ********************************************************/
13 
14 #include <QSet>
15 #include <cstring> // qstrlen
16 #include <stdexcept>
17 
18 // utility
19 #include "log.h"
20 #include "rand.h"
21 #include "shared.h"
22 #include "support.h"
23 
24 // common
25 #include "ai.h"
26 #include "city.h"
27 #include "game.h"
28 #include "movement.h"
29 #include "nation.h"
30 #include "packets.h"
31 #include "road.h"
32 #include "unit.h"
33 
34 #include "map.h"
35 
36 static struct startpos *startpos_new(struct tile *ptile);
37 static void startpos_destroy(struct startpos *psp);
38 
39 // these are initialized from the terrain ruleset
41 
42 /* used to compute neighboring tiles.
43  *
44  * using
45  * x1 = x + DIR_DX[dir];
46  * y1 = y + DIR_DY[dir];
47  * will give you the tile as shown below.
48  * -------
49  * |0|1|2|
50  * |-+-+-|
51  * |3| |4|
52  * |-+-+-|
53  * |5|6|7|
54  * -------
55  * Note that you must normalize x1 and y1 yourself.
56  */
57 const int DIR_DX[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
58 const int DIR_DY[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
59 
60 static bool dir_cardinality[9]; // Including invalid one
61 static bool dir_validity[9]; // Including invalid one
62 
63 static bool is_valid_dir_calculate(enum direction8 dir);
64 static bool is_cardinal_dir_calculate(enum direction8 dir);
65 
66 static bool restrict_infra(const struct player *pplayer,
67  const struct tile *t1, const struct tile *t2);
68 
72 bv_extras get_tile_infrastructure_set(const struct tile *ptile, int *pcount)
73 {
74  bv_extras pspresent;
75  int count = 0;
76 
77  BV_CLR_ALL(pspresent);
78 
79  extra_type_iterate(pextra)
80  {
81  if (is_extra_removed_by(pextra, ERM_PILLAGE)
82  && tile_has_extra(ptile, pextra)) {
83  struct tile *missingset = tile_virtual_new(ptile);
84  bool dependency = false;
85 
86  tile_remove_extra(missingset, pextra);
87  extra_type_iterate(pdependant)
88  {
89  if (tile_has_extra(ptile, pdependant)) {
90  if (!are_reqs_active(nullptr, nullptr, nullptr, nullptr,
91  missingset, nullptr, nullptr, nullptr,
92  nullptr, nullptr, &pdependant->reqs,
93  RPT_POSSIBLE)) {
94  dependency = true;
95  break;
96  }
97  }
98  }
100 
101  tile_virtual_destroy(missingset);
102 
103  if (!dependency) {
104  BV_SET(pspresent, extra_index(pextra));
105  count++;
106  }
107  }
108  }
110 
111  if (pcount) {
112  *pcount = count;
113  }
114 
115  return pspresent;
116 }
117 
124 bool map_is_empty() { return wld.map.tiles == nullptr; }
125 
129 void map_init(struct civ_map *imap, bool server_side)
130 {
132  imap->num_continents = 0;
133  imap->num_oceans = 0;
134  imap->tiles = nullptr;
135  imap->startpos_table = nullptr;
136  imap->iterate_outwards_indices = nullptr;
137 
138  /* The [xy]size values are set in map_init_topology. It is initialized
139  * to a non-zero value because some places erronously use these values
140  * before they're initialized. */
143 
144  if (server_side) {
145  imap->server.mapsize = MAP_DEFAULT_MAPSIZE;
146  imap->server.size = MAP_DEFAULT_SIZE;
147  imap->server.tilesperplayer = MAP_DEFAULT_TILESPERPLAYER;
148  imap->server.seed_setting = MAP_DEFAULT_SEED;
149  imap->server.seed = MAP_DEFAULT_SEED;
150  imap->server.riches = MAP_DEFAULT_RICHES;
151  imap->server.huts = MAP_DEFAULT_HUTS;
152  imap->server.huts_absolute = -1;
153  imap->server.animals = MAP_DEFAULT_ANIMALS;
154  imap->server.landpercent = MAP_DEFAULT_LANDMASS;
155  imap->server.wetness = MAP_DEFAULT_WETNESS;
156  imap->server.steepness = MAP_DEFAULT_STEEPNESS;
157  imap->server.generator = MAP_DEFAULT_GENERATOR;
158  imap->server.startpos = MAP_DEFAULT_STARTPOS;
159  imap->server.tinyisles = MAP_DEFAULT_TINYISLES;
160  imap->server.separatepoles = MAP_DEFAULT_SEPARATE_POLES;
161  imap->server.single_pole = MAP_DEFAULT_SINGLE_POLE;
162  imap->server.alltemperate = MAP_DEFAULT_ALLTEMPERATE;
163  imap->server.temperature = MAP_DEFAULT_TEMPERATURE;
164  imap->server.have_huts = false;
165  imap->server.have_resources = false;
166  imap->server.team_placement = MAP_DEFAULT_TEAM_PLACEMENT;
167  }
168 }
169 
173 static void generate_map_indices()
174 {
175  int i = 0, nat_x, nat_y, tiles;
176  int nat_center_x, nat_center_y, nat_min_x, nat_min_y, nat_max_x, nat_max_y;
177  int map_center_x, map_center_y;
178 
179  /* These caluclations are done via tricky native math. We need to make
180  * sure that when "exploring" positions in the iterate_outward we hit each
181  * position within the distance exactly once.
182  *
183  * To do this we pick a center position (at the center of the map, for
184  * convenience). Then we iterate over all of the positions around it,
185  * accounting for wrapping, in native coordinates. Note that some of the
186  * positions iterated over before will not even be real; the point is to
187  * use the native math so as to get the right behavior under different
188  * wrapping conditions.
189  *
190  * Thus the "center" position below is just an arbitrary point. We choose
191  * the center of the map to make the min/max values (below) simpler. */
192  nat_center_x = wld.map.xsize / 2;
193  nat_center_y = wld.map.ysize / 2;
194  NATIVE_TO_MAP_POS(&map_center_x, &map_center_y, nat_center_x,
195  nat_center_y);
196 
197  /* If we wrap in a particular direction (X or Y) we only need to explore a
198  * half of a map-width in that direction before we hit the wrap point. If
199  * not we need to explore the full width since we have to account for the
200  * worst-case where we start at one edge of the map. Of course if we try
201  * to explore too far the extra steps will just be skipped by the
202  * normalize check later on. So the purpose at this point is just to
203  * get the right set of positions, relative to the start position, that
204  * may be needed for the iteration.
205  *
206  * If the map does wrap, we go map.Nsize / 2 in each direction. This
207  * gives a min value of 0 and a max value of Nsize-1, because of the
208  * center position chosen above. This also avoids any off-by-one errors.
209  *
210  * If the map doesn't wrap, we go map.Nsize-1 in each direction. In this
211  * case we're not concerned with going too far and wrapping around, so we
212  * just have to make sure we go far enough if we're at one edge of the
213  * map. */
214  nat_min_x =
215  (current_topo_has_flag(TF_WRAPX) ? 0
216  : (nat_center_x - wld.map.xsize + 1));
217  nat_min_y =
218  (current_topo_has_flag(TF_WRAPY) ? 0
219  : (nat_center_y - wld.map.ysize + 1));
220 
221  nat_max_x =
222  (current_topo_has_flag(TF_WRAPX) ? (wld.map.xsize - 1)
223  : (nat_center_x + wld.map.xsize - 1));
224  nat_max_y =
225  (current_topo_has_flag(TF_WRAPY) ? (wld.map.ysize - 1)
226  : (nat_center_y + wld.map.ysize - 1));
227  tiles = (nat_max_x - nat_min_x + 1) * (nat_max_y - nat_min_y + 1);
228 
231 
232  for (nat_x = nat_min_x; nat_x <= nat_max_x; nat_x++) {
233  for (nat_y = nat_min_y; nat_y <= nat_max_y; nat_y++) {
234  int map_x, map_y, dx, dy;
235 
236  /* Now for each position, we find the vector (in map coordinates) from
237  * the center position to that position. Then we calculate the
238  * distance between the two points. Wrapping is ignored at this
239  * point since the use of native positions means we should always have
240  * the shortest vector. */
241  NATIVE_TO_MAP_POS(&map_x, &map_y, nat_x, nat_y);
242  dx = map_x - map_center_x;
243  dy = map_y - map_center_y;
244 
249  i++;
250  }
251  }
252  fc_assert(i == tiles);
253 
254  qsort(wld.map.iterate_outwards_indices, tiles,
256 
257 #if 0
258  for (i = 0; i < tiles; i++) {
259  log_debug("%5d : (%3d,%3d) : %d", i,
263  }
264 #endif
265 
267 }
268 
277 {
278  /* sanity check for iso topologies*/
279  fc_assert(!MAP_IS_ISOMETRIC || (wld.map.ysize % 2) == 0);
280 
281  /* The size and ratio must satisfy the minimum and maximum *linear*
282  * restrictions on width */
287  fc_assert(map_num_tiles() >= MAP_MIN_SIZE * 1000);
288  fc_assert(map_num_tiles() <= MAP_MAX_SIZE * 1000);
289 
291 
292  // Values for direction8_invalid()
293  fc_assert(direction8_invalid() == 8);
294  dir_validity[8] = false;
295  dir_cardinality[8] = false;
296 
297  // Values for actual directions
298  for (int dir = 0; dir < 8; dir++) {
299  if (is_valid_dir_calculate(direction8(dir))) {
300  wld.map.valid_dirs[wld.map.num_valid_dirs] = direction8(dir);
302  dir_validity[dir] = true;
303  } else {
304  dir_validity[dir] = false;
305  }
306  if (is_cardinal_dir_calculate(direction8(dir))) {
307  wld.map.cardinal_dirs[wld.map.num_cardinal_dirs] = direction8(dir);
309  dir_cardinality[dir] = true;
310  } else {
311  dir_cardinality[dir] = false;
312  }
313  }
317 }
318 
322 static void tile_init(struct tile *ptile)
323 {
324  ptile->continent = 0;
325 
326  BV_CLR_ALL(ptile->extras);
327  ptile->resource = nullptr;
328  ptile->terrain = T_UNKNOWN;
329  ptile->units = unit_list_new();
330  ptile->owner = nullptr; // Not claimed by any player.
331  ptile->extras_owner = nullptr;
332  ptile->placing = nullptr;
333  ptile->claimer = nullptr;
334  ptile->worked = nullptr; // No city working here.
335  ptile->spec_sprite = nullptr;
336 }
337 
342 struct tile *mapstep(const struct civ_map *nmap, const struct tile *ptile,
343  enum direction8 dir)
344 {
345  Q_UNUSED(nmap)
346  int dx, dy, tile_x, tile_y;
347 
348  if (tile_virtual_check(ptile) || !is_valid_dir(dir)) {
349  return nullptr;
350  }
351 
352  index_to_map_pos(&tile_x, &tile_y, tile_index(ptile));
353  DIRSTEP(dx, dy, dir);
354 
355  tile_x += dx;
356  tile_y += dy;
357 
358  return map_pos_to_tile(&(wld.map), tile_x, tile_y);
359 }
360 
367 static inline struct tile *
368 base_native_pos_to_tile(const struct civ_map *nmap, int nat_x, int nat_y)
369 {
370  // Wrap in X and Y directions, as needed.
371  /* If the position is out of range in a non-wrapping direction, it is
372  * unreal. */
373  if (current_topo_has_flag(TF_WRAPX)) {
375  } else if (nat_x < 0 || nat_x >= wld.map.xsize) {
376  return nullptr;
377  }
378  if (current_topo_has_flag(TF_WRAPY)) {
380  } else if (nat_y < 0 || nat_y >= wld.map.ysize) {
381  return nullptr;
382  }
383 
384  // We already checked legality of native pos above, don't repeat
385  return nmap->tiles + native_pos_to_index_nocheck(nat_x, nat_y);
386 }
387 
391 struct tile *map_pos_to_tile(const struct civ_map *nmap, int map_x,
392  int map_y)
393 {
394  /* Instead of introducing new variables for native coordinates,
395  * update the map coordinate variables = registers already in use.
396  * This is one of the most performance-critical functions we have,
397  * so taking measures like this makes sense. */
398 #define nat_x map_x
399 #define nat_y map_y
400 
401  if (nmap->tiles == nullptr) {
402  return nullptr;
403  }
404 
405  // Normalization is best done in native coordinates.
406  MAP_TO_NATIVE_POS(&nat_x, &nat_y, map_x, map_y);
407  return base_native_pos_to_tile(nmap, nat_x, nat_y);
408 
409 #undef nat_x
410 #undef nat_y
411 }
412 
416 struct tile *native_pos_to_tile(const struct civ_map *nmap, int nat_x,
417  int nat_y)
418 {
419  if (nmap->tiles == nullptr) {
420  return nullptr;
421  }
422 
423  return base_native_pos_to_tile(nmap, nat_x, nat_y);
424 }
425 
429 struct tile *index_to_tile(const struct civ_map *imap, int mindex)
430 {
431  if (!imap->tiles) {
432  return nullptr;
433  }
434 
435  if (mindex >= 0 && mindex < MAP_INDEX_SIZE) {
436  return imap->tiles + mindex;
437  } else {
438  /* Unwrapped index coordinates are impossible, so the best we can do is
439  * return nullptr. */
440  return nullptr;
441  }
442 }
443 
447 static void tile_free(struct tile *ptile)
448 {
449  unit_list_destroy(ptile->units);
450 
451  delete[] ptile->spec_sprite;
452  ptile->spec_sprite = nullptr;
453 
454  delete[] ptile->label;
455  ptile->label = nullptr;
456 }
457 
462 void map_allocate(struct civ_map *amap)
463 {
464  log_debug("map_allocate (was %p) (%d,%d)", (void *) amap->tiles,
465  amap->xsize, amap->ysize);
466 
467  fc_assert_ret(nullptr == amap->tiles);
468  amap->tiles = new tile[MAP_INDEX_SIZE]();
469 
470  /* Note this use of whole_map_iterate may be a bit sketchy, since the
471  * tile values (ptile->index, etc.) haven't been set yet. It might be
472  * better to do a manual loop here. */
473  whole_map_iterate(amap, ptile)
474  {
475  ptile->index = ptile - amap->tiles;
476  CHECK_INDEX(tile_index(ptile));
477  tile_init(ptile);
478  }
480  delete amap->startpos_table;
481  amap->startpos_table = new QHash<struct tile *, struct startpos *>;
482 }
483 
488 {
489  map_allocate(&(wld.map));
492  CALL_FUNC_EACH_AI(map_alloc);
493 }
494 
498 void map_free(struct civ_map *fmap)
499 {
500  if (fmap->tiles) {
501  // it is possible that map_init was called but not map_allocate
502 
503  whole_map_iterate(fmap, ptile) { tile_free(ptile); }
505 
506  delete[] fmap->tiles;
507  fmap->tiles = nullptr;
508 
509  if (fmap->startpos_table) {
510  for (auto *a : qAsConst(*fmap->startpos_table)) {
511  startpos_destroy(a);
512  }
513  delete fmap->startpos_table;
514  fmap->startpos_table = nullptr;
515  }
516 
517  delete[] fmap->iterate_outwards_indices;
518  fmap->iterate_outwards_indices = nullptr;
519  }
520 }
521 
526 {
527  map_free(&(wld.map));
529 }
530 
535 static int map_vector_to_distance(int dx, int dy)
536 {
537  if (current_topo_has_flag(TF_HEX)) {
538  /* Hex: all directions are cardinal so the distance is equivalent to
539  * the real distance. */
540  return map_vector_to_real_distance(dx, dy);
541  } else {
542  return abs(dx) + abs(dy);
543  }
544 }
545 
549 int map_vector_to_real_distance(int dx, int dy)
550 {
551  const int absdx = abs(dx), absdy = abs(dy);
552 
553  if (current_topo_has_flag(TF_HEX)) {
554  if (current_topo_has_flag(TF_ISO)) {
555  // Iso-hex: you can't move NE or SW.
556  if ((dx < 0 && dy > 0) || (dx > 0 && dy < 0)) {
557  /* Diagonal moves in this direction aren't allowed, so it will take
558  * the full number of moves. */
559  return absdx + absdy;
560  } else {
561  // Diagonal moves in this direction *are* allowed.
562  return MAX(absdx, absdy);
563  }
564  } else {
565  // Hex: you can't move SE or NW.
566  if ((dx > 0 && dy > 0) || (dx < 0 && dy < 0)) {
567  /* Diagonal moves in this direction aren't allowed, so it will take
568  * the full number of moves. */
569  return absdx + absdy;
570  } else {
571  // Diagonal moves in this direction *are* allowed.
572  return MAX(absdx, absdy);
573  }
574  }
575  } else {
576  return MAX(absdx, absdy);
577  }
578 }
579 
583 int map_vector_to_sq_distance(int dx, int dy)
584 {
585  if (current_topo_has_flag(TF_HEX)) {
586  /* Hex: The square distance is just the square of the real distance; we
587  * don't worry about pythagorean calculations. */
588  int dist = map_vector_to_real_distance(dx, dy);
589 
590  return dist * dist;
591  } else {
592  return dx * dx + dy * dy;
593  }
594 }
595 
599 int real_map_distance(const struct tile *tile0, const struct tile *tile1)
600 {
601  int dx, dy;
602 
603  map_distance_vector(&dx, &dy, tile0, tile1);
604  return map_vector_to_real_distance(dx, dy);
605 }
606 
610 int sq_map_distance(const struct tile *tile0, const struct tile *tile1)
611 {
612  /* We assume map_distance_vector gives us the vector with the
613  minimum squared distance. Right now this is true. */
614  int dx, dy;
615 
616  map_distance_vector(&dx, &dy, tile0, tile1);
617  return map_vector_to_sq_distance(dx, dy);
618 }
619 
623 int map_distance(const struct tile *tile0, const struct tile *tile1)
624 {
625  /* We assume map_distance_vector gives us the vector with the
626  minimum map distance. Right now this is true. */
627  int dx, dy;
628 
629  map_distance_vector(&dx, &dy, tile0, tile1);
630  return map_vector_to_distance(dx, dy);
631 }
632 
636 bool is_safe_ocean(const struct civ_map *nmap, const struct tile *ptile)
637 {
638  adjc_iterate(nmap, ptile, adjc_tile)
639  {
640  if (tile_terrain(adjc_tile) != T_UNKNOWN
641  && !terrain_has_flag(tile_terrain(adjc_tile), TER_UNSAFE_COAST)) {
642  return true;
643  }
644  }
646 
647  return false;
648 }
649 
655 bool can_reclaim_ocean(const struct tile *ptile)
656 {
657  int land_tiles =
658  100 - count_terrain_class_near_tile(ptile, false, true, TC_OCEAN);
659 
660  return land_tiles >= terrain_control.ocean_reclaim_requirement_pct;
661 }
662 
668 bool can_channel_land(const struct tile *ptile)
669 {
670  int ocean_tiles =
671  count_terrain_class_near_tile(ptile, false, true, TC_OCEAN);
672 
673  return ocean_tiles >= terrain_control.land_channel_requirement_pct;
674 }
675 
681 bool can_thaw_terrain(const struct tile *ptile)
682 {
683  int unfrozen_tiles =
684  100 - count_terrain_flag_near_tile(ptile, false, true, TER_FROZEN);
685 
686  return unfrozen_tiles >= terrain_control.terrain_thaw_requirement_pct;
687 }
688 
694 bool can_freeze_terrain(const struct tile *ptile)
695 {
696  int frozen_tiles =
697  count_terrain_flag_near_tile(ptile, false, true, TER_FROZEN);
698 
699  return frozen_tiles >= terrain_control.terrain_freeze_requirement_pct;
700 }
701 
706 bool terrain_surroundings_allow_change(const struct tile *ptile,
707  const struct terrain *pterrain)
708 {
709  bool ret = true;
710 
711  if (is_ocean(tile_terrain(ptile)) && !is_ocean(pterrain)
712  && !can_reclaim_ocean(ptile)) {
713  ret = false;
714  } else if (!is_ocean(tile_terrain(ptile)) && is_ocean(pterrain)
715  && !can_channel_land(ptile)) {
716  ret = false;
717  }
718 
719  if (ret) {
720  if (terrain_has_flag(tile_terrain(ptile), TER_FROZEN)
721  && !terrain_has_flag(pterrain, TER_FROZEN)
722  && !can_thaw_terrain(ptile)) {
723  ret = false;
724  } else if (!terrain_has_flag(tile_terrain(ptile), TER_FROZEN)
725  && terrain_has_flag(pterrain, TER_FROZEN)
726  && !can_freeze_terrain(ptile)) {
727  ret = false;
728  }
729  }
730 
731  return ret;
732 }
733 
743 int tile_move_cost_ptrs(const struct civ_map *nmap, const struct unit *punit,
744  const struct unit_type *punittype,
745  const struct player *pplayer, const struct tile *t1,
746  const struct tile *t2)
747 {
748  Q_UNUSED(punit)
749  const struct unit_class *pclass = utype_class(punittype);
750  int cost;
751  bool cardinality_checked = false;
752  bool cardinal_move BAD_HEURISTIC_INIT(false);
753  bool ri;
754 
755  // Try to exit early for detectable conditions
756  if (!uclass_has_flag(pclass, UCF_TERRAIN_SPEED)) {
757  // units without UCF_TERRAIN_SPEED have a constant cost.
758  return SINGLE_MOVE;
759 
760  } else if (!is_native_tile_to_class(pclass, t2)
761  || !is_native_tile_to_class(pclass, t1)) {
762  // UTYF_IGTER units get move benefit.
763  return (utype_has_flag(punittype, UTYF_IGTER) ? MOVE_COST_IGTER
764  : SINGLE_MOVE);
765  }
766 
767  cost = tile_terrain(t2)->movement_cost * SINGLE_MOVE;
768  ri = restrict_infra(pplayer, t1, t2);
769 
770  extra_type_list_iterate(pclass->cache.bonus_roads, pextra)
771  {
772  struct road_type *proad = extra_road_get(pextra);
773 
774  /* We check the destination tile first, as that's
775  * the end of move that determines the cost.
776  * If can avoid inner loop about integrating roads
777  * completely if the destination road has too high cost. */
778 
779  if (cost > proad->move_cost
780  && (!ri || road_has_flag(proad, RF_UNRESTRICTED_INFRA))
781  && tile_has_extra(t2, pextra)) {
782  extra_type_list_iterate(proad->integrators, iextra)
783  {
784  /* We have no unrestricted infra related check here,
785  * destination road is the one that counts. */
786  if (tile_has_extra(t1, iextra)
787  && is_native_extra_to_uclass(iextra, pclass)) {
788  if (proad->move_mode == RMM_FAST_ALWAYS) {
789  cost = proad->move_cost;
790  } else {
791  if (!cardinality_checked) {
792  cardinal_move = (ALL_DIRECTIONS_CARDINAL()
793  || is_move_cardinal(nmap, t1, t2));
794  cardinality_checked = true;
795  }
796  if (cardinal_move) {
797  cost = proad->move_cost;
798  } else {
799  switch (proad->move_mode) {
800  case RMM_CARDINAL:
801  break;
802  case RMM_RELAXED:
803  if (cost > proad->move_cost * 2) {
804  cardinal_between_iterate(nmap, t1, t2, between)
805  {
806  if (tile_has_extra(between, pextra)
807  || (pextra != iextra
808  && tile_has_extra(between, iextra))) {
809  /* 'pextra != iextra' is there just to avoid
810  * tile_has_extra() in by far more common case that
811  * 'pextra == iextra' */
812  /* TODO: Should we restrict this more?
813  * Should we check against enemy cities on between
814  * tile? Should we check against non-native terrain on
815  * between tile?
816  */
817  cost = proad->move_cost * 2;
818  }
819  }
821  }
822  break;
823  case RMM_FAST_ALWAYS:
824  fc_assert(proad->move_mode
825  != RMM_FAST_ALWAYS); // Already handled above
826  cost = proad->move_cost;
827  break;
828  }
829  }
830  }
831  }
832  }
834  }
835  }
837 
838  // UTYF_IGTER units have a maximum move cost per step.
839  if (utype_has_flag(punittype, UTYF_IGTER) && MOVE_COST_IGTER < cost) {
840  cost = MOVE_COST_IGTER;
841  }
842 
843  if (terrain_control.pythagorean_diagonal) {
844  if (!cardinality_checked) {
845  cardinal_move =
846  (ALL_DIRECTIONS_CARDINAL() || is_move_cardinal(nmap, t1, t2));
847  }
848  if (!cardinal_move) {
849  return cost * 181 >> 7; // == (int) (cost * 1.41421356f) if cost < 99
850  }
851  }
852 
853  return cost;
854 }
855 
862 static bool restrict_infra(const struct player *pplayer,
863  const struct tile *t1, const struct tile *t2)
864 {
865  struct player *plr1 = tile_owner(t1), *plr2 = tile_owner(t2);
866 
867  if (!pplayer || !game.info.restrictinfra) {
868  return false;
869  }
870 
871  return (plr1 && pplayers_at_war(plr1, pplayer))
872  || (plr2 && pplayers_at_war(plr2, pplayer));
873 }
874 
878 bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
879 {
880  return real_map_distance(tile0, tile1) == 1;
881 }
882 
887 bool same_pos(const struct tile *tile1, const struct tile *tile2)
888 {
889  fc_assert_ret_val(tile1 != nullptr && tile2 != nullptr, false);
890 
891  /* In case of virtual tile, tile1 can be different from tile2,
892  * but they have same index */
893  return (tile1->index == tile2->index);
894 }
895 
902 bool is_normal_map_pos(int x, int y)
903 {
904  int nat_x, nat_y;
905 
906  MAP_TO_NATIVE_POS(&nat_x, &nat_y, x, y);
907  return nat_x >= 0 && nat_x < wld.map.xsize && nat_y >= 0
908  && nat_y < wld.map.ysize;
909 }
910 
919 bool normalize_map_pos(const struct civ_map *nmap, int *x, int *y)
920 {
921  struct tile *ptile = map_pos_to_tile(nmap, *x, *y);
922 
923  if (ptile) {
924  index_to_map_pos(x, y, tile_index(ptile));
925  return true;
926  } else {
927  return false;
928  }
929 }
930 
935 struct tile *nearest_real_tile(const struct civ_map *nmap, int x, int y)
936 {
937  int nat_x, nat_y;
938 
939  MAP_TO_NATIVE_POS(&nat_x, &nat_y, x, y);
940  if (!current_topo_has_flag(TF_WRAPX)) {
941  nat_x = CLIP(0, nat_x, wld.map.xsize - 1);
942  }
943  if (!current_topo_has_flag(TF_WRAPY)) {
944  nat_y = CLIP(0, nat_y, wld.map.ysize - 1);
945  }
946  NATIVE_TO_MAP_POS(&x, &y, nat_x, nat_y);
947 
948  return map_pos_to_tile(nmap, x, y);
949 }
950 
954 int map_num_tiles() { return wld.map.xsize * wld.map.ysize; }
955 
961 void base_map_distance_vector(int *dx, int *dy, int x0dv, int y0dv, int x1dv,
962  int y1dv)
963 {
964  if (current_topo_has_flag(TF_WRAPX) || current_topo_has_flag(TF_WRAPY)) {
965  // Wrapping is done in native coordinates.
966  MAP_TO_NATIVE_POS(&x0dv, &y0dv, x0dv, y0dv);
967  MAP_TO_NATIVE_POS(&x1dv, &y1dv, x1dv, y1dv);
968 
969  /* Find the "native" distance vector. This corresponds closely to the
970  * map distance vector but is easier to wrap. */
971  *dx = x1dv - x0dv;
972  *dy = y1dv - y0dv;
973  if (current_topo_has_flag(TF_WRAPX)) {
974  /* Wrap dx to be in [-map.xsize/2, map.xsize/2). */
975  *dx = FC_WRAP(*dx + wld.map.xsize / 2, wld.map.xsize)
976  - wld.map.xsize / 2;
977  }
978  if (current_topo_has_flag(TF_WRAPY)) {
979  /* Wrap dy to be in [-map.ysize/2, map.ysize/2). */
980  *dy = FC_WRAP(*dy + wld.map.ysize / 2, wld.map.ysize)
981  - wld.map.ysize / 2;
982  }
983 
984  // Convert the native delta vector back to a pair of map positions.
985  x1dv = x0dv + *dx;
986  y1dv = y0dv + *dy;
987  NATIVE_TO_MAP_POS(&x0dv, &y0dv, x0dv, y0dv);
988  NATIVE_TO_MAP_POS(&x1dv, &y1dv, x1dv, y1dv);
989  }
990 
991  // Find the final (map) vector.
992  *dx = x1dv - x0dv;
993  *dy = y1dv - y0dv;
994 }
995 
1012 void map_distance_vector(int *dx, int *dy, const struct tile *tile0,
1013  const struct tile *tile1)
1014 {
1015  int tx0, ty0, tx1, ty1;
1016 
1017  index_to_map_pos(&tx0, &ty0, tile_index(tile0));
1018  index_to_map_pos(&tx1, &ty1, tile_index(tile1));
1019  base_map_distance_vector(dx, dy, tx0, ty0, tx1, ty1);
1020 }
1021 
1026 struct tile *rand_map_pos(const struct civ_map *nmap)
1027 {
1029 
1030  return native_pos_to_tile(nmap, nat_x, nat_y);
1031 }
1032 
1039 struct tile *rand_map_pos_filtered(const struct civ_map *nmap, void *data,
1040  bool (*filter)(const struct tile *ptile,
1041  const void *data))
1042 {
1043  struct tile *ptile;
1044  int tries = 0;
1045  const int max_tries = MAP_INDEX_SIZE / ACTIVITY_FACTOR;
1046 
1047  /* First do a few quick checks to find a spot. The limit on number of
1048  * tries could use some tweaking. */
1049  do {
1050  ptile = nmap->tiles + fc_rand(MAP_INDEX_SIZE);
1051  } while (filter && !filter(ptile, data) && ++tries < max_tries);
1052 
1053  /* If that fails, count all available spots and pick one.
1054  * Slow but reliable. */
1055  if (tries == max_tries) {
1056  int count = 0, *positions;
1057 
1058  positions = new int[MAP_INDEX_SIZE]();
1059 
1060  whole_map_iterate(nmap, check_tile)
1061  {
1062  if (filter && filter(check_tile, data)) {
1063  positions[count] = tile_index(check_tile);
1064  count++;
1065  }
1066  }
1068 
1069  if (count == 0) {
1070  ptile = nullptr;
1071  } else {
1072  ptile = wld.map.tiles + positions[fc_rand(count)];
1073  }
1074 
1075  delete[] positions;
1076  }
1077 
1078  return ptile;
1079 }
1080 
1084 const char *dir_get_name(enum direction8 dir)
1085 {
1086  // a switch statement is used so the ordering can be changed easily
1087  switch (dir) {
1088  case DIR8_NORTH:
1089  return "N";
1090  case DIR8_NORTHEAST:
1091  return "NE";
1092  case DIR8_EAST:
1093  return "E";
1094  case DIR8_SOUTHEAST:
1095  return "SE";
1096  case DIR8_SOUTH:
1097  return "S";
1098  case DIR8_SOUTHWEST:
1099  return "SW";
1100  case DIR8_WEST:
1101  return "W";
1102  case DIR8_NORTHWEST:
1103  return "NW";
1104  default:
1105  return "[Undef]";
1106  }
1107 }
1108 
1112 enum direction8 dir_cw(enum direction8 dir)
1113 {
1114  // a switch statement is used so the ordering can be changed easily
1115  switch (dir) {
1116  case DIR8_NORTH:
1117  return DIR8_NORTHEAST;
1118  case DIR8_NORTHEAST:
1119  return DIR8_EAST;
1120  case DIR8_EAST:
1121  return DIR8_SOUTHEAST;
1122  case DIR8_SOUTHEAST:
1123  return DIR8_SOUTH;
1124  case DIR8_SOUTH:
1125  return DIR8_SOUTHWEST;
1126  case DIR8_SOUTHWEST:
1127  return DIR8_WEST;
1128  case DIR8_WEST:
1129  return DIR8_NORTHWEST;
1130  case DIR8_NORTHWEST:
1131  return DIR8_NORTH;
1132  default:
1133  fc_assert(false);
1134  return DIR8_ORIGIN;
1135  }
1136 }
1137 
1141 enum direction8 dir_ccw(enum direction8 dir)
1142 {
1143  // a switch statement is used so the ordering can be changed easily
1144  switch (dir) {
1145  case DIR8_NORTH:
1146  return DIR8_NORTHWEST;
1147  case DIR8_NORTHEAST:
1148  return DIR8_NORTH;
1149  case DIR8_EAST:
1150  return DIR8_NORTHEAST;
1151  case DIR8_SOUTHEAST:
1152  return DIR8_EAST;
1153  case DIR8_SOUTH:
1154  return DIR8_SOUTHEAST;
1155  case DIR8_SOUTHWEST:
1156  return DIR8_SOUTH;
1157  case DIR8_WEST:
1158  return DIR8_SOUTHWEST;
1159  case DIR8_NORTHWEST:
1160  return DIR8_WEST;
1161  default:
1162  fc_assert(false);
1163  return DIR8_ORIGIN;
1164  }
1165 }
1166 
1171 static bool is_valid_dir_calculate(enum direction8 dir)
1172 {
1173  switch (dir) {
1174  case DIR8_SOUTHEAST:
1175  case DIR8_NORTHWEST:
1176  // These directions are invalid in hex topologies.
1177  return !(current_topo_has_flag(TF_HEX)
1178  && !current_topo_has_flag(TF_ISO));
1179  case DIR8_NORTHEAST:
1180  case DIR8_SOUTHWEST:
1181  // These directions are invalid in iso-hex topologies.
1182  return !(current_topo_has_flag(TF_HEX) && current_topo_has_flag(TF_ISO));
1183  case DIR8_NORTH:
1184  case DIR8_EAST:
1185  case DIR8_SOUTH:
1186  case DIR8_WEST:
1187  return true;
1188  default:
1189  return false;
1190  }
1191 }
1192 
1199 bool is_valid_dir(enum direction8 dir)
1200 {
1201  fc_assert_ret_val(dir <= direction8_invalid(), false);
1202 
1203  return dir_validity[dir];
1204 }
1205 
1212 bool map_untrusted_dir_is_valid(enum direction8 dir)
1213 {
1214  if (!direction8_is_valid(dir)) {
1215  // Isn't even in range of direction8.
1216  return false;
1217  }
1218 
1219  return is_valid_dir(dir);
1220 }
1221 
1229 static bool is_cardinal_dir_calculate(enum direction8 dir)
1230 {
1231  switch (dir) {
1232  case DIR8_NORTH:
1233  case DIR8_SOUTH:
1234  case DIR8_EAST:
1235  case DIR8_WEST:
1236  return true;
1237  case DIR8_SOUTHEAST:
1238  case DIR8_NORTHWEST:
1239  // These directions are cardinal in iso-hex topologies.
1240  return current_topo_has_flag(TF_HEX) && current_topo_has_flag(TF_ISO);
1241  case DIR8_NORTHEAST:
1242  case DIR8_SOUTHWEST:
1243  // These directions are cardinal in hexagonal topologies.
1244  return current_topo_has_flag(TF_HEX) && !current_topo_has_flag(TF_ISO);
1245  }
1246  return false;
1247 }
1248 
1255 bool is_cardinal_dir(enum direction8 dir)
1256 {
1257  fc_assert_ret_val(dir <= direction8_invalid(), false);
1258 
1259  return dir_cardinality[dir];
1260 }
1261 
1267 bool base_get_direction_for_step(const struct civ_map *nmap,
1268  const struct tile *start_tile,
1269  const struct tile *end_tile,
1270  enum direction8 *dir)
1271 {
1272  adjc_dir_iterate(nmap, start_tile, test_tile, test_dir)
1273  {
1274  if (same_pos(end_tile, test_tile)) {
1275  *dir = test_dir;
1276  return true;
1277  }
1278  }
1280 
1281  return false;
1282 }
1283 
1288 int get_direction_for_step(const struct civ_map *nmap,
1289  const struct tile *start_tile,
1290  const struct tile *end_tile)
1291 {
1292  enum direction8 dir;
1293 
1294  if (base_get_direction_for_step(nmap, start_tile, end_tile, &dir)) {
1295  return dir;
1296  }
1297 
1298  fc_assert(false);
1299  return 0;
1300 }
1301 
1306 bool is_move_cardinal(const struct civ_map *nmap,
1307  const struct tile *start_tile,
1308  const struct tile *end_tile)
1309 {
1310  cardinal_adjc_dir_iterate(nmap, start_tile, test_tile, test_dir)
1311  {
1312  if (same_pos(end_tile, test_tile)) {
1313  return true;
1314  }
1315  }
1317 
1318  return false;
1319 }
1320 
1329 bool is_singular_tile(const struct tile *ptile, int dist)
1330 {
1331  int tile_x, tile_y;
1332 
1333  index_to_map_pos(&tile_x, &tile_y, tile_index(ptile));
1334  do_in_natural_pos(ntl_x, ntl_y, tile_x, tile_y)
1335  {
1336  // Iso-natural coordinates are doubled in scale.
1337  dist *= MAP_IS_ISOMETRIC ? 2 : 1;
1338 
1339  return ((!current_topo_has_flag(TF_WRAPX)
1340  && (ntl_x < dist || ntl_x >= NATURAL_WIDTH - dist))
1341  || (!current_topo_has_flag(TF_WRAPY)
1342  && (ntl_y < dist || ntl_y >= NATURAL_HEIGHT - dist)));
1343  }
1345 }
1346 
1350 static struct startpos *startpos_new(struct tile *ptile)
1351 {
1352  auto *psp = new startpos;
1353 
1354  psp->location = ptile;
1355  psp->exclude = false;
1356  psp->nations = new QSet<const struct nation_type *>();
1357 
1358  return psp;
1359 }
1360 
1364 static void startpos_destroy(struct startpos *psp)
1365 {
1366  fc_assert_ret(nullptr != psp);
1367  delete psp->nations;
1368  delete psp;
1369 }
1370 
1375 int startpos_number(const struct startpos *psp)
1376 {
1377  fc_assert_ret_val(nullptr != psp, 0);
1378  return tile_index(psp->location);
1379 }
1380 
1385 bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
1386 {
1387  fc_assert_ret_val(nullptr != psp, false);
1388  fc_assert_ret_val(nullptr != pnation, false);
1389  bool ret = psp->nations->contains(pnation);
1390  psp->nations->remove(pnation);
1391  if (0 == psp->nations->size() || !psp->exclude) {
1392  psp->exclude = false; // Disable "excluding" mode.
1393  psp->nations->insert(pnation);
1394  }
1395  return ret;
1396 }
1397 
1402 bool startpos_disallow(struct startpos *psp, struct nation_type *pnation)
1403 {
1404  fc_assert_ret_val(nullptr != psp, false);
1405  fc_assert_ret_val(nullptr != pnation, false);
1406  bool ret = psp->nations->contains(pnation);
1407  psp->nations->remove(pnation);
1408  if (0 == psp->nations->size() || psp->exclude) {
1409  psp->exclude = true; // Enable "excluding" mode.
1410  } else {
1411  psp->nations->insert(pnation);
1412  }
1413  return ret;
1414 }
1415 
1419 struct tile *startpos_tile(const struct startpos *psp)
1420 {
1421  fc_assert_ret_val(nullptr != psp, nullptr);
1422  return psp->location;
1423 }
1424 
1428 bool startpos_nation_allowed(const struct startpos *psp,
1429  const struct nation_type *pnation)
1430 {
1431  fc_assert_ret_val(nullptr != psp, false);
1432  fc_assert_ret_val(nullptr != pnation, false);
1433  return XOR(psp->exclude, psp->nations->contains(pnation));
1434 }
1435 
1439 bool startpos_allows_all(const struct startpos *psp)
1440 {
1441  fc_assert_ret_val(nullptr != psp, false);
1442  return (psp->nations->isEmpty());
1443 }
1444 
1449 bool startpos_pack(const struct startpos *psp,
1450  struct packet_edit_startpos_full *packet)
1451 {
1452  fc_assert_ret_val(nullptr != psp, false);
1453  fc_assert_ret_val(nullptr != packet, false);
1454 
1455  packet->id = startpos_number(psp);
1456  packet->exclude = psp->exclude;
1457  BV_CLR_ALL(packet->nations);
1458 
1459  for (const auto *pnation : qAsConst(*psp->nations)) {
1460  BV_SET(packet->nations, nation_index(pnation));
1461  }
1462  return true;
1463 }
1464 
1469 bool startpos_unpack(struct startpos *psp,
1470  const struct packet_edit_startpos_full *packet)
1471 {
1472  fc_assert_ret_val(nullptr != psp, false);
1473  fc_assert_ret_val(nullptr != packet, false);
1474 
1475  psp->exclude = packet->exclude;
1476 
1477  psp->nations->clear();
1478  if (!BV_ISSET_ANY(packet->nations)) {
1479  return true;
1480  }
1481  for (const auto &pnation : nations) {
1482  if (BV_ISSET(packet->nations, nation_index(&pnation))) {
1483  psp->nations->insert(&pnation);
1484  }
1485  } // iterate over nations - pnation
1486  return true;
1487 }
1488 
1496 bool startpos_is_excluding(const struct startpos *psp)
1497 {
1498  fc_assert_ret_val(nullptr != psp, false);
1499  return psp->exclude;
1500 }
1501 
1508 QSet<const struct nation_type *> *
1509 startpos_raw_nations(const struct startpos *psp)
1510 {
1511  fc_assert_ret_val(nullptr != psp, nullptr);
1512  return psp->nations;
1513 }
1514 
1519 {
1520  if (nullptr != wld.map.startpos_table) {
1521  return wld.map.startpos_table->size();
1522  } else {
1523  return 0;
1524  }
1525 }
1526 
1531 struct startpos *map_startpos_new(struct tile *ptile)
1532 {
1533  struct startpos *psp;
1534 
1535  fc_assert_ret_val(nullptr != ptile, nullptr);
1536  fc_assert_ret_val(nullptr != wld.map.startpos_table, nullptr);
1537 
1538  psp = startpos_new(ptile);
1539  wld.map.startpos_table->insert(ptile, psp);
1540 
1541  return psp;
1542 }
1543 
1548 struct startpos *map_startpos_get(const struct tile *ptile)
1549 {
1550  struct startpos *psp;
1551 
1552  fc_assert_ret_val(nullptr != ptile, nullptr);
1553  fc_assert_ret_val(nullptr != wld.map.startpos_table, nullptr);
1554 
1555  psp = wld.map.startpos_table->value(const_cast<struct tile *>(ptile),
1556  nullptr);
1557 
1558  return psp;
1559 }
1560 
1565 bool map_startpos_remove(struct tile *ptile)
1566 {
1567  bool ret;
1568  fc_assert_ret_val(nullptr != ptile, false);
1569  fc_assert_ret_val(nullptr != wld.map.startpos_table, false);
1570  ret = wld.map.startpos_table->contains(ptile);
1571  if (ret) {
1572  startpos_destroy(wld.map.startpos_table->take(ptile));
1573  }
1574 
1575  return ret;
1576 }
1577 
1581 enum direction8 rand_direction()
1582 {
1584 }
1585 
1589 enum direction8 opposite_direction(enum direction8 dir)
1590 {
1591  return direction8(direction8_max() - dir);
1592 }
#define CALL_FUNC_EACH_AI(_func,...)
Definition: ai.h:393
#define BV_CLR_ALL(bv)
Definition: bitvector.h:62
#define BV_SET(bv, bit)
Definition: bitvector.h:44
bool BV_ISSET(const BV &bv, int bit)
Definition: bitvector.h:37
#define BV_ISSET_ANY(vec)
Definition: bitvector.h:76
void generate_city_map_indices()
Fill the arrays city_map_index, city_map_xy and city_map_numtiles.
Definition: city.cpp:499
int compare_iter_index(const void *a, const void *b)
Compare two iter_index values from the city_map_index.
Definition: city.cpp:335
bool is_extra_removed_by(const struct extra_type *pextra, enum extra_rmcause rmcause)
Is given cause one of the removal causes for the given extra?
Definition: extras.cpp:307
bool is_native_extra_to_uclass(const struct extra_type *pextra, const struct unit_class *pclass)
Is extra native to unit class?
Definition: extras.cpp:761
#define extra_type_iterate(_p)
Definition: extras.h:279
#define extra_type_list_iterate(extralist, pextra)
Definition: extras.h:145
#define extra_type_iterate_end
Definition: extras.h:285
#define extra_index(_e_)
Definition: extras.h:163
#define extra_type_list_iterate_end
Definition: extras.h:147
#define extra_road_get(_e_)
Definition: extras.h:171
@ RPT_POSSIBLE
Definition: fc_types.h:567
#define DIR8_ORIGIN
Definition: fc_types.h:372
struct civ_game game
Definition: game.cpp:47
struct world wld
Definition: game.cpp:48
#define fc_assert_ret(condition)
Definition: log.h:112
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
#define log_debug(message,...)
Definition: log.h:65
bv_extras get_tile_infrastructure_set(const struct tile *ptile, int *pcount)
Return a bitfield of the extras on the tile that are infrastructure.
Definition: map.cpp:72
bool terrain_surroundings_allow_change(const struct tile *ptile, const struct terrain *pterrain)
Returns FALSE if a terrain change to 'pterrain' would be prevented by not having enough similar terra...
Definition: map.cpp:706
bool is_normal_map_pos(int x, int y)
Returns TRUE iff the map position is normal.
Definition: map.cpp:902
const int DIR_DY[8]
Definition: map.cpp:58
int startpos_number(const struct startpos *psp)
Returns the unique ID number for this start position.
Definition: map.cpp:1375
void map_free(struct civ_map *fmap)
Frees the allocated memory of the map.
Definition: map.cpp:498
bool startpos_disallow(struct startpos *psp, struct nation_type *pnation)
Disallow the nation to start at the start position.
Definition: map.cpp:1402
bool can_thaw_terrain(const struct tile *ptile)
Returns true if the tile at the given location can be thawed from terrain with a 'Frozen' flag to ter...
Definition: map.cpp:681
#define nat_x
static int map_vector_to_distance(int dx, int dy)
Return the "distance" (which is really the Manhattan distance, and should rarely be used) for a given...
Definition: map.cpp:535
enum direction8 opposite_direction(enum direction8 dir)
Return direction that is opposite to given one.
Definition: map.cpp:1589
#define nat_y
bool is_move_cardinal(const struct civ_map *nmap, const struct tile *start_tile, const struct tile *end_tile)
Returns TRUE iff the move from the position (start_x,start_y) to (end_x,end_y) is a cardinal one.
Definition: map.cpp:1306
static void generate_map_indices()
Fill the iterate_outwards_indices array.
Definition: map.cpp:173
int sq_map_distance(const struct tile *tile0, const struct tile *tile1)
Return squared distance between two tiles.
Definition: map.cpp:610
void main_map_free()
Free main map and related global structures.
Definition: map.cpp:525
struct tile * rand_map_pos(const struct civ_map *nmap)
Random square anywhere on the map.
Definition: map.cpp:1026
struct tile * map_pos_to_tile(const struct civ_map *nmap, int map_x, int map_y)
Return the tile for the given cartesian (map) position.
Definition: map.cpp:391
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)
The basic cost to move punit from tile t1 to tile t2.
Definition: map.cpp:743
static void tile_free(struct tile *ptile)
Free memory associated with one tile.
Definition: map.cpp:447
bool startpos_nation_allowed(const struct startpos *psp, const struct nation_type *pnation)
Returns TRUE if the given nation can start here.
Definition: map.cpp:1428
static struct tile * base_native_pos_to_tile(const struct civ_map *nmap, int nat_x, int nat_y)
Return the tile for the given native position, with wrapping.
Definition: map.cpp:368
int get_direction_for_step(const struct civ_map *nmap, const struct tile *start_tile, const struct tile *end_tile)
Return the direction which is needed for a step on the map from (start_x, start_y) to (end_x,...
Definition: map.cpp:1288
bool map_is_empty()
Returns TRUE if we are at a stage of the game where the map has not yet been generated/loaded.
Definition: map.cpp:124
int map_num_tiles()
Returns the total number of (real) positions (or tiles) on the map.
Definition: map.cpp:954
bool startpos_allows_all(const struct startpos *psp)
Returns TRUE if any nation can start here.
Definition: map.cpp:1439
bool can_channel_land(const struct tile *ptile)
This function returns true if the tile at the given location can be "channeled" from land into ocean.
Definition: map.cpp:668
const int DIR_DX[8]
Definition: map.cpp:57
static bool restrict_infra(const struct player *pplayer, const struct tile *t1, const struct tile *t2)
Returns TRUE if there is a restriction with regard to the infrastructure, i.e.
Definition: map.cpp:862
enum direction8 dir_ccw(enum direction8 dir)
Returns the next direction counter-clock-wise.
Definition: map.cpp:1141
bool is_tiles_adjacent(const struct tile *tile0, const struct tile *tile1)
Are two tiles adjacent to each other.
Definition: map.cpp:878
int map_startpos_count()
Is there start positions set for map.
Definition: map.cpp:1518
struct startpos * map_startpos_get(const struct tile *ptile)
Returns the start position at the given tile, or nullptr if none exists there.
Definition: map.cpp:1548
void map_allocate(struct civ_map *amap)
Allocate space for map, and initialise the tiles.
Definition: map.cpp:462
struct tile * nearest_real_tile(const struct civ_map *nmap, int x, int y)
Twiddle *x and *y to point to the nearest real tile, and ensure that the position is normalized.
Definition: map.cpp:935
static bool dir_validity[9]
Definition: map.cpp:61
bool is_safe_ocean(const struct civ_map *nmap, const struct tile *ptile)
Return TRUE if this ocean terrain is adjacent to a safe coastline.
Definition: map.cpp:636
static struct startpos * startpos_new(struct tile *ptile)
Create a new, empty start position.
Definition: map.cpp:1350
enum direction8 rand_direction()
Return random direction that is valid in current map.
Definition: map.cpp:1581
bool startpos_pack(const struct startpos *psp, struct packet_edit_startpos_full *packet)
Fills the packet with all of the information at this start position.
Definition: map.cpp:1449
static bool is_valid_dir_calculate(enum direction8 dir)
Returns TRUE iff the given direction is a valid one.
Definition: map.cpp:1171
bool can_reclaim_ocean(const struct tile *ptile)
This function returns true if the tile at the given location can be "reclaimed" from ocean into land.
Definition: map.cpp:655
static bool is_cardinal_dir_calculate(enum direction8 dir)
Returns TRUE iff the given direction is a cardinal one.
Definition: map.cpp:1229
int map_vector_to_sq_distance(int dx, int dy)
Return the sq_distance for a given vector.
Definition: map.cpp:583
bool map_startpos_remove(struct tile *ptile)
Remove the start position at the given tile.
Definition: map.cpp:1565
bool can_freeze_terrain(const struct tile *ptile)
Returns true if the tile at the given location can be turned from terrain without a 'Frozen' flag to ...
Definition: map.cpp:694
struct startpos * map_startpos_new(struct tile *ptile)
Create a new start position at the given tile and return it.
Definition: map.cpp:1531
const char * dir_get_name(enum direction8 dir)
Return the debugging name of the direction.
Definition: map.cpp:1084
bool is_cardinal_dir(enum direction8 dir)
Returns TRUE iff the given direction is a cardinal one.
Definition: map.cpp:1255
static void tile_init(struct tile *ptile)
Initialize tile structure.
Definition: map.cpp:322
bool same_pos(const struct tile *tile1, const struct tile *tile2)
Are (x1,y1) and (x2,y2) really the same when adjusted? This function might be necessary ALOT of place...
Definition: map.cpp:887
bool map_untrusted_dir_is_valid(enum direction8 dir)
Returns TRUE iff the given direction is a valid one.
Definition: map.cpp:1212
struct tile * startpos_tile(const struct startpos *psp)
Returns the tile where this start position is located.
Definition: map.cpp:1419
int real_map_distance(const struct tile *tile0, const struct tile *tile1)
Return real distance between two tiles.
Definition: map.cpp:599
bool startpos_unpack(struct startpos *psp, const struct packet_edit_startpos_full *packet)
Fills the start position with the nation information in the packet.
Definition: map.cpp:1469
bool is_valid_dir(enum direction8 dir)
Returns TRUE iff the given direction is a valid one.
Definition: map.cpp:1199
void base_map_distance_vector(int *dx, int *dy, int x0dv, int y0dv, int x1dv, int y1dv)
Finds the difference between the two (unnormalized) positions, in cartesian (map) coordinates.
Definition: map.cpp:961
enum direction8 dir_cw(enum direction8 dir)
Returns the next direction clock-wise.
Definition: map.cpp:1112
QSet< const struct nation_type * > * startpos_raw_nations(const struct startpos *psp)
Return a the nations hash, used for the property editor.
Definition: map.cpp:1509
void map_init_topology()
map_init_topology needs to be called after map.topology_id is changed.
Definition: map.cpp:276
struct tile * native_pos_to_tile(const struct civ_map *nmap, int nat_x, int nat_y)
Return the tile for the given native position.
Definition: map.cpp:416
static void startpos_destroy(struct startpos *psp)
Free all memory allocated by the start position.
Definition: map.cpp:1364
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Return the tile for the given index position.
Definition: map.cpp:429
struct terrain_misc terrain_control
Definition: map.cpp:40
void main_map_allocate()
Allocate main map and related global structures.
Definition: map.cpp:487
bool base_get_direction_for_step(const struct civ_map *nmap, const struct tile *start_tile, const struct tile *end_tile, enum direction8 *dir)
Return TRUE and sets dir to the direction of the step if (end_x, end_y) can be reached from (start_x,...
Definition: map.cpp:1267
void map_distance_vector(int *dx, int *dy, const struct tile *tile0, const struct tile *tile1)
Topology function to find the vector which has the minimum "real" distance between the map positions ...
Definition: map.cpp:1012
static bool dir_cardinality[9]
Definition: map.cpp:60
void map_init(struct civ_map *imap, bool server_side)
Put some sensible values into the map structure.
Definition: map.cpp:129
bool startpos_is_excluding(const struct startpos *psp)
Returns TRUE if the nations returned by startpos_raw_nations() are actually excluded from the nations...
Definition: map.cpp:1496
int map_distance(const struct tile *tile0, const struct tile *tile1)
Return Manhattan distance between two tiles.
Definition: map.cpp:623
struct tile * rand_map_pos_filtered(const struct civ_map *nmap, void *data, bool(*filter)(const struct tile *ptile, const void *data))
Give a random tile anywhere on the map for which the 'filter' function returns TRUE.
Definition: map.cpp:1039
struct tile * mapstep(const struct civ_map *nmap, const struct tile *ptile, enum direction8 dir)
Step from the given tile in the given direction.
Definition: map.cpp:342
bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
Allow the nation to start at the start position.
Definition: map.cpp:1385
bool normalize_map_pos(const struct civ_map *nmap, int *x, int *y)
If the position is real, it will be normalized and TRUE will be returned.
Definition: map.cpp:919
bool is_singular_tile(const struct tile *ptile, int dist)
A "SINGULAR" position is any map position that has an abnormal number of tiles in the radius of dist.
Definition: map.cpp:1329
int map_vector_to_real_distance(int dx, int dy)
Return the "real" distance for a given vector.
Definition: map.cpp:549
#define MAP_MAX_SIZE
Definition: map.h:517
#define current_topo_has_flag(flag)
Definition: map.h:37
#define MAP_DEFAULT_SIZE
Definition: map.h:515
#define MAP_MAX_LINEAR_SIZE
Definition: map.h:530
#define adjc_dir_iterate(nmap, center_tile, itr_tile, dir_itr)
Definition: map.h:364
#define MAP_DEFAULT_HUTS
Definition: map.h:502
#define adjc_iterate_end
Definition: map.h:358
#define do_in_natural_pos(ntl_x, ntl_y, map_x, map_y)
Definition: map.h:143
#define MAP_INDEX_SIZE
Definition: map.h:91
#define MAP_DEFAULT_LINEAR_SIZE
Definition: map.h:529
#define MAP_DEFAULT_STARTPOS
Definition: map.h:563
#define NATURAL_HEIGHT
Definition: map.h:158
#define MAP_DEFAULT_ANIMALS
Definition: map.h:506
#define MAP_DEFAULT_TEAM_PLACEMENT
Definition: map.h:589
#define MAP_DEFAULT_TOPO
Definition: map.h:539
#define MAP_DEFAULT_SEED
Definition: map.h:541
#define MAP_IS_ISOMETRIC
Definition: map.h:32
#define CHECK_INDEX(mindex)
Definition: map.h:103
#define cardinal_between_iterate(nmap, tile1, tile2, between)
Definition: map.h:402
#define MAP_DEFAULT_MAPSIZE
Definition: map.h:510
#define MAP_MIN_LINEAR_SIZE
Definition: map.h:531
#define MAP_DEFAULT_LANDMASS
Definition: map.h:545
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition: map.h:351
#define MAP_TO_NATIVE_POS(pnat_x, pnat_y, map_x, map_y)
Definition: map.h:123
#define ALL_DIRECTIONS_CARDINAL()
Definition: map.h:39
#define NATIVE_TO_MAP_POS(pmap_x, pmap_y, nat_x, nat_y)
Definition: map.h:118
#define cardinal_adjc_dir_iterate_end
Definition: map.h:391
#define MAP_MIN_SIZE
Definition: map.h:516
#define MAP_DEFAULT_SINGLE_POLE
Definition: map.h:577
#define MAP_DEFAULT_SEPARATE_POLES
Definition: map.h:569
#define MAP_DEFAULT_RICHES
Definition: map.h:549
#define MAP_DEFAULT_TINYISLES
Definition: map.h:565
#define whole_map_iterate(_map, _tile)
Definition: map.h:473
#define MAP_DEFAULT_TILESPERPLAYER
Definition: map.h:524
#define adjc_dir_iterate_end
Definition: map.h:368
#define MAP_DEFAULT_TEMPERATURE
Definition: map.h:585
#define MAP_DEFAULT_ALLTEMPERATE
Definition: map.h:581
#define cardinal_between_iterate_end
Definition: map.h:409
#define MAP_DEFAULT_GENERATOR
Definition: map.h:561
#define NATURAL_WIDTH
Definition: map.h:157
#define do_in_natural_pos_end
Definition: map.h:150
#define MAP_DEFAULT_WETNESS
Definition: map.h:557
#define native_pos_to_index_nocheck(nat_x, nat_y)
Definition: map.h:106
#define cardinal_adjc_dir_iterate(nmap, center_tile, itr_tile, dir_itr)
Definition: map.h:387
#define whole_map_iterate_end
Definition: map.h:480
#define index_to_map_pos(pmap_x, pmap_y, mindex)
Definition: map.h:164
#define MAP_DEFAULT_STEEPNESS
Definition: map.h:553
#define DIRSTEP(dest_x, dest_y, dir)
Definition: map.h:170
#define terrain_misc
Definition: map_types.h:23
#define SINGLE_MOVE
Definition: movement.h:17
static bool is_native_tile_to_class(const struct unit_class *punitclass, const struct tile *ptile)
Definition: movement.h:73
#define MOVE_COST_IGTER
Definition: movement.h:18
std::vector< nation_type > nations
Definition: nation.cpp:38
Nation_type_id nation_index(const struct nation_type *pnation)
Return the nation index.
Definition: nation.cpp:464
bool pplayers_at_war(const struct player *pplayer, const struct player *pplayer2)
Returns true iff players can attack each other.
Definition: player.cpp:1317
#define fc_rand(_size)
Definition: rand.h:16
bool are_reqs_active(const struct player *target_player, const struct player *other_player, const struct city *target_city, const struct impr_type *target_building, const struct tile *target_tile, const struct unit *target_unit, const struct unit_type *target_unittype, const struct output_type *target_output, const struct specialist *target_specialist, const struct action *target_action, const struct requirement_vector *reqs, const enum req_problem_type prob_type, const enum vision_layer vision_layer, const enum national_intelligence nintel)
Checks the requirement(s) to see if they are active on the given target.
bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
Check if road provides effect.
Definition: road.cpp:367
#define CLIP(lower, current, upper)
Definition: shared.h:51
#define FC_WRAP(value, range)
Definition: shared.h:59
#define MAX(x, y)
Definition: shared.h:48
#define BAD_HEURISTIC_INIT(_ini_val_)
Definition: shared.h:37
#define XOR(p, q)
Definition: shared.h:64
struct packet_game_info info
Definition: game.h:80
struct tile * tiles
Definition: map_types.h:76
int xsize
Definition: map_types.h:73
int ysize
Definition: map_types.h:73
int num_continents
Definition: map_types.h:74
enum direction8 valid_dirs[8]
Definition: map_types.h:69
int num_iterate_outwards_indices
Definition: map_types.h:72
int num_cardinal_dirs
Definition: map_types.h:70
int num_valid_dirs
Definition: map_types.h:70
int num_oceans
Definition: map_types.h:75
struct iter_index * iterate_outwards_indices
Definition: map_types.h:71
int topology_id
Definition: map_types.h:68
enum direction8 cardinal_dirs[8]
Definition: map_types.h:69
QHash< struct tile *, struct startpos * > * startpos_table
Definition: map_types.h:77
struct civ_map::@39::@41 server
int dist
Definition: city.h:83
int dx
Definition: city.h:83
int dy
Definition: city.h:83
Definition: player.h:231
Definition: road.h:54
enum road_move_mode move_mode
Definition: road.h:58
struct extra_type_list * integrators
Definition: road.h:72
int move_cost
Definition: road.h:57
bool exclude
Definition: map_types.h:30
QSet< const struct nation_type * > * nations
Definition: map_types.h:31
struct tile * location
Definition: map_types.h:29
Definition: tile.h:42
char * spec_sprite
Definition: tile.h:58
char * label
Definition: tile.h:57
int index
Definition: tile.h:43
bv_extras extras
Definition: tile.h:47
struct extra_type * resource
Definition: tile.h:48
struct unit_list * units
Definition: tile.h:50
struct player * extras_owner
Definition: tile.h:55
struct terrain * terrain
Definition: tile.h:49
struct extra_type * placing
Definition: tile.h:53
struct city * worked
Definition: tile.h:51
struct player * owner
Definition: tile.h:52
Continent_id continent
Definition: tile.h:46
struct tile * claimer
Definition: tile.h:56
struct unit_class::@81 cache
struct extra_type_list * bonus_roads
Definition: unittype.h:142
Definition: unit.h:134
struct civ_map map
Definition: world_object.h:21
int count_terrain_flag_near_tile(const struct tile *ptile, bool cardinal_only, bool percentage, enum terrain_flag_id flag)
Return the number of adjacent tiles that have terrain with the given flag (not including ptile itself...
Definition: terrain.cpp:365
int count_terrain_class_near_tile(const struct tile *ptile, bool cardinal_only, bool percentage, enum terrain_class tclass)
Return the number of adjacent tiles that have given terrain class (not including ptile itself).
Definition: terrain.cpp:517
#define T_UNKNOWN
Definition: terrain.h:51
#define is_ocean(pterrain)
Definition: terrain.h:276
#define terrain_has_flag(terr, flag)
Definition: terrain.h:260
void tile_virtual_destroy(struct tile *vtile)
Frees all memory used by the virtual tile, including freeing virtual units in the tile's unit list an...
Definition: tile.cpp:1051
void tile_remove_extra(struct tile *ptile, const struct extra_type *pextra)
Removes extra from tile if such exist.
Definition: tile.cpp:984
bool tile_virtual_check(const tile *vtile)
Check if the given tile is a virtual one or not.
Definition: tile.cpp:1085
struct tile * tile_virtual_new(const struct tile *ptile)
Returns a virtual tile.
Definition: tile.cpp:997
#define tile_index(_pt_)
Definition: tile.h:70
#define ACTIVITY_FACTOR
Definition: tile.h:151
#define tile_terrain(_tile)
Definition: tile.h:93
#define tile_has_extra(ptile, pextra)
Definition: tile.h:130
#define tile_owner(_tile)
Definition: tile.h:78
static bool uclass_has_flag(const struct unit_class *punitclass, enum unit_class_flag_id flag)
Definition: unittype.h:704
#define utype_class(_t_)
Definition: unittype.h:691
static bool utype_has_flag(const struct unit_type *punittype, int flag)
Definition: unittype.h:584