mirror of https://github.com/OpenTTD/OpenTTD
Fix 07fba75: Immediately convert terraformed ground tiles into water tiles during river generation
parent
bf02cb014b
commit
4435f3d54a
|
@ -1043,6 +1043,20 @@ static bool MakeLake(TileIndex tile, void *user_data)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _river_terraform = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Terraform land around river.
|
||||||
|
* @param tile tile to terraform
|
||||||
|
* @param slope corners to terraform (SLOPE_xxx)
|
||||||
|
* @param dir_up direction; eg up (true) or down (false)
|
||||||
|
*/
|
||||||
|
static void RiverTerraform(TileIndex tile, Slope slope, bool dir_up)
|
||||||
|
{
|
||||||
|
AutoRestoreBackup old_river_terraform(_river_terraform, true);
|
||||||
|
Command<CMD_TERRAFORM_LAND>::Do(DC_EXEC | DC_AUTO, tile, slope, dir_up);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Widen a river by expanding into adjacent tiles via circular tile search.
|
* Widen a river by expanding into adjacent tiles via circular tile search.
|
||||||
* @param tile The tile to try expanding the river into.
|
* @param tile The tile to try expanding the river into.
|
||||||
|
@ -1057,9 +1071,6 @@ static bool RiverMakeWider(TileIndex tile, void *user_data)
|
||||||
/* If the tile is already sea or river, don't expand. */
|
/* If the tile is already sea or river, don't expand. */
|
||||||
if (IsWaterTile(tile)) return false;
|
if (IsWaterTile(tile)) return false;
|
||||||
|
|
||||||
/* If the tile is at height 0 after terraforming but the ocean hasn't flooded yet, don't build river. */
|
|
||||||
if (GetTileMaxZ(tile) == 0) return false;
|
|
||||||
|
|
||||||
TileIndex origin_tile = *static_cast<TileIndex *>(user_data);
|
TileIndex origin_tile = *static_cast<TileIndex *>(user_data);
|
||||||
Slope cur_slope = GetTileSlope(tile);
|
Slope cur_slope = GetTileSlope(tile);
|
||||||
Slope desired_slope = GetTileSlope(origin_tile); // Initialize matching the origin tile as a shortcut if no terraforming is needed.
|
Slope desired_slope = GetTileSlope(origin_tile); // Initialize matching the origin tile as a shortcut if no terraforming is needed.
|
||||||
|
@ -1116,7 +1127,7 @@ static bool RiverMakeWider(TileIndex tile, void *user_data)
|
||||||
TileIndex other_tile = TileAddByDiagDir(tile, d);
|
TileIndex other_tile = TileAddByDiagDir(tile, d);
|
||||||
if (IsInclinedSlope(GetTileSlope(other_tile)) && IsWaterTile(other_tile)) return false;
|
if (IsInclinedSlope(GetTileSlope(other_tile)) && IsWaterTile(other_tile)) return false;
|
||||||
}
|
}
|
||||||
Command<CMD_TERRAFORM_LAND>::Do(DC_EXEC | DC_AUTO, tile, ComplementSlope(cur_slope), true);
|
RiverTerraform(tile, ComplementSlope(cur_slope), true);
|
||||||
|
|
||||||
/* If the river is descending and the adjacent tile has either one or three corners raised, we want to make it match the slope. */
|
/* If the river is descending and the adjacent tile has either one or three corners raised, we want to make it match the slope. */
|
||||||
} else if (IsInclinedSlope(desired_slope)) {
|
} else if (IsInclinedSlope(desired_slope)) {
|
||||||
|
@ -1137,14 +1148,14 @@ static bool RiverMakeWider(TileIndex tile, void *user_data)
|
||||||
/* Lower unwanted corners first. If only one corner is raised, no corners need lowering. */
|
/* Lower unwanted corners first. If only one corner is raised, no corners need lowering. */
|
||||||
if (!IsSlopeWithOneCornerRaised(cur_slope)) {
|
if (!IsSlopeWithOneCornerRaised(cur_slope)) {
|
||||||
to_change = to_change & ComplementSlope(desired_slope);
|
to_change = to_change & ComplementSlope(desired_slope);
|
||||||
Command<CMD_TERRAFORM_LAND>::Do(DC_EXEC | DC_AUTO, tile, to_change, false);
|
RiverTerraform(tile, to_change, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now check the match and raise any corners needed. */
|
/* Now check the match and raise any corners needed. */
|
||||||
cur_slope = GetTileSlope(tile);
|
cur_slope = GetTileSlope(tile);
|
||||||
if (cur_slope != desired_slope && IsSlopeWithOneCornerRaised(cur_slope)) {
|
if (cur_slope != desired_slope && IsSlopeWithOneCornerRaised(cur_slope)) {
|
||||||
to_change = cur_slope ^ desired_slope;
|
to_change = cur_slope ^ desired_slope;
|
||||||
Command<CMD_TERRAFORM_LAND>::Do(DC_EXEC | DC_AUTO, tile, to_change, true);
|
RiverTerraform(tile, to_change, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Update cur_slope after possibly terraforming. */
|
/* Update cur_slope after possibly terraforming. */
|
||||||
|
@ -1161,7 +1172,7 @@ static bool RiverMakeWider(TileIndex tile, void *user_data)
|
||||||
/* Don't look outside the map. */
|
/* Don't look outside the map. */
|
||||||
if (!IsValidTile(upstream_tile) || !IsValidTile(downstream_tile)) return false;
|
if (!IsValidTile(upstream_tile) || !IsValidTile(downstream_tile)) return false;
|
||||||
|
|
||||||
/* Downstream might be new ocean created by our terraforming, and it hasn't flooded yet. */
|
/* Downstream might be new ocean created by our terraforming. */
|
||||||
bool downstream_is_ocean = GetTileZ(downstream_tile) == 0 && (GetTileSlope(downstream_tile) == SLOPE_FLAT || IsSlopeWithOneCornerRaised(GetTileSlope(downstream_tile)));
|
bool downstream_is_ocean = GetTileZ(downstream_tile) == 0 && (GetTileSlope(downstream_tile) == SLOPE_FLAT || IsSlopeWithOneCornerRaised(GetTileSlope(downstream_tile)));
|
||||||
|
|
||||||
/* If downstream is dry, flat, and not ocean, try making it a river tile. */
|
/* If downstream is dry, flat, and not ocean, try making it a river tile. */
|
||||||
|
@ -1422,9 +1433,6 @@ static void CreateRivers()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Widening rivers may have left some tiles requiring to be watered. */
|
|
||||||
ConvertGroundTilesIntoWaterTiles();
|
|
||||||
|
|
||||||
/* Run tile loop to update the ground density. */
|
/* Run tile loop to update the ground density. */
|
||||||
for (uint i = 0; i != TILE_UPDATE_FREQUENCY; i++) {
|
for (uint i = 0; i != TILE_UPDATE_FREQUENCY; i++) {
|
||||||
if (i % 64 == 0) IncreaseGeneratingWorldProgress(GWP_RIVER);
|
if (i % 64 == 0) IncreaseGeneratingWorldProgress(GWP_RIVER);
|
||||||
|
|
|
@ -137,5 +137,6 @@ void RunTileLoop();
|
||||||
|
|
||||||
void InitializeLandscape();
|
void InitializeLandscape();
|
||||||
bool GenerateLandscape(uint8_t mode);
|
bool GenerateLandscape(uint8_t mode);
|
||||||
|
extern bool _river_terraform;
|
||||||
|
|
||||||
#endif /* LANDSCAPE_H */
|
#endif /* LANDSCAPE_H */
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
#include "core/backup_type.hpp"
|
#include "core/backup_type.hpp"
|
||||||
#include "terraform_cmd.h"
|
#include "terraform_cmd.h"
|
||||||
#include "landscape_cmd.h"
|
#include "landscape_cmd.h"
|
||||||
|
#include "water.h"
|
||||||
|
#include "landscape.h"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
|
|
||||||
|
@ -297,6 +299,14 @@ std::tuple<CommandCost, Money, TileIndex> CmdTerraformLand(DoCommandFlag flags,
|
||||||
SetTileHeight(t, (uint)height);
|
SetTileHeight(t, (uint)height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_river_terraform) {
|
||||||
|
for (const auto &t : ts.dirty_tiles) {
|
||||||
|
/* Immediately convert ground tiles into water tiles during river generation. */
|
||||||
|
ConvertGroundTileIntoWaterTile(t);
|
||||||
|
MarkTileDirtyByTile(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (c != nullptr) c->terraform_limit -= (uint32_t)ts.tile_to_new_height.size() << 16;
|
if (c != nullptr) c->terraform_limit -= (uint32_t)ts.tile_to_new_height.size() << 16;
|
||||||
}
|
}
|
||||||
return { total_cost, 0, total_cost.Succeeded() ? tile : INVALID_TILE };
|
return { total_cost, 0, total_cost.Succeeded() ? tile : INVALID_TILE };
|
||||||
|
|
|
@ -29,6 +29,7 @@ void ClearNeighbourNonFloodingStates(TileIndex tile);
|
||||||
void TileLoop_Water(TileIndex tile);
|
void TileLoop_Water(TileIndex tile);
|
||||||
bool FloodHalftile(TileIndex t);
|
bool FloodHalftile(TileIndex t);
|
||||||
|
|
||||||
|
void ConvertGroundTileIntoWaterTile(TileIndex tile);
|
||||||
void ConvertGroundTilesIntoWaterTiles();
|
void ConvertGroundTilesIntoWaterTiles();
|
||||||
|
|
||||||
void DrawShipDepotSprite(int x, int y, Axis axis, DepotPart part);
|
void DrawShipDepotSprite(int x, int y, Axis axis, DepotPart part);
|
||||||
|
|
|
@ -1297,9 +1297,10 @@ void TileLoop_Water(TileIndex tile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConvertGroundTilesIntoWaterTiles()
|
void ConvertGroundTileIntoWaterTile(TileIndex tile)
|
||||||
{
|
{
|
||||||
for (const auto tile : Map::Iterate()) {
|
assert(tile < Map::Size());
|
||||||
|
|
||||||
auto [slope, z] = GetTileSlopeZ(tile);
|
auto [slope, z] = GetTileSlopeZ(tile);
|
||||||
if (IsTileType(tile, MP_CLEAR) && z == 0) {
|
if (IsTileType(tile, MP_CLEAR) && z == 0) {
|
||||||
/* Make both water for tiles at level 0
|
/* Make both water for tiles at level 0
|
||||||
|
@ -1329,6 +1330,12 @@ void ConvertGroundTilesIntoWaterTiles()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvertGroundTilesIntoWaterTiles()
|
||||||
|
{
|
||||||
|
for (const auto tile : Map::Iterate()) {
|
||||||
|
ConvertGroundTileIntoWaterTile(tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue