Freeciv21
Develop your civilization from humble roots to a global empire
mapgen.cpp
Go to the documentation of this file.
1 /*__ ___ ***************************************
2 / \ / \ Copyright (c) 1996-2021 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 <fc_config.h>
15 
16 #include <QBitArray>
17 #include <cstdlib>
18 #include <cstring>
19 // utility
20 #include "bitvector.h"
21 #include "fcintl.h"
22 #include "log.h"
23 #include "rand.h"
24 #include "shared.h"
25 
26 // common
27 #include "game.h"
28 #include "map.h"
29 #include "road.h"
30 
31 /* server/generator */
32 #include "fair_islands.h"
33 #include "fracture_map.h"
34 #include "height_map.h"
35 #include "islands.h"
36 #include "mapgen_topology.h"
37 #include "mapgen_utils.h"
38 #include "startpos.h"
39 #include "temperature_map.h"
40 
41 #include "mapgen.h"
42 
45 
46 static void make_huts(int number);
47 static void add_resources(int prob);
48 static void adjust_terrain_param();
49 
50 #define RIVERS_MAXTRIES 32767
51 /* This struct includes two dynamic bitvectors. They are needed to mark
52  tiles as blocked to prevent a river from falling into itself, and for
53  storing rivers temporarly. */
54 struct river_map {
55  QBitArray blocked;
56  QBitArray ok;
57 };
58 
59 static int river_test_blocked(struct river_map *privermap,
60  struct tile *ptile, struct extra_type *priver);
61 static int river_test_rivergrid(struct river_map *privermap,
62  struct tile *ptile,
63  struct extra_type *priver);
64 static int river_test_highlands(struct river_map *privermap,
65  struct tile *ptile,
66  struct extra_type *priver);
67 static int river_test_adjacent_ocean(struct river_map *privermap,
68  struct tile *ptile,
69  struct extra_type *priver);
70 static int river_test_adjacent_river(struct river_map *privermap,
71  struct tile *ptile,
72  struct extra_type *priver);
73 static int river_test_adjacent_highlands(struct river_map *privermap,
74  struct tile *ptile,
75  struct extra_type *priver);
76 static int river_test_swamp(struct river_map *privermap, struct tile *ptile,
77  struct extra_type *priver);
78 static int river_test_adjacent_swamp(struct river_map *privermap,
79  struct tile *ptile,
80  struct extra_type *priver);
81 static int river_test_height_map(struct river_map *privermap,
82  struct tile *ptile,
83  struct extra_type *priver);
84 static void river_blockmark(struct river_map *privermap, struct tile *ptile);
85 static bool make_river(struct river_map *privermap, struct tile *ptile,
86  struct extra_type *priver);
87 static void make_rivers();
88 
89 static void river_types_init();
90 
91 /* These are the old parameters of terrains types in %
92  TODO: they depend on the hardcoded terrains */
93 int forest_pct = 0;
94 int desert_pct = 0;
95 int swamp_pct = 0;
96 int mountain_pct = 0;
97 int jungle_pct = 0;
98 int river_pct = 0;
99 
100 // MISCELANEOUS (OTHER CONDITIONS)
101 
102 // necessary condition of swamp placement
103 static int hmap_low_level = 0;
104 #define ini_hmap_low_level() \
105  { \
106  hmap_low_level = \
107  (4 * swamp_pct * (hmap_max_level - hmap_shore_level)) / 100 \
108  + hmap_shore_level; \
109  }
110 // should be used after having hmap_low_level initialized
111 #define map_pos_is_low(ptile) ((hmap((ptile)) < hmap_low_level))
112 
114 
122 bool test_wetness(const struct tile *ptile, wetness_c c)
123 {
124  switch (c) {
125  case WC_ALL:
126  return true;
127  case WC_DRY:
128  return map_pos_is_dry(ptile);
129  case WC_NDRY:
130  return !map_pos_is_dry(ptile);
131  }
132  qCritical("Invalid wetness_c %d", c);
133  return false;
134 }
135 
139 static bool test_miscellaneous(const struct tile *ptile, miscellaneous_c c)
140 {
141  switch (c) {
142  case MC_NONE:
143  return true;
144  case MC_LOW:
145  return map_pos_is_low(ptile);
146  case MC_NLOW:
147  return !map_pos_is_low(ptile);
148  }
149  qCritical("Invalid miscellaneous_c %d", c);
150  return false;
151 }
152 
156 struct DataFilter {
160 };
161 
166 static bool condition_filter(const struct tile *ptile, const void *data)
167 {
168  const struct DataFilter *filter = static_cast<const DataFilter *>(data);
169 
170  return not_placed(ptile) && tmap_is(ptile, filter->tc)
171  && test_wetness(ptile, filter->wc)
172  && test_miscellaneous(ptile, filter->mc);
173 }
174 
181  temperature_type tc,
182  miscellaneous_c mc)
183 {
184  struct DataFilter filter;
185 
186  filter.wc = wc;
187  filter.tc = tc;
188  filter.mc = mc;
189 
190  return rand_map_pos_filtered(&(wld.map), &filter, condition_filter);
191 }
192 
199 static bool terrain_is_too_high(struct tile *ptile, int thill, int my_height)
200 {
201  square_iterate(&(wld.map), ptile, 1, tile1)
202  {
203  if (hmap(tile1) + (hmap_max_level - hmap_mountain_level) / 5 < thill) {
204  return false;
205  }
206  }
208  return true;
209 }
210 
217 static void make_relief()
218 {
219  /* Calculate the mountain level. map.server.mountains specifies the
220  * percentage of land that is turned into hills and mountains. */
222  * (100 - wld.map.server.steepness))
223  / 100
224  + hmap_shore_level);
225 
226  whole_map_iterate(&(wld.map), ptile)
227  {
228  if (not_placed(ptile)
229  && ((hmap_mountain_level < hmap(ptile)
230  && (fc_rand(10) > 5
232  hmap(ptile))))
233  || area_is_too_flat(ptile, hmap_mountain_level, hmap(ptile)))) {
234  if (tmap_is(ptile, TT_HOT)) {
235  // Prefer hills to mountains in hot regions.
236  tile_set_terrain(ptile,
237  pick_terrain(MG_MOUNTAINOUS,
238  fc_rand(10) < 4 ? MG_UNUSED : MG_GREEN,
239  MG_UNUSED));
240  } else {
241  // Prefer mountains hills to in cold regions.
243  ptile, pick_terrain(MG_MOUNTAINOUS, MG_UNUSED,
244  fc_rand(10) < 8 ? MG_GREEN : MG_UNUSED));
245  }
246  map_set_placed(ptile);
247  }
248  }
250 }
251 
259 {
260  struct terrain *ocean = pick_ocean(TERRAIN_OCEAN_DEPTH_MAXIMUM, true);
261 
262  whole_map_iterate(&(wld.map), ptile)
263  {
264  if (tmap_is(ptile, TT_FROZEN)
265  || (tmap_is(ptile, TT_COLD) && (fc_rand(10) > 7)
266  && is_temperature_type_near(ptile, TT_FROZEN))) {
267  if (ocean) {
268  tile_set_terrain(ptile, ocean);
269  } else {
270  tile_set_terrain(ptile,
271  pick_terrain(MG_FROZEN, MG_UNUSED, MG_TROPICAL));
272  }
273  }
274  }
276 }
277 
281 static bool ok_for_separate_poles(struct tile *ptile)
282 {
283  if (!wld.map.server.separatepoles) {
284  return true;
285  }
286  adjc_iterate(&(wld.map), ptile, tile1)
287  {
288  if (tile_continent(tile1) > 0) {
289  return false;
290  }
291  }
293  return true;
294 }
295 
301 static void make_polar_land()
302 {
304 
305  whole_map_iterate(&(wld.map), ptile)
306  {
307  if ((tile_terrain(ptile) == T_UNKNOWN
308  || !terrain_has_flag(tile_terrain(ptile), TER_FROZEN))
309  && ((tmap_is(ptile, TT_FROZEN) && ok_for_separate_poles(ptile))
310  || (tmap_is(ptile, TT_COLD) && fc_rand(10) > 7
312  && ok_for_separate_poles(ptile)))) {
313  tile_set_terrain(ptile, T_UNKNOWN);
314  tile_set_continent(ptile, 0);
315  }
316  }
318 }
319 
323 static void place_terrain(struct tile *ptile, int diff,
324  struct terrain *pterrain, int *to_be_placed,
326  miscellaneous_c mc)
327 {
328  if (*to_be_placed <= 0) {
329  return;
330  }
331  fc_assert_ret(not_placed(ptile));
332  tile_set_terrain(ptile, pterrain);
333  map_set_placed(ptile);
334  (*to_be_placed)--;
335 
336  cardinal_adjc_iterate(&(wld.map), ptile, tile1)
337  {
338  // Check L_UNIT and H_UNIT against 0.
339  int Delta =
340  (abs(map_colatitude(tile1) - map_colatitude(ptile)) / MAX(L_UNIT, 1)
341  + abs(hmap(tile1) - (hmap(ptile))) / MAX(H_UNIT, 1));
342  if (not_placed(tile1) && tmap_is(tile1, tc) && test_wetness(tile1, wc)
343  && test_miscellaneous(tile1, mc) && Delta < diff
344  && fc_rand(10) > 4) {
345  place_terrain(tile1, diff - 1 - Delta, pterrain, to_be_placed, wc, tc,
346  mc);
347  }
348  }
350 }
351 
356 static void make_plain(struct tile *ptile, int *to_be_placed)
357 {
358  // in cold place we get tundra instead
359  if (tmap_is(ptile, TT_FROZEN)) {
360  tile_set_terrain(ptile,
361  pick_terrain(MG_FROZEN, MG_UNUSED, MG_MOUNTAINOUS));
362  } else if (tmap_is(ptile, TT_COLD)) {
363  tile_set_terrain(ptile,
364  pick_terrain(MG_COLD, MG_UNUSED, MG_MOUNTAINOUS));
365  } else {
366  tile_set_terrain(ptile,
367  pick_terrain(MG_TEMPERATE, MG_GREEN, MG_MOUNTAINOUS));
368  }
369  map_set_placed(ptile);
370  (*to_be_placed)--;
371 }
372 
378 {
379  int to_be_placed;
380 
381  whole_map_iterate(&(wld.map), ptile)
382  {
383  if (not_placed(ptile)) {
384  to_be_placed = 1;
385  make_plain(ptile, &to_be_placed);
386  }
387  }
389 }
390 
394 #define PLACE_ONE_TYPE(count, alternate, ter, wc, tc, mc, weight) \
395  if ((count) > 0) { \
396  struct tile *ptile; \
397  /* Place some terrains */ \
398  if ((ptile = rand_map_pos_characteristic((wc), (tc), (mc)))) { \
399  place_terrain(ptile, (weight), (ter), &(count), (wc), (tc), (mc)); \
400  } else { \
401  /* If rand_map_pos_temperature returns FALSE we may as well stop */ \
402  /* looking for this time and go to alternate type. */ \
403  (alternate) += (count); \
404  (count) = 0; \
405  } \
406  }
407 
415 static void make_terrains()
416 {
417  int total = 0;
418  int forests_count = 0;
419  int jungles_count = 0;
420  int deserts_count = 0;
421  int alt_deserts_count = 0;
422  int plains_count = 0;
423  int swamps_count = 0;
424 
425  whole_map_iterate(&(wld.map), ptile)
426  {
427  if (not_placed(ptile)) {
428  total++;
429  }
430  }
432 
433  forests_count = total * forest_pct / (100 - mountain_pct);
434  jungles_count = total * jungle_pct / (100 - mountain_pct);
435 
436  deserts_count = total * desert_pct / (100 - mountain_pct);
437  swamps_count = total * swamp_pct / (100 - mountain_pct);
438 
439  // grassland, tundra,arctic and plains is counted in plains_count
440  plains_count =
441  total - forests_count - deserts_count - swamps_count - jungles_count;
442 
443  // the placement loop
444  do {
445  PLACE_ONE_TYPE(forests_count, plains_count,
446  pick_terrain(MG_FOLIAGE, MG_TEMPERATE, MG_TROPICAL),
447  WC_ALL, TT_NFROZEN, MC_NONE, 60);
448  PLACE_ONE_TYPE(jungles_count, forests_count,
449  pick_terrain(MG_FOLIAGE, MG_TROPICAL, MG_COLD), WC_ALL,
450  TT_TROPICAL, MC_NONE, 50);
451  PLACE_ONE_TYPE(swamps_count, forests_count,
452  pick_terrain(MG_WET, MG_UNUSED, MG_FOLIAGE), WC_NDRY,
453  TT_HOT, MC_LOW, 50);
454  PLACE_ONE_TYPE(deserts_count, alt_deserts_count,
455  pick_terrain(MG_DRY, MG_TROPICAL, MG_COLD), WC_DRY,
456  TT_NFROZEN, MC_NLOW, 80);
457  PLACE_ONE_TYPE(alt_deserts_count, plains_count,
458  pick_terrain(MG_DRY, MG_TROPICAL, MG_WET), WC_ALL,
459  TT_NFROZEN, MC_NLOW, 40);
460 
461  // make the plains and tundras
462  if (plains_count > 0) {
463  struct tile *ptile;
464 
465  // Don't use any restriction here !
467  make_plain(ptile, &plains_count);
468  } else {
469  /* If rand_map_pos_temperature returns FALSE we may as well stop
470  * looking for plains. */
471  plains_count = 0;
472  }
473  }
474  } while (forests_count > 0 || jungles_count > 0 || deserts_count > 0
475  || alt_deserts_count > 0 || plains_count > 0 || swamps_count > 0);
476 }
477 
481 static int river_test_blocked(struct river_map *privermap,
482  struct tile *ptile, struct extra_type *priver)
483 {
484  if (privermap->blocked.at(tile_index(ptile))) {
485  return 1;
486  }
487 
488  // any un-blocked?
489  cardinal_adjc_iterate(&(wld.map), ptile, ptile1)
490  {
491  if (!privermap->blocked.at(tile_index(ptile1))) {
492  return 0;
493  }
494  }
496 
497  return 1; // none non-blocked |- all blocked
498 }
499 
503 static int river_test_rivergrid(struct river_map *privermap,
504  struct tile *ptile,
505  struct extra_type *priver)
506 {
507  return (count_river_type_tile_card(ptile, priver, false) > 1) ? 1 : 0;
508 }
509 
513 static int river_test_highlands(struct river_map *privermap,
514  struct tile *ptile,
515  struct extra_type *priver)
516 {
517  return tile_terrain(ptile)->property[MG_MOUNTAINOUS];
518 }
519 
523 static int river_test_adjacent_ocean(struct river_map *privermap,
524  struct tile *ptile,
525  struct extra_type *priver)
526 {
527  return 100 - count_terrain_class_near_tile(ptile, true, true, TC_OCEAN);
528 }
529 
533 static int river_test_adjacent_river(struct river_map *privermap,
534  struct tile *ptile,
535  struct extra_type *priver)
536 {
537  return 100 - count_river_type_tile_card(ptile, priver, true);
538 }
539 
543 static int river_test_adjacent_highlands(struct river_map *privermap,
544  struct tile *ptile,
545  struct extra_type *priver)
546 {
547  int sum = 0;
548 
549  adjc_iterate(&(wld.map), ptile, ptile2)
550  {
551  sum += tile_terrain(ptile2)->property[MG_MOUNTAINOUS];
552  }
554 
555  return sum;
556 }
557 
561 static int river_test_swamp(struct river_map *privermap, struct tile *ptile,
562  struct extra_type *priver)
563 {
564  return FC_INFINITY - tile_terrain(ptile)->property[MG_WET];
565 }
566 
570 static int river_test_adjacent_swamp(struct river_map *privermap,
571  struct tile *ptile,
572  struct extra_type *priver)
573 {
574  int sum = 0;
575 
576  adjc_iterate(&(wld.map), ptile, ptile2)
577  {
578  sum += tile_terrain(ptile2)->property[MG_WET];
579  }
581 
582  return FC_INFINITY - sum;
583 }
584 
588 static int river_test_height_map(struct river_map *privermap,
589  struct tile *ptile,
590  struct extra_type *priver)
591 {
592  return hmap(ptile);
593 }
594 
598 static void river_blockmark(struct river_map *privermap, struct tile *ptile)
599 {
600  log_debug("Blockmarking (%d, %d) and adjacent tiles.", TILE_XY(ptile));
601 
602  privermap->blocked.setBit(tile_index(ptile));
603 
604  cardinal_adjc_iterate(&(wld.map), ptile, ptile1)
605  {
606  privermap->blocked.setBit(tile_index(ptile1));
607  }
609 }
610 
611 struct test_func {
612  int (*func)(struct river_map *privermap, struct tile *ptile,
613  struct extra_type *priver);
614  bool fatal;
615 };
616 
617 #define NUM_TEST_FUNCTIONS 9
618 static struct test_func test_funcs[NUM_TEST_FUNCTIONS] = {
619  {river_test_blocked, true},
620  {river_test_rivergrid, true},
621  {river_test_highlands, false},
622  {river_test_adjacent_ocean, false},
623  {river_test_adjacent_river, false},
625  {river_test_swamp, false},
626  {river_test_adjacent_swamp, false},
627  {river_test_height_map, false}};
628 
719 static bool make_river(struct river_map *privermap, struct tile *ptile,
720  struct extra_type *priver)
721 {
722  /* Comparison value for each tile surrounding the current tile. It is
723  * the suitability to continue a river to the tile in that direction;
724  * lower is better. However rivers may only run in cardinal directions;
725  * the other directions are ignored entirely. */
726  int rd_comparison_val[8];
727 
728  bool rd_direction_is_valid[8];
729  int num_valid_directions, func_num, direction;
730 
731  while (true) {
732  // Mark the current tile as river.
733  privermap->ok.setBit(tile_index(ptile));
734  log_debug("The tile at (%d, %d) has been marked as river in river_map.",
735  TILE_XY(ptile));
736 
737  // Test if the river is done.
738  // We arbitrarily make rivers end at the poles.
739  if (count_river_near_tile(ptile, priver) > 0
740  || count_terrain_class_near_tile(ptile, true, true, TC_OCEAN) > 0
741  || (tile_terrain(ptile)->property[MG_FROZEN] > 0
742  && map_colatitude(ptile) < 0.8 * COLD_LEVEL)) {
743  log_debug("The river ended at (%d, %d).", TILE_XY(ptile));
744  return true;
745  }
746 
747  // Else choose a direction to continue the river.
748  log_debug("The river did not end at (%d, %d). Evaluating directions...",
749  TILE_XY(ptile));
750 
751  // Mark all available cardinal directions as available.
752  memset(rd_direction_is_valid, 0, sizeof(rd_direction_is_valid));
753  cardinal_adjc_dir_base_iterate(&(wld.map), ptile, dir)
754  {
755  rd_direction_is_valid[dir] = true;
756  }
758 
759  // Test series that selects a direction for the river.
760  for (func_num = 0; func_num < NUM_TEST_FUNCTIONS; func_num++) {
761  int best_val = -1;
762 
763  // first get the tile values for the function
764  cardinal_adjc_dir_iterate(&(wld.map), ptile, ptile1, dir)
765  {
766  if (rd_direction_is_valid[dir]) {
767  rd_comparison_val[dir] =
768  (test_funcs[func_num].func)(privermap, ptile1, priver);
769  fc_assert_action(rd_comparison_val[dir] >= 0, continue);
770  if (best_val == -1) {
771  best_val = rd_comparison_val[dir];
772  } else {
773  best_val = MIN(rd_comparison_val[dir], best_val);
774  }
775  }
776  }
778  fc_assert_action(best_val != -1, continue);
779 
780  // should we abort?
781  if (best_val > 0 && test_funcs[func_num].fatal) {
782  return false;
783  }
784 
785  // mark the less attractive directions as invalid
786  cardinal_adjc_dir_base_iterate(&(wld.map), ptile, dir)
787  {
788  if (rd_direction_is_valid[dir]) {
789  if (rd_comparison_val[dir] != best_val) {
790  rd_direction_is_valid[dir] = false;
791  }
792  }
793  }
795  }
796 
797  /* Directions evaluated with all functions. Now choose the best
798  direction before going to the next iteration of the while loop */
799  num_valid_directions = 0;
800  cardinal_adjc_dir_base_iterate(&(wld.map), ptile, dir)
801  {
802  if (rd_direction_is_valid[dir]) {
803  num_valid_directions++;
804  }
805  }
807 
808  if (num_valid_directions == 0) {
809  return false; // river aborted
810  }
811 
812  // One or more valid directions: choose randomly.
813  log_debug("mapgen.c: Had to let the random number"
814  " generator select a direction for a river.");
815  direction = fc_rand(num_valid_directions);
816  log_debug("mapgen.c: direction: %d", direction);
817 
818  // Find the direction that the random number generator selected.
819  cardinal_adjc_dir_iterate(&(wld.map), ptile, tile1, dir)
820  {
821  if (rd_direction_is_valid[dir]) {
822  if (direction > 0) {
823  direction--;
824  } else {
825  river_blockmark(privermap, ptile);
826  ptile = tile1;
827  break;
828  }
829  }
830  }
832  fc_assert_ret_val(direction == 0, false);
833  } // end while; (Make a river.)
834 }
835 
840 static void make_rivers()
841 {
842  struct tile *ptile;
843  struct terrain *pterrain;
844  struct river_map rivermap;
845  struct extra_type *road_river = nullptr;
846 
847  /* Formula to make the river density similar om different sized maps.
848  Avoids too few rivers on large maps and too many rivers on small maps.
849  */
850  int desirable_riverlength =
851  river_pct *
852  // The size of the map (poles counted in river_pct).
853  map_num_tiles() *
854  // Rivers need to be on land only.
855  wld.map.server.landpercent /
856  /* Adjustment value. Tested by me. Gives no rivers with 'set
857  rivers 0', gives a reasonable amount of rivers with default
858  settings and as many rivers as possible with 'set rivers 100'. */
859  5325;
860 
861  // The number of river tiles that have been set.
862  int current_riverlength = 0;
863 
864  /* Counts the number of iterations (should increase with 1 during
865  every iteration of the main loop in this function).
866  Is needed to stop a potentially infinite loop. */
867  int iteration_counter = 0;
868 
869  if (river_type_count <= 0) {
870  // No river type available
871  return;
872  }
873 
874  create_placed_map(); // needed bu rand_map_characteristic
876 
877  rivermap.blocked.resize(MAP_INDEX_SIZE);
878  rivermap.ok.resize(MAP_INDEX_SIZE);
879 
880  // The main loop in this function.
881  while (current_riverlength < desirable_riverlength
882  && iteration_counter < RIVERS_MAXTRIES) {
883  if (!(ptile =
885  break; // mo more spring places
886  }
887  pterrain = tile_terrain(ptile);
888 
889  /* Check if it is suitable to start a river on the current tile.
890  */
891  if (
892  // Don't start a river on ocean.
893  !is_ocean(pterrain)
894 
895  // Don't start a river on river.
896  && !tile_has_river(ptile)
897 
898  /* Don't start a river on a tile is surrounded by > 1 river +
899  ocean tile. */
900  && (count_river_near_tile(ptile, nullptr)
901  + count_terrain_class_near_tile(ptile, true, false, TC_OCEAN)
902  <= 1)
903 
904  /* Don't start a river on a tile that is surrounded by hills or
905  mountains unless it is hard to find somewhere else to start
906  it. */
907  && (count_terrain_property_near_tile(ptile, true, true,
908  MG_MOUNTAINOUS)
909  < 90
910  || iteration_counter >= RIVERS_MAXTRIES / 10 * 5)
911 
912  /* Don't start a river on hills unless it is hard to find
913  somewhere else to start it. */
914  && (pterrain->property[MG_MOUNTAINOUS] == 0
915  || iteration_counter >= RIVERS_MAXTRIES / 10 * 6)
916 
917  /* Don't start a river on arctic unless it is hard to find
918  somewhere else to start it. */
919  && (pterrain->property[MG_FROZEN] == 0
920  || iteration_counter >= RIVERS_MAXTRIES / 10 * 8)
921 
922  /* Don't start a river on desert unless it is hard to find
923  somewhere else to start it. */
924  && (pterrain->property[MG_DRY] == 0
925  || iteration_counter >= RIVERS_MAXTRIES / 10 * 9)) {
926  // Reset river map before making a new river.
927  rivermap.blocked.fill(false);
928  rivermap.ok.fill(false);
929 
930  road_river = river_types[fc_rand(river_type_count)];
931 
932  extra_type_by_cause_iterate(EC_ROAD, oriver)
933  {
934  if (oriver != road_river) {
935  whole_map_iterate(&(wld.map), rtile)
936  {
937  if (tile_has_extra(rtile, oriver)) {
938  rivermap.blocked.setBit(tile_index(rtile));
939  }
940  }
942  }
943  }
945 
946  log_debug("Found a suitable starting tile for a river at (%d, %d)."
947  " Starting to make it.",
948  TILE_XY(ptile));
949 
950  // Try to make a river. If it is OK, apply it to the map.
951  if (make_river(&rivermap, ptile, road_river)) {
952  whole_map_iterate(&(wld.map), ptile1)
953  {
954  if (rivermap.ok.at(tile_index(ptile1))) {
955  struct terrain *river_terrain = tile_terrain(ptile1);
956 
957  if (!terrain_has_flag(river_terrain, TER_CAN_HAVE_RIVER)) {
958  // We have to change the terrain to put a river here.
959  river_terrain = pick_terrain_by_flag(TER_CAN_HAVE_RIVER);
960  if (river_terrain != nullptr) {
961  tile_set_terrain(ptile1, river_terrain);
962  }
963  }
964 
965  tile_add_extra(ptile1, road_river);
966  current_riverlength++;
967  map_set_placed(ptile1);
968  log_debug("Applied a river to (%d, %d).", TILE_XY(ptile1));
969  }
970  }
972  } else {
973  log_debug("mapgen.c: A river failed. It might have gotten stuck "
974  "in a helix.");
975  }
976  } // end if;
977  iteration_counter++;
978  log_debug("current_riverlength: %d; desirable_riverlength: %d; "
979  "iteration_counter: %d",
980  current_riverlength, desirable_riverlength, iteration_counter);
981  } // end while;
982 
984 }
985 
991 static void make_land()
992 {
993  struct terrain *land_fill = nullptr;
994 
995  if (HAS_POLES) {
997  }
998 
999  /* Pick a non-ocean terrain just once and fill all land tiles with "
1000  * that terrain. We must set some terrain (and not T_UNKNOWN) so that "
1001  * continent number assignment works. */
1002  terrain_type_iterate(pterrain)
1003  {
1004  if (!is_ocean(pterrain)
1005  && !terrain_has_flag(pterrain, TER_NOT_GENERATED)) {
1006  land_fill = pterrain;
1007  break;
1008  }
1009  }
1011 
1012  fc_assert_exit_msg(nullptr != land_fill,
1013  "No land terrain type could be found for the purpose "
1014  "of temporarily filling in land tiles during map "
1015  "generation. This could be an error in Freeciv21, or a "
1016  "mistake in the terrain.ruleset file. Please make sure "
1017  "there is at least one land terrain type in the "
1018  "ruleset, or use a different map generator. If this "
1019  "error persists, please report it at: %s",
1020  BUG_URL);
1021 
1023  (hmap_max_level * (100 - wld.map.server.landpercent)) / 100;
1025  whole_map_iterate(&(wld.map), ptile)
1026  {
1027  tile_set_terrain(ptile, T_UNKNOWN); // set as oceans count is used
1028  if (hmap(ptile) < hmap_shore_level) {
1029  int depth = (hmap_shore_level - hmap(ptile)) * 100 / hmap_shore_level;
1030  int ocean = 0;
1031  int land = 0;
1032 
1033  // This is to make shallow connection between continents less likely
1034  adjc_iterate(&(wld.map), ptile, other)
1035  {
1036  if (hmap(other) < hmap_shore_level) {
1037  ocean++;
1038  } else {
1039  land++;
1040  break;
1041  }
1042  }
1044 
1045  depth += 30 * (ocean - land) / MAX(1, (ocean + land));
1046 
1047  depth = MIN(depth, TERRAIN_OCEAN_DEPTH_MAXIMUM);
1048 
1049  /* Generate sea ice here, if ruleset supports it. Dummy temperature
1050  * map is sufficient for this. If ruleset doesn't support it,
1051  * use unfrozen ocean; make_polar_land() will later fill in with
1052  * land-based ice. Ice has a ragged margin. */
1053  {
1054  bool frozen =
1055  HAS_POLES
1056  && (tmap_is(ptile, TT_FROZEN)
1057  || (tmap_is(ptile, TT_COLD) && fc_rand(10) > 7
1058  && is_temperature_type_near(ptile, TT_FROZEN)));
1059  struct terrain *pterrain = pick_ocean(depth, frozen);
1060 
1061  if (frozen && !pterrain) {
1062  pterrain = pick_ocean(depth, false);
1063  fc_assert(pterrain);
1064  }
1065  tile_set_terrain(ptile, pterrain);
1066  }
1067  } else {
1068  // See note above for 'land_fill'.
1069  tile_set_terrain(ptile, land_fill);
1070  }
1071  }
1073 
1074  if (HAS_POLES) {
1076  }
1077 
1078  // destroy old dummy temperature map ...
1079  destroy_tmap();
1080  // ... and create a real temperature map (needs hmap and oceans)
1081  create_tmap(true);
1082 
1083  if (HAS_POLES) { /* this is a hack to terrains set with not frizzed
1084  oceans*/
1085  make_polar_land(); /* make extra land at poles*/
1086  }
1087 
1088  create_placed_map(); // here it means land terrains to be placed
1090  if (MAPGEN_FRACTURE == wld.map.server.generator) {
1092  } else {
1093  make_relief(); // base relief on map
1094  }
1095  make_terrains(); // place all exept mountains and hill
1097 
1098  make_rivers(); // use a new placed_map. destroy older before call
1099 }
1100 
1104 static bool is_tiny_island(struct tile *ptile)
1105 {
1106  struct terrain *pterrain = tile_terrain(ptile);
1107 
1108  if (is_ocean(pterrain) || pterrain->property[MG_FROZEN] > 0) {
1109  /* The arctic check is needed for iso-maps: the poles may not have
1110  * any cardinally adjacent land tiles, but that's okay. */
1111  return false;
1112  }
1113 
1114  adjc_iterate(&(wld.map), ptile, tile1)
1115  {
1116  /* This was originally a cardinal_adjc_iterate, which seemed to cause
1117  * two or three problems. /MSS */
1118  if (!is_ocean_tile(tile1)) {
1119  return false;
1120  }
1121  }
1123 
1124  return true;
1125 }
1126 
1132 static void remove_tiny_islands()
1133 {
1134  whole_map_iterate(&(wld.map), ptile)
1135  {
1136  if (is_tiny_island(ptile)) {
1137  struct terrain *shallow = most_shallow_ocean(
1138  terrain_has_flag(tile_terrain(ptile), TER_FROZEN));
1139 
1140  fc_assert_ret(nullptr != shallow);
1141  tile_set_terrain(ptile, shallow);
1142  extra_type_by_cause_iterate(EC_ROAD, priver)
1143  {
1144  if (tile_has_extra(ptile, priver)
1145  && road_has_flag(extra_road_get(priver), RF_RIVER)) {
1146  tile_extra_rm_apply(ptile, priver);
1147  }
1148  }
1150  tile_set_continent(ptile, 0);
1151  }
1152  }
1154 }
1155 
1160 static void print_mapgen_map()
1161 {
1162  int terrain_counts[terrain_count()];
1163  int total = 0, ocean = 0;
1164 
1165  terrain_type_iterate(pterrain)
1166  {
1167  terrain_counts[terrain_index(pterrain)] = 0;
1168  }
1170 
1171  whole_map_iterate(&(wld.map), ptile)
1172  {
1173  struct terrain *pterrain = tile_terrain(ptile);
1174 
1175  terrain_counts[terrain_index(pterrain)]++;
1176  if (is_ocean(pterrain)) {
1177  ocean++;
1178  }
1179  total++;
1180  }
1182 
1183  qDebug("map settings:");
1184  qDebug(" %-20s : %5d%%", "mountain_pct", mountain_pct);
1185  qDebug(" %-20s : %5d%%", "desert_pct", desert_pct);
1186  qDebug(" %-20s : %5d%%", "forest_pct", forest_pct);
1187  qDebug(" %-20s : %5d%%", "jungle_pct", jungle_pct);
1188  qDebug(" %-20s : %5d%%", "swamp_pct", swamp_pct);
1189 
1190  qDebug("map statistics:");
1191 
1192  // avoid div by 0
1193  total = qMax(1, total);
1194  ocean = qMax(1, ocean);
1195  terrain_type_iterate(pterrain)
1196  {
1197  if (is_ocean(pterrain)) {
1198  qDebug(" %-20s : %6d %5.1f%% (ocean: %5.1f%%)",
1199  terrain_rule_name(pterrain),
1200  terrain_counts[terrain_index(pterrain)],
1201  static_cast<float>(terrain_counts[terrain_index(pterrain)])
1202  * 100 / total,
1203  static_cast<float>(terrain_counts[terrain_index(pterrain)])
1204  * 100 / ocean);
1205  } else {
1206  fc_assert_ret_msg(total - ocean, "Div by zero");
1207  qDebug(" %-20s : %6d %5.1f%% (land: %5.1f%%)",
1208  terrain_rule_name(pterrain),
1209  terrain_counts[terrain_index(pterrain)],
1210  static_cast<float>(terrain_counts[terrain_index(pterrain)])
1211  * 100 / total,
1212  static_cast<float>(terrain_counts[terrain_index(pterrain)])
1213  * 100 / (total - ocean));
1214  }
1215  }
1217 }
1218 
1232 bool map_generate(bool autosize, struct unit_type *initial_unit)
1233 {
1234  auto rstate = fc_rand_state();
1235 
1236  if (wld.map.server.seed_setting == 0) {
1237  // Create a random map seed.
1239  } else {
1240  fc_srand(wld.map.server.seed_setting);
1241  }
1242  wld.map.server.seed = wld.map.server.seed_setting;
1243 
1244  /* don't generate tiles with mapgen == MAPGEN_SCENARIO as we've loaded *
1245  them from file.
1246  Also, don't delete (the handcrafted!) tiny islands in a scenario */
1247  if (wld.map.server.generator != MAPGEN_SCENARIO) {
1248  wld.map.server.have_huts = false;
1249  wld.map.server.have_resources = false;
1250  river_types_init();
1251 
1252  generator_init_topology(autosize);
1253  // Map can be already allocated, if we failed first map generation
1254  if (map_is_empty()) {
1256  }
1258  // if one mapgenerator fails, it will choose another mapgenerator
1259  // with a lower number to try again
1260 
1261  // create a temperature map
1262  create_tmap(false);
1263 
1264  if (MAPGEN_FAIR == wld.map.server.generator
1265  && !map_generate_fair_islands()) {
1266  wld.map.server.generator = MAPGEN_ISLAND;
1267  }
1268 
1269  if (MAPGEN_ISLAND == wld.map.server.generator
1270  && !map_generate_island()) {
1271  wld.map.server.generator = MAPGEN_FRACTAL;
1272  }
1273 
1274  if (MAPGEN_FRACTAL == wld.map.server.generator) {
1276  }
1277 
1278  if (MAPGEN_RANDOM == wld.map.server.generator) {
1279  make_random_hmap();
1280  }
1281 
1282  if (MAPGEN_FRACTURE == wld.map.server.generator) {
1284  }
1285 
1286  // if hmap only generator make anything else
1287  if (MAPGEN_RANDOM == wld.map.server.generator
1288  || MAPGEN_FRACTAL == wld.map.server.generator
1289  || MAPGEN_FRACTURE == wld.map.server.generator) {
1290  make_land();
1291  delete[] height_map;
1292  height_map = nullptr;
1293  }
1294  if (!wld.map.server.tinyisles) {
1296  }
1297 
1299 
1300  // Continent numbers must be assigned before regenerate_lakes()
1302 
1303  // Turn small oceans into lakes.
1304  regenerate_lakes();
1305  } else {
1307  }
1308 
1309  // create a temperature map if it was not done before
1310  if (!temperature_is_initialized()) {
1311  create_tmap(false);
1312  }
1313 
1314  // some scenarios already provide specials
1315  if (!wld.map.server.have_resources) {
1316  add_resources(wld.map.server.riches);
1317  }
1318 
1319  if (!wld.map.server.have_huts) {
1320  make_huts(wld.map.server.huts * map_num_tiles() / 1000);
1321  }
1322 
1323  // restore previous random state:
1324  fc_rand_set_state(rstate);
1325 
1326  /* We don't want random start positions in a scenario which already
1327  * provides them. */
1328  if (0 == map_startpos_count()) {
1329  enum map_startpos mode = MAPSTARTPOS_ALL;
1330 
1331  switch (wld.map.server.generator) {
1332  case MAPGEN_FAIR:
1333  fc_assert_msg(false, "Fair island generator failed to allocated "
1334  "start positions!");
1335  break;
1336  case MAPGEN_SCENARIO:
1337  case MAPGEN_RANDOM:
1338  case MAPGEN_FRACTURE:
1339  mode = wld.map.server.startpos;
1340  break;
1341  case MAPGEN_FRACTAL:
1342  if (wld.map.server.startpos == MAPSTARTPOS_DEFAULT) {
1343  qDebug("Map generator chose startpos=ALL");
1344  mode = MAPSTARTPOS_ALL;
1345  } else {
1346  mode = wld.map.server.startpos;
1347  }
1348  break;
1349  case MAPGEN_ISLAND:
1350  switch (wld.map.server.startpos) {
1351  case MAPSTARTPOS_DEFAULT:
1352  case MAPSTARTPOS_VARIABLE:
1353  qDebug("Map generator chose startpos=SINGLE");
1354  // fallthrough
1355  case MAPSTARTPOS_SINGLE:
1356  mode = MAPSTARTPOS_SINGLE;
1357  break;
1358  default:
1359  qDebug("Map generator chose startpos=2or3");
1360  // fallthrough
1361  case MAPSTARTPOS_2or3:
1362  mode = MAPSTARTPOS_2or3;
1363  break;
1364  }
1365  break;
1366  }
1367 
1368  for (;;) {
1369  bool success;
1370 
1371  success = create_start_positions(mode, initial_unit);
1372  if (success) {
1373  wld.map.server.startpos = mode;
1374  break;
1375  }
1376 
1377  switch (mode) {
1378  case MAPSTARTPOS_SINGLE:
1379  qDebug("Falling back to startpos=2or3");
1380  mode = MAPSTARTPOS_2or3;
1381  continue;
1382  case MAPSTARTPOS_2or3:
1383  qDebug("Falling back to startpos=ALL");
1384  mode = MAPSTARTPOS_ALL;
1385  break;
1386  case MAPSTARTPOS_ALL:
1387  qDebug("Falling back to startpos=VARIABLE");
1388  mode = MAPSTARTPOS_VARIABLE;
1389  break;
1390  default:
1391  qCritical(_("The server couldn't allocate starting positions."));
1392  destroy_tmap();
1393  return false;
1394  }
1395  }
1396  }
1397 
1398  // destroy temperature map
1399  destroy_tmap();
1400 
1401  print_mapgen_map();
1402 
1403  return true;
1404 }
1405 
1411 {
1412  int polar =
1413  2 * ICE_BASE_LEVEL * wld.map.server.landpercent / MAX_COLATITUDE;
1414  float mount_factor = (100.0 - polar - 30 * 0.8) / 10000;
1415  float factor = (100.0 - polar - wld.map.server.steepness * 0.8) / 10000;
1416 
1417  mountain_pct = mount_factor * wld.map.server.steepness * 90;
1418 
1419  // 27 % if wetness == 50 &
1420  forest_pct = factor * (wld.map.server.wetness * 40 + 700);
1421  jungle_pct =
1424 
1425  // 3 - 11 %
1426  river_pct = (100 - polar) * (3 + wld.map.server.wetness / 12) / 100;
1427 
1428  // 7 % if wetness == 50 && temperature == 50
1429  swamp_pct = factor
1430  * MAX(0, (wld.map.server.wetness * 12 - 150
1431  + wld.map.server.temperature * 10));
1432  desert_pct = factor
1433  * MAX(0, (wld.map.server.temperature * 15 - 250
1434  + (100 - wld.map.server.wetness) * 10));
1435 }
1436 
1441 static bool near_safe_tiles(struct tile *ptile)
1442 {
1443  square_iterate(&(wld.map), ptile, 1, tile1)
1444  {
1445  if (!terrain_has_flag(tile_terrain(tile1), TER_UNSAFE_COAST)) {
1446  return true;
1447  }
1448  }
1450 
1451  return false;
1452 }
1453 
1458 static void make_huts(int number)
1459 {
1460  int count = 0;
1461  struct tile *ptile;
1462 
1463  create_placed_map(); // here it means placed huts
1464 
1465  while (number > 0 && count++ < map_num_tiles() * 2) {
1466  // Add a hut. But not on a polar area, or too close to another hut.
1468  struct extra_type *phut = rand_extra_for_tile(ptile, EC_HUT, true);
1469 
1470  number--;
1471  if (phut != nullptr) {
1472  tile_add_extra(ptile, phut);
1473  }
1474  set_placed_near_pos(ptile, 3);
1475  }
1476  }
1478 }
1479 
1484 static bool is_resource_close(const struct tile *ptile)
1485 {
1486  square_iterate(&(wld.map), ptile, 1, tile1)
1487  {
1488  if (nullptr != tile_resource(tile1)) {
1489  return true;
1490  }
1491  }
1493 
1494  return false;
1495 }
1496 
1500 static void add_resources(int prob)
1501 {
1502  whole_map_iterate(&(wld.map), ptile)
1503  {
1504  const struct terrain *pterrain = tile_terrain(ptile);
1505 
1506  if (is_resource_close(ptile) || fc_rand(1000) >= prob) {
1507  continue;
1508  }
1509  if (!is_ocean(pterrain) || near_safe_tiles(ptile)
1510  || wld.map.server.ocean_resources) {
1511  int i = 0;
1512  struct extra_type **r;
1513 
1514  for (r = pterrain->resources; *r; r++) {
1515  /* This is a standard way to get a random element from the
1516  * pterrain->resources list, without computing its length in
1517  * advance. Note that if *(pterrain->resources) == nullptr, then
1518  * this loop is a no-op. */
1519  if ((*r)->generated) {
1520  if (0 == fc_rand(++i)) {
1521  tile_set_resource(ptile, *r);
1522  }
1523  }
1524  }
1525  }
1526  }
1528 
1529  wld.map.server.have_resources = true;
1530 }
1531 
1532 /*************************************************************************/
1533 
1537 static void river_types_init()
1538 {
1539  river_type_count = 0;
1540 
1541  extra_type_by_cause_iterate(EC_ROAD, priver)
1542  {
1543  if (road_has_flag(extra_road_get(priver), RF_RIVER)
1544  && priver->generated) {
1545  river_types[river_type_count++] = priver;
1546  }
1547  }
1549 }
struct extra_type * rand_extra_for_tile(struct tile *ptile, enum extra_cause cause, bool generated)
Return random extra type for given cause that is native to the tile.
Definition: extras.cpp:242
#define extra_road_get(_e_)
Definition: extras.h:171
#define extra_type_by_cause_iterate_end
Definition: extras.h:307
#define extra_type_by_cause_iterate(_cause, _extra)
Definition: extras.h:299
bool map_generate_fair_islands()
Build a map using generator 'FAIR'.
#define MAX_ROAD_TYPES
Definition: fc_types.h:44
#define _(String)
Definition: fcintl.h:50
void make_fracture_hmap()
Fracture map generator.
void make_fracture_relief()
make_fracture_relief() Goes through a couple of iterations.
int hmap_mountain_level
Definition: fracture_map.h:25
#define MG_UNUSED
Definition: fracture_map.h:29
int hmap_shore_level
Definition: height_map.cpp:24
int * height_map
Definition: height_map.cpp:23
struct world wld
Definition: game.cpp:48
void make_random_hmap()
Create uncorrelated rand map and do some call to smoth to correlate it a little and create randoms sh...
Definition: height_map.cpp:99
void renormalize_hmap_poles()
Invert (most of) the effects of normalize_hmap_poles so that we have accurate heights for texturing t...
Definition: height_map.cpp:77
void normalize_hmap_poles()
Lower the land near the map edges and (optionally) the polar region to avoid too much land there.
Definition: height_map.cpp:59
bool area_is_too_flat(struct tile *ptile, int thill, int my_height)
We don't want huge areas of grass/plains, so we put in a hill here and there, where it gets too 'clea...
Definition: height_map.cpp:285
void make_pseudofractal_hmap()
Generator 5 makes earthlike worlds with one or more large continents and a scattering of smaller isla...
Definition: height_map.cpp:203
#define H_UNIT
Definition: height_map.h:17
#define hmap_max_level
Definition: height_map.h:30
#define hmap(_tile)
Definition: height_map.h:14
bool map_generate_island()
Generate a map with the ISLAND family of generators.
Definition: islands.cpp:574
#define fc_assert_msg(condition, message,...)
Definition: log.h:96
#define fc_assert_ret(condition)
Definition: log.h:112
#define fc_assert_exit_msg(condition, message,...)
Definition: log.h:135
#define fc_assert(condition)
Definition: log.h:89
#define fc_assert_ret_msg(condition, message,...)
Definition: log.h:129
#define fc_assert_ret_val(condition, val)
Definition: log.h:114
#define fc_assert_action(condition, action)
Definition: log.h:104
#define log_debug(message,...)
Definition: log.h:65
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
int map_startpos_count()
Is there start positions set for map.
Definition: map.cpp:1518
void main_map_allocate()
Allocate main map and related global structures.
Definition: map.cpp:487
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
#define adjc_iterate_end
Definition: map.h:358
#define MAP_INDEX_SIZE
Definition: map.h:91
#define square_iterate(nmap, center_tile, radius, tile_itr)
Definition: map.h:312
#define cardinal_adjc_iterate_end
Definition: map.h:384
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition: map.h:351
#define cardinal_adjc_dir_iterate_end
Definition: map.h:391
#define square_iterate_end
Definition: map.h:315
#define cardinal_adjc_iterate(nmap, center_tile, itr_tile)
Definition: map.h:380
#define whole_map_iterate(_map, _tile)
Definition: map.h:473
#define cardinal_adjc_dir_base_iterate_end
Definition: map.h:399
#define cardinal_adjc_dir_base_iterate(nmap, center_tile, dir_itr)
Definition: map.h:394
#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
@ MAPGEN_SCENARIO
Definition: map_types.h:43
@ MAPGEN_FRACTURE
Definition: map_types.h:48
@ MAPGEN_ISLAND
Definition: map_types.h:46
@ MAPGEN_FAIR
Definition: map_types.h:47
@ MAPGEN_FRACTAL
Definition: map_types.h:45
@ MAPGEN_RANDOM
Definition: map_types.h:44
map_startpos
Definition: map_types.h:51
@ MAPSTARTPOS_VARIABLE
Definition: map_types.h:56
@ MAPSTARTPOS_2or3
Definition: map_types.h:54
@ MAPSTARTPOS_ALL
Definition: map_types.h:55
@ MAPSTARTPOS_DEFAULT
Definition: map_types.h:52
@ MAPSTARTPOS_SINGLE
Definition: map_types.h:53
static int hmap_low_level
Definition: mapgen.cpp:103
#define NUM_TEST_FUNCTIONS
Definition: mapgen.cpp:617
int jungle_pct
Definition: mapgen.cpp:97
static void river_types_init()
Initialize river types array.
Definition: mapgen.cpp:1537
static int river_test_adjacent_swamp(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Help function used in make_river().
Definition: mapgen.cpp:570
static int river_test_height_map(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Help function used in make_river().
Definition: mapgen.cpp:588
static struct tile * rand_map_pos_characteristic(wetness_c wc, temperature_type tc, miscellaneous_c mc)
Return random map coordinates which have some conditions and which are not yet placed on pmap.
Definition: mapgen.cpp:180
int mountain_pct
Definition: mapgen.cpp:96
void make_polar()
Add frozen tiles in the arctic zone.
Definition: mapgen.cpp:258
static void make_rivers()
Calls make_river until there are enough river tiles on the map.
Definition: mapgen.cpp:840
int desert_pct
Definition: mapgen.cpp:94
static void adjust_terrain_param()
Convert parameters from the server into terrains percents parameters for the generators.
Definition: mapgen.cpp:1410
int forest_pct
Definition: mapgen.cpp:93
#define RIVERS_MAXTRIES
Definition: mapgen.cpp:50
static void make_relief()
make_relief() will convert all squares that are higher than thill to mountains and hills.
Definition: mapgen.cpp:217
static void print_mapgen_map()
Debugging function to print information about the map that's been generated.
Definition: mapgen.cpp:1160
static void remove_tiny_islands()
Removes all 1x1 islands (sets them to ocean).
Definition: mapgen.cpp:1132
struct extra_type * river_types[MAX_ROAD_TYPES]
Definition: mapgen.cpp:43
#define map_pos_is_low(ptile)
Definition: mapgen.cpp:111
#define ini_hmap_low_level()
Definition: mapgen.cpp:104
static bool test_miscellaneous(const struct tile *ptile, miscellaneous_c c)
Checks if the given location satisfy some miscellaneous condition.
Definition: mapgen.cpp:139
static int river_test_adjacent_ocean(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Help function used in make_river().
Definition: mapgen.cpp:523
static void river_blockmark(struct river_map *privermap, struct tile *ptile)
Called from make_river.
Definition: mapgen.cpp:598
static void make_huts(int number)
This function spreads out huts on the map, a position can be used for a hut if there isn't another hu...
Definition: mapgen.cpp:1458
static bool is_tiny_island(struct tile *ptile)
Returns if this is a 1x1 island.
Definition: mapgen.cpp:1104
int river_type_count
Definition: mapgen.cpp:44
#define PLACE_ONE_TYPE(count, alternate, ter, wc, tc, mc, weight)
This place randomly a cluster of terrains with some characteristics.
Definition: mapgen.cpp:394
static int river_test_adjacent_highlands(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Help function used in make_river().
Definition: mapgen.cpp:543
static bool near_safe_tiles(struct tile *ptile)
Return TRUE if a safe tile is in a radius of 1.
Definition: mapgen.cpp:1441
static bool ok_for_separate_poles(struct tile *ptile)
If separatepoles is set, return false if this tile has to keep ocean.
Definition: mapgen.cpp:281
miscellaneous_c
Definition: mapgen.cpp:113
@ MC_LOW
Definition: mapgen.cpp:113
@ MC_NLOW
Definition: mapgen.cpp:113
@ MC_NONE
Definition: mapgen.cpp:113
static bool condition_filter(const struct tile *ptile, const void *data)
A filter function to be passed to rand_map_pos_filtered().
Definition: mapgen.cpp:166
bool test_wetness(const struct tile *ptile, wetness_c c)
These functions test for conditions used in rand_map_pos_characteristic.
Definition: mapgen.cpp:122
int swamp_pct
Definition: mapgen.cpp:95
static bool is_resource_close(const struct tile *ptile)
Return TRUE iff there's a resource within one tile of the given map position.
Definition: mapgen.cpp:1484
static void add_resources(int prob)
Add specials to the map with given probability (out of 1000).
Definition: mapgen.cpp:1500
static int river_test_highlands(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Help function used in make_river().
Definition: mapgen.cpp:513
static bool make_river(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Makes a river starting at (x, y).
Definition: mapgen.cpp:719
bool map_generate(bool autosize, struct unit_type *initial_unit)
See stdinhand.c for information on map generation methods.
Definition: mapgen.cpp:1232
static int river_test_rivergrid(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Help function used in make_river().
Definition: mapgen.cpp:503
static void make_land()
make land simply does it all based on a generated heightmap 1) with map.server.landpercent it generat...
Definition: mapgen.cpp:991
int river_pct
Definition: mapgen.cpp:98
static void make_plain(struct tile *ptile, int *to_be_placed)
A simple function that adds plains grassland or tundra to the current location.
Definition: mapgen.cpp:356
static struct test_func test_funcs[NUM_TEST_FUNCTIONS]
Definition: mapgen.cpp:618
void make_plains()
Make_plains converts all not yet placed terrains to plains (tundra, grass) used by generators 2-4.
Definition: mapgen.cpp:377
static int river_test_adjacent_river(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Help function used in make_river().
Definition: mapgen.cpp:533
static void make_polar_land()
Place untextured land at the poles on any tile that is not already covered with TER_FROZEN terrain.
Definition: mapgen.cpp:301
static int river_test_swamp(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Help function used in make_river().
Definition: mapgen.cpp:561
static void place_terrain(struct tile *ptile, int diff, struct terrain *pterrain, int *to_be_placed, wetness_c wc, temperature_type tc, miscellaneous_c mc)
Recursively generate terrains.
Definition: mapgen.cpp:323
static bool terrain_is_too_high(struct tile *ptile, int thill, int my_height)
We don't want huge areas of hill/mountains, so we put in a plains here and there, where it gets too '...
Definition: mapgen.cpp:199
static void make_terrains()
Make_terrains calls make_forest, make_dessert,etc with random free locations until there has been mad...
Definition: mapgen.cpp:415
static int river_test_blocked(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Help function used in make_river().
Definition: mapgen.cpp:481
wetness_c
Definition: mapgen.h:28
@ WC_NDRY
Definition: mapgen.h:28
@ WC_ALL
Definition: mapgen.h:28
@ WC_DRY
Definition: mapgen.h:28
#define map_pos_is_dry(ptile)
Conditions used mainly in rand_map_pos_characteristic()
Definition: mapgen.h:24
#define HAS_POLES
Definition: mapgen.h:15
void generator_init_topology(bool autosize)
This function sets sizes in a topology-specific way then calls map_init_topology().
int map_colatitude(const struct tile *ptile)
Returns the colatitude of this map position.
#define L_UNIT
#define COLD_LEVEL
#define ICE_BASE_LEVEL
#define TROPICAL_LEVEL
#define MAX_COLATITUDE
void map_set_placed(struct tile *ptile)
Mark tile terrain as placed.
bool not_placed(const struct tile *ptile)
Checks if land has not yet been placed on pmap at (x, y)
struct terrain * pick_ocean(int depth, bool frozen)
Picks an ocean terrain to match the given depth.
void create_placed_map()
Create a clean pmap.
void destroy_placed_map()
Free the pmap.
void set_all_ocean_tiles_placed()
Set all oceanics tiles in placed_map.
void set_placed_near_pos(struct tile *ptile, int dist)
Set all nearby tiles as placed on pmap.
struct terrain * most_shallow_ocean(bool frozen)
Return most shallow ocean terrain type.
void regenerate_lakes()
Regenerate all oceanic tiles for small water bodies as lakes.
struct terrain * pick_terrain_by_flag(enum terrain_flag_id flag)
Return a random terrain that has the specified flag.
void smooth_water_depth()
Makes a simple depth map for all ocean tiles based on their proximity to any land tiles and reassigne...
struct terrain * pick_terrain(enum mapgen_terrain_property target, enum mapgen_terrain_property prefer, enum mapgen_terrain_property avoid)
Pick a terrain based on the target property and a property to avoid.
void assign_continent_numbers()
Assigns continent and ocean numbers to all tiles, and set map.num_continents and map....
std::mt19937 & fc_rand_state()
Returns a reference to the current random generator state; eg for save/restore.
Definition: rand.cpp:123
void fc_rand_set_state(const std::mt19937 &state)
Replace current rand_state with user-supplied; eg for save/restore.
Definition: rand.cpp:129
void fc_srand(std::uint_fast32_t seed)
Initialize the generator; see comment at top of file.
Definition: rand.cpp:69
void fc_rand_seed(std::mt19937 &gen)
Seeds the given generator with a random value.
Definition: rand.cpp:113
#define fc_rand(_size)
Definition: rand.h:16
bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
Check if road provides effect.
Definition: road.cpp:367
int count_river_near_tile(const struct tile *ptile, const struct extra_type *priver)
Count tiles with any river near the tile.
Definition: road.cpp:290
int count_river_type_tile_card(const struct tile *ptile, const struct extra_type *priver, bool percentage)
Count tiles with river of specific type cardinally adjacent to the tile.
Definition: road.cpp:313
#define MIN(x, y)
Definition: shared.h:49
#define FC_INFINITY
Definition: shared.h:32
#define MAX(x, y)
Definition: shared.h:48
bool create_start_positions(enum map_startpos mode, struct unit_type *initial_unit)
where do the different nations start on the map? well this function tries to spread them out on the d...
Definition: startpos.cpp:310
Passed as data to rand_map_pos_filtered() by rand_map_pos_characteristic()
Definition: mapgen.cpp:156
miscellaneous_c mc
Definition: mapgen.cpp:159
wetness_c wc
Definition: mapgen.cpp:157
temperature_type tc
Definition: mapgen.cpp:158
struct civ_map::@39::@41 server
QBitArray blocked
Definition: mapgen.cpp:55
QBitArray ok
Definition: mapgen.cpp:56
int property[MG_COUNT]
Definition: terrain.h:232
struct extra_type ** resources
Definition: terrain.h:190
bool fatal
Definition: mapgen.cpp:614
int(* func)(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Definition: mapgen.cpp:612
Definition: tile.h:42
struct civ_map map
Definition: world_object.h:21
bool temperature_is_initialized()
Returns one line (given by the y coordinate) of the temperature map.
bool tmap_is(const struct tile *ptile, temperature_type tt)
Return true if the tile has tt temperature type.
void destroy_tmap()
Free the tmap.
bool is_temperature_type_near(const struct tile *ptile, temperature_type tt)
Return true if at least one tile has tt temperature type.
void create_tmap(bool real)
Initialize the temperature_map if arg is FALSE, create a dummy tmap == map_colatitude to be used if h...
int temperature_type
#define TT_COLD
#define TT_HOT
#define TT_FROZEN
#define TT_TROPICAL
#define TT_ALL
#define TT_NFROZEN
Terrain_type_id terrain_count()
Return the number of terrains.
Definition: terrain.cpp:93
const char * terrain_rule_name(const struct terrain *pterrain)
Return the (untranslated) rule name of the terrain.
Definition: terrain.cpp:184
int count_terrain_property_near_tile(const struct tile *ptile, bool cardinal_only, bool percentage, enum mapgen_terrain_property prop)
Return the number of adjacent tiles that have the given terrain property.
Definition: terrain.cpp:298
Terrain_type_id terrain_index(const struct terrain *pterrain)
Return the terrain index.
Definition: terrain.cpp:110
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 terrain_type_iterate(_p)
Definition: terrain.h:331
#define T_UNKNOWN
Definition: terrain.h:51
#define is_ocean(pterrain)
Definition: terrain.h:276
#define is_ocean_tile(ptile)
Definition: terrain.h:279
#define terrain_type_iterate_end
Definition: terrain.h:337
#define TERRAIN_OCEAN_DEPTH_MAXIMUM
Definition: terrain.h:234
#define terrain_has_flag(terr, flag)
Definition: terrain.h:260
void tile_add_extra(struct tile *ptile, const struct extra_type *pextra)
Adds extra to tile.
Definition: tile.cpp:974
void tile_set_terrain(struct tile *ptile, struct terrain *pterrain)
Set the given terrain at the specified tile.
Definition: tile.cpp:114
bool tile_has_river(const struct tile *ptile)
Tile has any river type.
Definition: tile.cpp:876
bool tile_extra_rm_apply(struct tile *ptile, struct extra_type *tgt)
Remove extra and adjust other extras accordingly.
Definition: tile.cpp:605
void tile_set_resource(struct tile *ptile, struct extra_type *presource)
Set the given resource at the specified tile.
Definition: tile.cpp:355
void tile_set_continent(struct tile *ptile, Continent_id val)
Set the continent ID of the tile.
Definition: tile.cpp:388
#define tile_index(_pt_)
Definition: tile.h:70
#define tile_resource(_tile)
Definition: tile.h:84
#define tile_terrain(_tile)
Definition: tile.h:93
#define TILE_XY(ptile)
Definition: tile.h:36
#define tile_continent(_tile)
Definition: tile.h:74
#define tile_has_extra(ptile, pextra)
Definition: tile.h:130