MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / TerraformTileHeight

Function TerraformTileHeight

src/terraform_cmd.cpp:99–159  ·  view source on GitHub ↗

* Terraform the north corner of a tile to a specific height. * * @param ts TerraformerState. * @param tile Tile. * @param height Aimed height. * @return Error code or cost. */

Source from the content-addressed store, hash-verified

97 * @return Error code or cost.
98 */
99static std::tuple<CommandCost, TileIndex> TerraformTileHeight(TerraformerState *ts, TileIndex tile, int height)
100{
101 assert(tile < Map::Size());
102
103 /* Check range of destination height */
104 if (height < 0) return { CommandCost(STR_ERROR_ALREADY_AT_SEA_LEVEL), INVALID_TILE };
105 if (height > _settings_game.construction.map_height_limit) return { CommandCost(STR_ERROR_TOO_HIGH), INVALID_TILE };
106
107 /*
108 * Check if the terraforming has any effect.
109 * This can only be true, if multiple corners of the start-tile are terraformed (i.e. the terraforming is done by towns/industries etc.).
110 * In this case the terraforming should fail. (Don't know why.)
111 */
112 if (height == TerraformGetHeightOfTile(ts, tile)) return { CMD_ERROR, INVALID_TILE };
113
114 /* Check "too close to edge of map". Only possible when freeform-edges is off. */
115 uint x = TileX(tile);
116 uint y = TileY(tile);
117 if (!_settings_game.construction.freeform_edges && ((x <= 1) || (y <= 1) || (x >= Map::MaxX() - 1) || (y >= Map::MaxY() - 1))) {
118 /*
119 * Determine a sensible error tile
120 */
121 if (x == 1) x = 0;
122 if (y == 1) y = 0;
123 return { CommandCost(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP), TileXY(x, y) };
124 }
125
126 /* Mark incident tiles that are involved in the terraforming. */
127 TerraformAddDirtyTileAround(ts, tile);
128
129 /* Store the height modification */
130 TerraformSetHeightOfTile(ts, tile, height);
131
132 CommandCost total_cost(EXPENSES_CONSTRUCTION);
133
134 /* Increment cost */
135 total_cost.AddCost(_price[PR_TERRAFORM]);
136
137 /* Recurse to neighboured corners if height difference is larger than 1 */
138 for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
139 TileIndex neighbour_tile = AddTileIndexDiffCWrap(tile, TileIndexDiffCByDiagDir(dir));
140
141 /* Not using IsValidTile as we want to also change MP_VOID tiles, which IsValidTile excludes. */
142 if (neighbour_tile == INVALID_TILE) continue;
143
144 /* Get TileHeight of neighboured tile as of current terraform progress */
145 int r = TerraformGetHeightOfTile(ts, neighbour_tile);
146 int height_diff = height - r;
147
148 /* Is the height difference to the neighboured corner greater than 1? */
149 if (abs(height_diff) > 1) {
150 /* Terraform the neighboured corner. The resulting height difference should be 1. */
151 height_diff += (height_diff < 0 ? 1 : -1);
152 auto [cost, err_tile] = TerraformTileHeight(ts, neighbour_tile, r + height_diff);
153 if (cost.Failed()) return { cost, err_tile };
154 total_cost.AddCost(cost.GetCost());
155 }
156 }

Callers 1

CmdTerraformLandFunction · 0.85

Calls 13

CommandCostClass · 0.85
TerraformGetHeightOfTileFunction · 0.85
TileXFunction · 0.85
TileYFunction · 0.85
TileXYFunction · 0.85
TerraformSetHeightOfTileFunction · 0.85
AddTileIndexDiffCWrapFunction · 0.85
TileIndexDiffCByDiagDirFunction · 0.85
absFunction · 0.85
FailedMethod · 0.80
AddCostMethod · 0.45

Tested by

no test coverage detected