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 */
|
||