Freeciv-3.2: /fast/freeciv/nightly/S3_2/server/generator/mapgen_utils.c Source File

Freeciv-3.2

Loading...
Searching...
No Matches
mapgen_utils.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 2004 - Marcelo J. Burda
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#ifdef HAVE_CONFIG_H
14#include <fc_config.h>
15#endif
16
17/* utility */
18#include "fcintl.h"
19#include "log.h"
20#include "rand.h"
21#include "support.h" /* bool type */
22
23/* common */
24#include "map.h"
25#include "packets.h"
26#include "terrain.h"
27#include "tile.h"
28
29#include "mapgen_utils.h"
30
31/**************************************************************************
32 Map that contains, according to circumstances, information on whether
33 we have already placed terrain (special, hut) here.
34**************************************************************************/
35 static bool *placed_map;
36
37/**********************************************************************/
40 bool placed_map_is_initialized(void)
41{
42 return placed_map != NULL;
43}
44
45/**********************************************************************/
48 void create_placed_map(void)
49{
50 fc_assert_ret(!placed_map_is_initialized());
51 placed_map = fc_malloc (sizeof(bool) * MAP_INDEX_SIZE);
52 INITIALIZE_ARRAY(placed_map, MAP_INDEX_SIZE, FALSE );
53}
54
55/**********************************************************************/
58 void destroy_placed_map(void)
59{
60 fc_assert_ret(placed_map_is_initialized());
61 free(placed_map);
62 placed_map = NULL;
63}
64
65
66#define pmap(_tile) (placed_map[tile_index(_tile)])
67
68/**********************************************************************/
71 bool not_placed(const struct tile *ptile)
72{
73 return !pmap(ptile);
74}
75
76/**********************************************************************/
79 void map_set_placed(struct tile *ptile)
80{
81 pmap(ptile) = TRUE;
82}
83
84/**********************************************************************/
87 void map_unset_placed(struct tile *ptile)
88{
89 pmap(ptile) = FALSE;
90}
91
92/**********************************************************************/
95 void set_all_ocean_tiles_placed(void)
96{
97 whole_map_iterate(&(wld.map), ptile) {
98 if (is_ocean_tile(ptile)) {
99 map_set_placed(ptile);
100 }
101 } whole_map_iterate_end;
102}
103
104/**********************************************************************/
107 void set_placed_near_pos(struct tile *ptile, int dist)
108{
109 square_iterate(&(wld.map), ptile, dist, tile1) {
110 map_set_placed(tile1);
111 } square_iterate_end;
112}
113
114/**********************************************************************/
123 void adjust_int_map_filtered(int *int_map, int int_map_min,
124 int int_map_max, void *data,
125 bool (*filter)(const struct tile *ptile,
126 const void *data))
127{
128 const int int_map_delta = int_map_max - int_map_min;
129 int minval = 0, maxval = 0, total = 0;
130 bool first = TRUE;
131
132 /* Determine minimum and maximum value. */
133 whole_map_iterate_filtered(ptile, data, filter) {
134 if (first) {
135 minval = int_map[tile_index(ptile)];
136 maxval = int_map[tile_index(ptile)];
137 } else {
138 maxval = MAX(maxval, int_map[tile_index(ptile)]);
139 minval = MIN(minval, int_map[tile_index(ptile)]);
140 }
141 first = FALSE;
142 total++;
143 } whole_map_iterate_filtered_end;
144
145 if (total == 0) {
146 return;
147 }
148
149 {
150 int const size = 1 + maxval - minval;
151 int i, count = 0, frequencies[size];
152
153 INITIALIZE_ARRAY(frequencies, size, 0);
154
155 /* Translate value so the minimum value is 0
156 and count the number of occurrences of all values to initialize the
157 frequencies[] */
158 whole_map_iterate_filtered(ptile, data, filter) {
159 int_map[tile_index(ptile)] -= minval;
160 frequencies[int_map[tile_index(ptile)]]++;
161 } whole_map_iterate_filtered_end;
162
163 /* create the linearize function as "incremental" frequencies */
164 for (i = 0; i < size; i++) {
165 count += frequencies[i];
166 frequencies[i] = int_map_min + (count * int_map_delta) / total;
167 }
168
169 /* apply the linearize function */
170 whole_map_iterate_filtered(ptile, data, filter) {
171 int_map[tile_index(ptile)] = frequencies[int_map[tile_index(ptile)]];
172 } whole_map_iterate_filtered_end;
173 }
174}
175
176/**********************************************************************/
179 bool is_normal_nat_pos(int x, int y)
180{
181 NATIVE_TO_MAP_POS(&x, &y, x, y);
182 return is_normal_map_pos(x, y);
183}
184
185/**********************************************************************/
191 void smooth_int_map(int *int_map, bool zeroes_at_edges)
192{
193 static const float weight_standard[5] = { 0.13, 0.19, 0.37, 0.19, 0.13 };
194 static const float weight_isometric[5] = { 0.15, 0.21, 0.29, 0.21, 0.15 };
195 const float *weight;
196 bool axe = TRUE;
197 int *target_map, *source_map;
198 int *alt_int_map = fc_calloc(MAP_INDEX_SIZE, sizeof(*alt_int_map));
199
200 fc_assert_ret(NULL != int_map);
201
202 weight = weight_standard;
203 target_map = alt_int_map;
204 source_map = int_map;
205
206 do {
207 whole_map_iterate(&(wld.map), ptile) {
208 float N = 0, D = 0;
209
210 axis_iterate(&(wld.map), ptile, pnear, i, 2, axe) {
211 D += weight[i + 2];
212 N += weight[i + 2] * source_map[tile_index(pnear)];
213 } axis_iterate_end;
214 if (zeroes_at_edges) {
215 D = 1;
216 }
217 target_map[tile_index(ptile)] = (float)N / D;
218 } whole_map_iterate_end;
219
220 if (MAP_IS_ISOMETRIC) {
221 weight = weight_isometric;
222 }
223
224 axe = !axe;
225
226 source_map = alt_int_map;
227 target_map = int_map;
228
229 } while (!axe);
230
231 FC_FREE(alt_int_map);
232}
233
234/* These arrays are indexed by continent number (or negative of the
235 * ocean number) so the 0th element is unused and the array is 1 element
236 * larger than you'd expect.
237 *
238 * The lake surrounders array tells how many land continents surround each
239 * ocean (or -1 if the ocean touches more than one continent).
240 *
241 * The _sizes arrays give the sizes (in tiles) of each continent and
242 * ocean.
243 */
244 static Continent_id *lake_surrounders = NULL;
245 static int *continent_sizes = NULL;
246 static int *ocean_sizes = NULL;
247
248/**********************************************************************/
251 static void recalculate_lake_surrounders(void)
252{
253 const size_t size = (wld.map.num_oceans + 1) * sizeof(*lake_surrounders);
254
255 lake_surrounders = fc_realloc(lake_surrounders, size);
256 memset(lake_surrounders, 0, size);
257
258 whole_map_iterate(&(wld.map), ptile) {
259 const struct terrain *pterrain = tile_terrain(ptile);
260 Continent_id cont = tile_continent(ptile);
261
262 if (T_UNKNOWN == pterrain) {
263 continue;
264 }
265
266 if (terrain_type_terrain_class(pterrain) != TC_OCEAN) {
267 adjc_iterate(&(wld.map), ptile, tile2) {
268 Continent_id cont2 = tile_continent(tile2);
269
270 if (is_ocean_tile(tile2)) {
271 if (lake_surrounders[-cont2] == 0) {
272 lake_surrounders[-cont2] = cont;
273 } else if (lake_surrounders[-cont2] != cont) {
274 lake_surrounders[-cont2] = -1;
275 }
276 }
277 } adjc_iterate_end;
278 }
279 } whole_map_iterate_end;
280}
281
282/**********************************************************************/
290 static void assign_continent_flood(struct tile *ptile, bool is_land, int nr)
291{
292 struct tile_list *tlist = NULL;
293 const struct terrain *pterrain;
294
295 fc_assert_ret(ptile != NULL);
296
297#ifndef FREECIV_NDEBUG
298 pterrain = tile_terrain(ptile);
299#endif
300 /* Check if the initial tile is a valid tile for continent / ocean. */
301 fc_assert_ret(tile_continent(ptile) == 0
302 && T_UNKNOWN != pterrain
303 && XOR(is_land, terrain_type_terrain_class(pterrain) == TC_OCEAN));
304
305 /* Create tile list and insert the initial tile. */
306 tlist = tile_list_new();
307 tile_list_append(tlist, ptile);
308
309 while (tile_list_size(tlist) > 0) {
310 struct tile *ptile2 = tile_list_get(tlist, 0);
311
312 /* Iterate over the adjacent tiles. */
313 adjc_iterate(&(wld.map), ptile2, ptile3) {
314 pterrain = tile_terrain(ptile3);
315
316 /* Check if it is a valid tile for continent / ocean. */
317 if (tile_continent(ptile3) != 0
318 || T_UNKNOWN == pterrain
319 || !XOR(is_land, terrain_type_terrain_class(pterrain) == TC_OCEAN)) {
320 continue;
321 }
322
323 /* Add the tile to the list of tiles to check. */
324 if (!tile_list_search(tlist, ptile3)) {
325 tile_list_append(tlist, ptile3);
326 }
327 } adjc_iterate_end;
328
329 /* Set the continent data and remove the tile from the list. */
330 tile_set_continent(ptile2, nr);
331 tile_list_remove(tlist, ptile2);
332
333 /* Count the tile */
334 if (nr < 0) {
335 ocean_sizes[-nr]++;
336 } else {
337 continent_sizes[nr]++;
338 }
339 }
340
341 tile_list_destroy(tlist);
342}
343
344/**********************************************************************/
350 void regenerate_lakes(void)
351{
352 struct terrain *lake_for_ocean[2][wld.map.num_oceans];
353
354 {
355 struct terrain *lakes[2][5];
356 int num_laketypes[2] = { 0, 0 };
357 int i;
358
359 terrain_type_iterate(pterr) {
360 if (terrain_has_flag(pterr, TER_FRESHWATER)
361 && !terrain_has_flag(pterr, TER_NOT_GENERATED)) {
362 int frozen = terrain_has_flag(pterr, TER_FROZEN);
363
364 if (num_laketypes[frozen] < ARRAY_SIZE(lakes[frozen])) {
365 lakes[frozen][num_laketypes[frozen]++] = pterr;
366 } else {
367 log_verbose("Ruleset has more than %d %s lake types, ignoring %s",
368 (int) ARRAY_SIZE(lakes[frozen]),
369 frozen ? "frozen" : "unfrozen",
370 terrain_rule_name(pterr));
371 }
372 }
373 } terrain_type_iterate_end;
374
375 /* We don't want to generate any boundaries between fresh and
376 * non-fresh water.
377 * If there are no unfrozen lake types, just give up.
378 * Else if there are no frozen lake types, use unfrozen lake instead.
379 * If both are available, preserve frozenness of previous terrain. */
380 if (num_laketypes[0] == 0) {
381 return;
382 } else if (num_laketypes[1] == 0) {
383 for (i = 0; i < wld.map.num_oceans; i++) {
384 lake_for_ocean[0][i] = lake_for_ocean[1][i]
385 = lakes[0][fc_rand(num_laketypes[0])];
386 }
387 } else {
388 for (i = 0; i < wld.map.num_oceans; i++) {
389 int frozen;
390 for (frozen = 0; frozen < 2; frozen++) {
391 lake_for_ocean[frozen][i]
392 = lakes[frozen][fc_rand(num_laketypes[frozen])];
393 }
394 }
395 }
396 }
397
398 whole_map_iterate(&(wld.map), ptile) {
399 struct terrain *pterrain = tile_terrain(ptile);
400 Continent_id here = tile_continent(ptile);
401
402 if (T_UNKNOWN == pterrain) {
403 continue;
404 }
405 if (terrain_type_terrain_class(pterrain) != TC_OCEAN) {
406 continue;
407 }
408 if (0 < lake_surrounders[-here]) {
409 if (terrain_control.lake_max_size >= ocean_sizes[-here]) {
410 int frozen = terrain_has_flag(pterrain, TER_FROZEN);
411 tile_change_terrain(ptile, lake_for_ocean[frozen][-here-1]);
412 }
413 }
414 } whole_map_iterate_end;
415}
416
417/**********************************************************************/
420 int get_lake_surrounders(Continent_id cont)
421{
422 return lake_surrounders[-cont];
423}
424
425/**********************************************************************/
428 int get_continent_size(Continent_id id)
429{
430 fc_assert_ret_val(id > 0, -1);
431 return continent_sizes[id];
432}
433
434/**********************************************************************/
438 int get_ocean_size(Continent_id id)
439{
440 fc_assert_ret_val(id > 0, -1);
441 return ocean_sizes[id];
442}
443
444/**********************************************************************/
452 void assign_continent_numbers(void)
453{
454 /* Initialize */
455 wld.map.num_continents = 0;
456 wld.map.num_oceans = 0;
457
458 whole_map_iterate(&(wld.map), ptile) {
459 tile_set_continent(ptile, 0);
460 } whole_map_iterate_end;
461
462 /* Assign new numbers */
463 whole_map_iterate(&(wld.map), ptile) {
464 const struct terrain *pterrain = tile_terrain(ptile);
465
466 if (tile_continent(ptile) != 0) {
467 /* Already assigned. */
468 continue;
469 }
470
471 if (T_UNKNOWN == pterrain) {
472 continue; /* Can't assign this. */
473 }
474
475 if (terrain_type_terrain_class(pterrain) != TC_OCEAN) {
476 wld.map.num_continents++;
477 continent_sizes = fc_realloc(continent_sizes,
478 (wld.map.num_continents + 1) * sizeof(*continent_sizes));
479 continent_sizes[wld.map.num_continents] = 0;
480 assign_continent_flood(ptile, TRUE, wld.map.num_continents);
481 } else {
482 wld.map.num_oceans++;
483 ocean_sizes = fc_realloc(ocean_sizes,
484 (wld.map.num_oceans + 1) * sizeof(*ocean_sizes));
485 ocean_sizes[wld.map.num_oceans] = 0;
486 assign_continent_flood(ptile, FALSE, -wld.map.num_oceans);
487 }
488 } whole_map_iterate_end;
489
490 recalculate_lake_surrounders();
491
492 log_verbose("Map has %d continents and %d oceans",
493 wld.map.num_continents, wld.map.num_oceans);
494}
495
496/**********************************************************************/
500 struct terrain *most_shallow_ocean(bool frozen)
501{
502 bool oceans = FALSE, frozenmatch = FALSE;
503 struct terrain *shallow = NULL;
504
505 terrain_type_iterate(pterr) {
506 if (is_ocean(pterr) && !terrain_has_flag(pterr, TER_NOT_GENERATED)) {
507 bool nonfresh = !terrain_has_flag(pterr, TER_FRESHWATER);
508 bool frozen_ok = terrain_has_flag(pterr, TER_FROZEN) == frozen;
509
510 if (!oceans && nonfresh) {
511 /* First ocean type seen, reset even if frozenness doesn't match */
512 oceans = TRUE;
513 shallow = pterr;
514 frozenmatch = frozen_ok;
515 continue;
516 } else if (oceans && !nonfresh) {
517 /* Dismiss any step backward on freshness */
518 continue;
519 }
520 if (!frozenmatch && frozen_ok) {
521 /* Prefer terrain that matches frozenness (as long as we don't go
522 * backwards on freshness) */
523 frozenmatch = TRUE;
524 shallow = pterr;
525 continue;
526 } else if (frozenmatch && !frozen_ok) {
527 /* Dismiss any step backward on frozenness */
528 continue;
529 }
530 if (!shallow
531 || pterr->property[MG_OCEAN_DEPTH] <
532 shallow->property[MG_OCEAN_DEPTH]) {
533 shallow = pterr;
534 }
535 }
536 } terrain_type_iterate_end;
537
538 return shallow;
539}
540
541/**********************************************************************/
546 struct terrain *pick_ocean(int depth, bool frozen)
547{
548 struct terrain *best_terrain = NULL;
549 int best_match = TERRAIN_OCEAN_DEPTH_MAXIMUM;
550
551 terrain_type_iterate(pterrain) {
552 if (terrain_type_terrain_class(pterrain) == TC_OCEAN
553 && TERRAIN_OCEAN_DEPTH_MINIMUM <= pterrain-> property[MG_OCEAN_DEPTH]
554 && !!frozen == terrain_has_flag(pterrain, TER_FROZEN)
555 && !terrain_has_flag(pterrain, TER_NOT_GENERATED)) {
556 int match = abs(depth - pterrain->property[MG_OCEAN_DEPTH]);
557
558 if (best_match > match) {
559 best_match = match;
560 best_terrain = pterrain;
561 }
562 }
563 } terrain_type_iterate_end;
564
565 return best_terrain;
566}
567
568/**********************************************************************/
571 static int real_distance_to_land(const struct tile *ptile, int max)
572{
573 square_dxy_iterate(&(wld.map), ptile, max, atile, dx, dy) {
574 if (terrain_type_terrain_class(tile_terrain(atile)) != TC_OCEAN) {
575 return map_vector_to_real_distance(dx, dy);
576 }
577 } square_dxy_iterate_end;
578
579 return max + 1;
580}
581
582/**********************************************************************/
586 static struct terrain *most_adjacent_ocean_type(const struct tile *ptile)
587{
588 const int need = 2 * wld.map.num_valid_dirs / 3;
589 int count;
590
591 terrain_type_iterate(pterrain) {
592 if (terrain_type_terrain_class(pterrain) != TC_OCEAN) {
593 continue;
594 }
595
596 count = 0;
597 adjc_iterate(&(wld.map), ptile, atile) {
598 if (pterrain == tile_terrain(atile) && need <= ++count) {
599 return pterrain;
600 }
601 } adjc_iterate_end;
602 } terrain_type_iterate_end;
603
604 return NULL;
605}
606
607/**********************************************************************/
612 void smooth_water_depth(void)
613{
614 const int OCEAN_DEPTH_STEP = 25;
615 const int OCEAN_DEPTH_RAND = 15;
616 const int OCEAN_DIST_MAX = TERRAIN_OCEAN_DEPTH_MAXIMUM / OCEAN_DEPTH_STEP;
617 struct terrain *ocean;
618 int dist;
619
620 /* First, improve the coasts. */
621 whole_map_iterate(&(wld.map), ptile) {
622 if (terrain_type_terrain_class(tile_terrain(ptile)) != TC_OCEAN) {
623 continue;
624 }
625
626 dist = real_distance_to_land(ptile, OCEAN_DIST_MAX);
627 if (dist <= OCEAN_DIST_MAX) {
628 /* Overwrite the terrain (but preserve frozenness). */
629 ocean = pick_ocean(dist * OCEAN_DEPTH_STEP
630 + fc_rand(OCEAN_DEPTH_RAND),
631 terrain_has_flag(tile_terrain(ptile), TER_FROZEN));
632 if (NULL != ocean && ocean != tile_terrain(ptile)) {
633 log_debug("Replacing %s by %s at (%d, %d) "
634 "to have shallow ocean on coast.",
635 terrain_rule_name(tile_terrain(ptile)),
636 terrain_rule_name(ocean), TILE_XY(ptile));
637 tile_set_terrain(ptile, ocean);
638 }
639 }
640 } whole_map_iterate_end;
641
642 /* Now, try to have something more continuous. */
643 whole_map_iterate(&(wld.map), ptile) {
644 if (terrain_type_terrain_class(tile_terrain(ptile)) != TC_OCEAN) {
645 continue;
646 }
647
648 ocean = most_adjacent_ocean_type(ptile);
649 if (NULL != ocean && ocean != tile_terrain(ptile)) {
650 log_debug("Replacing %s by %s at (%d, %d) "
651 "to smooth the ocean types.",
652 terrain_rule_name(tile_terrain(ptile)),
653 terrain_rule_name(ocean), TILE_XY(ptile));
654 tile_set_terrain(ptile, ocean);
655 }
656 } whole_map_iterate_end;
657}
658
659/**********************************************************************/
662 void generator_free(void)
663{
664 if (lake_surrounders != NULL) {
665 free(lake_surrounders);
666 lake_surrounders = NULL;
667 }
668 if (continent_sizes != NULL) {
669 free(continent_sizes);
670 continent_sizes = NULL;
671 }
672 if (ocean_sizes != NULL) {
673 free(ocean_sizes);
674 ocean_sizes = NULL;
675 }
676}
677
678/**********************************************************************/
682 struct terrain *pick_terrain_by_flag(enum terrain_flag_id flag)
683{
684 bool has_flag[terrain_count()];
685 int count = 0;
686
687 terrain_type_iterate(pterrain) {
688 if ((has_flag[terrain_index(pterrain)]
689 = (terrain_has_flag(pterrain, flag)
690 && !terrain_has_flag(pterrain, TER_NOT_GENERATED)))) {
691 count++;
692 }
693 } terrain_type_iterate_end;
694
695 count = fc_rand(count);
696 terrain_type_iterate(pterrain) {
697 if (has_flag[terrain_index(pterrain)]) {
698 if (count == 0) {
699 return pterrain;
700 }
701 count--;
702 }
703 } terrain_type_iterate_end;
704
705 return T_UNKNOWN;
706}
707
708
709/**********************************************************************/
725 struct terrain *pick_terrain(enum mapgen_terrain_property target,
726 enum mapgen_terrain_property prefer,
727 enum mapgen_terrain_property avoid)
728{
729 int sum = 0;
730
731 /* Find the total weight. */
732 terrain_type_iterate(pterrain) {
733 if (!terrain_has_flag(pterrain, TER_NOT_GENERATED)) {
734 if (avoid != MG_UNUSED && pterrain->property[avoid] > 0) {
735 continue;
736 }
737 if (prefer != MG_UNUSED && pterrain->property[prefer] == 0) {
738 continue;
739 }
740
741 if (target != MG_UNUSED) {
742 sum += pterrain->property[target];
743 } else {
744 sum++;
745 }
746 }
747 } terrain_type_iterate_end;
748
749 /* Now pick. */
750 sum = fc_rand(sum);
751
752 /* Finally figure out which one we picked. */
753 terrain_type_iterate(pterrain) {
754 if (!terrain_has_flag(pterrain, TER_NOT_GENERATED)) {
755 int property;
756
757 if (avoid != MG_UNUSED && pterrain->property[avoid] > 0) {
758 continue;
759 }
760 if (prefer != MG_UNUSED && pterrain->property[prefer] == 0) {
761 continue;
762 }
763
764 if (target != MG_UNUSED) {
765 property = pterrain->property[target];
766 } else {
767 property = 1;
768 }
769 if (sum < property) {
770 return pterrain;
771 }
772 sum -= property;
773 }
774 } terrain_type_iterate_end;
775
776 /* This can happen with sufficient quantities of preferred and avoided
777 * characteristics. Drop a requirement and try again. */
778 if (prefer != MG_UNUSED) {
779 log_debug("pick_terrain(target: %s, [dropping prefer: %s], avoid: %s)",
780 mapgen_terrain_property_name(target),
781 mapgen_terrain_property_name(prefer),
782 mapgen_terrain_property_name(avoid));
783 return pick_terrain(target, MG_UNUSED, avoid);
784 } else if (avoid != MG_UNUSED) {
785 log_debug("pick_terrain(target: %s, prefer: MG_UNUSED, [dropping avoid: %s])",
786 mapgen_terrain_property_name(target),
787 mapgen_terrain_property_name(avoid));
788 return pick_terrain(target, prefer, MG_UNUSED);
789 } else {
790 log_debug("pick_terrain([dropping target: %s], prefer: MG_UNUSED, avoid: MG_UNUSED)",
791 mapgen_terrain_property_name(target));
792 return pick_terrain(MG_UNUSED, prefer, avoid);
793 }
794}
795
796/**********************************************************************/
800 struct extra_type *pick_resource(const struct terrain *pterrain)
801{
802 int freq_sum = 0;
803 struct extra_type *result = NULL;
804
805 fc_assert_ret_val(NULL != pterrain, NULL);
806
807 terrain_resources_iterate(pterrain, res, freq) {
808 /* This is a standard way to get a weighted random element from
809 * pterrain->resources with weights from pterrain->resource_freq,
810 * without computing its length or total weight in advance.
811 * Note that if *(pterrain->resources) == NULL,
812 * then this loop is a no-op. */
813
814 if (res->generated && freq > 0) {
815 freq_sum += freq;
816 if (freq > fc_rand(freq_sum)) {
817 result = res;
818 }
819 }
820 } terrain_resources_iterate_end;
821
822 return result;
823}
incite_cost
char * incite_cost
Definition comments.c:74
id
int int id
Definition editgui_g.h:28
Continent_id
signed short Continent_id
Definition fc_types.h:375
fcintl.h
MG_UNUSED
#define MG_UNUSED
Definition fracture_map.h:32
wld
struct world wld
Definition game.c:63
log.h
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
log_verbose
#define log_verbose(message,...)
Definition log.h:109
fc_assert_ret_val
#define fc_assert_ret_val(condition, val)
Definition log.h:194
log_debug
#define log_debug(message,...)
Definition log.h:115
is_normal_map_pos
bool is_normal_map_pos(int x, int y)
Definition map.c:963
terrain_control
struct terrain_misc terrain_control
Definition map.c:69
map_vector_to_real_distance
int map_vector_to_real_distance(int dx, int dy)
Definition map.c:578
map.h
adjc_iterate_end
#define adjc_iterate_end
Definition map.h:433
MAP_INDEX_SIZE
#define MAP_INDEX_SIZE
Definition map.h:137
square_iterate
#define square_iterate(nmap, center_tile, radius, tile_itr)
Definition map.h:391
MAP_IS_ISOMETRIC
#define MAP_IS_ISOMETRIC
Definition map.h:42
adjc_iterate
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition map.h:428
NATIVE_TO_MAP_POS
#define NATIVE_TO_MAP_POS(pmap_x, pmap_y, nat_x, nat_y)
Definition map.h:166
square_iterate_end
#define square_iterate_end
Definition map.h:394
whole_map_iterate
#define whole_map_iterate(_map, _tile)
Definition map.h:545
square_dxy_iterate
#define square_dxy_iterate(nmap, center_tile, radius, tile_itr, dx_itr, dy_itr)
Definition map.h:381
whole_map_iterate_end
#define whole_map_iterate_end
Definition map.h:554
square_dxy_iterate_end
#define square_dxy_iterate_end
Definition map.h:384
get_continent_size
int get_continent_size(Continent_id id)
Definition mapgen_utils.c:428
pick_resource
struct extra_type * pick_resource(const struct terrain *pterrain)
Definition mapgen_utils.c:800
most_adjacent_ocean_type
static struct terrain * most_adjacent_ocean_type(const struct tile *ptile)
Definition mapgen_utils.c:586
continent_sizes
static int * continent_sizes
Definition mapgen_utils.c:245
ocean_sizes
static int * ocean_sizes
Definition mapgen_utils.c:246
smooth_int_map
void smooth_int_map(int *int_map, bool zeroes_at_edges)
Definition mapgen_utils.c:191
set_all_ocean_tiles_placed
void set_all_ocean_tiles_placed(void)
Definition mapgen_utils.c:95
create_placed_map
void create_placed_map(void)
Definition mapgen_utils.c:48
real_distance_to_land
static int real_distance_to_land(const struct tile *ptile, int max)
Definition mapgen_utils.c:571
pmap
#define pmap(_tile)
Definition mapgen_utils.c:66
placed_map
static bool * placed_map
Definition mapgen_utils.c:35
map_set_placed
void map_set_placed(struct tile *ptile)
Definition mapgen_utils.c:79
destroy_placed_map
void destroy_placed_map(void)
Definition mapgen_utils.c:58
adjust_int_map_filtered
void adjust_int_map_filtered(int *int_map, int int_map_min, int int_map_max, void *data, bool(*filter)(const struct tile *ptile, const void *data))
Definition mapgen_utils.c:123
not_placed
bool not_placed(const struct tile *ptile)
Definition mapgen_utils.c:71
pick_terrain_by_flag
struct terrain * pick_terrain_by_flag(enum terrain_flag_id flag)
Definition mapgen_utils.c:682
assign_continent_numbers
void assign_continent_numbers(void)
Definition mapgen_utils.c:452
lake_surrounders
static Continent_id * lake_surrounders
Definition mapgen_utils.c:244
regenerate_lakes
void regenerate_lakes(void)
Definition mapgen_utils.c:350
recalculate_lake_surrounders
static void recalculate_lake_surrounders(void)
Definition mapgen_utils.c:251
set_placed_near_pos
void set_placed_near_pos(struct tile *ptile, int dist)
Definition mapgen_utils.c:107
get_ocean_size
int get_ocean_size(Continent_id id)
Definition mapgen_utils.c:438
generator_free
void generator_free(void)
Definition mapgen_utils.c:662
smooth_water_depth
void smooth_water_depth(void)
Definition mapgen_utils.c:612
placed_map_is_initialized
bool placed_map_is_initialized(void)
Definition mapgen_utils.c:40
is_normal_nat_pos
bool is_normal_nat_pos(int x, int y)
Definition mapgen_utils.c:179
pick_terrain
struct terrain * pick_terrain(enum mapgen_terrain_property target, enum mapgen_terrain_property prefer, enum mapgen_terrain_property avoid)
Definition mapgen_utils.c:725
most_shallow_ocean
struct terrain * most_shallow_ocean(bool frozen)
Definition mapgen_utils.c:500
pick_ocean
struct terrain * pick_ocean(int depth, bool frozen)
Definition mapgen_utils.c:546
assign_continent_flood
static void assign_continent_flood(struct tile *ptile, bool is_land, int nr)
Definition mapgen_utils.c:290
map_unset_placed
void map_unset_placed(struct tile *ptile)
Definition mapgen_utils.c:87
get_lake_surrounders
int get_lake_surrounders(Continent_id cont)
Definition mapgen_utils.c:420
mapgen_utils.h
whole_map_iterate_filtered
#define whole_map_iterate_filtered(_tile, pdata, pfilter)
Definition mapgen_utils.h:85
axis_iterate
#define axis_iterate(nmap, center_tile, _tile, _index, dist, is_X_axis)
Definition mapgen_utils.h:60
whole_map_iterate_filtered_end
#define whole_map_iterate_filtered_end
Definition mapgen_utils.h:93
axis_iterate_end
#define axis_iterate_end
Definition mapgen_utils.h:77
fc_calloc
#define fc_calloc(n, esz)
Definition mem.h:38
FC_FREE
#define FC_FREE(ptr)
Definition mem.h:41
fc_realloc
#define fc_realloc(ptr, sz)
Definition mem.h:36
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
packets.h
rand.h
fc_rand
#define fc_rand(_size)
Definition rand.h:56
INITIALIZE_ARRAY
#define INITIALIZE_ARRAY(array, size, value)
Definition shared.h:101
ARRAY_SIZE
#define ARRAY_SIZE(x)
Definition shared.h:85
MIN
#define MIN(x, y)
Definition shared.h:55
MAX
#define MAX(x, y)
Definition shared.h:54
XOR
#define XOR(p, q)
Definition shared.h:71
size
size_t size
Definition specvec.h:72
y
struct sprite int int y
Definition sprite_g.h:31
x
struct sprite int x
Definition sprite_g.h:31
civ_map::num_continents
int num_continents
Definition map_types.h:81
civ_map::num_valid_dirs
int num_valid_dirs
Definition map_types.h:75
civ_map::num_oceans
int num_oceans
Definition map_types.h:82
extra_type
Definition extras.h:88
terrain
Definition terrain.h:182
terrain::property
int property[MG_COUNT]
Definition terrain.h:253
tile
Definition tile.h:50
world::map
struct civ_map map
Definition world_object.h:38
support.h
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
terrain_count
Terrain_type_id terrain_count(void)
Definition terrain.c:118
terrain_index
Terrain_type_id terrain_index(const struct terrain *pterrain)
Definition terrain.c:138
terrain_rule_name
const char * terrain_rule_name(const struct terrain *pterrain)
Definition terrain.c:247
terrain_type_terrain_class
enum terrain_class terrain_type_terrain_class(const struct terrain *pterrain)
Definition terrain.c:582
terrain.h
terrain_type_iterate
#define terrain_type_iterate(_p)
Definition terrain.h:373
T_UNKNOWN
#define T_UNKNOWN
Definition terrain.h:57
is_ocean
#define is_ocean(pterrain)
Definition terrain.h:301
is_ocean_tile
#define is_ocean_tile(ptile)
Definition terrain.h:303
terrain_type_iterate_end
#define terrain_type_iterate_end
Definition terrain.h:379
TERRAIN_OCEAN_DEPTH_MAXIMUM
#define TERRAIN_OCEAN_DEPTH_MAXIMUM
Definition terrain.h:255
terrain_has_flag
#define terrain_has_flag(terr, flag)
Definition terrain.h:283
terrain_resources_iterate_end
#define terrain_resources_iterate_end
Definition terrain.h:401
terrain_resources_iterate
#define terrain_resources_iterate(pterrain, _res, _freq)
Definition terrain.h:392
tile_set_terrain
void tile_set_terrain(struct tile *ptile, struct terrain *pterrain)
Definition tile.c:124
tile_change_terrain
void tile_change_terrain(struct tile *ptile, struct terrain *pterrain)
Definition tile.c:496
tile_set_continent
void tile_set_continent(struct tile *ptile, Continent_id val)
Definition tile.c:382
tile.h
tile_index
#define tile_index(_pt_)
Definition tile.h:88
tile_terrain
#define tile_terrain(_tile)
Definition tile.h:110
TILE_XY
#define TILE_XY(ptile)
Definition tile.h:43
tile_continent
#define tile_continent(_tile)
Definition tile.h:92