Project

General

Profile

Feature #45 ยป 0017-height_map.-ch-Improve-coding-style.patch

Marko Lindqvist, 12/09/2023 05:31 AM

View differences:

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 */
    (1-1/1)