Freeciv-3.2
Loading...
Searching...
No Matches
mapgen.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <time.h>
22
23/* utility */
24#include "bitvector.h"
25#include "fcintl.h"
26#include "log.h"
27#include "maphand.h" /* assign_continent_numbers(), MAP_NCONT */
28#include "mem.h"
29#include "nation.h"
30#include "rand.h"
31#include "shared.h"
32
33/* common */
34#include "game.h"
35#include "map.h"
36#include "road.h"
37
38/* server/generator */
39#include "fracture_map.h"
40#include "height_map.h"
41#include "mapgen_topology.h"
42#include "mapgen_utils.h"
43#include "startpos.h"
44#include "temperature_map.h"
45
46#include "mapgen.h"
47
48static void make_huts(int number);
49static void add_resources(int prob);
50static void mapgenerator2(void);
51static void mapgenerator3(void);
52static void mapgenerator4(void);
53static bool map_generate_fair_islands(void);
54static void adjust_terrain_param(void);
55
56/* common variables for generator 2, 3 and 4 */
58 int isleindex, n, e, s, w;
59 long int totalmass;
60};
61
62/* define one terrain selection */
71
72
74static int river_type_count = 0;
75
76#define SPECLIST_TAG terrain_select
77#include "speclist.h"
78/* list iterator for terrain_select */
79#define terrain_select_list_iterate(tersel_list, ptersel) \
80 TYPED_LIST_ITERATE(struct terrain_select, tersel_list, ptersel)
81#define terrain_select_list_iterate_end \
82 LIST_ITERATE_END
83
84static struct terrain_select *tersel_new(int weight,
89 int wet_condition);
90static void tersel_free(struct terrain_select *ptersel);
91
92/* terrain selection lists for make_island() */
93static struct {
94 bool init;
99} island_terrain = { .init = FALSE };
100
101static void island_terrain_init(void);
102static void island_terrain_free(void);
103
104static void fill_island(int coast, long int *bucket,
105 const struct terrain_select_list *tersel_list,
106 const struct gen234_state *const pstate);
107static bool make_island(int islemass, int starters,
108 struct gen234_state *pstate,
110
111#define RIVERS_MAXTRIES 32767
112/* This struct includes two dynamic bitvectors. They are needed to mark
113 tiles as blocked to prevent a river from falling into itself, and for
114 storing rivers temporarly. */
115struct river_map {
116 struct dbv blocked;
117 struct dbv ok;
118};
119
120static int river_test_blocked(struct river_map *privermap,
121 struct tile *ptile,
122 struct extra_type *priver);
123static int river_test_rivergrid(struct river_map *privermap,
124 struct tile *ptile,
125 struct extra_type *priver);
126static int river_test_highlands(struct river_map *privermap,
127 struct tile *ptile,
128 struct extra_type *priver);
130 struct tile *ptile,
131 struct extra_type *priver);
133 struct tile *ptile,
134 struct extra_type *priver);
136 struct tile *ptile,
137 struct extra_type *priver);
138static int river_test_swamp(struct river_map *privermap,
139 struct tile *ptile,
140 struct extra_type *priver);
142 struct tile *ptile,
143 struct extra_type *priver);
144static int river_test_height_map(struct river_map *privermap,
145 struct tile *ptile,
146 struct extra_type *priver);
147static void river_blockmark(struct river_map *privermap,
148 struct tile *ptile);
149static bool make_river(struct river_map *privermap,
150 struct tile *ptile,
151 struct extra_type *priver);
152static void make_rivers(void);
153
154static void river_types_init(void);
155
156/* Note: Only use after calling generator_init_topology() */
157#define HAS_POLES \
158 (MIN(COLD_LEVEL, 2 * ICE_BASE_LEVEL) > MIN_REAL_COLATITUDE(wld.map))
159
160/* These are the old parameters of terrains types in %
161 TODO: they depend on the hardcoded terrains */
162static int forest_pct = 0;
163static int desert_pct = 0;
164static int swamp_pct = 0;
165static int mountain_pct = 0;
166static int jungle_pct = 0;
167static int river_pct = 0;
168
169/**********************************************************************/
172/* WETNESS */
173
174/* necessary condition of deserts placement */
175#define map_pos_is_dry(ptile) \
176 (map_colatitude((ptile)) <= DRY_MAX_LEVEL \
177 && map_colatitude((ptile)) > DRY_MIN_LEVEL \
178 && count_terrain_class_near_tile(&(wld.map), (ptile), \
179 FALSE, TRUE, TC_OCEAN) <= 35)
180typedef enum { WC_ALL = 200, WC_DRY, WC_NDRY } wetness_c;
181
182/* MISCELANEOUS (OTHER CONDITIONS) */
183
184/* necessary condition of swamp placement */
185static int hmap_low_level = 0;
186#define ini_hmap_low_level() \
187{ \
188hmap_low_level = (4 * swamp_pct * \
189 (hmap_max_level - hmap_shore_level)) / 100 + hmap_shore_level; \
190}
191/* should be used after having hmap_low_level initialized */
192#define map_pos_is_low(ptile) ((hmap((ptile)) < hmap_low_level))
193
195
196/**************************************************************************
197 These functions test for conditions used in rand_map_pos_characteristic()
198**************************************************************************/
199
200/**********************************************************************/
203static bool test_wetness(const struct tile *ptile, wetness_c c)
204{
205 switch (c) {
206 case WC_ALL:
207 return TRUE;
208 case WC_DRY:
209 return map_pos_is_dry(ptile);
210 case WC_NDRY:
211 return !map_pos_is_dry(ptile);
212 }
213 log_error("Invalid wetness_c %d", c);
214 return FALSE;
215}
216
217/**********************************************************************/
220static bool test_miscellaneous(const struct tile *ptile, miscellaneous_c c)
221{
222 switch (c) {
223 case MC_NONE:
224 return TRUE;
225 case MC_LOW:
226 return map_pos_is_low(ptile);
227 case MC_NLOW:
228 return !map_pos_is_low(ptile);
229 }
230 log_error("Invalid miscellaneous_c %d", c);
231 return FALSE;
232}
233
234/**************************************************************************
235 Passed as data to rand_map_pos_filtered() by rand_map_pos_characteristic()
236**************************************************************************/
242
243/**********************************************************************/
247static bool condition_filter(const struct tile *ptile, const void *data)
248{
249 const struct DataFilter *filter = data;
250
251 return not_placed(ptile)
252 && tmap_is(ptile, filter->tc)
253 && test_wetness(ptile, filter->wc)
254 && test_miscellaneous(ptile, filter->mc);
255}
256
257/**********************************************************************/
264 miscellaneous_c mc )
265{
266 struct DataFilter filter = { .wc = wc, .tc = tc, .mc = mc };
267
268 return rand_map_pos_filtered(&(wld.map), &filter, condition_filter);
269}
270
271/**********************************************************************/
277static bool terrain_is_too_high(struct tile *ptile,
278 int thill, int my_height)
279{
280 square_iterate(&(wld.map), ptile, 1, tile1) {
282 return FALSE;
283 }
285 return TRUE;
286}
287
288/**********************************************************************/
294static void make_relief(void)
295{
296 /* Calculate the mountain level. map.server.mountains specifies the
297 * percentage of land that is turned into hills and mountains. */
299 * (100 - wld.map.server.steepness))
300 / 100 + hmap_shore_level);
301
302 whole_map_iterate(&(wld.map), ptile) {
303 if (not_placed(ptile)
304 && ((hmap_mountain_level < hmap(ptile)
305 && (fc_rand(10) > 5
307 hmap(ptile))))
308 || area_is_too_flat(ptile, hmap_mountain_level, hmap(ptile)))) {
309 if (tmap_is(ptile, TT_HOT)) {
310 /* Prefer hills to mountains in hot regions. */
311 tile_set_terrain(ptile,
314 } else {
315 /* Prefer mountains hills to in cold regions. */
316 tile_set_terrain(ptile,
318 fc_rand(10) < 8 ? MG_GREEN : MG_UNUSED));
319 }
320 map_set_placed(ptile);
321 }
323}
324
325/**********************************************************************/
331static void make_polar(void)
332{
334
335 whole_map_iterate(&(wld.map), ptile) {
336 if (tmap_is(ptile, TT_FROZEN)
337 || (tmap_is(ptile, TT_COLD)
338 && (fc_rand(10) > 7)
339 && is_temperature_type_near(ptile, TT_FROZEN))) {
340 if (ocean) {
341 tile_set_terrain(ptile, ocean);
342 } else {
343 tile_set_terrain(ptile,
345 }
346 }
348}
349
350/**********************************************************************/
353static bool ok_for_separate_poles(struct tile *ptile)
354{
356 return TRUE;
357 }
358 adjc_iterate(&(wld.map), ptile, tile1) {
359 if (tile_continent(tile1) > 0) {
360 return FALSE;
361 }
363 return TRUE;
364}
365
366/**********************************************************************/
371static void make_polar_land(void)
372{
374
375 whole_map_iterate(&(wld.map), ptile) {
376 if ((tile_terrain(ptile) == T_UNKNOWN
378 && ((tmap_is(ptile, TT_FROZEN)
379 && ok_for_separate_poles(ptile))
380 || (tmap_is(ptile, TT_COLD)
381 && fc_rand(10) > 7
383 && ok_for_separate_poles(ptile)))) {
385 tile_set_continent(ptile, 0);
386 }
388}
389
390/**********************************************************************/
393static void place_terrain(struct tile *ptile, int diff,
394 struct terrain *pterrain, int *to_be_placed,
395 wetness_c wc,
398{
399 if (*to_be_placed <= 0) {
400 return;
401 }
403 tile_set_terrain(ptile, pterrain);
404 map_set_placed(ptile);
405 (*to_be_placed)--;
406
407 cardinal_adjc_iterate(&(wld.map), ptile, tile1) {
408 /* Check L_UNIT and H_UNIT against 0. */
410 / MAX(L_UNIT, 1)
411 + abs(hmap(tile1) - (hmap(ptile))) / MAX(H_UNIT, 1));
412 if (not_placed(tile1)
413 && tmap_is(tile1, tc)
414 && test_wetness(tile1, wc)
416 && Delta < diff
417 && fc_rand(10) > 4) {
418 place_terrain(tile1, diff - 1 - Delta, pterrain,
419 to_be_placed, wc, tc, mc);
420 }
422}
423
424/**********************************************************************/
428static void make_plain(struct tile *ptile, int *to_be_placed )
429{
430 /* in cold place we get tundra instead */
431 if (tmap_is(ptile, TT_FROZEN)) {
432 tile_set_terrain(ptile,
434 } else if (tmap_is(ptile, TT_COLD)) {
435 tile_set_terrain(ptile,
437 } else {
438 tile_set_terrain(ptile,
440 }
441 map_set_placed(ptile);
442 (*to_be_placed)--;
443}
444
445/**********************************************************************/
449static void make_plains(void)
450{
451 int to_be_placed;
452
453 whole_map_iterate(&(wld.map), ptile) {
454 if (not_placed(ptile)) {
455 to_be_placed = 1;
456 make_plain(ptile, &to_be_placed);
457 }
459}
460
461/**********************************************************************/
464#define PLACE_ONE_TYPE(count, alternate, ter, wc, tc, mc, weight) \
465 if ((count) > 0) { \
466 struct tile *ptile; \
467 /* Place some terrains */ \
468 if ((ptile = rand_map_pos_characteristic((wc), (tc), (mc)))) { \
469 place_terrain(ptile, (weight), (ter), &(count), (wc),(tc), (mc)); \
470 } else { \
471 /* If rand_map_pos_temperature returns FALSE we may as well stop */ \
472 /* looking for this time and go to alternate type. */ \
473 (alternate) += (count); \
474 (count) = 0; \
475 } \
476 }
477
478/**********************************************************************/
485static void make_terrains(void)
486{
487 int total = 0;
488 int forests_count = 0;
489 int jungles_count = 0;
490 int deserts_count = 0;
491 int alt_deserts_count = 0;
492 int plains_count = 0;
493 int swamps_count = 0;
494
495 whole_map_iterate(&(wld.map), ptile) {
496 if (not_placed(ptile)) {
497 total++;
498 }
500
501 forests_count = total * forest_pct / (100 - mountain_pct);
502 jungles_count = total * jungle_pct / (100 - mountain_pct);
503
504 deserts_count = total * desert_pct / (100 - mountain_pct);
505 swamps_count = total * swamp_pct / (100 - mountain_pct);
506
507 /* grassland, tundra,arctic and plains is counted in plains_count */
510
511 /* the placement loop */
512 do {
513
522 WC_NDRY, TT_HOT, MC_LOW, 50);
529
530 /* make the plains and tundras */
531 if (plains_count > 0) {
532 struct tile *ptile;
533
534 /* Don't use any restriction here ! */
536 make_plain(ptile, &plains_count);
537 } else {
538 /* If rand_map_pos_temperature returns FALSE we may as well stop
539 * looking for plains. */
540 plains_count = 0;
541 }
542 }
543 } while (forests_count > 0 || jungles_count > 0
544 || deserts_count > 0 || alt_deserts_count > 0
545 || plains_count > 0 || swamps_count > 0 );
546}
547
548/**********************************************************************/
552 struct tile *ptile,
553 struct extra_type *priver)
554{
555 if (dbv_isset(&privermap->blocked, tile_index(ptile))) {
556 return 1;
557 }
558
559 /* any un-blocked? */
560 cardinal_adjc_iterate(&(wld.map), ptile, ptile1) {
561 if (!dbv_isset(&privermap->blocked, tile_index(ptile1))) {
562 return 0;
563 }
565
566 return 1; /* none non-blocked |- all blocked */
567}
568
569/**********************************************************************/
573 struct tile *ptile,
574 struct extra_type *priver)
575{
576 return (count_river_type_tile_card(&(wld.map), ptile, priver, FALSE) > 1)
577 ? 1 : 0;
578}
579
580/**********************************************************************/
584 struct tile *ptile,
585 struct extra_type *priver)
586{
587 return tile_terrain(ptile)->property[MG_MOUNTAINOUS];
588}
589
590/**********************************************************************/
594 struct tile *ptile,
595 struct extra_type *priver)
596{
597 return 100 - count_terrain_class_near_tile(&(wld.map), ptile,
598 TRUE, TRUE, TC_OCEAN);
599}
600
601/**********************************************************************/
605 struct tile *ptile,
606 struct extra_type *priver)
607{
608 return 100 - count_river_type_tile_card(&(wld.map), ptile, priver, TRUE);
609}
610
611/**********************************************************************/
615 struct tile *ptile,
616 struct extra_type *priver)
617{
618 int sum = 0;
619
620 adjc_iterate(&(wld.map), ptile, ptile2) {
621 sum += tile_terrain(ptile2)->property[MG_MOUNTAINOUS];
623
624 return sum;
625}
626
627/**********************************************************************/
631 struct tile *ptile,
632 struct extra_type *priver)
633{
634 return FC_INFINITY - tile_terrain(ptile)->property[MG_WET];
635}
636
637/**********************************************************************/
641 struct tile *ptile,
642 struct extra_type *priver)
643{
644 int sum = 0;
645
646 adjc_iterate(&(wld.map), ptile, ptile2) {
647 sum += tile_terrain(ptile2)->property[MG_WET];
649
650 return FC_INFINITY - sum;
651}
652
653/**********************************************************************/
657 struct tile *ptile,
658 struct extra_type *priver)
659{
660 return hmap(ptile);
661}
662
663/**********************************************************************/
667 struct tile *ptile)
668{
669 log_debug("Blockmarking (%d, %d) and adjacent tiles.", TILE_XY(ptile));
670
671 dbv_set(&privermap->blocked, tile_index(ptile));
672
673 cardinal_adjc_iterate(&(wld.map), ptile, ptile1) {
674 dbv_set(&privermap->blocked, tile_index(ptile1));
676}
677
678struct test_func {
679 int (*func)(struct river_map *privermap, struct tile *ptile, struct extra_type *priver);
680 bool fatal;
681};
682
683#define NUM_TEST_FUNCTIONS 9
695
696/**********************************************************************/
786static bool make_river(struct river_map *privermap, struct tile *ptile,
787 struct extra_type *priver)
788{
789 /* Comparison value for each tile surrounding the current tile. It is
790 * the suitability to continue a river to the tile in that direction;
791 * lower is better. However rivers may only run in cardinal directions;
792 * the other directions are ignored entirely. */
793 int rd_comparison_val[8];
794
795 bool rd_direction_is_valid[8];
796 int num_valid_directions, func_num, direction;
797
798 while (TRUE) {
799 /* Mark the current tile as river. */
800 dbv_set(&privermap->ok, tile_index(ptile));
801 log_debug("The tile at (%d, %d) has been marked as river in river_map.",
802 TILE_XY(ptile));
803
804 /* Test if the river is done. */
805 /* We arbitrarily make rivers end at the poles. */
806 if (count_river_near_tile(&(wld.map), ptile, priver) > 0
808 TRUE, TRUE, TC_OCEAN) > 0
809 || (tile_terrain(ptile)->property[MG_FROZEN] > 0
810 && map_colatitude(ptile) < 0.8 * COLD_LEVEL)) {
811
812 log_debug("The river ended at (%d, %d).", TILE_XY(ptile));
813 return TRUE;
814 }
815
816 /* Else choose a direction to continue the river. */
817 log_debug("The river did not end at (%d, %d). Evaluating directions...",
818 TILE_XY(ptile));
819
820 /* Mark all available cardinal directions as available. */
822 cardinal_adjc_dir_base_iterate(&(wld.map), ptile, dir) {
825
826 /* Test series that selects a direction for the river. */
828 int best_val = -1;
829
830 /* first get the tile values for the function */
831 cardinal_adjc_dir_iterate(&(wld.map), ptile, ptile1, dir) {
832 if (rd_direction_is_valid[dir]) {
834 ptile1, priver);
835 fc_assert_action(rd_comparison_val[dir] >= 0, continue);
836 if (best_val == -1) {
838 } else {
840 }
841 }
843 fc_assert_action(best_val != -1, continue);
844
845 /* should we abort? */
846 if (best_val > 0 && test_funcs[func_num].fatal) {
847 return FALSE;
848 }
849
850 /* mark the less attractive directions as invalid */
851 cardinal_adjc_dir_base_iterate(&(wld.map), ptile, dir) {
852 if (rd_direction_is_valid[dir]) {
853 if (rd_comparison_val[dir] != best_val) {
855 }
856 }
858 }
859
860 /* Directions evaluated with all functions. Now choose the best
861 direction before going to the next iteration of the while loop */
863 cardinal_adjc_dir_base_iterate(&(wld.map), ptile, dir) {
864 if (rd_direction_is_valid[dir]) {
866 }
868
869 if (num_valid_directions == 0) {
870 return FALSE; /* river aborted */
871 }
872
873 /* One or more valid directions: choose randomly. */
874 log_debug("mapgen.c: Had to let the random number"
875 " generator select a direction for a river.");
876 direction = fc_rand(num_valid_directions);
877 log_debug("mapgen.c: direction: %d", direction);
878
879 /* Find the direction that the random number generator selected. */
880 cardinal_adjc_dir_iterate(&(wld.map), ptile, tile1, dir) {
881 if (rd_direction_is_valid[dir]) {
882 if (direction > 0) {
883 direction--;
884 } else {
886 ptile = tile1;
887 break;
888 }
889 }
891 fc_assert_ret_val(direction == 0, FALSE);
892
893 } /* end while; (Make a river.) */
894}
895
896/**********************************************************************/
900static void make_rivers(void)
901{
902 struct tile *ptile;
903 struct terrain *pterrain;
904 struct river_map rivermap;
905 struct extra_type *road_river = NULL;
906
907 /* Formula to make the river density similar om different sized maps. Avoids
908 too few rivers on large maps and too many rivers on small maps. */
910 river_pct *
911 /* The size of the map (poles counted in river_pct). */
912 map_num_tiles() *
913 /* Rivers need to be on land only. */
915 /* Adjustment value. Tested by me. Gives no rivers with 'set
916 rivers 0', gives a reasonable amount of rivers with default
917 settings and as many rivers as possible with 'set rivers 100'. */
918 5325;
919
920 /* The number of river tiles that have been set. */
921 int current_riverlength = 0;
922
923 /* Counts the number of iterations (should increase with 1 during
924 every iteration of the main loop in this function).
925 Is needed to stop a potentially infinite loop. */
926 int iteration_counter = 0;
927
928 if (river_type_count <= 0) {
929 /* No river type available */
930 return;
931 }
932
933 create_placed_map(); /* needed bu rand_map_characteristic */
935
938
939 /* The main loop in this function. */
942
944 MC_NLOW))) {
945 break; /* No more spring places */
946 }
947 pterrain = tile_terrain(ptile);
948
949 /* Check if it is suitable to start a river on the current tile.
950 */
951 if (
952 /* Don't start a river on ocean. */
953 !is_ocean(pterrain)
954
955 /* Don't start a river on river. */
956 && !tile_has_river(ptile)
957
958 /* Don't start a river on a tile is surrounded by > 1 river +
959 ocean tile. */
960 && (count_river_near_tile(&(wld.map), ptile, NULL)
962 TRUE, FALSE, TC_OCEAN) <= 1)
963
964 /* Don't start a river on a tile that is surrounded by hills or
965 mountains unless it is hard to find somewhere else to start
966 it. */
968 MG_MOUNTAINOUS) < 90
969 || iteration_counter >= RIVERS_MAXTRIES / 10 * 5)
970
971 /* Don't start a river on hills unless it is hard to find
972 somewhere else to start it. */
973 && (pterrain->property[MG_MOUNTAINOUS] == 0
974 || iteration_counter >= RIVERS_MAXTRIES / 10 * 6)
975
976 /* Don't start a river on arctic unless it is hard to find
977 somewhere else to start it. */
978 && (pterrain->property[MG_FROZEN] == 0
979 || iteration_counter >= RIVERS_MAXTRIES / 10 * 8)
980
981 /* Don't start a river on desert unless it is hard to find
982 somewhere else to start it. */
983 && (pterrain->property[MG_DRY] == 0
984 || iteration_counter >= RIVERS_MAXTRIES / 10 * 9)) {
985
986 /* Reset river map before making a new river. */
987 dbv_clr_all(&rivermap.blocked);
989
991
993 if (oriver != road_river) {
996 dbv_set(&rivermap.blocked, tile_index(rtile));
997 }
999 }
1001
1002 log_debug("Found a suitable starting tile for a river at (%d, %d)."
1003 " Starting to make it.", TILE_XY(ptile));
1004
1005 /* Try to make a river. If it is OK, apply it to the map. */
1006 if (make_river(&rivermap, ptile, road_river)) {
1008 if (dbv_isset(&rivermap.ok, tile_index(ptile1))) {
1010
1012 /* We have to change the terrain to put a river here. */
1014 if (river_terrain != NULL) {
1016 }
1017 }
1018
1022 log_debug("Applied a river to (%d, %d).", TILE_XY(ptile1));
1023 }
1025 } else {
1026 log_debug("mapgen.c: A river failed. It might have gotten stuck "
1027 "in a helix.");
1028 }
1029 } /* end if; */
1031 log_debug("current_riverlength: %d; desirable_riverlength: %d; "
1032 "iteration_counter: %d",
1034 } /* end while; */
1035
1036 dbv_free(&rivermap.blocked);
1037 dbv_free(&rivermap.ok);
1038
1040}
1041
1042/**********************************************************************/
1047static void make_land(void)
1048{
1049 struct terrain *land_fill = NULL;
1050
1051 if (HAS_POLES) {
1053 }
1054
1055 /* Pick a non-ocean terrain just once and fill all land tiles with "
1056 * that terrain. We must set some terrain (and not T_UNKNOWN) so that "
1057 * continent number assignment works. */
1058 terrain_type_iterate(pterrain) {
1059 if (!is_ocean(pterrain) && !terrain_has_flag(pterrain, TER_NOT_GENERATED)) {
1060 land_fill = pterrain;
1061 break;
1062 }
1064
1066 "No land terrain type could be found for the purpose "
1067 "of temporarily filling in land tiles during map "
1068 "generation. This could be an error in Freeciv, or a "
1069 "mistake in the terrain.ruleset file. Please make sure "
1070 "there is at least one land terrain type in the "
1071 "ruleset, or use a different map generator. If this "
1072 "error persists, please report it at: %s", BUG_URL);
1073
1076 whole_map_iterate(&(wld.map), ptile) {
1077 tile_set_terrain(ptile, T_UNKNOWN); /* set as oceans count is used */
1078 if (hmap(ptile) < hmap_shore_level) {
1079 int depth = (hmap_shore_level - hmap(ptile)) * 100 / hmap_shore_level;
1080 int ocean = 0;
1081 int land = 0;
1082
1083 /* This is to make shallow connection between continents less likely */
1084 adjc_iterate(&(wld.map), ptile, other) {
1085 if (hmap(other) < hmap_shore_level) {
1086 ocean++;
1087 } else {
1088 land++;
1089 break;
1090 }
1092
1093 depth += 30 * (ocean - land) / MAX(1, (ocean + land));
1094
1095 depth = MIN(depth, TERRAIN_OCEAN_DEPTH_MAXIMUM);
1096
1097 /* Generate sea ice here, if ruleset supports it. Dummy temperature
1098 * map is sufficient for this. If ruleset doesn't support it,
1099 * use unfrozen ocean; make_polar_land() will later fill in with
1100 * land-based ice. Ice has a ragged margin. */
1101 {
1102 bool frozen = HAS_POLES
1103 && (tmap_is(ptile, TT_FROZEN)
1104 || (tmap_is(ptile, TT_COLD)
1105 && fc_rand(10) > 7
1107 struct terrain *pterrain = pick_ocean(depth, frozen);
1108
1109 if (frozen && !pterrain) {
1110 pterrain = pick_ocean(depth, FALSE);
1111 fc_assert(pterrain);
1112 }
1113 tile_set_terrain(ptile, pterrain);
1114 }
1115 } else {
1116 /* See note above for 'land_fill'. */
1118 }
1120
1121 if (HAS_POLES) {
1123 }
1124
1125 /* destroy old dummy temperature map ... */
1126 destroy_tmap();
1127 /* ... and create a real temperature map (needs hmap and oceans) */
1129
1130 if (HAS_POLES) { /* this is a hack to terrains set with not frizzed oceans*/
1131 make_polar_land(); /* make extra land at poles*/
1132 }
1133
1134 create_placed_map(); /* here it means land terrains to be placed */
1138 } else {
1139 make_relief(); /* base relief on map */
1140 }
1141 make_terrains(); /* place all exept mountains and hill */
1143
1144 make_rivers(); /* use a new placed_map. destroy older before call */
1145}
1146
1147/**********************************************************************/
1150static bool is_tiny_island(struct tile *ptile)
1151{
1152 struct terrain *pterrain = tile_terrain(ptile);
1153
1154 if (is_ocean(pterrain) || pterrain->property[MG_FROZEN] > 0) {
1155 /* The arctic check is needed for iso-maps: the poles may not have
1156 * any cardinally adjacent land tiles, but that's okay. */
1157 return FALSE;
1158 }
1159
1160 adjc_iterate(&(wld.map), ptile, tile1) {
1161 /* This was originally a cardinal_adjc_iterate, which seemed to cause
1162 * two or three problems. /MSS */
1163 if (!is_ocean_tile(tile1)) {
1164 return FALSE;
1165 }
1167
1168 return TRUE;
1169}
1170
1171/**********************************************************************/
1176static void remove_tiny_islands(void)
1177{
1178 whole_map_iterate(&(wld.map), ptile) {
1179 if (is_tiny_island(ptile)) {
1180 struct terrain *shallow
1182
1184 tile_set_terrain(ptile, shallow);
1186 if (tile_has_extra(ptile, priver)
1189 }
1191 tile_set_continent(ptile, 0);
1192 }
1194}
1195
1196/**********************************************************************/
1200static void print_mapgen_map(void)
1201{
1203 int total = 0, ocean = 0;
1204
1205 terrain_type_iterate(pterrain) {
1206 terrain_counts[terrain_index(pterrain)] = 0;
1208
1209 whole_map_iterate(&(wld.map), ptile) {
1210 struct terrain *pterrain = tile_terrain(ptile);
1211
1212 terrain_counts[terrain_index(pterrain)]++;
1213 if (is_ocean(pterrain)) {
1214 ocean++;
1215 }
1216 total++;
1218
1219 log_verbose("map settings:");
1220 log_verbose(" %-20s : %5d%%", "mountain_pct", mountain_pct);
1221 log_verbose(" %-20s : %5d%%", "desert_pct", desert_pct);
1222 log_verbose(" %-20s : %5d%%", "forest_pct", forest_pct);
1223 log_verbose(" %-20s : %5d%%", "jungle_pct", jungle_pct);
1224 log_verbose(" %-20s : %5d%%", "swamp_pct", swamp_pct);
1225
1226 log_verbose("map statistics:");
1227 terrain_type_iterate(pterrain) {
1228 if (is_ocean(pterrain)) {
1229 log_verbose(" %-20s : %6d %5.1f%% (ocean: %5.1f%%)",
1230 terrain_rule_name(pterrain),
1231 terrain_counts[terrain_index(pterrain)],
1232 (float) terrain_counts[terrain_index(pterrain)] * 100
1233 / total,
1234 (float) terrain_counts[terrain_index(pterrain)] * 100
1235 / ocean);
1236 } else {
1237 log_verbose(" %-20s : %6d %5.1f%% (land: %5.1f%%)",
1238 terrain_rule_name(pterrain),
1239 terrain_counts[terrain_index(pterrain)],
1240 (float) terrain_counts[terrain_index(pterrain)] * 100
1241 / total,
1242 (float) terrain_counts[terrain_index(pterrain)] * 100
1243 / (total - ocean));
1244 }
1246}
1247
1248/**********************************************************************/
1261bool map_fractal_generate(bool autosize, struct unit_type *initial_unit)
1262{
1263 /* save the current random state: */
1264 RANDOM_STATE rstate;
1266
1267 /* Call fc_rand() even when result is not needed to make sure
1268 * random state proceeds equally for random seeds and explicitly
1269 * set seed. */
1271
1272 if (wld.map.server.seed_setting == 0) {
1273 /* Create a "random" map seed. */
1275#ifdef FREECIV_TESTMATIC
1276 /* Log command to reproduce the mapseed */
1277 log_testmatic("set mapseed %d", wld.map.server.seed);
1278#else /* FREECIV_TESTMATICE */
1279 log_debug("Setting map.seed:%d", wld.map.server.seed);
1280#endif /* FREECIV_TESTMATIC */
1281 } else {
1283 }
1284
1285 rstate = fc_rand_state();
1286
1288
1289 /* don't generate tiles with mapgen == MAPGEN_SCENARIO as we've loaded *
1290 them from file.
1291 Also, don't delete (the handcrafted!) tiny islands in a scenario */
1295
1297 /* Map can be already allocated, if we failed first map generation */
1298 if (map_is_empty()) {
1300 }
1302 /* if one mapgenerator fails, it will choose another mapgenerator */
1303 /* with a lower number to try again */
1304
1305 /* create a temperature map */
1307
1311 }
1312
1314 /* initialise terrain selection lists used by make_island() */
1316
1317 /* 2 or 3 players per isle? */
1320 mapgenerator4();
1321 }
1324 /* Single player per isle. */
1325 mapgenerator3();
1326 }
1328 /* "Variable" single player. */
1329 mapgenerator2();
1330 }
1331
1332 /* free terrain selection lists used by make_island() */
1334 }
1335
1340 ? 0 : player_count()));
1341 }
1342
1346 ? player_count() / 4 : 0)));
1347 }
1348
1351 }
1352
1353 /* if hmap only generator make anything else */
1357
1358 make_land();
1360 height_map = NULL;
1361 }
1362 if (!wld.map.server.tinyisles) {
1364 }
1365
1367
1368 /* Continent numbers must be assigned before regenerate_lakes() */
1370
1371 /* Turn small oceans into lakes. */
1372 if (wld.map.num_oceans > 0) {
1374 }
1375
1376 } else {
1378 }
1379
1380 /* create a temperature map if it was not done before */
1383 }
1384
1385 /* some scenarios already provide specials */
1388 }
1389
1390 if (!wld.map.server.have_huts) {
1392 }
1393
1394 /* restore previous random state: */
1395 fc_rand_set_state(rstate);
1396
1397 /* We don't want random start positions in a scenario which already
1398 * provides them. */
1399 if (0 == map_startpos_count()) {
1400 enum map_startpos mode = MAPSTARTPOS_ALL;
1401
1402 switch (wld.map.server.generator) {
1403 case MAPGEN_FAIR:
1405 "Fair island generator failed to allocated "
1406 "start positions!");
1407 break;
1408 case MAPGEN_SCENARIO:
1409 case MAPGEN_RANDOM:
1410 case MAPGEN_FRACTURE:
1411 mode = wld.map.server.startpos;
1412 break;
1413 case MAPGEN_FRACTAL:
1415 log_verbose("Map generator chose startpos=ALL");
1416 mode = MAPSTARTPOS_ALL;
1417 } else {
1418 mode = wld.map.server.startpos;
1419 }
1420 break;
1421 case MAPGEN_ISLAND:
1422 switch (wld.map.server.startpos) {
1425 log_verbose("Map generator chose startpos=SINGLE");
1426
1428 case MAPSTARTPOS_SINGLE:
1429 mode = MAPSTARTPOS_SINGLE;
1430 break;
1431 default:
1432 log_verbose("Map generator chose startpos=2or3");
1433
1435 case MAPSTARTPOS_2or3:
1436 mode = MAPSTARTPOS_2or3;
1437 break;
1438 }
1439 break;
1440 }
1441
1442 for (;;) {
1443 bool success;
1444
1445 success = create_start_positions(mode, initial_unit);
1446 if (success) {
1447 wld.map.server.startpos = mode;
1448 break;
1449 }
1450
1451 switch (mode) {
1452 case MAPSTARTPOS_SINGLE:
1453 log_verbose("Falling back to startpos=2or3");
1454 mode = MAPSTARTPOS_2or3;
1455 continue;
1456 case MAPSTARTPOS_2or3:
1457 log_verbose("Falling back to startpos=ALL");
1458 mode = MAPSTARTPOS_ALL;
1459 break;
1460 case MAPSTARTPOS_ALL:
1461 log_verbose("Falling back to startpos=VARIABLE");
1462 mode = MAPSTARTPOS_VARIABLE;
1463 break;
1464 default:
1465 log_error(_("The server couldn't allocate starting positions."));
1466 destroy_tmap();
1467 return FALSE;
1468 }
1469 }
1470 }
1471
1472 /* destroy temperature map */
1473 destroy_tmap();
1474
1476
1477 return TRUE;
1478}
1479
1480/**********************************************************************/
1484static void adjust_terrain_param(void)
1485{
1487 float mount_factor = (100.0 - polar - 30 * 0.8) / 10000;
1488 float factor = (100.0 - polar - wld.map.server.steepness * 0.8) / 10000;
1489
1491
1492 /* 27 % if wetness == 50 & */
1493 forest_pct = factor * (wld.map.server.wetness * 40 + 700);
1495 / (MAX_COLATITUDE * 2);
1497
1498 /* 3 - 11 % */
1499 river_pct = (100 - polar) * (3 + wld.map.server.wetness / 12) / 100;
1500
1501 /* 7 % if wetness == 50 && temperature == 50 */
1502 swamp_pct = factor * MAX(0, (wld.map.server.wetness * 12 - 150
1503 + wld.map.server.temperature * 10));
1504 desert_pct = factor * MAX(0, (wld.map.server.temperature * 15 - 250
1505 + (100 - wld.map.server.wetness) * 10));
1506}
1507
1508/**********************************************************************/
1512static bool near_safe_tiles(struct tile *ptile)
1513{
1514 square_iterate(&(wld.map), ptile, 1, tile1) {
1516 return TRUE;
1517 }
1519
1520 return FALSE;
1521}
1522
1523/**********************************************************************/
1527static void make_huts(int number)
1528{
1529 int count = 0;
1530 struct tile *ptile;
1531
1532 create_placed_map(); /* here it means placed huts */
1533
1534 while (number > 0 && count++ < map_num_tiles() * 2) {
1535
1536 /* Add a hut. But not too close to another hut. */
1538 struct extra_type *phut = rand_extra_for_tile(ptile, EC_HUT, TRUE);
1539
1540 number--;
1541 if (phut != NULL) {
1542 tile_add_extra(ptile, phut);
1543 }
1544 set_placed_near_pos(ptile, 3);
1545 }
1546 }
1548}
1549
1550/**********************************************************************/
1554static bool is_resource_close(const struct tile *ptile)
1555{
1556 square_iterate(&(wld.map), ptile, 1, tile1) {
1557 if (NULL != tile_resource(tile1)) {
1558 return TRUE;
1559 }
1561
1562 return FALSE;
1563}
1564
1565/**********************************************************************/
1568static void add_resources(int prob)
1569{
1570 whole_map_iterate(&(wld.map), ptile) {
1571 const struct terrain *pterrain = tile_terrain(ptile);
1572
1573 if (is_resource_close(ptile) || fc_rand (1000) >= prob) {
1574 continue;
1575 }
1576 if (!is_ocean(pterrain) || near_safe_tiles(ptile)
1578 struct extra_type *res = pick_resource(pterrain);
1579
1580 if (NULL != res) {
1581 tile_set_resource(ptile, res);
1582 }
1583 }
1585
1587}
1588
1589/**********************************************************************/
1593 const struct gen234_state *const pstate)
1594{
1595 int xrnd, yrnd;
1596
1597 fc_assert_ret_val((pstate->e - pstate->w) > 0, NULL);
1599 fc_assert_ret_val((pstate->s - pstate->n) > 0, NULL);
1601
1602 xrnd = pstate->w + fc_rand(pstate->e - pstate->w);
1603 yrnd = pstate->n + fc_rand(pstate->s - pstate->n);
1604
1605 return native_pos_to_tile(&(wld.map), xrnd, yrnd);
1606}
1607
1608/**********************************************************************/
1615 int temp_condition,
1616 int wet_condition)
1617{
1618 struct terrain_select *ptersel = fc_malloc(sizeof(*ptersel));
1619
1620 ptersel->weight = weight;
1621 ptersel->target = target;
1622 ptersel->prefer = prefer;
1623 ptersel->avoid = avoid;
1624 ptersel->temp_condition = temp_condition;
1625 ptersel->wet_condition = wet_condition;
1626
1627 return ptersel;
1628}
1629
1630/**********************************************************************/
1634{
1635 if (ptersel != NULL) {
1637 }
1638}
1639
1640/**********************************************************************/
1643static void fill_island(int coast, long int *bucket,
1644 const struct terrain_select_list *tersel_list,
1645 const struct gen234_state *const pstate)
1646{
1647 int i, k, capac, total_weight = 0;
1649 long int failsafe;
1650
1651 if (*bucket <= 0 ) {
1652 return;
1653 }
1654
1655 /* must have at least one terrain selection given in tersel_list */
1656 fc_assert_ret(ntersel != 0);
1657
1658 capac = pstate->totalmass;
1659 i = *bucket / capac;
1660 i++;
1661 *bucket -= i * capac;
1662
1663 k = i;
1664 failsafe = i * (pstate->s - pstate->n) * (pstate->e - pstate->w);
1665 if (failsafe < 0) {
1666 failsafe = -failsafe;
1667 }
1668
1670 total_weight += ptersel->weight;
1672
1673 if (total_weight <= 0) {
1674 return;
1675 }
1676
1677 while (i > 0 && (failsafe--) > 0) {
1679
1680 if (tile_continent(ptile) != pstate->isleindex || !not_placed(ptile)) {
1681 continue;
1682 }
1683
1684 struct terrain_select *ptersel
1686
1687 if (fc_rand(total_weight) > ptersel->weight) {
1688 continue;
1689 }
1690
1691 if (!tmap_is(ptile, ptersel->temp_condition)
1692 || !test_wetness(ptile, ptersel->wet_condition)) {
1693 continue;
1694 }
1695
1696 struct terrain *pterrain = pick_terrain(ptersel->target, ptersel->prefer,
1697 ptersel->avoid);
1698
1699 /* The first condition helps make terrain more contiguous,
1700 the second lets it avoid the coast: */
1701 if ((i * 3 > k * 2
1702 || fc_rand(100) < 50
1703 || is_terrain_near_tile(&(wld.map), ptile, pterrain, FALSE))
1705 || fc_rand(100) < coast)) {
1706 tile_set_terrain(ptile, pterrain);
1707 map_set_placed(ptile);
1708
1709 log_debug("[fill_island] placed terrain '%s' at (%2d,%2d)",
1710 terrain_rule_name(pterrain), TILE_XY(ptile));
1711 }
1712
1713 if (!not_placed(ptile)) {
1714 i--;
1715 }
1716 }
1717}
1718
1719/**********************************************************************/
1722static bool island_river_mouth_suitability(const struct tile *ptile,
1723 const struct extra_type *priver)
1724{
1726
1729 TC_OCEAN);
1732 TC_OCEAN);
1734
1735 return (num_card_ocean == 1 && pct_adj_ocean <= 35
1736 && num_adj_river == 0);
1737}
1738
1739/**********************************************************************/
1743static bool island_river_suitability(const struct tile *ptile,
1744 const struct extra_type *priver)
1745{
1747
1751 TC_OCEAN);
1754 TC_OCEAN);
1756
1757 return (num_card_river == 1 && num_card_ocean == 0
1758 && pct_adj_ocean < 20 && pct_adj_river < 35
1759 /* The following expression helps with straightness,
1760 * ocean avoidance, and reduces forking. */
1761 && (pct_adj_river + pct_adj_ocean * 2) < fc_rand(25) + 25);
1762}
1763
1764/**********************************************************************/
1767static void fill_island_rivers(int coast, long int *bucket,
1768 const struct gen234_state *const pstate)
1769{
1770 long int failsafe, capac, i, k;
1771 struct tile *ptile;
1772
1773 if (*bucket <= 0) {
1774 return;
1775 }
1776 if (river_type_count <= 0) {
1777 return;
1778 }
1779
1780 capac = pstate->totalmass;
1781 i = *bucket / capac;
1782 i++;
1783 *bucket -= i * capac;
1784
1785 /* Generate 75% more rivers than generator 1 */
1786 i = (i * 175) / 100;
1787
1788 k = i;
1789 failsafe = i * (pstate->s - pstate->n) * (pstate->e - pstate->w) * 5;
1790 if (failsafe < 0) {
1791 failsafe = -failsafe;
1792 }
1793
1794 while (i > 0 && failsafe-- > 0) {
1795 struct extra_type *priver;
1796
1798 if (tile_continent(ptile) != pstate->isleindex
1799 || tile_has_river(ptile)) {
1800 continue;
1801 }
1802
1804
1805 if (test_wetness(ptile, WC_DRY) && fc_rand(100) < 50) {
1806 /* rivers don't like dry locations */
1807 continue;
1808 }
1809
1811 && (fc_rand(100) < coast || i == k))
1812 || island_river_suitability(ptile, priver)) {
1813 tile_add_extra(ptile, priver);
1814 i--;
1815 }
1816 }
1817}
1818
1819/**********************************************************************/
1823static bool is_near_land(struct tile *ptile)
1824{
1825 /* Note this function may sometimes be called on land tiles. */
1826 adjc_iterate(&(wld.map), ptile, tile1) {
1827 if (!is_ocean(tile_terrain(tile1))) {
1828 return TRUE;
1829 }
1831
1832 return FALSE;
1833}
1834
1835static long int checkmass;
1836
1837/**********************************************************************/
1841{
1842 int i = 0, xcur, ycur, nat_x, nat_y;
1843 struct tile *ptile;
1844
1845 ptile = rand_map_pos(&(wld.map));
1847
1848 /* this helps a lot for maps with high landmass */
1849 for (ycur = pstate->n, xcur = pstate->w;
1850 ycur < pstate->s && xcur < pstate->e;
1851 ycur++, xcur++) {
1852 struct tile *tile0 = native_pos_to_tile(&(wld.map), xcur, ycur);
1853 struct tile *tile1 = native_pos_to_tile(&(wld.map),
1854 xcur + nat_x - pstate->w,
1855 ycur + nat_y - pstate->n);
1856
1857 if (!tile0 || !tile1) {
1858 return FALSE;
1859 }
1860 if (hmap(tile0) != 0 && is_near_land(tile1)) {
1861 return FALSE;
1862 }
1863 }
1864
1865 for (ycur = pstate->n; ycur < pstate->s; ycur++) {
1866 for (xcur = pstate->w; xcur < pstate->e; xcur++) {
1867 struct tile *tile0 = native_pos_to_tile(&(wld.map), xcur, ycur);
1868 struct tile *tile1 = native_pos_to_tile(&(wld.map),
1869 xcur + nat_x - pstate->w,
1870 ycur + nat_y - pstate->n);
1871
1872 if (!tile0 || !tile1) {
1873 return FALSE;
1874 }
1875 if (hmap(tile0) != 0 && is_near_land(tile1)) {
1876 return FALSE;
1877 }
1878 }
1879 }
1880
1881 for (ycur = pstate->n; ycur < pstate->s; ycur++) {
1882 for (xcur = pstate->w; xcur < pstate->e; xcur++) {
1883 if (hmap(native_pos_to_tile(&(wld.map), xcur, ycur)) != 0) {
1884 struct tile *tile1 = native_pos_to_tile(&(wld.map),
1885 xcur + nat_x - pstate->w,
1886 ycur + nat_y - pstate->n);
1887
1888 checkmass--;
1889 if (checkmass <= 0) {
1890 log_error("mapgen.c: mass doesn't sum up.");
1891 return i != 0;
1892 }
1893
1896
1897 tile_set_continent(tile1, pstate->isleindex);
1898 i++;
1899 }
1900 }
1901 }
1902
1903 pstate->s += nat_y - pstate->n;
1904 pstate->e += nat_x - pstate->w;
1905 pstate->n = nat_y;
1906 pstate->w = nat_x;
1907
1908 return i != 0;
1909}
1910
1911/**********************************************************************/
1914static int count_card_adjc_elevated_tiles(struct tile *ptile)
1915{
1916 int count = 0;
1917
1918 cardinal_adjc_iterate(&(wld.map), ptile, tile1) {
1919 if (hmap(tile1) != 0) {
1920 count++;
1921 }
1923
1924 return count;
1925}
1926
1927/**********************************************************************/
1931{
1932 int i, nat_x, nat_y;
1933 long int tries = islemass*(2+islemass/20)+99;
1934 bool j;
1935 struct tile *ptile = native_pos_to_tile(&(wld.map),
1936 wld.map.xsize / 2, wld.map.ysize / 2);
1937
1938 memset(height_map, '\0', MAP_INDEX_SIZE * sizeof(*height_map));
1940 wld.map.xsize / 2, wld.map.ysize / 2)) = 1;
1941
1943 pstate->n = nat_y - 1;
1944 pstate->w = nat_x - 1;
1945 pstate->s = nat_y + 2;
1946 pstate->e = nat_x + 2;
1947 i = islemass - 1;
1948 while (i > 0 && tries-->0) {
1951
1952 if ((!near_singularity(ptile) || fc_rand(50) < 25 )
1953 && hmap(ptile) == 0 && count_card_adjc_elevated_tiles(ptile) > 0) {
1954 hmap(ptile) = 1;
1955 i--;
1956 if (nat_y >= pstate->s - 1 && pstate->s < wld.map.ysize - 2) {
1957 pstate->s++;
1958 }
1959 if (nat_x >= pstate->e - 1 && pstate->e < wld.map.xsize - 2) {
1960 pstate->e++;
1961 }
1962 if (nat_y <= pstate->n && pstate->n > 2) {
1963 pstate->n--;
1964 }
1965 if (nat_x <= pstate->w && pstate->w > 2) {
1966 pstate->w--;
1967 }
1968 }
1969 if (i < islemass / 10) {
1970 int xcur, ycur;
1971
1972 for (ycur = pstate->n; ycur < pstate->s; ycur++) {
1973 for (xcur = pstate->w; xcur < pstate->e; xcur++) {
1974 ptile = native_pos_to_tile(&(wld.map), xcur, ycur);
1975 if (hmap(ptile) == 0 && i > 0
1976 && count_card_adjc_elevated_tiles(ptile) == 4) {
1977 hmap(ptile) = 1;
1978 i--;
1979 }
1980 }
1981 }
1982 }
1983 }
1984 if (tries <= 0) {
1985 log_error("create_island ended early with %d/%d.", islemass-i, islemass);
1986 }
1987
1988 tries = map_num_tiles() / 4; /* on a 40x60 map, there are 2400 places */
1989 while (!(j = place_island(pstate)) && (--tries) > 0) {
1990 /* nothing */
1991 }
1992 return j;
1993}
1994
1995/*************************************************************************/
1996
1997/**********************************************************************/
2000static void island_terrain_init(void)
2001{
2002 struct terrain_select *ptersel;
2003
2004 /* forest */
2010 TT_ALL, WC_ALL);
2018
2019 /* desert */
2022 TT_HOT, WC_DRY);
2028 TT_NHOT, WC_DRY);
2031 TT_FROZEN, WC_DRY);
2033
2034 /* mountain */
2037 TT_ALL, WC_ALL);
2040 TT_ALL, WC_ALL);
2042
2043 /* swamp */
2049 TT_HOT, WC_NDRY);
2052 TT_NHOT, WC_NDRY);
2054
2055 island_terrain.init = TRUE;
2056}
2057
2058/**********************************************************************/
2061static void island_terrain_free(void)
2062{
2063 if (!island_terrain.init) {
2064 return;
2065 }
2066
2071
2072 island_terrain.init = FALSE;
2073}
2074
2075/**********************************************************************/
2081static bool make_island(int islemass, int starters,
2082 struct gen234_state *pstate,
2084{
2085 /* int may be only 2 byte ! */
2086 static long int tilefactor, balance, lastplaced;
2088 int i;
2089
2090 /* The terrain selection lists have to be initialised.
2091 * (see island_terrain_init()) */
2093
2094 if (islemass == 0) {
2095 /* this only runs to initialise static things, not to actually
2096 * create an island. */
2097 balance = 0;
2098 /* 0 = none, poles, then isles */
2099 pstate->isleindex = wld.map.num_continents + 1;
2100
2101 checkmass = pstate->totalmass;
2102
2103 /* caveat: this should really be sent to all players */
2104 if (pstate->totalmass > 3000) {
2105 log_normal(_("High landmass - this may take a few seconds."));
2106 }
2107
2109 i = (i <= 90) ? 100 : i * 11 / 10;
2110 tilefactor = pstate->totalmass / i;
2111 riverbuck = -(long int) fc_rand(pstate->totalmass);
2112 mountbuck = -(long int) fc_rand(pstate->totalmass);
2113 desertbuck = -(long int) fc_rand(pstate->totalmass);
2114 forestbuck = -(long int) fc_rand(pstate->totalmass);
2115 swampbuck = -(long int) fc_rand(pstate->totalmass);
2116 lastplaced = pstate->totalmass;
2117 } else {
2118
2119 /* makes the islands this big */
2121
2122 if (islemass > lastplaced + 1 + lastplaced / 50) {
2123 /* don't create big isles we can't place */
2124 islemass = lastplaced + 1 + lastplaced / 50;
2125 }
2126
2127 /* isle creation does not perform well for nonsquare islands */
2128 if (islemass > (wld.map.ysize - 6) * (wld.map.ysize - 6)) {
2129 islemass = (wld.map.ysize - 6) * (wld.map.ysize - 6);
2130 }
2131
2132 if (islemass > (wld.map.xsize - 2) * (wld.map.xsize - 2)) {
2133 islemass = (wld.map.xsize - 2) * (wld.map.xsize - 2);
2134 }
2135
2136 i = islemass;
2137 if (i <= 0) {
2138 return FALSE;
2139 }
2140 fc_assert_ret_val(starters >= 0, FALSE);
2141 log_verbose("island %i", pstate->isleindex);
2142
2143 /* keep trying to place an island, and decrease the size of
2144 * the island we're trying to create until we succeed.
2145 * If we get too small, return an error. */
2146 while (!create_island(i, pstate)) {
2147 if (i < islemass * min_specific_island_size / 100) {
2148 return FALSE;
2149 }
2150 i--;
2151 }
2152 i++;
2153 lastplaced = i;
2154 if (i * 10 > islemass) {
2155 balance = i - islemass;
2156 } else {
2157 balance = 0;
2158 }
2159
2160 log_verbose("ini=%d, plc=%d, bal=%ld, tot=%ld",
2162
2163 i *= tilefactor;
2164
2165 riverbuck += river_pct * i;
2167
2168 /* forest */
2169 forestbuck += forest_pct * i;
2171
2172 /* desert */
2173 desertbuck += desert_pct * i;
2175
2176 /* mountain */
2178 fill_island(20, &mountbuck, island_terrain.mountain, pstate);
2179
2180 /* swamp */
2181 swampbuck += swamp_pct * i;
2183
2184 pstate->isleindex++;
2186 }
2187 return TRUE;
2188}
2189
2190/**********************************************************************/
2194static void initworld(struct gen234_state *pstate)
2195{
2197 FALSE);
2198
2201 create_placed_map(); /* land tiles which aren't placed yet */
2202
2203 whole_map_iterate(&(wld.map), ptile) {
2205 tile_set_continent(ptile, 0);
2206 map_set_placed(ptile); /* not a land tile */
2207 BV_CLR_ALL(ptile->extras);
2208 tile_set_owner(ptile, NULL, NULL);
2209 ptile->extras_owner = NULL;
2211
2212 if (HAS_POLES) {
2213 make_polar();
2214 }
2215
2216 /* Set poles numbers. After the map is generated continents will
2217 * be renumbered. */
2218 make_island(0, 0, pstate, 0);
2219}
2220
2221/* This variable is the Default Minimum Specific Island Size,
2222 * ie the smallest size we'll typically permit our island, as a % of
2223 * the size we wanted. So if we ask for an island of size x, the island
2224 * creation will return if it would create an island smaller than
2225 * x * DMSIS / 100 */
2226#define DMSIS 10
2227
2228/**********************************************************************/
2231static void mapgenerator2(void)
2232{
2233 long int totalweight;
2234 struct gen234_state state;
2235 struct gen234_state *pstate = &state;
2236 int i;
2237 bool done = FALSE;
2238 int spares = 1;
2239 /* constant that makes up that an island actually needs additional space */
2240
2241 /* put 70% of land in big continents,
2242 * 20% in medium, and
2243 * 10% in small. */
2244 int bigfrac = 70, midfrac = 20, smallfrac = 10;
2245
2246 if (wld.map.server.landpercent > 85) {
2247 log_verbose("ISLAND generator: falling back to RANDOM generator");
2249 return;
2250 }
2251
2252 pstate->totalmass = ((wld.map.ysize - 6 - spares) * wld.map.server.landpercent
2253 * (wld.map.xsize - spares)) / 100;
2254 totalweight = 100 * player_count();
2255
2258
2259 while (!done && bigfrac > midfrac) {
2260 done = TRUE;
2261
2264 }
2265
2267
2268 /* Create one big island for each player. */
2269 for (i = player_count(); i > 0; i--) {
2270 if (!make_island(bigfrac * pstate->totalmass / totalweight,
2271 1, pstate, 95)) {
2272 /* we couldn't make an island at least 95% as big as we wanted,
2273 * and since we're trying hard to be fair, we need to start again,
2274 * with all big islands reduced slightly in size.
2275 * Take the size reduction from the big islands and add it to the
2276 * small islands to keep overall landmass unchanged.
2277 * Note that the big islands can get very small if necessary, and
2278 * the smaller islands will not exist if we can't place them
2279 * easily. */
2280 log_verbose("Island too small, trying again with all smaller "
2281 "islands.");
2282 midfrac += bigfrac * 0.01;
2283 smallfrac += bigfrac * 0.04;
2284 bigfrac *= 0.95;
2285 done = FALSE;
2286 break;
2287 }
2288 }
2289 }
2290
2291 if (bigfrac <= midfrac) {
2292 /* We could never make adequately big islands. */
2293 log_verbose("ISLAND generator: falling back to RANDOM generator");
2295
2296 /* init world created this map, destroy it before abort */
2299 height_map = NULL;
2300 return;
2301 }
2302
2303 /* Now place smaller islands, but don't worry if they're small,
2304 * or even non-existent. One medium and one small per player. */
2305 for (i = player_count(); i > 0; i--) {
2306 make_island(midfrac * pstate->totalmass / totalweight, 0, pstate, DMSIS);
2307 }
2308 for (i = player_count(); i > 0; i--) {
2309 make_island(smallfrac * pstate->totalmass / totalweight, 0, pstate, DMSIS);
2310 }
2311
2312 make_plains();
2315 height_map = NULL;
2316
2318 log_verbose("%ld mass left unplaced", checkmass);
2319 }
2320}
2321
2322/**********************************************************************/
2326static void mapgenerator3(void)
2327{
2328 int spares = 1;
2329 int j = 0;
2330 long int islandmass, landmass, size;
2331 long int maxmassdiv6 = 20;
2332 int bigislands;
2333 struct gen234_state state;
2334 struct gen234_state *pstate = &state;
2335
2336 if (wld.map.server.landpercent > 80) {
2337 log_verbose("ISLAND generator: falling back to FRACTAL generator due "
2338 "to landpercent > 80.");
2340 return;
2341 }
2342
2343 if (wld.map.xsize < 40 || wld.map.ysize < 40) {
2344 log_verbose("ISLAND generator: falling back to FRACTAL generator due "
2345 "to unsupported map size.");
2347 return;
2348 }
2349
2350 pstate->totalmass = (((wld.map.ysize - 6 - spares) * wld.map.server.landpercent
2351 * (wld.map.xsize - spares)) / 100);
2352
2354
2356 /* subtracting the arctics */
2357 if (landmass > 3 * wld.map.ysize + player_count() * 3) {
2358 landmass -= 3 * wld.map.ysize;
2359 }
2360
2361
2362 islandmass = (landmass)/(3 * bigislands);
2363 if (islandmass < 4 * maxmassdiv6) {
2364 islandmass = (landmass)/(2 * bigislands);
2365 }
2366 if (islandmass < 3 * maxmassdiv6 && player_count() * 2 < landmass) {
2368 }
2369
2370 if (islandmass < 2) {
2371 islandmass = 2;
2372 }
2373 if (islandmass > maxmassdiv6 * 6) {
2374 islandmass = maxmassdiv6 * 6;/* !PS: let's try this */
2375 }
2376
2378
2379 while (pstate->isleindex - 2 <= bigislands && checkmass > islandmass
2380 && ++j < 500) {
2382 }
2383
2384 if (j == 500) {
2385 log_normal(_("Generator 3 didn't place all big islands."));
2386 }
2387
2388 islandmass = (islandmass * 11) / 8;
2390 if (islandmass < 2) {
2391 islandmass = 2;
2392 }
2393
2394 while (checkmass > islandmass && ++j < 1500) {
2395 if (j < 1000) {
2396 size = fc_rand((islandmass + 1) / 2 + 1) + islandmass / 2;
2397 } else {
2398 size = fc_rand((islandmass + 1) / 2 + 1);
2399 }
2400 if (size < 2) {
2401 size = 2;
2402 }
2403
2404 make_island(size, (pstate->isleindex - 2 <= player_count()) ? 1 : 0,
2405 pstate, DMSIS);
2406 }
2407
2408 make_plains();
2411 height_map = NULL;
2412
2413 if (j == 1500) {
2414 log_normal(_("Generator 3 left %li landmass unplaced."), checkmass);
2415 } else if (checkmass > wld.map.xsize + wld.map.ysize) {
2416 log_verbose("%ld mass left unplaced", checkmass);
2417 }
2418}
2419
2420/**********************************************************************/
2423static void mapgenerator4(void)
2424{
2425 int bigweight = 70;
2426 int spares = 1;
2427 int i;
2428 long int totalweight;
2429 struct gen234_state state;
2430 struct gen234_state *pstate = &state;
2431
2432
2433 /* no islands with mass >> sqr(min(xsize,ysize)) */
2434
2435 if (player_count() < 2 || wld.map.server.landpercent > 80) {
2436 log_verbose("ISLAND generator: falling back to startpos=SINGLE");
2438 return;
2439 }
2440
2441 if (wld.map.server.landpercent > 60) {
2442 bigweight = 30;
2443 } else if (wld.map.server.landpercent > 40) {
2444 bigweight = 50;
2445 } else {
2446 bigweight = 70;
2447 }
2448
2449 spares = (wld.map.server.landpercent - 5) / 30;
2450
2451 pstate->totalmass = (((wld.map.ysize - 6 - spares) * wld.map.server.landpercent
2452 * (wld.map.xsize - spares)) / 100);
2453
2455 totalweight = (30 + bigweight) * player_count();
2456
2458
2459 i = player_count() / 2;
2460 if ((player_count() & 1) == 1) {
2461 make_island(bigweight * 3 * pstate->totalmass / totalweight, 3,
2462 pstate, DMSIS);
2463 } else {
2464 i++;
2465 }
2466 while ((--i) > 0) {
2467 make_island(bigweight * 2 * pstate->totalmass / totalweight, 2,
2468 pstate, DMSIS);
2469 }
2470 for (i = player_count(); i > 0; i--) {
2471 make_island(20 * pstate->totalmass / totalweight, 0, pstate, DMSIS);
2472 }
2473 for (i = player_count(); i > 0; i--) {
2474 make_island(10 * pstate->totalmass / totalweight, 0, pstate, DMSIS);
2475 }
2476 make_plains();
2479 height_map = NULL;
2480
2482 log_verbose("%ld mass left unplaced", checkmass);
2483 }
2484}
2485
2486#undef DMSIS
2487
2488/**********************************************************************/
2491static void river_types_init(void)
2492{
2493 river_type_count = 0;
2494
2497 && priver->generated) {
2499 }
2501}
2502
2503
2504/****************************************************************************
2505 Fair island generator types.
2506****************************************************************************/
2516
2524
2525typedef void (*fair_geometry_func)(int *x, int *y);
2530
2531/**********************************************************************/
2535static inline struct fair_tile *fair_map_new(void)
2536{
2537 return fc_calloc(MAP_INDEX_SIZE, sizeof(struct fair_tile));
2538}
2539
2540/**********************************************************************/
2543static inline void fair_map_destroy(struct fair_tile *pmap)
2544{
2545 free(pmap);
2546}
2547
2548/**********************************************************************/
2551static inline void fair_map_tile_pos(struct fair_tile *pmap,
2552 struct fair_tile *ptile, int *x, int *y)
2553{
2554 index_to_map_pos(x, y, ptile - pmap);
2555}
2556
2557/**********************************************************************/
2560static inline struct fair_tile *
2562{
2563 int nat_x, nat_y;
2564
2566
2567 /* Wrap in X and Y directions, as needed. */
2571 } else {
2572 return NULL;
2573 }
2574 }
2578 } else {
2579 return NULL;
2580 }
2581 }
2582
2584}
2585
2586/**********************************************************************/
2589static inline struct fair_tile *
2591 enum direction8 dir)
2592{
2593 int x, y, dx, dy;
2594
2595 fair_map_tile_pos(pmap, ptile, &x, &y);
2596 DIRSTEP(dx, dy, dir);
2597 return fair_map_pos_tile(pmap, x + dx, y + dy);
2598}
2599
2600/**********************************************************************/
2604static inline bool
2606 int dist)
2607{
2608 int nat_x, nat_y;
2609
2610 index_to_native_pos(&nat_x, &nat_y, ptile - pmap);
2611
2613 && (nat_x < dist || nat_x >= wld.map.xsize - dist)) {
2614 return TRUE;
2615 }
2616
2617 if (MAP_IS_ISOMETRIC) {
2618 dist *= 2;
2619 }
2620
2622 && (nat_y < dist || nat_y >= wld.map.ysize - dist)) {
2623 return TRUE;
2624 }
2625
2626 return FALSE;
2627}
2628
2629/**********************************************************************/
2632static int fair_team_placement_closest(const void *a, const void *b)
2633{
2634 const struct iter_index *index1 = a, *index2 = b;
2635
2636 return index1->dist - index2->dist;
2637}
2638
2639/**********************************************************************/
2642static int fair_team_placement_horizontal(const void *a, const void *b)
2643{
2644 const struct iter_index *index1 = a, *index2 = b;
2645 /* Map vector to natural vector (Y axis). */
2646 int diff = (MAP_IS_ISOMETRIC
2647 ? abs(index1->dx + index1->dy) - abs(index2->dx + index2->dy)
2648 : abs(index1->dy) - abs(index2->dy));
2649
2650 return (diff != 0 ? diff : index1->dist - index2->dist);
2651}
2652
2653/**********************************************************************/
2656static int fair_team_placement_vertical(const void *a, const void *b)
2657{
2658 const struct iter_index *index1 = a, *index2 = b;
2659 /* Map vector to natural vector (X axis). */
2660 int diff = (MAP_IS_ISOMETRIC
2661 ? abs(index1->dx - index1->dy) - abs(index2->dx - index2->dy)
2662 : abs(index1->dx) - abs(index2->dx));
2663
2664 return (diff != 0 ? diff : index1->dist - index2->dist);
2665}
2666
2667/**********************************************************************/
2670static void fair_do_symmetry1(int *x, int *y)
2671{
2672 *x = -*x;
2673}
2674
2675/**********************************************************************/
2678static void fair_do_symmetry2(int *x, int *y)
2679{
2680 *y = -*y;
2681}
2682
2683/**********************************************************************/
2686static void fair_do_hex_symmetry1(int *x, int *y)
2687{
2688 *x = -(*x + *y);
2689}
2690
2691/**********************************************************************/
2694static void fair_do_hex_symmetry2(int *x, int *y)
2695{
2696 *x = -*x;
2697 *y = -*y;
2698}
2699
2700/**********************************************************************/
2703static void fair_do_iso_hex_symmetry1(int *x, int *y)
2704{
2705 *y = *x - *y;
2706}
2707
2708#define fair_do_iso_hex_symmetry2 fair_do_rotation
2709
2710/**********************************************************************/
2713static void fair_do_rotation(int *x, int *y)
2714{
2715 int z = *x;
2716
2717 *x = *y;
2718 *y = z;
2719}
2720
2721/**********************************************************************/
2724static void fair_do_hex_rotation(int *x, int *y)
2725{
2726 int z = *x + *y;
2727
2728 *x = -*y;
2729 *y = z;
2730}
2731
2732/**********************************************************************/
2735static void fair_do_iso_hex_rotation(int *x, int *y)
2736{
2737 int z = *x - *y;
2738
2739 *y = *x;
2740 *x = z;
2741}
2742
2743/**********************************************************************/
2746static void fair_do_geometry(const struct fair_geometry_data *data,
2747 int *x, int *y)
2748{
2749 int i;
2750
2751 for (i = 0; i < data->transform_num; i++) {
2752 data->transform[i](x, y);
2753 }
2754}
2755
2756/**********************************************************************/
2760{
2761 int i = 0;
2762
2764 if (fc_rand(100) < 50) {
2765 data->transform[i++] = fair_do_symmetry1;
2766 }
2767 if (fc_rand(100) < 50) {
2768 data->transform[i++] = fair_do_symmetry2;
2769 }
2770 if (fc_rand(100) < 50) {
2771 data->transform[i++] = fair_do_rotation;
2772 }
2773 } else if (!current_topo_has_flag(TF_ISO)) {
2774 int steps;
2775
2776 if (fc_rand(100) < 50) {
2778 }
2779 if (fc_rand(100) < 50) {
2781 }
2782 /* Rotations have 2 steps on hexgonal topologies. */
2783 for (steps = fc_rand(99) % 3; steps > 0; steps--) {
2784 data->transform[i++] = fair_do_hex_rotation;
2785 }
2786 } else {
2787 int steps;
2788
2789 if (fc_rand(100) < 50) {
2791 }
2792 if (fc_rand(100) < 50) {
2794 }
2795 /* Rotations have 2 steps on hexgonal topologies. */
2796 for (steps = fc_rand(99) % 3; steps > 0; steps--) {
2798 }
2799 }
2800 fc_assert(i <= ARRAY_SIZE(data->transform));
2801 data->transform_num = i;
2802}
2803
2804/**********************************************************************/
2810static bool fair_map_copy(struct fair_tile *ptarget, int tx, int ty,
2811 struct fair_tile *psource,
2812 const struct fair_geometry_data *data,
2813 int startpos_team_id)
2814{
2815 int sdx = wld.map.xsize / 2, sdy = wld.map.ysize / 2;
2817 struct fair_tile *pstile, *pttile;
2818 int x, y;
2819
2820 /* Check. */
2821 for (pstile = psource; pstile < smax_tile; pstile++) {
2822 if (pstile->flags == FTF_NONE) {
2823 continue;
2824 }
2825
2826 /* Do translation and eventually other transformations. */
2828 x -= sdx;
2829 y -= sdy;
2830 fair_do_geometry(data, &x, &y);
2831 x += tx;
2832 y += ty;
2834 if (pttile == NULL) {
2835 return FALSE; /* Limit of the map. */
2836 }
2837 if (pttile->flags & FTF_ASSIGNED) {
2838 if (pstile->flags & FTF_ASSIGNED
2839 || !(pttile->flags & FTF_OCEAN)
2840 || !(pstile->flags & FTF_OCEAN)) {
2841 return FALSE; /* Already assigned for another usage. */
2842 }
2843 } else if (pttile->flags & FTF_OCEAN && !(pstile->flags & FTF_OCEAN)) {
2844 return FALSE; /* We clearly want a sea tile here. */
2845 }
2846 if ((pttile->flags & FTF_NO_RESOURCE && pstile->presource != NULL)
2847 || (pstile->flags & FTF_NO_RESOURCE && pttile->presource != NULL)) {
2848 return FALSE; /* Resource disallowed there. */
2849 }
2850 if ((pttile->flags & FTF_NO_HUT && pstile->flags & FTF_HAS_HUT)
2851 || (pstile->flags & FTF_NO_HUT && pttile->flags & FTF_HAS_HUT)) {
2852 return FALSE; /* Resource disallowed there. */
2853 }
2854 }
2855
2856 /* Copy. */
2857 for (pstile = psource; pstile < smax_tile; pstile++) {
2858 if (pstile->flags == FTF_NONE) {
2859 continue;
2860 }
2861
2862 /* Do translation and eventually other transformations. */
2864 x -= sdx;
2865 y -= sdy;
2866 fair_do_geometry(data, &x, &y);
2867 x += tx;
2868 y += ty;
2871 pttile->flags |= pstile->flags;
2872 if (pstile->pterrain != NULL) {
2873 pttile->pterrain = pstile->pterrain;
2874 pttile->presource = pstile->presource;
2875 pttile->extras = pstile->extras;
2876 }
2877 if (pstile->flags & FTF_STARTPOS) {
2878 pttile->startpos_team_id = startpos_team_id;
2879 }
2880 }
2881 return TRUE; /* Looks ok. */
2882}
2883
2884/**********************************************************************/
2889 struct fair_tile *psource)
2890{
2892 int i, r, x, y;
2893
2895
2896 /* Try random positions. */
2897 for (i = 0; i < 10; i++) {
2899 index_to_map_pos(&x, &y, r);
2900 if (fair_map_copy(ptarget, x, y, psource, &geometry, -1)) {
2901 return TRUE;
2902 }
2903 }
2904
2905 /* Try hard placement. */
2907 for (i = (r + 1) % MAP_INDEX_SIZE; i != r; i = (i + 1) % MAP_INDEX_SIZE) {
2908 index_to_map_pos(&x, &y, i);
2909 if (fair_map_copy(ptarget, x, y, psource, &geometry, -1)) {
2910 return TRUE;
2911 }
2912 }
2913
2914 /* Impossible placement. */
2915 return FALSE;
2916}
2917
2918/**********************************************************************/
2922static bool
2924 struct fair_tile *psource,
2925 const struct iter_index *outwards_indices,
2926 int startpos_team_id)
2927{
2929 int i, x, y;
2930
2932
2933 /* Iterate positions, beginning by a random index of the outwards
2934 * indices. */
2937 x = tx + outwards_indices[i].dx;
2938 y = ty + outwards_indices[i].dy;
2939 if (normalize_map_pos(&(wld.map), &x, &y)
2941 startpos_team_id)) {
2942 return TRUE;
2943 }
2944 }
2945
2946 /* Impossible placement. */
2947 return FALSE;
2948}
2949
2950/**********************************************************************/
2954{
2955 struct fair_tile *pftile, *pftile2;
2956 int i, j;
2957
2958 for (i = 0; i < MAP_INDEX_SIZE; i++) {
2959 pftile = pmap + i;
2960 if (pftile->flags == FTF_NONE
2961 || pftile->flags & FTF_NO_RESOURCE
2962 || fc_rand (1000) >= wld.map.server.riches) {
2963 continue;
2964 }
2965
2966 if (pftile->flags & FTF_OCEAN) {
2967 bool land_around = FALSE;
2968
2969 for (j = 0; j < wld.map.num_valid_dirs; j++) {
2971 if (pftile2 != NULL
2972 && pftile2->flags & FTF_ASSIGNED
2973 && !(pftile2->flags & FTF_OCEAN)) {
2974 land_around = TRUE;
2975 break;
2976 }
2977 }
2978 if (!land_around) {
2979 continue;
2980 }
2981 }
2982
2983 pftile->presource = pick_resource(pftile->pterrain);
2984 /* Note that 'pftile->presource' might be NULL if there is no suitable
2985 * resource for the terrain. */
2986 if (pftile->presource != NULL) {
2987 pftile->flags |= FTF_NO_RESOURCE;
2988 for (j = 0; j < wld.map.num_valid_dirs; j++) {
2990 if (pftile2 != NULL) {
2991 pftile2->flags |= FTF_NO_RESOURCE;
2992 }
2993 }
2994
2995 BV_SET(pftile->extras, extra_index(pftile->presource));
2996 }
2997 }
2998}
2999
3000/**********************************************************************/
3004{
3005 struct fair_tile *pftile;
3006 struct tile *pvtile = tile_virtual_new(NULL);
3007 struct extra_type *phut;
3008 int i, j, k;
3009
3010 for (i = wld.map.server.huts * map_num_tiles() / 1000, j = 0;
3011 i > 0 && j < map_num_tiles() * 2; j++) {
3013 pftile = pmap + k;
3014 while (pftile->flags & FTF_NO_HUT) {
3015 pftile++;
3016 if (pftile - pmap == MAP_INDEX_SIZE) {
3017 pftile = pmap;
3018 }
3019 if (pftile - pmap == k) {
3020 break;
3021 }
3022 }
3023 if (pftile->flags & FTF_NO_HUT) {
3024 break; /* Cannot make huts anymore. */
3025 }
3026
3027 i--;
3028 if (pftile->pterrain == NULL) {
3029 continue; /* Not an used tile. */
3030 }
3031
3032 pvtile->index = pftile - pmap;
3033 tile_set_terrain(pvtile, pftile->pterrain);
3034 tile_set_resource(pvtile, pftile->presource);
3035 pvtile->extras = pftile->extras;
3036
3038 if (phut != NULL) {
3040 pftile->extras = pvtile->extras;
3041 pftile->flags |= FTF_HAS_HUT;
3043 3, ptile) {
3044 pmap[tile_index(ptile)].flags |= FTF_NO_HUT;
3046 }
3047 }
3048
3050}
3051
3052/**********************************************************************/
3056{
3057 enum {
3059 FT_FOREST,
3060 FT_DESERT,
3061 FT_HILL,
3063 FT_SWAMP,
3064 FT_COUNT
3065 };
3066 struct {
3067 int count;
3068 enum mapgen_terrain_property target;
3069 enum mapgen_terrain_property prefer;
3070 enum mapgen_terrain_property avoid;
3071 } terrain[FT_COUNT] = {
3074 { 0, MG_DRY, MG_TEMPERATE, MG_GREEN },
3078 };
3079
3080 struct fair_tile *pisland;
3081 struct fair_tile *land_tiles[1000];
3082 struct fair_tile *pftile, *pftile2, *pftile3;
3083 int fantasy;
3084 const int sea_around_island = (startpos_num > 0
3086 const int sea_around_island_sq = (startpos_num > 0
3088 int i, j, k;
3089
3091 fantasy = (size * 2) / 5;
3095 pftile->flags |= FTF_ASSIGNED;
3096 land_tiles[0] = pftile;
3097 i = 1;
3098
3099 log_debug("Generating an island with %d land tiles [fantasy=%d].",
3100 size, fantasy);
3101
3102 /* Make land. */
3103 while (i < fantasy) {
3105
3106 for (j = 0; j < wld.map.num_valid_dirs; j++) {
3110 continue;
3111 }
3112
3113 if (pftile2->flags == FTF_NONE) {
3114 pftile2->flags = FTF_ASSIGNED;
3115 land_tiles[i++] = pftile2;
3116 if (i == fantasy) {
3117 break;
3118 }
3119 }
3120 }
3121 }
3122 while (i < size) {
3123 pftile = land_tiles[i - fc_rand(fantasy) - 1];
3128 continue;
3129 }
3130
3131 if (pftile2->flags == FTF_NONE) {
3132 pftile2->flags = FTF_ASSIGNED;
3133 land_tiles[i++] = pftile2;
3134 }
3135 }
3136 fc_assert(i == size);
3137
3138 /* Add start positions. */
3139 for (i = 0; i < startpos_num;) {
3141 fc_assert(pftile->flags & FTF_ASSIGNED);
3142 if (!(pftile->flags & FTF_STARTPOS)) {
3143 pftile->flags |= FTF_STARTPOS;
3144 i++;
3145 }
3146 }
3147
3148 /* Make terrain. */
3150 terrain[FT_FOREST].count = ((forest_pct + jungle_pct) * size) / 100;
3151 terrain[FT_DESERT].count = (desert_pct * size) / 100;
3152 terrain[FT_HILL].count = (mountain_pct * size) / 150;
3153 terrain[FT_MOUNTAIN].count = (mountain_pct * size) / 300;
3154 terrain[FT_SWAMP].count = (swamp_pct * size) / 100;
3155
3156 j = FT_GRASSLAND;
3157 for (i = 0; i < size; i++) {
3158 pftile = land_tiles[i];
3159
3160 if (pftile->flags & FTF_STARTPOS) {
3162 } else {
3163 if (terrain[j].count == 0 || fc_rand(100) < 70) {
3164 do {
3165 j = fc_rand(FT_COUNT);
3166 } while (terrain[j].count == 0);
3167 }
3168 pftile->pterrain = pick_terrain(terrain[j].target, terrain[j].prefer,
3169 terrain[j].avoid);
3170 terrain[j].count--;
3171 }
3172 }
3173
3174 /* Make sea around the island. */
3175 for (i = 0; i < size; i++) {
3178 sea_around_island_sq, ptile) {
3179 pftile = pisland + tile_index(ptile);
3180
3181 if (pftile->flags == FTF_NONE) {
3182 pftile->flags = FTF_OCEAN;
3183 /* No ice around island */
3184 pftile->pterrain =
3187 if (startpos_num > 0) {
3188 pftile->flags |= FTF_ASSIGNED;
3189 }
3190 }
3192 }
3193
3194 /* Make rivers. */
3195 if (river_type_count > 0) {
3196 struct extra_type *priver;
3197 struct fair_tile *pend;
3199 * wld.map.num_cardinal_dirs) / 200);
3200 int length_max = 3, length, l;
3201 enum direction8 dir;
3202 int extra_idx;
3203 int dirs_num;
3204 bool cardinal_only;
3206 int river_around;
3207 bool finished;
3208
3209 for (i = 0; i < n; i++) {
3211 if (!terrain_has_flag(pftile->pterrain, TER_CAN_HAVE_RIVER)) {
3212 continue;
3213 }
3214
3217 if (BV_ISSET(pftile->extras, extra_idx)) {
3218 continue;
3219 }
3221
3222 river_around = 0;
3225 for (j = 0; j < wld.map.num_valid_dirs; j++) {
3227 if (pftile2 == NULL) {
3228 continue;
3229 }
3230
3231 if (pftile2->flags & FTF_OCEAN) {
3233 break;
3234 } else if (BV_ISSET(pftile2->extras, extra_idx)) {
3235 river_around++;
3238 }
3239 }
3240 }
3241 if (ocean_around
3242 || river_around > 1
3243 || (river_around == 1 && !connectable_river_around)) {
3244 continue;
3245 }
3246
3248 log_debug("Adding river at (%d, %d)",
3251 BV_SET(pftile->extras, extra_idx);
3252 continue;
3253 }
3254
3255 /* Check a river in one direction. */
3256 pend = NULL;
3257 length = -1;
3258 dir = direction8_invalid();
3259 dirs_num = 0;
3260 for (j = 0; j < wld.map.num_valid_dirs; j++) {
3262 continue;
3263 }
3264
3265 finished = FALSE;
3266 pftile2 = pftile;
3267 for (l = 2; l < length_max; l++) {
3269 if (pftile2 == NULL
3271 break;
3272 }
3273
3274 river_around = 0;
3277 for (k = 0; k < wld.map.num_valid_dirs; k++) {
3278 if (wld.map.valid_dirs[k] == DIR_REVERSE(wld.map.valid_dirs[j])) {
3279 continue;
3280 }
3281
3283 wld.map.valid_dirs[k]);
3284 if (pftile3 == NULL) {
3285 continue;
3286 }
3287
3288 if (pftile3->flags & FTF_OCEAN) {
3291 }
3292 } else if (BV_ISSET(pftile3->extras, extra_idx)) {
3293 river_around++;
3296 }
3297 }
3298 }
3300 break;
3301 } else if (ocean_around || connectable_river_around) {
3302 finished = TRUE;
3303 break;
3304 }
3305 }
3306 if (finished && fc_rand(++dirs_num) == 0) {
3307 dir = wld.map.valid_dirs[j];
3308 pend = pftile2;
3309 length = l;
3310 }
3311 }
3312 if (pend == NULL) {
3313 continue;
3314 }
3315
3316 log_debug("Make river from (%d, %d) to (%d, %d) [dir=%s, length=%d]",
3321 direction8_name(dir),
3322 length);
3323 for (;;) {
3324 BV_SET(pftile->extras, extra_idx);
3325 length--;
3326 if (pftile == pend) {
3327 fc_assert(length == 0);
3328 break;
3329 }
3331 fc_assert(pftile != NULL);
3332 }
3333 }
3334 }
3335
3336 if (startpos_num > 0) {
3337 /* Islands with start positions must have the same resources and the
3338 * same huts. Other ones don't matter. */
3339
3340 /* Make resources. */
3341 if (wld.map.server.riches > 0) {
3343 }
3344
3345 /* Make huts. */
3346 if (wld.map.server.huts > 0) {
3348 }
3349
3350 /* Make sure there will be no more resources and huts on assigned
3351 * tiles. */
3352 for (i = 0; i < MAP_INDEX_SIZE; i++) {
3353 pftile = pisland + i;
3354 if (pftile->flags & FTF_ASSIGNED) {
3355 pftile->flags |= (FTF_NO_RESOURCE | FTF_NO_HUT);
3356 }
3357 }
3358 }
3359
3360 return pisland;
3361}
3362
3363/**********************************************************************/
3367{
3368 struct terrain *deepest_ocean
3370 struct fair_tile *pmap, *pisland;
3372 int min_island_size = wld.map.server.tinyisles ? 1 : 2;
3373 int players_per_island = 1;
3375 int i, iter = CLIP(1, 100000 / map_num_tiles(), 10);
3376 bool done = FALSE;
3377
3380 fc_assert(0 < i);
3381 if (i == 1) {
3383 } else {
3384 teams_num++;
3386 }
3389
3390 /* Take in account the 'startpos' setting. */
3394 }
3395
3396 switch (wld.map.server.startpos) {
3397 case MAPSTARTPOS_2or3:
3398 {
3399 bool maybe2 = (0 == player_count() % 2);
3400 bool maybe3 = (0 == player_count() % 3);
3401
3405 if (i > 1) {
3406 if (0 != i % 2) {
3407 maybe2 = FALSE;
3408 }
3409 if (0 != i % 3) {
3410 maybe3 = FALSE;
3411 }
3412 }
3414 }
3415
3416 if (maybe3) {
3418 } else if (maybe2) {
3420 }
3421 }
3422 break;
3423 case MAPSTARTPOS_ALL:
3427 if (i > 1) {
3428 if (players_per_island == 1) {
3430 } else if (i != players_per_island) {
3431 /* Every team doesn't have the same number of players. Cannot
3432 * consider this option. */
3435 break;
3436 }
3437 }
3439 }
3440 break;
3442 case MAPSTARTPOS_SINGLE:
3444 break;
3445 }
3446 if (players_per_island == 1) {
3448 }
3449
3450 whole_map_iterate(&(wld.map), ptile) {
3452 tile_set_continent(ptile, 0);
3453 BV_CLR_ALL(ptile->extras);
3454 tile_set_owner(ptile, NULL, NULL);
3455 ptile->extras_owner = NULL;
3457
3458 i = 0;
3459 if (HAS_POLES) {
3460 make_polar();
3461
3462 whole_map_iterate(&(wld.map), ptile) {
3463 if (tile_terrain(ptile) != deepest_ocean) {
3464 i++;
3465 }
3467 }
3468
3471 } else {
3473 / (player_count() * 100));
3474 }
3478 }
3479 islandmass2 = (playermass * 2) / 10;
3482 }
3483 islandmass3 = playermass / 10;
3486 }
3487
3488 log_verbose("Creating a map with fair island generator");
3489 log_debug("max iterations=%d", iter);
3490 log_debug("players_per_island=%d", players_per_island);
3491 log_debug("team_placement=%s",
3493 log_debug("teams_num=%d, team_players_num=%d, single_players_num=%d",
3495 log_debug("playermass=%d, islandmass1=%d, islandmass2=%d, islandmass3=%d",
3497
3498 pmap = fair_map_new();
3499
3500 while (--iter >= 0) {
3501 done = TRUE;
3502
3503 whole_map_iterate(&(wld.map), ptile) {
3504 struct fair_tile *pftile = pmap + tile_index(ptile);
3505
3506 if (tile_terrain(ptile) != deepest_ocean) {
3507 pftile->flags |= (FTF_ASSIGNED | FTF_NO_HUT);
3508 adjc_iterate(&(wld.map), ptile, atile) {
3509 struct fair_tile *aftile = pmap + tile_index(atile);
3510
3511 if (!(aftile->flags & FTF_ASSIGNED)
3513 aftile->flags |= FTF_OCEAN;
3514 }
3516 }
3517 pftile->pterrain = tile_terrain(ptile);
3518 pftile->presource = tile_resource(ptile);
3519 pftile->extras = *tile_extras(ptile);
3521
3522 /* Create main player island. */
3523 log_debug("Making main island.");
3525
3526 log_debug("Place main islands on the map.");
3527 i = 0;
3528
3530 && team_players_num > 0) {
3531 /* Do team placement. */
3532 struct iter_index outwards_indices[wld.map.num_iterate_outwards_indices];
3533 int start_x[teams_num], start_y[teams_num];
3534 int dx = 0, dy = 0;
3535 int j, k;
3536
3537 /* Build outwards_indices. */
3539 sizeof(outwards_indices));
3540 switch (wld.map.server.team_placement) {
3543 break;
3546 for (j = 0; j < wld.map.num_iterate_outwards_indices; j++) {
3547 /* We want square distances for comparing. */
3548 outwards_indices[j].dist =
3550 outwards_indices[j].dy);
3551 }
3554 break;
3558 break;
3562 break;
3563 }
3564
3565 /* Make start point for teams. */
3567 dx = fc_rand(wld.map.xsize);
3568 }
3570 dy = fc_rand(wld.map.ysize);
3571 }
3572 for (j = 0; j < teams_num; j++) {
3573 start_x[j] = (wld.map.xsize * (2 * j + 1)) / (2 * teams_num) + dx;
3574 start_y[j] = (wld.map.ysize * (2 * j + 1)) / (2 * teams_num) + dy;
3576 start_x[j] = FC_WRAP(start_x[j], wld.map.xsize);
3577 }
3579 start_y[j] = FC_WRAP(start_y[j], wld.map.ysize);
3580 }
3581 }
3582 /* Randomize. */
3583 array_shuffle(start_x, teams_num);
3585
3586 j = 0;
3589 int team_id;
3590 int x, y;
3591
3592 if (members_count <= 1) {
3593 continue;
3594 }
3595 team_id = team_number(pteam);
3596
3597 NATIVE_TO_MAP_POS(&x, &y, start_x[j], start_y[j]);
3598 log_verbose("Team %d (%s) will start on (%d, %d)",
3599 team_id, team_rule_name(pteam), x, y);
3600
3601 for (k = 0; k < members_count; k += players_per_island) {
3603 outwards_indices, team_id)) {
3604 log_verbose("Failed to place island number %d for team %d (%s).",
3605 k, team_id, team_rule_name(pteam));
3606 done = FALSE;
3607 break;
3608 }
3609 }
3610 if (!done) {
3611 break;
3612 }
3613 i += k;
3614 j++;
3616
3617 fc_assert(!done || i == team_players_num);
3618 }
3619
3620 if (done) {
3621 /* Place last player islands. */
3622 for (; i < player_count(); i += players_per_island) {
3624 log_verbose("Failed to place island number %d.", i);
3625 done = FALSE;
3626 break;
3627 }
3628 }
3629 fc_assert(!done || i == player_count());
3630 }
3632
3633 if (done) {
3634 log_debug("Create and place small islands on the map.");
3635 for (i = 0; i < player_count(); i++) {
3638 log_verbose("Failed to place small island2 number %d.", i);
3639 done = FALSE;
3641 break;
3642 }
3644 }
3645 }
3646 if (done) {
3647 for (i = 0; i < player_count(); i++) {
3650 log_verbose("Failed to place small island3 number %d.", i);
3651 done = FALSE;
3653 break;
3654 }
3656 }
3657 }
3658
3659 if (done) {
3660 break;
3661 }
3662
3664 pmap = fair_map_new();
3665
3666 /* Decrease land mass, for better chances. */
3667 islandmass1 = (islandmass1 * 99) / 100;
3670 }
3671 islandmass2 = (islandmass2 * 99) / 100;
3674 }
3675 islandmass3 = (islandmass3 * 99) / 100;
3678 }
3679 }
3680
3681 if (!done) {
3682 log_verbose("Failed to create map after %d iterations.", iter);
3684 return FALSE;
3685 }
3686
3687 /* Finalize the map. */
3688 for (i = 0; i < MAP_INDEX_SIZE; i++) {
3689 /* Mark all tiles as assigned, for adding resources and huts. */
3690 pmap[i].flags |= FTF_ASSIGNED;
3691 }
3692 if (wld.map.server.riches > 0) {
3694 }
3695 if (wld.map.server.huts > 0) {
3697 }
3698
3699 /* Apply the map. */
3700 log_debug("Applying the map...");
3701 whole_map_iterate(&(wld.map), ptile) {
3702 struct fair_tile *pftile = pmap + tile_index(ptile);
3703
3704 fc_assert(pftile->pterrain != NULL);
3705 tile_set_terrain(ptile, pftile->pterrain);
3706 ptile->extras = pftile->extras;
3707 tile_set_resource(ptile, pftile->presource);
3708 if (pftile->flags & FTF_STARTPOS) {
3709 struct startpos *psp = map_startpos_new(ptile);
3710
3711 if (pftile->startpos_team_id != -1) {
3713 (pftile->startpos_team_id)), pplayer) {
3714 startpos_allow(psp, nation_of_player(pplayer));
3716 } else {
3718 }
3719 }
3721
3724
3726
3727 log_verbose("Fair island map created with success!");
3728 return TRUE;
3729}
#define n
Definition astring.c:77
void dbv_init(struct dbv *pdbv, int bits)
Definition bitvector.c:50
void dbv_set(struct dbv *pdbv, int bit)
Definition bitvector.c:144
bool dbv_isset(const struct dbv *pdbv, int bit)
Definition bitvector.c:120
void dbv_free(struct dbv *pdbv)
Definition bitvector.c:95
void dbv_clr_all(struct dbv *pdbv)
Definition bitvector.c:179
#define BV_CLR_ALL(bv)
Definition bitvector.h:95
#define BV_SET(bv, bit)
Definition bitvector.h:81
#define BV_ISSET(bv, bit)
Definition bitvector.h:78
#define CITY_MAP_DEFAULT_RADIUS_SQ
Definition city.h:82
char * incite_cost
Definition comments.c:75
struct unit struct city struct unit struct tile struct extra_type const struct act_prob *act_probs int actor_unit_id struct unit struct unit int const struct action *paction bool fatal
Definition dialogs_g.h:86
struct extra_type * rand_extra_for_tile(struct tile *ptile, enum extra_cause cause, bool generated)
Definition extras.c:283
#define extra_index(_e_)
Definition extras.h:183
#define extra_road_get(_e_)
Definition extras.h:191
#define extra_type_by_cause_iterate_end
Definition extras.h:339
#define extra_type_by_cause_iterate(_cause, _extra)
Definition extras.h:333
#define CITY_MAP_DEFAULT_RADIUS
Definition fc_types.h:82
#define MAX_EXTRA_TYPES
Definition fc_types.h:50
#define _(String)
Definition fcintl.h:67
void make_fracture_map(void)
void make_fracture_relief(void)
static map_landmass * landmass
int * height_map
Definition height_map.c:29
int hmap_mountain_level
#define MG_UNUSED
int hmap_shore_level
Definition height_map.c:30
struct world wld
Definition game.c:63
void renormalize_hmap_poles(void)
Definition height_map.c:80
void normalize_hmap_poles(void)
Definition height_map.c:64
bool area_is_too_flat(struct tile *ptile, int thill, int my_height)
Definition height_map.c:269
void make_pseudofractal1_hmap(int extra_div)
Definition height_map.c:197
void make_random_hmap(int smooth)
Definition height_map.c:100
#define H_UNIT
Definition height_map.h:20
#define hmap_max_level
Definition height_map.h:33
#define hmap(_tile)
Definition height_map.h:17
#define fc_assert_msg(condition, message,...)
Definition log.h:181
#define fc_assert_ret(condition)
Definition log.h:191
#define fc_assert_exit_msg(condition, message,...)
Definition log.h:211
#define log_verbose(message,...)
Definition log.h:109
#define fc_assert(condition)
Definition log.h:176
#define fc_assert_ret_val(condition, val)
Definition log.h:194
#define fc_assert_action(condition, action)
Definition log.h:187
#define log_debug(message,...)
Definition log.h:115
#define log_normal(message,...)
Definition log.h:107
#define log_error(message,...)
Definition log.h:103
#define log_testmatic(message,...)
Definition log.h:123
#define nat_x
#define nat_y
struct startpos * map_startpos_new(struct tile *ptile)
Definition map.c:1866
int map_num_tiles(void)
Definition map.c:1014
bool startpos_allows_all(const struct startpos *psp)
Definition map.c:1696
struct tile * rand_map_pos(const struct civ_map *nmap)
Definition map.c:1088
void main_map_allocate(void)
Definition map.c:519
struct tile * index_to_tile(const struct civ_map *imap, int mindex)
Definition map.c:456
int map_vector_to_sq_distance(int dx, int dy)
Definition map.c:614
struct tile * rand_map_pos_filtered(const struct civ_map *nmap, void *data, bool(*filter)(const struct tile *ptile, const void *data))
Definition map.c:1101
int map_startpos_count(void)
Definition map.c:1853
bool is_cardinal_dir(enum direction8 dir)
Definition map.c:1316
struct tile * native_pos_to_tile(const struct civ_map *nmap, int nat_x, int nat_y)
Definition map.c:443
bool map_is_empty(void)
Definition map.c:149
bool startpos_allow(struct startpos *psp, struct nation_type *pnation)
Definition map.c:1643
bool normalize_map_pos(const struct civ_map *nmap, int *x, int *y)
Definition map.c:979
#define current_topo_has_flag(flag)
Definition map.h:48
#define native_pos_to_index(nat_x, nat_y)
Definition map.h:154
#define adjc_iterate_end
Definition map.h:433
static int index_to_map_pos_y(int mindex)
Definition map.h:724
#define MAP_INDEX_SIZE
Definition map.h:137
static const bool C_PERCENT
Definition map.h:40
static const bool C_NUMBER
Definition map.h:39
#define square_iterate(nmap, center_tile, radius, tile_itr)
Definition map.h:391
#define MAP_IS_ISOMETRIC
Definition map.h:42
#define cardinal_adjc_iterate_end
Definition map.h:459
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:428
#define MAP_TO_NATIVE_POS(pnat_x, pnat_y, map_x, map_y)
Definition map.h:172
static const bool C_ADJACENT
Definition map.h:37
#define NATIVE_TO_MAP_POS(pmap_x, pmap_y, nat_x, nat_y)
Definition map.h:166
#define cardinal_adjc_dir_iterate_end
Definition map.h:466
#define square_iterate_end
Definition map.h:394
#define cardinal_adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:455
#define circle_iterate(nmap, center_tile, sq_radius, tile_itr)
Definition map.h:401
static int index_to_map_pos_x(int mindex)
Definition map.h:715
#define whole_map_iterate(_map, _tile)
Definition map.h:545
static const bool C_CARDINAL
Definition map.h:38
#define cardinal_adjc_dir_base_iterate_end
Definition map.h:473
#define DIR_REVERSE(dir)
Definition map.h:561
#define current_wrap_has_flag(flag)
Definition map.h:51
#define cardinal_adjc_dir_base_iterate(nmap, center_tile, dir_itr)
Definition map.h:469
#define index_to_native_pos(pnat_x, pnat_y, mindex)
Definition map.h:157
#define cardinal_adjc_dir_iterate(nmap, center_tile, itr_tile, dir_itr)
Definition map.h:462
#define whole_map_iterate_end
Definition map.h:554
#define index_to_map_pos(pmap_x, pmap_y, mindex)
Definition map.h:233
#define circle_iterate_end
Definition map.h:404
#define DIRSTEP(dest_x, dest_y, dir)
Definition map.h:240
@ MAPSIZE_PLAYER
Definition map_types.h:40
@ MAPGEN_SCENARIO
Definition map_types.h:47
@ MAPGEN_FRACTURE
Definition map_types.h:52
@ MAPGEN_ISLAND
Definition map_types.h:50
@ MAPGEN_FAIR
Definition map_types.h:51
@ MAPGEN_FRACTAL
Definition map_types.h:49
@ MAPGEN_RANDOM
Definition map_types.h:48
map_startpos
Definition map_types.h:55
@ MAPSTARTPOS_VARIABLE
Definition map_types.h:60
@ MAPSTARTPOS_2or3
Definition map_types.h:58
@ MAPSTARTPOS_ALL
Definition map_types.h:59
@ MAPSTARTPOS_DEFAULT
Definition map_types.h:56
@ MAPSTARTPOS_SINGLE
Definition map_types.h:57
static void make_plains(void)
Definition mapgen.c:449
static int fair_team_placement_vertical(const void *a, const void *b)
Definition mapgen.c:2656
static void make_terrains(void)
Definition mapgen.c:485
static int hmap_low_level
Definition mapgen.c:185
static void make_rivers(void)
Definition mapgen.c:900
static void mapgenerator2(void)
Definition mapgen.c:2231
wetness_c
Definition mapgen.c:180
@ WC_NDRY
Definition mapgen.c:180
@ WC_ALL
Definition mapgen.c:180
@ WC_DRY
Definition mapgen.c:180
#define terrain_select_list_iterate_end
Definition mapgen.c:81
#define NUM_TEST_FUNCTIONS
Definition mapgen.c:683
static void fair_do_hex_symmetry1(int *x, int *y)
Definition mapgen.c:2686
static int jungle_pct
Definition mapgen.c:166
#define fair_do_iso_hex_symmetry2
Definition mapgen.c:2708
static void fair_map_make_resources(struct fair_tile *pmap)
Definition mapgen.c:2953
static bool make_island(int islemass, int starters, struct gen234_state *pstate, int min_specific_island_size)
Definition mapgen.c:2081
static int river_test_adjacent_swamp(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Definition mapgen.c:640
static struct fair_tile * fair_map_new(void)
Definition mapgen.c:2535
static int river_test_height_map(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Definition mapgen.c:656
struct terrain_select_list * mountain
Definition mapgen.c:97
static void fair_geometry_rand(struct fair_geometry_data *data)
Definition mapgen.c:2759
static int mountain_pct
Definition mapgen.c:165
#define map_pos_is_dry(ptile)
Definition mapgen.c:175
#define DMSIS
Definition mapgen.c:2226
void(* fair_geometry_func)(int *x, int *y)
Definition mapgen.c:2525
static void fair_do_iso_hex_symmetry1(int *x, int *y)
Definition mapgen.c:2703
static int desert_pct
Definition mapgen.c:163
static void fair_do_geometry(const struct fair_geometry_data *data, int *x, int *y)
Definition mapgen.c:2746
static void make_land(void)
Definition mapgen.c:1047
static void initworld(struct gen234_state *pstate)
Definition mapgen.c:2194
static struct fair_tile * fair_map_island_new(int size, int startpos_num)
Definition mapgen.c:3055
static void fair_map_destroy(struct fair_tile *pmap)
Definition mapgen.c:2543
static bool fair_map_tile_border(struct fair_tile *pmap, struct fair_tile *ptile, int dist)
Definition mapgen.c:2605
static void mapgenerator4(void)
Definition mapgen.c:2423
static void make_polar_land(void)
Definition mapgen.c:371
static int forest_pct
Definition mapgen.c:162
bool init
Definition mapgen.c:94
#define RIVERS_MAXTRIES
Definition mapgen.c:111
static void fair_do_hex_symmetry2(int *x, int *y)
Definition mapgen.c:2694
static void fill_island(int coast, long int *bucket, const struct terrain_select_list *tersel_list, const struct gen234_state *const pstate)
Definition mapgen.c:1643
#define map_pos_is_low(ptile)
Definition mapgen.c:192
static struct tile * rand_map_pos_characteristic(wetness_c wc, temperature_type tc, miscellaneous_c mc)
Definition mapgen.c:262
#define ini_hmap_low_level()
Definition mapgen.c:186
static void fair_map_tile_pos(struct fair_tile *pmap, struct fair_tile *ptile, int *x, int *y)
Definition mapgen.c:2551
static void adjust_terrain_param(void)
Definition mapgen.c:1484
static struct terrain_select * tersel_new(int weight, enum mapgen_terrain_property target, enum mapgen_terrain_property prefer, enum mapgen_terrain_property avoid, int temp_condition, int wet_condition)
Definition mapgen.c:1611
#define terrain_select_list_iterate(tersel_list, ptersel)
Definition mapgen.c:79
static bool test_miscellaneous(const struct tile *ptile, miscellaneous_c c)
Definition mapgen.c:220
static int river_test_adjacent_ocean(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Definition mapgen.c:593
static void print_mapgen_map(void)
Definition mapgen.c:1200
struct terrain_select_list * forest
Definition mapgen.c:95
static bool place_island(struct gen234_state *pstate)
Definition mapgen.c:1840
static void river_blockmark(struct river_map *privermap, struct tile *ptile)
Definition mapgen.c:666
static void make_huts(int number)
Definition mapgen.c:1527
static bool test_wetness(const struct tile *ptile, wetness_c c)
Definition mapgen.c:203
static void island_terrain_free(void)
Definition mapgen.c:2061
static bool is_tiny_island(struct tile *ptile)
Definition mapgen.c:1150
struct terrain_select_list * swamp
Definition mapgen.c:98
static struct extra_type * river_types[MAX_EXTRA_TYPES]
Definition mapgen.c:73
static int river_type_count
Definition mapgen.c:74
#define PLACE_ONE_TYPE(count, alternate, ter, wc, tc, mc, weight)
Definition mapgen.c:464
static int river_test_adjacent_highlands(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Definition mapgen.c:614
static void river_types_init(void)
Definition mapgen.c:2491
static bool near_safe_tiles(struct tile *ptile)
Definition mapgen.c:1512
static bool ok_for_separate_poles(struct tile *ptile)
Definition mapgen.c:353
static void fair_do_symmetry1(int *x, int *y)
Definition mapgen.c:2670
miscellaneous_c
Definition mapgen.c:194
@ MC_LOW
Definition mapgen.c:194
@ MC_NLOW
Definition mapgen.c:194
@ MC_NONE
Definition mapgen.c:194
static bool is_near_land(struct tile *ptile)
Definition mapgen.c:1823
static int fair_team_placement_horizontal(const void *a, const void *b)
Definition mapgen.c:2642
static bool condition_filter(const struct tile *ptile, const void *data)
Definition mapgen.c:247
static int swamp_pct
Definition mapgen.c:164
static struct tile * get_random_map_position_from_state(const struct gen234_state *const pstate)
Definition mapgen.c:1592
static bool is_resource_close(const struct tile *ptile)
Definition mapgen.c:1554
static void add_resources(int prob)
Definition mapgen.c:1568
static void mapgenerator3(void)
Definition mapgen.c:2326
static void fair_do_rotation(int *x, int *y)
Definition mapgen.c:2713
static bool fair_map_place_island_rand(struct fair_tile *ptarget, struct fair_tile *psource)
Definition mapgen.c:2888
static int river_test_highlands(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Definition mapgen.c:583
static void fill_island_rivers(int coast, long int *bucket, const struct gen234_state *const pstate)
Definition mapgen.c:1767
static void fair_map_make_huts(struct fair_tile *pmap)
Definition mapgen.c:3003
static int fair_team_placement_closest(const void *a, const void *b)
Definition mapgen.c:2632
static bool make_river(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Definition mapgen.c:786
static void island_terrain_init(void)
Definition mapgen.c:2000
static bool island_river_mouth_suitability(const struct tile *ptile, const struct extra_type *priver)
Definition mapgen.c:1722
static int river_test_rivergrid(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Definition mapgen.c:572
static bool map_generate_fair_islands(void)
Definition mapgen.c:3366
static void fair_do_iso_hex_rotation(int *x, int *y)
Definition mapgen.c:2735
static int river_pct
Definition mapgen.c:167
static void make_polar(void)
Definition mapgen.c:331
static bool create_island(int islemass, struct gen234_state *pstate)
Definition mapgen.c:1930
static void make_plain(struct tile *ptile, int *to_be_placed)
Definition mapgen.c:428
static bool island_river_suitability(const struct tile *ptile, const struct extra_type *priver)
Definition mapgen.c:1743
static bool fair_map_place_island_team(struct fair_tile *ptarget, int tx, int ty, struct fair_tile *psource, const struct iter_index *outwards_indices, int startpos_team_id)
Definition mapgen.c:2923
static struct test_func test_funcs[NUM_TEST_FUNCTIONS]
Definition mapgen.c:684
static bool fair_map_copy(struct fair_tile *ptarget, int tx, int ty, struct fair_tile *psource, const struct fair_geometry_data *data, int startpos_team_id)
Definition mapgen.c:2810
struct terrain_select_list * desert
Definition mapgen.c:96
static void make_relief(void)
Definition mapgen.c:294
#define HAS_POLES
Definition mapgen.c:157
static struct @96 island_terrain
static int river_test_adjacent_river(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Definition mapgen.c:604
static void fair_do_hex_rotation(int *x, int *y)
Definition mapgen.c:2724
static void remove_tiny_islands(void)
Definition mapgen.c:1176
static int river_test_swamp(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Definition mapgen.c:630
static int count_card_adjc_elevated_tiles(struct tile *ptile)
Definition mapgen.c:1914
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)
Definition mapgen.c:393
static bool terrain_is_too_high(struct tile *ptile, int thill, int my_height)
Definition mapgen.c:277
bool map_fractal_generate(bool autosize, struct unit_type *initial_unit)
Definition mapgen.c:1261
static void fair_do_symmetry2(int *x, int *y)
Definition mapgen.c:2678
static struct fair_tile * fair_map_pos_tile(struct fair_tile *pmap, int x, int y)
Definition mapgen.c:2561
static void tersel_free(struct terrain_select *ptersel)
Definition mapgen.c:1633
static long int checkmass
Definition mapgen.c:1835
static struct fair_tile * fair_map_tile_step(struct fair_tile *pmap, struct fair_tile *ptile, enum direction8 dir)
Definition mapgen.c:2590
static int river_test_blocked(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Definition mapgen.c:551
fair_tile_flag
Definition mapgen.c:2507
@ FTF_NONE
Definition mapgen.c:2508
@ FTF_NO_RESOURCE
Definition mapgen.c:2512
@ FTF_HAS_HUT
Definition mapgen.c:2513
@ FTF_ASSIGNED
Definition mapgen.c:2509
@ FTF_OCEAN
Definition mapgen.c:2510
@ FTF_STARTPOS
Definition mapgen.c:2511
@ FTF_NO_HUT
Definition mapgen.c:2514
void generator_init_topology(bool autosize)
int get_sqsize(void)
int map_colatitude(const struct tile *ptile)
bool near_singularity(const struct tile *ptile)
#define L_UNIT
#define COLD_LEVEL
#define ICE_BASE_LEVEL
#define TROPICAL_LEVEL
#define MAX_COLATITUDE
struct extra_type * pick_resource(const struct terrain *pterrain)
void set_all_ocean_tiles_placed(void)
void create_placed_map(void)
#define pmap(_tile)
void map_set_placed(struct tile *ptile)
void destroy_placed_map(void)
bool not_placed(const struct tile *ptile)
struct terrain * pick_terrain_by_flag(enum terrain_flag_id flag)
void assign_continent_numbers(void)
void regenerate_lakes(void)
void set_placed_near_pos(struct tile *ptile, int dist)
void smooth_water_depth(void)
bool placed_map_is_initialized(void)
struct terrain * pick_terrain(enum mapgen_terrain_property target, enum mapgen_terrain_property prefer, enum mapgen_terrain_property avoid)
struct terrain * most_shallow_ocean(bool frozen)
struct terrain * pick_ocean(int depth, bool frozen)
void map_unset_placed(struct tile *ptile)
#define fc_calloc(n, esz)
Definition mem.h:38
#define FC_FREE(ptr)
Definition mem.h:41
#define fc_malloc(sz)
Definition mem.h:34
struct nation_type * nation_of_player(const struct player *pplayer)
Definition nation.c:444
int player_count(void)
Definition player.c:817
#define player_list_iterate(playerlist, pplayer)
Definition player.h:555
#define player_list_iterate_end
Definition player.h:557
RANDOM_STATE fc_rand_state(void)
Definition rand.c:208
void fc_srand(RANDOM_TYPE seed)
Definition rand.c:161
void fc_rand_set_state(RANDOM_STATE state)
Definition rand.c:229
uint32_t RANDOM_TYPE
Definition rand.h:26
#define fc_rand(_size)
Definition rand.h:56
bool road_has_flag(const struct road_type *proad, enum road_flag_id flag)
Definition road.c:410
bool is_cardinal_only_road(const struct extra_type *pextra)
Definition road.c:483
int count_river_type_tile_card(struct civ_map *nmap, const struct tile *ptile, const struct extra_type *priver, bool percentage)
Definition road.c:356
int count_river_type_near_tile(struct civ_map *nmap, const struct tile *ptile, const struct extra_type *priver, bool percentage)
Definition road.c:383
int count_river_near_tile(struct civ_map *nmap, const struct tile *ptile, const struct extra_type *priver)
Definition road.c:334
void array_shuffle(int *array, int n)
Definition shared.c:2010
#define MAX_UINT32
Definition shared.h:81
#define CLIP(lower, current, upper)
Definition shared.h:57
#define ARRAY_SIZE(x)
Definition shared.h:85
#define FC_WRAP(value, range)
Definition shared.h:65
#define MIN(x, y)
Definition shared.h:55
#define FC_INFINITY
Definition shared.h:36
#define MAX(x, y)
Definition shared.h:54
size_t size
Definition specvec.h:72
struct sprite int int y
Definition sprite_g.h:31
struct sprite int x
Definition sprite_g.h:31
bool create_start_positions(enum map_startpos mode, struct unit_type *initial_unit)
Definition startpos.c:300
miscellaneous_c mc
Definition mapgen.c:240
wetness_c wc
Definition mapgen.c:238
temperature_type tc
Definition mapgen.c:239
int xsize
Definition map_types.h:78
randseed seed
Definition map_types.h:92
bool tinyisles
Definition map_types.h:100
int ysize
Definition map_types.h:78
enum direction8 valid_dirs[8]
Definition map_types.h:74
int riches
Definition map_types.h:93
Continent_id num_continents
Definition map_types.h:81
int num_iterate_outwards_indices
Definition map_types.h:77
int num_cardinal_dirs
Definition map_types.h:75
enum mapsize_type mapsize
Definition map_types.h:88
int num_valid_dirs
Definition map_types.h:75
enum map_startpos startpos
Definition map_types.h:99
bool have_resources
Definition map_types.h:108
struct civ_map::@42::@44 server
int steepness
Definition map_types.h:105
int wetness
Definition map_types.h:104
int tilesperplayer
Definition map_types.h:90
randseed seed_setting
Definition map_types.h:91
struct iter_index * iterate_outwards_indices
Definition map_types.h:76
int landpercent
Definition map_types.h:97
enum team_placement team_placement
Definition map_types.h:109
enum direction8 cardinal_dirs[8]
Definition map_types.h:74
int huts
Definition map_types.h:94
bool have_huts
Definition map_types.h:107
enum map_generator generator
Definition map_types.h:98
bool ocean_resources
Definition map_types.h:106
bool separatepoles
Definition map_types.h:101
Continent_id num_oceans
Definition map_types.h:82
int temperature
Definition map_types.h:103
fair_geometry_func transform[4]
Definition mapgen.c:2527
bv_extras extras
Definition mapgen.c:2521
struct terrain * pterrain
Definition mapgen.c:2519
enum fair_tile_flag flags
Definition mapgen.c:2518
int startpos_team_id
Definition mapgen.c:2522
struct extra_type * presource
Definition mapgen.c:2520
int isleindex
Definition mapgen.c:58
long int totalmass
Definition mapgen.c:59
int dist
Definition city.h:110
int dx
Definition city.h:110
int dy
Definition city.h:110
struct dbv ok
Definition mapgen.c:117
struct dbv blocked
Definition mapgen.c:116
Definition map.c:41
int wet_condition
Definition mapgen.c:69
enum mapgen_terrain_property avoid
Definition mapgen.c:67
int temp_condition
Definition mapgen.c:68
enum mapgen_terrain_property target
Definition mapgen.c:65
enum mapgen_terrain_property prefer
Definition mapgen.c:66
int property[MG_COUNT]
Definition terrain.h:253
bool fatal
Definition mapgen.c:680
int(* func)(struct river_map *privermap, struct tile *ptile, struct extra_type *priver)
Definition mapgen.c:679
Definition tile.h:50
struct civ_map map
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define fc__fallthrough
Definition support.h:119
struct team * team_by_number(const int team_id)
Definition team.c:400
const char * team_rule_name(const struct team *pteam)
Definition team.c:410
int team_number(const struct team *pteam)
Definition team.c:391
const struct player_list * team_members(const struct team *pteam)
Definition team.c:456
#define teams_iterate_end
Definition team.h:87
#define teams_iterate(_pteam)
Definition team.h:82
bool temperature_is_initialized(void)
void destroy_tmap(void)
bool tmap_is(const struct tile *ptile, temperature_type tt)
bool is_temperature_type_near(const struct tile *ptile, temperature_type tt)
void create_tmap(bool real)
int temperature_type
#define TT_COLD
#define TT_NHOT
#define TT_HOT
#define TT_FROZEN
#define TT_TROPICAL
#define TT_ALL
#define TT_NFROZEN
Terrain_type_id terrain_count(void)
Definition terrain.c:118
int count_terrain_class_near_tile(const struct civ_map *nmap, const struct tile *ptile, bool cardinal_only, bool percentage, enum terrain_class tclass)
Definition terrain.c:633
bool is_terrain_class_card_near(const struct civ_map *nmap, const struct tile *ptile, enum terrain_class tclass)
Definition terrain.c:591
Terrain_type_id terrain_index(const struct terrain *pterrain)
Definition terrain.c:138
const char * terrain_rule_name(const struct terrain *pterrain)
Definition terrain.c:247
int count_terrain_property_near_tile(const struct civ_map *nmap, const struct tile *ptile, bool cardinal_only, bool percentage, enum mapgen_terrain_property prop)
Definition terrain.c:369
bool is_terrain_near_tile(const struct civ_map *nmap, const struct tile *ptile, const struct terrain *pterrain, bool check_self)
Definition terrain.c:348
#define terrain_type_iterate(_p)
Definition terrain.h:373
#define T_UNKNOWN
Definition terrain.h:57
#define is_ocean(pterrain)
Definition terrain.h:301
#define is_ocean_tile(ptile)
Definition terrain.h:303
#define TERRAIN_OCEAN_DEPTH_MINIMUM
Definition terrain.h:254
#define terrain_type_iterate_end
Definition terrain.h:379
#define TERRAIN_OCEAN_DEPTH_MAXIMUM
Definition terrain.h:255
#define terrain_has_flag(terr, flag)
Definition terrain.h:283
void tile_add_extra(struct tile *ptile, const struct extra_type *pextra)
Definition tile.c:955
void tile_set_terrain(struct tile *ptile, struct terrain *pterrain)
Definition tile.c:124
void tile_virtual_destroy(struct tile *vtile)
Definition tile.c:1033
bool tile_has_river(const struct tile *ptile)
Definition tile.c:852
void tile_set_owner(struct tile *ptile, struct player *pplayer, struct tile *claimer)
Definition tile.c:69
struct tile * tile_virtual_new(const struct tile *ptile)
Definition tile.c:981
bool tile_extra_rm_apply(struct tile *ptile, struct extra_type *tgt)
Definition tile.c:601
void tile_set_resource(struct tile *ptile, struct extra_type *presource)
Definition tile.c:349
void tile_set_continent(struct tile *ptile, Continent_id val)
Definition tile.c:382
#define tile_index(_pt_)
Definition tile.h:88
#define tile_resource(_tile)
Definition tile.h:102
#define tile_terrain(_tile)
Definition tile.h:110
#define TILE_XY(ptile)
Definition tile.h:43
static const bv_extras * tile_extras(const struct tile *ptile)
Definition tile.h:120
#define tile_continent(_tile)
Definition tile.h:92
#define tile_has_extra(ptile, pextra)
Definition tile.h:147