Feature #45 ยป 0017-height_map.-ch-Improve-coding-style.patch
server/generator/height_map.c | ||
---|---|---|
#include "height_map.h"
|
||
int *height_map = NULL;
|
||
int *height_map = nullptr;
|
||
int hmap_shore_level = 0, hmap_mountain_level = 0;
|
||
/**********************************************************************//**
|
||
Factor by which to lower height map near poles in normalize_hmap_poles
|
||
Factor by which to lower height map near poles in normalize_hmap_poles()
|
||
**************************************************************************/
|
||
static float hmap_pole_factor(struct tile *ptile)
|
||
{
|
||
... | ... | |
* only assumed to be called <= 2.5*ICE_BASE_LEVEL) */
|
||
factor = MIN(factor, 0.1);
|
||
}
|
||
return factor;
|
||
}
|
||
... | ... | |
Lower the land near the map edges and (optionally) the polar region to
|
||
avoid too much land there.
|
||
See also renormalize_hmap_poles
|
||
See also renormalize_hmap_poles()
|
||
**************************************************************************/
|
||
void normalize_hmap_poles(void)
|
||
{
|
||
... | ... | |
}
|
||
/**********************************************************************//**
|
||
Invert (most of) the effects of normalize_hmap_poles so that we have
|
||
Invert (most of) the effects of normalize_hmap_poles() so that we have
|
||
accurate heights for texturing the poles.
|
||
**************************************************************************/
|
||
void renormalize_hmap_poles(void)
|
||
... | ... | |
/**********************************************************************//**
|
||
Recursive function which does the work for generator 5.
|
||
All (x0,y0) and (x1,y1) are in native coordinates.
|
||
All (x0, y0) and (x1, y1) are in native coordinates.
|
||
**************************************************************************/
|
||
static void gen5rec(int step, int xl, int yt, int xr, int yb)
|
||
{
|
||
int val[2][2];
|
||
int x1wrap = xr; /* to wrap correctly */
|
||
int y1wrap = yb;
|
||
int x1wrap = xr; /* To wrap correctly */
|
||
int y1wrap = yb;
|
||
/* All x and y values are native. */
|
||
if (((yb - yt <= 0) || (xr - xl <= 0))
|
||
if (((yb - yt <= 0) || (xr - xl <= 0))
|
||
|| ((yb - yt == 1) && (xr - xl == 1))) {
|
||
return;
|
||
}
|
||
... | ... | |
val[1][0] = hmap(native_pos_to_tile(&(wld.map), x1wrap, yt));
|
||
val[1][1] = hmap(native_pos_to_tile(&(wld.map), x1wrap, y1wrap));
|
||
/* set midpoints of sides to avg of side's vertices plus a random factor */
|
||
/* unset points are zero, don't reset if set */
|
||
#define set_midpoints(X, Y, V) \
|
||
{ \
|
||
struct tile *ptile = native_pos_to_tile(&(wld.map), (X), (Y)); \
|
||
if (map_colatitude(ptile) <= ICE_BASE_LEVEL / 2) { \
|
||
/* possibly flatten poles, or possibly not (even at map edge) */ \
|
||
hmap(ptile) = (V) * (100 - wld.map.server.flatpoles) / 100; \
|
||
} else if (near_singularity(ptile) \
|
||
|| hmap(ptile) != 0) { \
|
||
/* do nothing */ \
|
||
} else { \
|
||
hmap(ptile) = (V); \
|
||
} \
|
||
/* Set midpoints of sides to avg of side's vertices plus a random factor.
|
||
* Unset points are zero, don't reset if set */
|
||
#define set_midpoints(X, Y, V) \
|
||
{ \
|
||
struct tile *ptile = native_pos_to_tile(&(wld.map), (X), (Y)); \
|
||
if (map_colatitude(ptile) <= ICE_BASE_LEVEL / 2) { \
|
||
/* Possibly flatten poles, or possibly not (even at map edge) */ \
|
||
hmap(ptile) = (V) * (100 - wld.map.server.flatpoles) / 100; \
|
||
} else if (near_singularity(ptile) \
|
||
|| hmap(ptile) != 0) { \
|
||
/* Do nothing */ \
|
||
} else { \
|
||
hmap(ptile) = (V); \
|
||
} \
|
||
}
|
||
set_midpoints((xl + xr) / 2, yt,
|
||
... | ... | |
set_midpoints(x1wrap, (yt + yb) / 2,
|
||
(val[1][0] + val[1][1]) / 2 + (int)fc_rand(step) - step / 2);
|
||
/* set middle to average of midpoints plus a random factor, if not set */
|
||
/* Set middle to average of midpoints plus a random factor, if not set */
|
||
set_midpoints((xl + xr) / 2, (yt + yb) / 2,
|
||
((val[0][0] + val[0][1] + val[1][0] + val[1][1]) / 4
|
||
+ (int)fc_rand(step) - step / 2));
|
||
#undef set_midpoints
|
||
/* now call recursively on the four subrectangles */
|
||
/* Now call recursively on the four subrectangles */
|
||
gen5rec(2 * step / 3, xl, yt, (xr + xl) / 2, (yb + yt) / 2);
|
||
gen5rec(2 * step / 3, xl, (yb + yt) / 2, (xr + xl) / 2, yb);
|
||
gen5rec(2 * step / 3, (xr + xl) / 2, yt, xr, (yb + yt) / 2);
|
||
... | ... | |
Generator 5 makes earthlike worlds with one or more large continents and
|
||
a scattering of smaller islands. It does so by dividing the world into
|
||
blocks and on each block raising or lowering the corners, then the
|
||
midpoints and middle and so on recursively. Fiddling with 'xdiv' and
|
||
midpoints and middle and so on recursively. Fiddling with 'xdiv' and
|
||
'ydiv' will change the size of the initial blocks and, if the map does not
|
||
wrap in at least one direction, fiddling with 'avoidedge' will change the
|
||
likelihood of continents butting up to non-wrapped edges.
|
||
... | ... | |
All X and Y values used in this function are in native coordinates.
|
||
extra_div can be increased to break the world up into more, smaller
|
||
islands. This is used in conjunction with the startpos setting.
|
||
islands. This is used in conjunction with the startpos setting.
|
||
**************************************************************************/
|
||
void make_pseudofractal1_hmap(int extra_div)
|
||
{
|
||
... | ... | |
int xmax = wld.map.xsize - (xnowrap ? 1 : 0);
|
||
int ymax = wld.map.ysize - (ynowrap ? 1 : 0);
|
||
int x_current, y_current;
|
||
/* just need something > log(max(xsize, ysize)) for the recursion */
|
||
/* Just need something > log(max(xsize, ysize)) for the recursion */
|
||
int step = wld.map.xsize + wld.map.ysize;
|
||
/* edges are avoided more strongly as this increases */
|
||
/* Edges are avoided more strongly as this increases */
|
||
int avoidedge = (100 - wld.map.server.landpercent) * step / 100 + step / 3;
|
||
height_map = fc_malloc(sizeof(*height_map) * MAP_INDEX_SIZE);
|
||
/* initialize map */
|
||
/* Initialize map */
|
||
INITIALIZE_ARRAY(height_map, MAP_INDEX_SIZE, 0);
|
||
/* set initial points */
|
||
/* Set initial points */
|
||
for (x_current = 0; x_current < xdiv2; x_current++) {
|
||
for (y_current = 0; y_current < ydiv2; y_current++) {
|
||
do_in_map_pos(&(wld.map), ptile,
|
||
(x_current * xmax / xdiv), (y_current * ymax / ydiv)) {
|
||
/* set initial points */
|
||
/* Set initial points */
|
||
hmap(ptile) = fc_rand(2 * step) - (2 * step) / 2;
|
||
if (near_singularity(ptile)) {
|
||
/* avoid edges (topological singularities) */
|
||
hmap(ptile) -= avoidedge;
|
||
}
|
||
if (near_singularity(ptile)) {
|
||
/* Avoid edges (topological singularities) */
|
||
hmap(ptile) -= avoidedge;
|
||
}
|
||
if (map_colatitude(ptile) <= ICE_BASE_LEVEL / 2 ) {
|
||
/* separate poles and avoid too much land at poles */
|
||
if (map_colatitude(ptile) <= ICE_BASE_LEVEL / 2 ) {
|
||
/* Separate poles and avoid too much land at poles */
|
||
hmap(ptile) -= fc_rand(avoidedge * wld.map.server.flatpoles / 100);
|
||
}
|
||
}
|
||
} do_in_map_pos_end;
|
||
}
|
||
}
|
||
/* calculate recursively on each block */
|
||
/* Calculate recursively on each block */
|
||
for (x_current = 0; x_current < xdiv; x_current++) {
|
||
for (y_current = 0; y_current < ydiv; y_current++) {
|
||
gen5rec(step, x_current * xmax / xdiv, y_current * ymax / ydiv,
|
||
(x_current + 1) * xmax / xdiv, (y_current + 1) * ymax / ydiv);
|
||
gen5rec(step, x_current * xmax / xdiv, y_current * ymax / ydiv,
|
||
(x_current + 1) * xmax / xdiv, (y_current + 1) * ymax / ydiv);
|
||
}
|
||
}
|
||
/* put in some random fuzz */
|
||
/* Put in some random fuzz */
|
||
whole_map_iterate(&(wld.map), ptile) {
|
||
hmap(ptile) = 8 * hmap(ptile) + fc_rand(4) - 2;
|
||
} whole_map_iterate_end;
|
||
... | ... | |
}
|
||
/**********************************************************************//**
|
||
We don't want huge areas of grass/plains,
|
||
We don't want huge areas of grassland/plains,
|
||
so we put in a hill here and there, where it gets too 'clean'
|
||
Return TRUE if the terrain around the given map position is "clean". This
|
||
means that all the terrain for 2 squares around it is not mountain or hill.
|
||
Return TRUE if the terrain around the given map position is "clean".
|
||
This means that all the terrain for 2 squares around it
|
||
is not mountain or hill.
|
||
**************************************************************************/
|
||
bool area_is_too_flat(struct tile *ptile, int thill, int my_height)
|
||
{
|
server/generator/height_map.h | ||
---|---|---|
#ifndef FC__HEIGHT_MAP_H
|
||
#define FC__HEIGHT_MAP_H
|
||
/* Wrappers for easy access. They are a macros so they can be a lvalues.*/
|
||
/* Wrappers for easy access. They are a macros so they can be lvalues.*/
|
||
#define hmap(_tile) (height_map[tile_index(_tile)])
|
||
/* shore_level safe unit of height */
|
||
... | ... | |
*
|
||
* height_map[] stores the height of each tile
|
||
* hmap_max_level is the maximum height (heights will range from
|
||
* [0,hmap_max_level).
|
||
* hmap_shore_level is the level of ocean. Any tile at this height or
|
||
* [0, hmap_max_level).
|
||
* hmap_shore_level is the level of ocean. Any tile at this height or
|
||
* above is land; anything below is ocean.
|
||
* hmap_mount_level is the level of mountains and hills. Any tile above
|
||
* hmap_mount_level is the level of mountains and hills. Any tile above
|
||
* this height will usually be a mountain or hill.
|
||
*/
|
||
#define hmap_max_level 1000
|
||
... | ... | |
bool area_is_too_flat(struct tile *ptile, int thill, int my_height);
|
||
#endif /* FC__HEIGHT__MAP_H */
|
||
#endif /* FC__HEIGHT__MAP_H */
|