/** * Build a piece of canal. * @param tile end tile of stretch-dragging * @param flags type of operation * @param p1 start tile of stretch-dragging * @param p2 waterclass to build. sea and river can only be built in scenario editor * @param text unused * @return the cost of this operation or an error */ CommandCost CmdBuildCanal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { WaterClass wc = Extract<WaterClass, 0, 2>(p2); if (p1 >= MapSize() || wc == WATER_CLASS_INVALID) return CMD_ERROR; /* Outside of the editor you can only build canals, not oceans */ if (wc != WATER_CLASS_CANAL && _game_mode != GM_EDITOR) return CMD_ERROR; TileArea ta(tile, p1); /* Outside the editor you can only drag canals, and not areas */ if (_game_mode != GM_EDITOR && ta.w != 1 && ta.h != 1) return CMD_ERROR; CommandCost cost(EXPENSES_CONSTRUCTION); TILE_AREA_LOOP(tile, ta) { CommandCost ret; Slope slope = GetTileSlope(tile, NULL); if (slope != SLOPE_FLAT && (wc != WATER_CLASS_RIVER || !IsInclinedSlope(slope))) { return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED); } /* can't make water of water! */ if (IsTileType(tile, MP_WATER) && (!IsTileOwner(tile, OWNER_WATER) || wc == WATER_CLASS_SEA)) continue; ret = DoCommand(tile, 0, 0, flags | DC_FORCE_CLEAR_TILE, CMD_LANDSCAPE_CLEAR); if (ret.Failed()) return ret; cost.AddCost(ret); if (flags & DC_EXEC) { switch (wc) { case WATER_CLASS_RIVER: MakeRiver(tile, Random()); break; case WATER_CLASS_SEA: if (TileHeight(tile) == 0) { MakeSea(tile); break; } /* FALL THROUGH */ default: MakeCanal(tile, _current_company, Random()); break; } MarkTileDirtyByTile(tile); MarkCanalsAndRiversAroundDirty(tile); } cost.AddCost(_price[PR_BUILD_CANAL]); }
void MakeWaterKeepingClass(TileIndex tile, Owner o) { WaterClass wc = GetWaterClass(tile); /* Autoslope might turn an originally canal or river tile into land */ int z; Slope slope = GetTileSlope(tile, &z); if (slope != SLOPE_FLAT) { if (wc == WATER_CLASS_CANAL) { /* If we clear the canal, we have to remove it from the infrastructure count as well. */ Company *c = Company::GetIfValid(o); if (c != NULL) { c->infrastructure.water--; DirtyCompanyInfrastructureWindows(c->index); } /* Sloped canals are locks and no natural water remains whatever the slope direction */ wc = WATER_CLASS_INVALID; } /* Only river water should be restored on appropriate slopes. Other water would be invalid on slopes */ if (wc != WATER_CLASS_RIVER || GetInclinedSlopeDirection(slope) == INVALID_DIAGDIR) { wc = WATER_CLASS_INVALID; } } if (wc == WATER_CLASS_SEA && z > 0) { /* Update company infrastructure count. */ Company *c = Company::GetIfValid(o); if (c != NULL) { c->infrastructure.water++; DirtyCompanyInfrastructureWindows(c->index); } wc = WATER_CLASS_CANAL; } /* Zero map array and terminate animation */ DoClearSquare(tile); /* Maybe change to water */ switch (wc) { case WATER_CLASS_SEA: MakeSea(tile); break; case WATER_CLASS_CANAL: MakeCanal(tile, o, Random()); break; case WATER_CLASS_RIVER: MakeRiver(tile, Random()); break; default: break; } MarkTileDirtyByTile(tile); }
/** Build a piece of canal. * @param tile end tile of stretch-dragging * @param flags type of operation * @param p1 start tile of stretch-dragging * @param p2 specifies canal (0), water (1) or river (2); last two can only be built in scenario editor * @param text unused * @return the cost of this operation or an error */ CommandCost CmdBuildCanal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { CommandCost cost(EXPENSES_CONSTRUCTION); if (p1 >= MapSize()) return CMD_ERROR; /* Outside of the editor you can only build canals, not oceans */ if (p2 != 0 && _game_mode != GM_EDITOR) return CMD_ERROR; TileArea ta(tile, p1); /* Outside the editor you can only drag canals, and not areas */ if (_game_mode != GM_EDITOR && ta.w != 1 && ta.h != 1) return CMD_ERROR; TILE_AREA_LOOP(tile, ta) { CommandCost ret; Slope slope = GetTileSlope(tile, NULL); if (slope != SLOPE_FLAT && (p2 != 2 || !IsInclinedSlope(slope))) { return_cmd_error(STR_ERROR_FLAT_LAND_REQUIRED); } /* can't make water of water! */ if (IsTileType(tile, MP_WATER) && (!IsTileOwner(tile, OWNER_WATER) || p2 == 1)) continue; ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); if (CmdFailed(ret)) return ret; cost.AddCost(ret); if (flags & DC_EXEC) { if (TileHeight(tile) == 0 && p2 == 1) { MakeSea(tile); } else if (p2 == 2) { MakeRiver(tile, Random()); } else { MakeCanal(tile, _current_company, Random()); } MarkTileDirtyByTile(tile); MarkCanalsAndRiversAroundDirty(tile); } cost.AddCost(_price[PR_CLEAR_WATER]); }
void MakeWaterKeepingClass(TileIndex tile, Owner o) { assert(IsTileType(tile, MP_WATER) || (IsTileType(tile, MP_STATION) && (IsBuoy(tile) || IsDock(tile) || IsOilRig(tile))) || IsTileType(tile, MP_INDUSTRY)); WaterClass wc = GetWaterClass(tile); /* Autoslope might turn an originally canal or river tile into land */ uint z; if (GetTileSlope(tile, &z) != SLOPE_FLAT) wc = WATER_CLASS_INVALID; if (wc == WATER_CLASS_SEA && z > 0) wc = WATER_CLASS_CANAL; switch (wc) { case WATER_CLASS_SEA: MakeSea(tile); break; case WATER_CLASS_CANAL: MakeCanal(tile, o, Random()); break; case WATER_CLASS_RIVER: MakeRiver(tile, Random()); break; default: DoClearSquare(tile); break; } }
void MakeWaterKeepingClass(TileIndex tile, Owner o) { WaterClass wc = GetWaterClass(tile); /* Autoslope might turn an originally canal or river tile into land */ uint z; if (GetTileSlope(tile, &z) != SLOPE_FLAT) wc = WATER_CLASS_INVALID; if (wc == WATER_CLASS_SEA && z > 0) wc = WATER_CLASS_CANAL; /* Zero map array and terminate animation */ DoClearSquare(tile); /* Maybe change to water */ switch (wc) { case WATER_CLASS_SEA: MakeSea(tile); break; case WATER_CLASS_CANAL: MakeCanal(tile, o, Random()); break; case WATER_CLASS_RIVER: MakeRiver(tile, Random()); break; default: break; } MarkTileDirtyByTile(tile); }