Project

General

Profile

Feature #379 ยป 0047-mapgen.-ch-Improve-coding-style.patch

Marko Lindqvist, 03/31/2024 08:59 AM

View differences:

server/generator/mapgen.c
static int mountain_pct = 0;
static int jungle_pct = 0;
static int river_pct = 0;
/**********************************************************************//**
Conditions used mainly in rand_map_pos_characteristic()
**************************************************************************/
/* WETNESS */
/* Necessary condition of deserts placement */
#define map_pos_is_dry(ptile) \
(map_colatitude((ptile)) <= DRY_MAX_LEVEL \
&& map_colatitude((ptile)) > DRY_MIN_LEVEL \
#define map_pos_is_dry(ptile) \
(map_colatitude((ptile)) <= DRY_MAX_LEVEL \
&& map_colatitude((ptile)) > DRY_MIN_LEVEL \
&& count_terrain_class_near_tile(&(wld.map), (ptile), \
FALSE, TRUE, TC_OCEAN) <= 35)
typedef enum { WC_ALL = 200, WC_DRY, WC_NDRY } wetness_c;
......
typedef enum { MC_NONE, MC_LOW, MC_NLOW } miscellaneous_c;
/**************************************************************************
These functions test for conditions used in rand_map_pos_characteristic
These functions test for conditions used in rand_map_pos_characteristic()
**************************************************************************/
/**********************************************************************//**
......
return !map_pos_is_dry(ptile);
}
log_error("Invalid wetness_c %d", c);
return FALSE;
}
......
return !map_pos_is_low(ptile);
}
log_error("Invalid miscellaneous_c %d", c);
return FALSE;
}
......
/**********************************************************************//**
A filter function to be passed to rand_map_pos_filtered(). See
rand_map_pos_characteristic for more explanation.
rand_map_pos_characteristic() for more explanation.
**************************************************************************/
static bool condition_filter(const struct tile *ptile, const void *data)
{
......
return FALSE;
}
} square_iterate_end;
return TRUE;
}
......
**************************************************************************/
static void make_relief(void)
{
/* Calculate the mountain level. map.server.mountains specifies the
/* Calculate the mountain level. map.server.mountains specifies the
* percentage of land that is turned into hills and mountains. */
hmap_mountain_level = (((hmap_max_level - hmap_shore_level)
* (100 - wld.map.server.steepness))
......
if (tmap_is(ptile, TT_FROZEN)
|| (tmap_is(ptile, TT_COLD)
&& (fc_rand(10) > 7)
&& is_temperature_type_near(ptile, TT_FROZEN))) {
&& is_temperature_type_near(ptile, TT_FROZEN))) {
if (ocean) {
tile_set_terrain(ptile, ocean);
} else {
......
return FALSE;
}
} adjc_iterate_end;
return TRUE;
}
......
&& ok_for_separate_poles(ptile)))) {
tile_set_terrain(ptile, T_UNKNOWN);
tile_set_continent(ptile, 0);
}
}
} whole_map_iterate_end;
}
/**********************************************************************//**
Recursively generate terrains.
**************************************************************************/
static void place_terrain(struct tile *ptile, int diff,
static void place_terrain(struct tile *ptile, int diff,
struct terrain *pterrain, int *to_be_placed,
wetness_c wc,
temperature_type tc,
......
int Delta = (abs(map_colatitude(tile1) - map_colatitude(ptile))
/ MAX(L_UNIT, 1)
+ abs(hmap(tile1) - (hmap(ptile))) / MAX(H_UNIT, 1));
if (not_placed(tile1)
&& tmap_is(tile1, tc)
&& test_wetness(tile1, wc)
......
**************************************************************************/
#define PLACE_ONE_TYPE(count, alternate, ter, wc, tc, mc, weight) \
if ((count) > 0) { \
struct tile *ptile; \
struct tile *ptile; \
/* Place some terrains */ \
if ((ptile = rand_map_pos_characteristic((wc), (tc), (mc)))) { \
if ((ptile = rand_map_pos_characteristic((wc), (tc), (mc)))) { \
place_terrain(ptile, (weight), (ter), &(count), (wc),(tc), (mc)); \
} else { \
/* If rand_map_pos_temperature returns FALSE we may as well stop */ \
......
}
/**********************************************************************//**
Make_terrains calls make_forest, make_dessert,etc with random free
locations until there has been made enough.
Make_terrains calls make_forest, make_dessert,etc with random free
locations until there has been made enough.
Comment: funtions as make_swamp, etc. has to have a non 0 probability
to place one terrains in called position. Else make_terrains will get
in a infinite loop!
......
forests_count = total * forest_pct / (100 - mountain_pct);
jungles_count = total * jungle_pct / (100 - mountain_pct);
deserts_count = total * desert_pct / (100 - mountain_pct);
deserts_count = total * desert_pct / (100 - mountain_pct);
swamps_count = total * swamp_pct / (100 - mountain_pct);
/* grassland, tundra,arctic and plains is counted in plains_count */
/* Grassland, tundra,arctic and plains is counted in plains_count */
plains_count = total - forests_count - deserts_count
- swamps_count - jungles_count;
/* the placement loop */
/* The placement loop */
do {
PLACE_ONE_TYPE(forests_count , plains_count,
......
pick_terrain(MG_DRY, MG_TROPICAL, MG_WET),
WC_ALL, TT_NFROZEN, MC_NLOW, 40);
/* make the plains and tundras */
/* Make the plains and tundras */
if (plains_count > 0) {
struct tile *ptile;
......
return 1;
}
/* any un-blocked? */
/* Any un-blocked? */
cardinal_adjc_iterate(&(wld.map), ptile, ptile1) {
if (!dbv_isset(&privermap->blocked, tile_index(ptile1))) {
return 0;
}
} cardinal_adjc_iterate_end;
return 1; /* none non-blocked |- all blocked */
return 1; /* None non-blocked |- all blocked */
}
/**********************************************************************//**
......
}
/**********************************************************************//**
Called from make_river. Marks all directions as blocked. -Erik Sigra
Called from make_river(). Marks all directions as blocked. -Erik Sigra
**************************************************************************/
static void river_blockmark(struct river_map *privermap,
struct tile *ptile)
......
};
/**********************************************************************//**
Makes a river starting at (x, y). Returns 1 if it succeeds.
Return 0 if it fails. The river is stored in river_map.
Makes a river starting at (x, y). Returns 1 if it succeeds.
Return 0 if it fails. The river is stored in river_map.
How to make a river path look natural
=====================================
Rivers always flow down. Thus rivers are best implemented on maps
where every tile has an explicit height value. However, Freeciv has a
flat map. But there are certain things that help the user imagine
differences in height between tiles. The selection of direction for
rivers should confirm and even amplify the user's image of the map's
topology.
How to make a river path look natural
=====================================
Rivers always flow down. Thus rivers are best implemented on maps
where every tile has an explicit height value. However, Freeciv has a
flat map. But there are certain things that help the user imagine
differences in height between tiles. The selection of direction for
rivers should confirm and even amplify the user's image of the map's
topology.
To decide which direction the river takes, the possible directions
are tested in a series of test until there is only 1 direction
left. Some tests are fatal. This means that they can sort away all
remaining directions. If they do so, the river is aborted. Here
follows a description of the test series.
To decide which direction the river takes, the possible directions
are tested in a series of test until there is only 1 direction
left. Some tests are fatal. This means that they can sort away all
remaining directions. If they do so, the river is aborted. Here
follows a description of the test series.
* Falling into itself: fatal
(river_test_blocked)
This is tested by looking up in the river_map array if a tile or
every tile surrounding the tile is marked as blocked. A tile is
marked as blocked if it belongs to the current river or has been
evaluated in a previous iteration in the creation of the current
river.
* Falling into itself: fatal
(river_test_blocked)
This is tested by looking up in the river_map array if a tile or
every tile surrounding the tile is marked as blocked. A tile is
marked as blocked if it belongs to the current river or has been
evaluated in a previous iteration in the creation of the current
river.
Possible values:
0: Is not falling into itself.
1: Is falling into itself.
Possible values:
0: Is not falling into itself.
1: Is falling into itself.
* Forming a 4-river-grid: optionally fatal
(river_test_rivergrid)
A minimal 4-river-grid is formed when an intersection in the map
grid is surrounded by 4 river tiles. There can be larger river
grids consisting of several overlapping minimal 4-river-grids.
* Forming a 4-river-grid: optionally fatal
(river_test_rivergrid)
A minimal 4-river-grid is formed when an intersection in the map
grid is surrounded by 4 river tiles. There can be larger river
grids consisting of several overlapping minimal 4-river-grids.
Possible values:
0: Is not forming a 4-river-grid.
1: Is forming a 4-river-grid.
Possible values:
0: Is not forming a 4-river-grid.
1: Is forming a 4-river-grid.
* Highlands:
(river_test_highlands)
Rivers must not flow up in mountains or hills if there are
alternatives.
* Highlands:
(river_test_highlands)
Rivers must not flow up in mountains or hills if there are
alternatives.
Possible values:
0: Is not hills and not mountains.
1: Is hills.
2: Is mountains.
Possible values:
0: Is not hills and not mountains.
1: Is hills.
2: Is mountains.
* Adjacent ocean:
(river_test_adjacent_ocean)
Rivers must flow down to coastal areas when possible:
* Adjacent ocean:
(river_test_adjacent_ocean)
Rivers must flow down to coastal areas when possible:
Possible values: 0-100
Possible values: 0-100
* Adjacent river:
(river_test_adjacent_river)
Rivers must flow down to areas near other rivers when possible:
* Adjacent river:
(river_test_adjacent_river)
Rivers must flow down to areas near other rivers when possible:
Possible values: 0-100
Possible values: 0-100
* Adjacent highlands:
(river_test_adjacent_highlands)
Rivers must not flow towards highlands if there are alternatives.
* Adjacent highlands:
(river_test_adjacent_highlands)
Rivers must not flow towards highlands if there are alternatives.
* Swamps:
(river_test_swamp)
Rivers must flow down in swamps when possible.
* Swamps:
(river_test_swamp)
Rivers must flow down in swamps when possible.
Possible values:
0: Is swamps.
1: Is not swamps.
Possible values:
0: Is swamps.
1: Is not swamps.
* Adjacent swamps:
(river_test_adjacent_swamp)
Rivers must flow towards swamps when possible.
* Adjacent swamps:
(river_test_adjacent_swamp)
Rivers must flow towards swamps when possible.
* height_map:
(river_test_height_map)
Rivers must flow in the direction which takes it to the tile with
the lowest value on the height_map.
* height_map:
(river_test_height_map)
Rivers must flow in the direction which takes it to the tile with
the lowest value on the height_map.
Possible values:
n: height_map[...]
Possible values:
n: height_map[...]
If these rules haven't decided the direction, the random number
generator gets the desicion. -Erik Sigra
If these rules haven't decided the direction, the random number
generator gets the desicion. -Erik Sigra
**************************************************************************/
static bool make_river(struct river_map *privermap, struct tile *ptile,
struct extra_type *priver)
{
/* Comparison value for each tile surrounding the current tile. It is
/* Comparison value for each tile surrounding the current tile. It is
* the suitability to continue a river to the tile in that direction;
* lower is better. However rivers may only run in cardinal directions;
* lower is better. However rivers may only run in cardinal directions;
* the other directions are ignored entirely. */
int rd_comparison_val[8];
......
for (func_num = 0; func_num < NUM_TEST_FUNCTIONS; func_num++) {
int best_val = -1;
/* first get the tile values for the function */
/* First get the tile values for the function */
cardinal_adjc_dir_iterate(&(wld.map), ptile, ptile1, dir) {
if (rd_direction_is_valid[dir]) {
rd_comparison_val[dir] = (test_funcs[func_num].func)(privermap,
......
struct tile *ptile;
struct terrain *pterrain;
struct river_map rivermap;
struct extra_type *road_river = NULL;
struct extra_type *road_river = nullptr;
/* Formula to make the river density similar om different sized maps. Avoids
too few rivers on large maps and too many rivers on small maps. */
......
return;
}
create_placed_map(); /* needed bu rand_map_characteristic */
create_placed_map(); /* Needed by rand_map_characteristic() */
set_all_ocean_tiles_placed();
dbv_init(&rivermap.blocked, MAP_INDEX_SIZE);
......
while (current_riverlength < desirable_riverlength
&& iteration_counter < RIVERS_MAXTRIES) {
if (!(ptile = rand_map_pos_characteristic(WC_ALL, TT_NFROZEN,
MC_NLOW))) {
if ((ptile = rand_map_pos_characteristic(WC_ALL, TT_NFROZEN,
MC_NLOW)) == nullptr) {
break; /* No more spring places */
}
pterrain = tile_terrain(ptile);
......
/* Don't start a river on a tile is surrounded by > 1 river +
ocean tile. */
&& (count_river_near_tile(&(wld.map), ptile, NULL)
&& (count_river_near_tile(&(wld.map), ptile, nullptr)
+ count_terrain_class_near_tile(&(wld.map), ptile,
TRUE, FALSE, TC_OCEAN) <= 1)
......
if (!terrain_has_flag(river_terrain, TER_CAN_HAVE_RIVER)) {
/* We have to change the terrain to put a river here. */
river_terrain = pick_terrain_by_flag(TER_CAN_HAVE_RIVER);
if (river_terrain != NULL) {
if (river_terrain != nullptr) {
tile_set_terrain(ptile1, river_terrain);
}
}
......
}
/**********************************************************************//**
make land simply does it all based on a generated heightmap
Make land simply does it all based on a generated heightmap
1) with map.server.landpercent it generates a ocean/unknown map
2) it then calls the above functions to generate the different terrains
**************************************************************************/
static void make_land(void)
{
struct terrain *land_fill = NULL;
struct terrain *land_fill = nullptr;
if (HAS_POLES) {
normalize_hmap_poles();
......
}
} terrain_type_iterate_end;
fc_assert_exit_msg(NULL != land_fill,
fc_assert_exit_msg(land_fill != nullptr,
"No land terrain type could be found for the purpose "
"of temporarily filling in land tiles during map "
"generation. This could be an error in Freeciv, or a "
......
hmap_shore_level = (hmap_max_level * (100 - wld.map.server.landpercent)) / 100;
ini_hmap_low_level();
whole_map_iterate(&(wld.map), ptile) {
tile_set_terrain(ptile, T_UNKNOWN); /* set as oceans count is used */
tile_set_terrain(ptile, T_UNKNOWN); /* Set as oceans count is used */
if (hmap(ptile) < hmap_shore_level) {
int depth = (hmap_shore_level - hmap(ptile)) * 100 / hmap_shore_level;
int ocean = 0;
......
renormalize_hmap_poles();
}
/* destroy old dummy temperature map ... */
/* Destroy old dummy temperature map ... */
destroy_tmap();
/* ... and create a real temperature map (needs hmap and oceans) */
create_tmap(TRUE);
if (HAS_POLES) { /* this is a hack to terrains set with not frizzed oceans*/
make_polar_land(); /* make extra land at poles*/
if (HAS_POLES) { /* This is a hack to terrains set with not frizzed oceans*/
make_polar_land(); /* Make extra land at poles*/
}
create_placed_map(); /* here it means land terrains to be placed */
create_placed_map(); /* Here it means land terrains to be placed */
set_all_ocean_tiles_placed();
if (MAPGEN_FRACTURE == wld.map.server.generator) {
make_fracture_relief();
} else {
make_relief(); /* base relief on map */
make_relief(); /* Base relief on map */
}
make_terrains(); /* place all exept mountains and hill */
make_terrains(); /* Place all exept mountains and hill */
destroy_placed_map();
make_rivers(); /* use a new placed_map. destroy older before call */
make_rivers(); /* Use a new placed_map. Destroy older before call */
}
/**********************************************************************//**
Returns if this is a 1x1 island
**************************************************************************/
static bool is_tiny_island(struct tile *ptile)
static bool is_tiny_island(struct tile *ptile)
{
struct terrain *pterrain = tile_terrain(ptile);
......
}
adjc_iterate(&(wld.map), ptile, tile1) {
/* This was originally a cardinal_adjc_iterate, which seemed to cause
/* This was originally a cardinal_adjc_iterate(), which seemed to cause
* two or three problems. /MSS */
if (!is_ocean_tile(tile1)) {
return FALSE;
......
struct terrain *shallow
= most_shallow_ocean(terrain_has_flag(tile_terrain(ptile), TER_FROZEN));
fc_assert_ret(NULL != shallow);
fc_assert_ret(shallow != nullptr);
tile_set_terrain(ptile, shallow);
extra_type_by_cause_iterate(EC_ROAD, priver) {
if (tile_has_extra(ptile, priver)
......
**************************************************************************/
bool map_fractal_generate(bool autosize, struct unit_type *initial_unit)
{
/* save the current random state: */
/* Save the current random state: */
RANDOM_STATE rstate;
RANDOM_TYPE seed_rand;
......
#ifdef FREECIV_TESTMATIC
/* Log command to reproduce the mapseed */
log_testmatic("set mapseed %d", wld.map.server.seed);
#else /* FREECIV_TESTMATICE */
#else /* FREECIV_TESTMATIC */
log_debug("Setting map.seed:%d", wld.map.server.seed);
#endif /* FREECIV_TESTMATIC */
} else {
......
fc_srand(wld.map.server.seed);
/* don't generate tiles with mapgen == MAPGEN_SCENARIO as we've loaded *
/* Don't generate tiles with mapgen == MAPGEN_SCENARIO as we've loaded *
them from file.
Also, don't delete (the handcrafted!) tiny islands in a scenario */
if (wld.map.server.generator != MAPGEN_SCENARIO) {
......
main_map_allocate();
}
adjust_terrain_param();
/* if one mapgenerator fails, it will choose another mapgenerator */
/* If one mapgenerator fails, it will choose another mapgenerator */
/* with a lower number to try again */
/* create a temperature map */
/* Create a temperature map */
create_tmap(FALSE);
if (MAPGEN_FAIR == wld.map.server.generator
......
}
if (MAPGEN_ISLAND == wld.map.server.generator) {
/* initialise terrain selection lists used by make_island() */
/* Initialise terrain selection lists used by make_island() */
island_terrain_init();
/* 2 or 3 players per isle? */
......
mapgenerator2();
}
/* free terrain selection lists used by make_island() */
/* Free terrain selection lists used by make_island() */
island_terrain_free();
}
......
assign_continent_numbers();
}
/* create a temperature map if it was not done before */
/* Create a temperature map if it was not done before */
if (!temperature_is_initialized()) {
create_tmap(FALSE);
}
/* some scenarios already provide specials */
/* Some scenarios already provide specials */
if (!wld.map.server.have_resources) {
add_resources(wld.map.server.riches);
}
if (!wld.map.server.have_huts) {
make_huts(wld.map.server.huts * map_num_tiles() / 1000);
make_huts(wld.map.server.huts * map_num_tiles() / 1000);
}
/* restore previous random state: */
/* Restore previous random state: */
fc_rand_set_state(rstate);
/* We don't want random start positions in a scenario which already
......
}
}
/* destroy temperature map */
/* Destroy temperature map */
destroy_tmap();
print_mapgen_map();
......
/* 3 - 11 % */
river_pct = (100 - polar) * (3 + wld.map.server.wetness / 12) / 100;
/* 7 % if wetness == 50 && temperature == 50 */
/* 7 % if wetness == 50 && temperature == 50 */
swamp_pct = factor * MAX(0, (wld.map.server.wetness * 12 - 150
+ wld.map.server.temperature * 10));
desert_pct = factor * MAX(0, (wld.map.server.temperature * 15 - 250
......
}
/**********************************************************************//**
Return TRUE if a safe tile is in a radius of 1. This function is used to
Return TRUE if a safe tile is in a radius of 1. This function is used to
test where to place specials on the sea.
**************************************************************************/
static bool near_safe_tiles(struct tile *ptile)
......
int count = 0;
struct tile *ptile;
create_placed_map(); /* here it means placed huts */
create_placed_map(); /* Here it means placed huts */
while (number > 0 && count++ < map_num_tiles() * 2) {
/* Add a hut. But not too close to another hut. */
/* Add a hut. But not too close to another hut. */
if ((ptile = rand_map_pos_characteristic(WC_ALL, TT_ALL, MC_NONE))) {
struct extra_type *phut = rand_extra_for_tile(ptile, EC_HUT, TRUE);
number--;
if (phut != NULL) {
if (phut != nullptr) {
tile_add_extra(ptile, phut);
}
set_placed_near_pos(ptile, 3);
}
}
destroy_placed_map();
}
......
static bool is_resource_close(const struct tile *ptile)
{
square_iterate(&(wld.map), ptile, 1, tile1) {
if (NULL != tile_resource(tile1)) {
if (tile_resource(tile1) != nullptr) {
return TRUE;
}
} square_iterate_end;
......
|| wld.map.server.ocean_resources) {
struct extra_type *res = pick_resource(pterrain);
if (NULL != res) {
if (res != nullptr) {
tile_set_resource(ptile, res);
}
}
......
**************************************************************************/
static void tersel_free(struct terrain_select *ptersel)
{
if (ptersel != NULL) {
if (ptersel != nullptr) {
FC_FREE(ptersel);
}
}
......
return;
}
/* must have at least one terrain selection given in tersel_list */
/* Must have at least one terrain selection given in tersel_list */
fc_assert_ret(ntersel != 0);
capac = pstate->totalmass;
......
priver = river_types[fc_rand(river_type_count)];
if (test_wetness(ptile, WC_DRY) && fc_rand(100) < 50) {
/* rivers don't like dry locations */
/* Rivers don't like dry locations */
continue;
}
......
}
/**********************************************************************//**
Return TRUE if the ocean position is near land. This is used in the
Return TRUE if the ocean position is near land. This is used in the
creation of islands, so it differs logically from near_safe_tiles().
**************************************************************************/
static bool is_near_land(struct tile *ptile)
......
ptile = rand_map_pos(&(wld.map));
index_to_native_pos(&nat_x, &nat_y, tile_index(ptile));
/* this helps a lot for maps with high landmass */
/* This helps a lot for maps with high landmass */
for (ycur = pstate->n, xcur = pstate->w;
ycur < pstate->s && xcur < pstate->e;
ycur++, xcur++) {
......
pstate->s = nat_y + 2;
pstate->e = nat_x + 2;
i = islemass - 1;
while (i > 0 && tries-->0) {
ptile = get_random_map_position_from_state(pstate);
index_to_native_pos(&nat_x, &nat_y, tile_index(ptile));
if ((!near_singularity(ptile) || fc_rand(50) < 25 )
if ((!near_singularity(ptile) || fc_rand(50) < 25 )
&& hmap(ptile) == 0 && count_card_adjc_elevated_tiles(ptile) > 0) {
hmap(ptile) = 1;
i--;
......
if (hmap(ptile) == 0 && i > 0
&& count_card_adjc_elevated_tiles(ptile) == 4) {
hmap(ptile) = 1;
i--;
i--;
}
}
}
}
}
if (tries <= 0) {
log_error("create_island ended early with %d/%d.", islemass-i, islemass);
}
......
while (!(j = place_island(pstate)) && (--tries) > 0) {
/* Nothing */
}
return j;
}
......
{
struct terrain_select *ptersel;
/* forest */
/* Forest */
island_terrain.forest = terrain_select_list_new_full(tersel_free);
ptersel = tersel_new(1, MG_FOLIAGE, MG_TROPICAL, MG_DRY,
TT_TROPICAL, WC_ALL);
......
TT_NFROZEN, WC_ALL);
terrain_select_list_append(island_terrain.forest, ptersel);
/* desert */
/* Desert */
island_terrain.desert = terrain_select_list_new_full(tersel_free);
ptersel = tersel_new(3, MG_DRY, MG_TROPICAL, MG_GREEN,
TT_HOT, WC_DRY);
......
TT_FROZEN, WC_DRY);
terrain_select_list_append(island_terrain.desert, ptersel);
/* mountain */
/* Mountain */
island_terrain.mountain = terrain_select_list_new_full(tersel_free);
ptersel = tersel_new(2, MG_MOUNTAINOUS, MG_GREEN, MG_UNUSED,
TT_ALL, WC_ALL);
......
TT_ALL, WC_ALL);
terrain_select_list_append(island_terrain.mountain, ptersel);
/* swamp */
/* Swamp */
island_terrain.swamp = terrain_select_list_new_full(tersel_free);
ptersel = tersel_new(1, MG_WET, MG_TROPICAL, MG_FOLIAGE,
TT_TROPICAL, WC_NDRY);
......
tile_set_continent(ptile, 0);
map_set_placed(ptile); /* Not a land tile */
BV_CLR_ALL(ptile->extras);
tile_set_owner(ptile, NULL, NULL);
ptile->extras_owner = NULL;
tile_set_owner(ptile, nullptr, nullptr);
ptile->extras_owner = nullptr;
} whole_map_iterate_end;
if (HAS_POLES) {
make_polar();
}
/* Set poles numbers. After the map is generated continents will
/* Set poles numbers. After the map is generated continents will
* be renumbered. */
make_island(0, 0, pstate, 0);
}
/* This variable is the Default Minimum Specific Island Size,
/* This variable is the Default Minimum Specific Island Size,
* ie the smallest size we'll typically permit our island, as a % of
* the size we wanted. So if we ask for an island of size x, the island
* the size we wanted. So if we ask for an island of size x, the island
* creation will return if it would create an island smaller than
* x * DMSIS / 100 */
#define DMSIS 10
......
/* Constant that makes up that an island actually needs additional space */
/* Put 70% of land in big continents,
* 20% in medium, and
* 10% in small. */
* 20% in medium, and
* 10% in small. */
int bigfrac = 70, midfrac = 20, smallfrac = 10;
if (wld.map.server.landpercent > 85) {
log_verbose("ISLAND generator: falling back to RANDOM generator");
wld.map.server.generator = MAPGEN_RANDOM;
return;
}
......
data->transform[i++] = fair_do_iso_hex_rotation;
}
}
fc_assert(i <= ARRAY_SIZE(data->transform));
data->transform_num = i;
}
......
x += tx;
y += ty;
pttile = fair_map_pos_tile(ptarget, x, y);
if (pttile == NULL) {
if (pttile == nullptr) {
return FALSE; /* Limit of the map. */
}
if (pttile->flags & FTF_ASSIGNED) {
......
} else if (pttile->flags & FTF_OCEAN && !(pstile->flags & FTF_OCEAN)) {
return FALSE; /* We clearly want a sea tile here. */
}
if ((pttile->flags & FTF_NO_RESOURCE && pstile->presource != NULL)
|| (pstile->flags & FTF_NO_RESOURCE && pttile->presource != NULL)) {
if ((pttile->flags & FTF_NO_RESOURCE && pstile->presource != nullptr)
|| (pstile->flags & FTF_NO_RESOURCE && pttile->presource != nullptr)) {
return FALSE; /* Resource disallowed there. */
}
if ((pttile->flags & FTF_NO_HUT && pstile->flags & FTF_HAS_HUT)
......
x += tx;
y += ty;
pttile = fair_map_pos_tile(ptarget, x, y);
fc_assert_ret_val(pttile != NULL, FALSE);
fc_assert_ret_val(pttile != nullptr, FALSE);
pttile->flags |= pstile->flags;
if (pstile->pterrain != NULL) {
if (pstile->pterrain != nullptr) {
pttile->pterrain = pstile->pterrain;
pttile->presource = pstile->presource;
pttile->extras = pstile->extras;
......
for (j = 0; j < MAP_NUM_VALID_DIRS; j++) {
pftile2 = fair_map_tile_step(pmap, pftile, MAP_VALID_DIRS[j]);
if (pftile2 != NULL
if (pftile2 != nullptr
&& pftile2->flags & FTF_ASSIGNED
&& !(pftile2->flags & FTF_OCEAN)) {
land_around = TRUE;
......
}
pftile->presource = pick_resource(pftile->pterrain);
/* Note that 'pftile->presource' might be NULL if there is no suitable
/* Note that 'pftile->presource' might be nullptr if there is no suitable
* resource for the terrain. */
if (pftile->presource != NULL) {
if (pftile->presource != nullptr) {
pftile->flags |= FTF_NO_RESOURCE;
for (j = 0; j < MAP_NUM_VALID_DIRS; j++) {
pftile2 = fair_map_tile_step(pmap, pftile, MAP_VALID_DIRS[j]);
if (pftile2 != NULL) {
if (pftile2 != nullptr) {
pftile2->flags |= FTF_NO_RESOURCE;
}
}
......
static void fair_map_make_huts(struct fair_tile *pmap)
{
struct fair_tile *pftile;
struct tile *pvtile = tile_virtual_new(NULL);
struct tile *pvtile = tile_virtual_new(nullptr);
struct extra_type *phut;
int i, j, k;
......
}
i--;
if (pftile->pterrain == NULL) {
if (pftile->pterrain == nullptr) {
continue; /* Not an used tile. */
}
......
pvtile->extras = pftile->extras;
phut = rand_extra_for_tile(pvtile, EC_HUT, TRUE);
if (phut != NULL) {
if (phut != nullptr) {
tile_add_extra(pvtile, phut);
pftile->extras = pvtile->extras;
pftile->flags |= FTF_HAS_HUT;
......
for (j = 0; j < MAP_NUM_VALID_DIRS; j++) {
pftile2 = fair_map_tile_step(pisland, pftile, MAP_VALID_DIRS[j]);
fc_assert(pftile2 != NULL);
fc_assert(pftile2 != nullptr);
if (fair_map_tile_border(pisland, pftile2, sea_around_island)) {
continue;
}
......
}
}
}
while (i < size) {
pftile = land_tiles[i - fc_rand(fantasy) - 1];
pftile2 = fair_map_tile_step(pisland, pftile,
MAP_CARDINAL_DIRS[fc_rand(MAP_NUM_CARDINAL_DIRS)]);
fc_assert(pftile2 != NULL);
fc_assert(pftile2 != nullptr);
if (fair_map_tile_border(pisland, pftile2, sea_around_island)) {
continue;
}
......
ocean_around = FALSE;
for (j = 0; j < MAP_NUM_VALID_DIRS; j++) {
pftile2 = fair_map_tile_step(pisland, pftile, MAP_VALID_DIRS[j]);
if (pftile2 == NULL) {
if (pftile2 == nullptr) {
continue;
}
......
}
/* Check a river in one direction. */
pend = NULL;
pend = nullptr;
length = -1;
dir = direction8_invalid();
dirs_num = 0;
......
pftile2 = pftile;
for (l = 2; l < length_max; l++) {
pftile2 = fair_map_tile_step(pisland, pftile2, MAP_VALID_DIRS[j]);
if (pftile2 == NULL
if (pftile2 == nullptr
|| !terrain_has_flag(pftile2->pterrain, TER_CAN_HAVE_RIVER)) {
break;
}
......
pftile3 = fair_map_tile_step(pisland, pftile2,
MAP_VALID_DIRS[k]);
if (pftile3 == NULL) {
if (pftile3 == nullptr) {
continue;
}
......
length = l;
}
}
if (pend == NULL) {
if (pend == nullptr) {
continue;
}
......
break;
}
pftile = fair_map_tile_step(pisland, pftile, dir);
fc_assert(pftile != NULL);
fc_assert(pftile != nullptr);
}
}
}
......
tile_set_terrain(ptile, deepest_ocean);
tile_set_continent(ptile, 0);
BV_CLR_ALL(ptile->extras);
tile_set_owner(ptile, NULL, NULL);
ptile->extras_owner = NULL;
tile_set_owner(ptile, nullptr, nullptr);
ptile->extras_owner = nullptr;
} whole_map_iterate_end;
i = 0;
......
whole_map_iterate(&(wld.map), ptile) {
struct fair_tile *pftile = pmap + tile_index(ptile);
fc_assert(pftile->pterrain != NULL);
fc_assert(pftile->pterrain != nullptr);
tile_set_terrain(ptile, pftile->pterrain);
ptile->extras = pftile->extras;
tile_set_resource(ptile, pftile->presource);
......
fair_map_destroy(pmap);
log_verbose("Fair island map created with success!");
return TRUE;
}
server/generator/mapgen.h
/**********************************************************************
/***********************************************************************
Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......
#ifndef FC__MAPGEN_H
#define FC__MAPGEN_H
/* utility */
#include "support.h" /* bool type */
bool map_fractal_generate(bool autosize, struct unit_type *initial_unit);
#endif /* FC__MAPGEN_H */
#endif /* FC__MAPGEN_H */
    (1-1/1)