summaryrefslogtreecommitdiff
path: root/src/tgp.cpp
diff options
context:
space:
mode:
authorYexo <yexo@openttd.org>2009-01-21 02:31:55 +0000
committerYexo <yexo@openttd.org>2009-01-21 02:31:55 +0000
commitdb3ee34b4468aa3448b64e339258760885c5d716 (patch)
tree272533ac91b7bc3ab16c3ee1a997e142f3170a2a /src/tgp.cpp
parent5e7669b539002cb9ec9e608f4601a827b5e9da57 (diff)
downloadopenttd-db3ee34b4468aa3448b64e339258760885c5d716.tar.xz
(svn r15190) -Feature: Allow terraforming of the tiles at the edges of the map.
Diffstat (limited to 'src/tgp.cpp')
-rw-r--r--src/tgp.cpp115
1 files changed, 69 insertions, 46 deletions
diff --git a/src/tgp.cpp b/src/tgp.cpp
index 18e4026d8..e72acf5e0 100644
--- a/src/tgp.cpp
+++ b/src/tgp.cpp
@@ -552,6 +552,13 @@ static void HeightMapAdjustWaterLevel(amplitude_t water_percent, height_t h_max_
static double perlin_coast_noise_2D(const double x, const double y, const double p, const int prime);
+enum Borders {
+ BORDER_NE = 0,
+ BORDER_SE = 1,
+ BORDER_SW = 2,
+ BORDER_NW = 3,
+};
+
/**
* This routine sculpts in from the edge a random amount, again a Perlin
* sequence, to avoid the rigid flat-edge slopes that were present before. The
@@ -572,7 +579,7 @@ static double perlin_coast_noise_2D(const double x, const double y, const double
* Please note that all the small numbers; 53, 101, 167, etc. are small primes
* to help give the perlin noise a bit more of a random feel.
*/
-static void HeightMapCoastLines()
+static void HeightMapCoastLines(uint8 water_borders)
{
int smallest_size = min(_settings_game.game_creation.map_x, _settings_game.game_creation.map_y);
const int margin = 4;
@@ -582,40 +589,47 @@ static void HeightMapCoastLines()
/* Lower to sea level */
for (y = 0; y <= _height_map.size_y; y++) {
- /* Top right */
- max_x = abs((perlin_coast_noise_2D(_height_map.size_y - y, y, 0.9, 53) + 0.25) * 5 + (perlin_coast_noise_2D(y, y, 0.35, 179) + 1) * 12);
- max_x = max((smallest_size * smallest_size / 16) + max_x, (smallest_size * smallest_size / 16) + margin - max_x);
- if (smallest_size < 8 && max_x > 5) max_x /= 1.5;
- for (x = 0; x < max_x; x++) {
- _height_map.height(x, y) = 0;
+ if (HasBit(water_borders, BORDER_NE)) {
+ /* Top right */
+ max_x = abs((perlin_coast_noise_2D(_height_map.size_y - y, y, 0.9, 53) + 0.25) * 5 + (perlin_coast_noise_2D(y, y, 0.35, 179) + 1) * 12);
+ max_x = max((smallest_size * smallest_size / 16) + max_x, (smallest_size * smallest_size / 16) + margin - max_x);
+ if (smallest_size < 8 && max_x > 5) max_x /= 1.5;
+ for (x = 0; x < max_x; x++) {
+ _height_map.height(x, y) = 0;
+ }
}
- /* Bottom left */
- max_x = abs((perlin_coast_noise_2D(_height_map.size_y - y, y, 0.85, 101) + 0.3) * 6 + (perlin_coast_noise_2D(y, y, 0.45, 67) + 0.75) * 8);
- max_x = max((smallest_size * smallest_size / 16) + max_x, (smallest_size * smallest_size / 16) + margin - max_x);
- if (smallest_size < 8 && max_x > 5) max_x /= 1.5;
- for (x = _height_map.size_x; x > (_height_map.size_x - 1 - max_x); x--) {
- _height_map.height(x, y) = 0;
+ if (HasBit(water_borders, BORDER_SW)) {
+ /* Bottom left */
+ max_x = abs((perlin_coast_noise_2D(_height_map.size_y - y, y, 0.85, 101) + 0.3) * 6 + (perlin_coast_noise_2D(y, y, 0.45, 67) + 0.75) * 8);
+ max_x = max((smallest_size * smallest_size / 16) + max_x, (smallest_size * smallest_size / 16) + margin - max_x);
+ if (smallest_size < 8 && max_x > 5) max_x /= 1.5;
+ for (x = _height_map.size_x; x > (_height_map.size_x - 1 - max_x); x--) {
+ _height_map.height(x, y) = 0;
+ }
}
}
/* Lower to sea level */
for (x = 0; x <= _height_map.size_x; x++) {
- /* Top left */
- max_y = abs((perlin_coast_noise_2D(x, _height_map.size_y / 2, 0.9, 167) + 0.4) * 5 + (perlin_coast_noise_2D(x, _height_map.size_y / 3, 0.4, 211) + 0.7) * 9);
- max_y = max((smallest_size * smallest_size / 16) + max_y, (smallest_size * smallest_size / 16) + margin - max_y);
- if (smallest_size < 8 && max_y > 5) max_y /= 1.5;
- for (y = 0; y < max_y; y++) {
- _height_map.height(x, y) = 0;
+ if (HasBit(water_borders, BORDER_NW)) {
+ /* Top left */
+ max_y = abs((perlin_coast_noise_2D(x, _height_map.size_y / 2, 0.9, 167) + 0.4) * 5 + (perlin_coast_noise_2D(x, _height_map.size_y / 3, 0.4, 211) + 0.7) * 9);
+ max_y = max((smallest_size * smallest_size / 16) + max_y, (smallest_size * smallest_size / 16) + margin - max_y);
+ if (smallest_size < 8 && max_y > 5) max_y /= 1.5;
+ for (y = 0; y < max_y; y++) {
+ _height_map.height(x, y) = 0;
+ }
}
-
- /* Bottom right */
- max_y = abs((perlin_coast_noise_2D(x, _height_map.size_y / 3, 0.85, 71) + 0.25) * 6 + (perlin_coast_noise_2D(x, _height_map.size_y / 3, 0.35, 193) + 0.75) * 12);
- max_y = max((smallest_size * smallest_size / 16) + max_y, (smallest_size * smallest_size / 16) + margin - max_y);
- if (smallest_size < 8 && max_y > 5) max_y /= 1.5;
- for (y = _height_map.size_y; y > (_height_map.size_y - 1 - max_y); y--) {
- _height_map.height(x, y) = 0;
+ if (HasBit(water_borders, BORDER_SE)) {
+ /* Bottom right */
+ max_y = abs((perlin_coast_noise_2D(x, _height_map.size_y / 3, 0.85, 71) + 0.25) * 6 + (perlin_coast_noise_2D(x, _height_map.size_y / 3, 0.35, 193) + 0.75) * 12);
+ max_y = max((smallest_size * smallest_size / 16) + max_y, (smallest_size * smallest_size / 16) + margin - max_y);
+ if (smallest_size < 8 && max_y > 5) max_y /= 1.5;
+ for (y = _height_map.size_y; y > (_height_map.size_y - 1 - max_y); y--) {
+ _height_map.height(x, y) = 0;
+ }
}
}
}
@@ -658,18 +672,18 @@ static void HeightMapSmoothCoastInDirection(int org_x, int org_y, int dir_x, int
}
/** Smooth coasts by modulating height of tiles close to map edges with cosine of distance from edge */
-static void HeightMapSmoothCoasts()
+static void HeightMapSmoothCoasts(uint8 water_borders)
{
uint x, y;
/* First Smooth NW and SE coasts (y close to 0 and y close to size_y) */
for (x = 0; x < _height_map.size_x; x++) {
- HeightMapSmoothCoastInDirection(x, 0, 0, 1);
- HeightMapSmoothCoastInDirection(x, _height_map.size_y - 1, 0, -1);
+ if (HasBit(water_borders, BORDER_NW)) HeightMapSmoothCoastInDirection(x, 0, 0, 1);
+ if (HasBit(water_borders, BORDER_SE)) HeightMapSmoothCoastInDirection(x, _height_map.size_y - 1, 0, -1);
}
/* First Smooth NE and SW coasts (x close to 0 and x close to size_x) */
for (y = 0; y < _height_map.size_y; y++) {
- HeightMapSmoothCoastInDirection(0, y, 1, 0);
- HeightMapSmoothCoastInDirection(_height_map.size_x - 1, y, -1, 0);
+ if (HasBit(water_borders, BORDER_NE)) HeightMapSmoothCoastInDirection(0, y, 1, 0);
+ if (HasBit(water_borders, BORDER_SW)) HeightMapSmoothCoastInDirection(_height_map.size_x - 1, y, -1, 0);
}
}
@@ -683,15 +697,15 @@ static void HeightMapSmoothCoasts()
static void HeightMapSmoothSlopes(height_t dh_max)
{
int x, y;
- for (y = 1; y <= (int)_height_map.size_y; y++) {
- for (x = 1; x <= (int)_height_map.size_x; x++) {
- height_t h_max = min(_height_map.height(x - 1, y), _height_map.height(x, y - 1)) + dh_max;
+ for (y = 0; y <= (int)_height_map.size_y; y++) {
+ for (x = 0; x <= (int)_height_map.size_x; x++) {
+ height_t h_max = min(_height_map.height(x > 0 ? x - 1 : x, y), _height_map.height(x, y > 0 ? y - 1 : y)) + dh_max;
if (_height_map.height(x, y) > h_max) _height_map.height(x, y) = h_max;
}
}
- for (y = _height_map.size_y - 1; y >= 0; y--) {
- for (x = _height_map.size_x - 1; x >= 0; x--) {
- height_t h_max = min(_height_map.height(x + 1, y), _height_map.height(x, y + 1)) + dh_max;
+ for (y = _height_map.size_y; y >= 0; y--) {
+ for (x = _height_map.size_x; x >= 0; x--) {
+ height_t h_max = min(_height_map.height((uint)x < _height_map.size_x ? x + 1 : x, y), _height_map.height(x, (uint)y < _height_map.size_y ? y + 1 : y)) + dh_max;
if (_height_map.height(x, y) > h_max) _height_map.height(x, y) = h_max;
}
}
@@ -710,10 +724,12 @@ static void HeightMapNormalize()
HeightMapAdjustWaterLevel(water_percent, h_max_new);
- HeightMapCoastLines();
+ byte water_borders = _settings_game.construction.freeform_edges ? _settings_game.game_creation.water_borders : 0xF;
+
+ HeightMapCoastLines(water_borders);
HeightMapSmoothSlopes(roughness);
- HeightMapSmoothCoasts();
+ HeightMapSmoothCoasts(water_borders);
HeightMapSmoothSlopes(roughness);
HeightMapSineTransform(12, h_max_new);
@@ -817,7 +833,12 @@ static double perlin_coast_noise_2D(const double x, const double y, const double
static void TgenSetTileHeight(TileIndex tile, int height)
{
SetTileHeight(tile, height);
- MakeClear(tile, CLEAR_GRASS, 3);
+
+ /* Only clear the tiles within the map area. */
+ if (TileX(tile) != MapMaxX() && TileY(tile) != MapMaxY() &&
+ (!_settings_game.construction.freeform_edges || (TileX(tile) != 0 && TileY(tile) != 0))) {
+ MakeClear(tile, CLEAR_GRASS, 3);
+ }
}
/**
@@ -842,9 +863,15 @@ void GenerateTerrainPerlin()
IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
+ /* First make sure the tiles at the north border are void tiles if needed. */
+ if (_settings_game.construction.freeform_edges) {
+ for (y = 0; y < _height_map.size_y - 1; y++) MakeVoid(_height_map.size_x * y);
+ for (x = 0; x < _height_map.size_x; x++) MakeVoid(x);
+ }
+
/* Transfer height map into OTTD map */
- for (y = 2; y < _height_map.size_y - 2; y++) {
- for (x = 2; x < _height_map.size_x - 2; x++) {
+ for (y = 0; y < _height_map.size_y; y++) {
+ for (x = 0; x < _height_map.size_x; x++) {
int height = H2I(_height_map.height(x, y));
if (height < 0) height = 0;
if (height > 15) height = 15;
@@ -854,10 +881,6 @@ void GenerateTerrainPerlin()
IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
- /* Recreate void tiles at the border in case they have been affected by generation */
- for (y = 0; y < _height_map.size_y - 1; y++) MakeVoid(_height_map.size_x * y + _height_map.size_x - 1);
- for (x = 0; x < _height_map.size_x; x++) MakeVoid(_height_map.size_x * y + x);
-
FreeHeightMap();
GenerateWorldSetAbortCallback(NULL);
}