static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlag flags)
{
CommandCost cost(EXPENSES_CONSTRUCTION);
int delta = TileOffsByDiagDir(dir);
CommandCost ret = EnsureNoVehicleOnGround(tile);
if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile + delta);
if (ret.Succeeded()) ret = EnsureNoVehicleOnGround(tile - delta);
if (ret.Failed()) return ret;
/* middle tile */
WaterClass wc_middle = IsWaterTile(tile) ? GetWaterClass(tile) : WATER_CLASS_CANAL;
if (!IsWaterTile(tile)) {
ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (ret.Failed()) return ret;
cost.AddCost(ret);
}
/* lower tile */
WaterClass wc_lower = IsWaterTile(tile - delta) ? GetWaterClass(tile - delta) : WATER_CLASS_CANAL;
if (!IsWaterTile(tile - delta)) {
ret = DoCommand(tile - delta, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (ret.Failed()) return ret;
cost.AddCost(ret);
cost.AddCost(_price[PR_BUILD_CANAL]);
}
if (!IsTileFlat(tile - delta)) {
return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
}
/* upper tile */
WaterClass wc_upper = IsWaterTile(tile + delta) ? GetWaterClass(tile + delta) : WATER_CLASS_CANAL;
if (!IsWaterTile(tile + delta)) {
ret = DoCommand(tile + delta, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
if (ret.Failed()) return ret;
cost.AddCost(ret);
cost.AddCost(_price[PR_BUILD_CANAL]);
}
if (!IsTileFlat(tile + delta)) {
return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION);
}
if (IsBridgeAbove(tile) || IsBridgeAbove(tile - delta) || IsBridgeAbove(tile + delta)) {
return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST);
}
if (flags & DC_EXEC) {
/* Update company infrastructure counts. */
Company *c = Company::GetIfValid(_current_company);
if (c != NULL) {
/* Counts for the water. */
if (!IsWaterTile(tile - delta)) c->infrastructure.water++;
if (!IsWaterTile(tile + delta)) c->infrastructure.water++;
/* Count for the lock itself. */
c->infrastructure.water += 3 * LOCK_DEPOT_TILE_FACTOR; // Lock is three tiles.
DirtyCompanyInfrastructureWindows(_current_company);
}
MakeLock(tile, _current_company, dir, wc_lower, wc_upper, wc_middle);
MarkTileDirtyByTile(tile);
MarkTileDirtyByTile(tile - delta);
MarkTileDirtyByTile(tile + delta);
MarkCanalsAndRiversAroundDirty(tile - delta);
MarkCanalsAndRiversAroundDirty(tile + delta);
}
cost.AddCost(_price[PR_BUILD_LOCK]);
return cost;
}