static CommandCost ClearTile_Water(TileIndex tile, DoCommandFlag flags)
{
bool canal_on_river = HasTileCanalOnRiver(tile);
switch (GetWaterTileType(tile)) {
case WATER_TILE_CLEAR: {
if (flags & DC_NO_WATER) return_cmd_error(STR_ERROR_CAN_T_BUILD_ON_WATER);
Money base_cost = IsCanal(tile) ? _price[PR_CLEAR_CANAL] : _price[PR_CLEAR_WATER];
if (IsRiver(tile) && _game_mode == GM_NORMAL && !_cheats.magic_bulldozer.value) base_cost = 0;
/* Make sure freeform edges are allowed or it's not an edge tile. */
if (!_settings_game.construction.freeform_edges && (!IsInsideMM(TileX(tile), 1, MapMaxX() - 1) ||
!IsInsideMM(TileY(tile), 1, MapMaxY() - 1))) {
return_cmd_error(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP);
}
/* Make sure no vehicle is on the tile */
CommandCost ret = EnsureNoVehicleOnGround(tile);
if (ret.Failed()) return ret;
Owner owner = GetTileOwner(tile);
if (owner != OWNER_WATER && owner != OWNER_NONE) {
CommandCost ret = CheckTileOwnership(tile);
if (ret.Failed()) { // Canals of OWNER_NONE or of same owner always succeed.
/* Fail Oil Rig on random creation on canal owned by any company when the setting is on. */
if (_settings_game.construction.build_on_competitor_canal && _current_company == OWNER_NONE) return ret;
/* Fail Oil Rig on prospecting on canal of competitor when the setting is on. */
if (_settings_game.construction.build_on_competitor_canal && _current_company == OWNER_TOWN && _local_company != owner) return ret;
/* Fail for clearance check. */
if (_settings_game.construction.build_on_competitor_canal && _current_company == _local_company && _local_company != owner) return ret;
/* Fail for everything else when the setting is off. */
if (!_settings_game.construction.build_on_competitor_canal) return ret;
}
}
if (flags & DC_EXEC) {
if (IsCanal(tile) && Company::IsValidID(owner)) {
Company::Get(owner)->infrastructure.water--;
DirtyCompanyInfrastructureWindows(owner);
}
bool restore_river = HasTileWaterClass(tile) && GetWaterClass(tile) == WATER_CLASS_RIVER;
uint8 same_aspect = GetWaterTileRandomBits(tile);
DoClearSquare(tile);
if (canal_on_river) {
MakeRiver(tile, Random());
}
if (restore_river && (_game_mode == GM_NORMAL && !_cheats.magic_bulldozer.value)) {
MakeRiver(tile, same_aspect);
}
MarkCanalsAndRiversAroundDirty(tile);
}
return CommandCost(EXPENSES_CONSTRUCTION, base_cost);
}
case WATER_TILE_COAST: {
Slope slope = GetTileSlope(tile);
/* Make sure no vehicle is on the tile */
CommandCost ret = EnsureNoVehicleOnGround(tile);
if (ret.Failed()) return ret;
if (flags & DC_EXEC) {
DoClearSquare(tile);
MarkCanalsAndRiversAroundDirty(tile);
}
if (IsSlopeWithOneCornerRaised(slope)) {
return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_WATER]);
} else {
return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_ROUGH]);
}
}
case WATER_TILE_LOCK: {
static const TileIndexDiffC _lock_tomiddle_offs[][DIAGDIR_END] = {
/* NE SE SW NW */
{ { 0, 0}, {0, 0}, { 0, 0}, {0, 0} }, // LOCK_PART_MIDDLE
{ {-1, 0}, {0, 1}, { 1, 0}, {0, -1} }, // LOCK_PART_LOWER
{ { 1, 0}, {0, -1}, {-1, 0}, {0, 1} }, // LOCK_PART_UPPER
};
if (flags & DC_AUTO) return_cmd_error(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
if (_current_company == OWNER_WATER) return CMD_ERROR;
/* move to the middle tile.. */
return RemoveLock(tile + ToTileIndexDiff(_lock_tomiddle_offs[GetLockPart(tile)][GetLockDirection(tile)]), flags);
}
case WATER_TILE_DEPOT:
if (flags & DC_AUTO) return_cmd_error(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
return RemoveShipDepot(tile, flags);
default:
NOT_REACHED();
}
}