* Build a Bridge * @param flags type of operation * @param tile_end end tile * @param tile_start start tile * @param transport_type transport type. * @param bridge_type bridge type (hi bh) * @param road_rail_type rail type or road types. * @return the cost of this operation or an error */
| 308 | * @return the cost of this operation or an error |
| 309 | */ |
| 310 | CommandCost CmdBuildBridge(DoCommandFlags flags, TileIndex tile_end, TileIndex tile_start, TransportType transport_type, BridgeType bridge_type, uint8_t road_rail_type) |
| 311 | { |
| 312 | CompanyID company = _current_company; |
| 313 | |
| 314 | RailType railtype = INVALID_RAILTYPE; |
| 315 | RoadType roadtype = INVALID_ROADTYPE; |
| 316 | |
| 317 | for (TileIndex t : {tile_start, tile_end}) { |
| 318 | if (!IsValidTile(t)) return CommandCost(STR_ERROR_BRIDGE_THROUGH_MAP_BORDER); |
| 319 | /* User cannot modify height of tiles with one coordinate equal to zero, they are always at the sea level, and you can't build bridge in the sea. |
| 320 | * Furthermore, they are void tiles unless map is infinite water. If we don't return for them here, we will still fail as their slope is invalid. */ |
| 321 | if (TileX(t) == 0 || TileY(t) == 0) return CommandCost(transport_type == TRANSPORT_WATER ? STR_ERROR_BRIDGE_THROUGH_MAP_BORDER : STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP); |
| 322 | } |
| 323 | |
| 324 | /* type of bridge */ |
| 325 | switch (transport_type) { |
| 326 | case TRANSPORT_ROAD: |
| 327 | roadtype = (RoadType)road_rail_type; |
| 328 | if (!ValParamRoadType(roadtype)) return CMD_ERROR; |
| 329 | break; |
| 330 | |
| 331 | case TRANSPORT_RAIL: |
| 332 | railtype = (RailType)road_rail_type; |
| 333 | if (!ValParamRailType(railtype)) return CMD_ERROR; |
| 334 | break; |
| 335 | |
| 336 | case TRANSPORT_WATER: |
| 337 | break; |
| 338 | |
| 339 | default: |
| 340 | /* Airports don't have bridges. */ |
| 341 | return CMD_ERROR; |
| 342 | } |
| 343 | |
| 344 | if (company == OWNER_DEITY) { |
| 345 | if (transport_type != TRANSPORT_ROAD) return CMD_ERROR; |
| 346 | const Town *town = CalcClosestTownFromTile(tile_start); |
| 347 | |
| 348 | company = OWNER_TOWN; |
| 349 | |
| 350 | /* If we are not within a town, we are not owned by the town */ |
| 351 | if (town == nullptr || DistanceSquare(tile_start, town->xy) > town->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)]) { |
| 352 | company = OWNER_NONE; |
| 353 | } |
| 354 | } |
| 355 | |
| 356 | if (tile_start == tile_end) { |
| 357 | return CommandCost(STR_ERROR_CAN_T_START_AND_END_ON); |
| 358 | } |
| 359 | |
| 360 | Axis direction; |
| 361 | if (TileX(tile_start) == TileX(tile_end)) { |
| 362 | direction = AXIS_Y; |
| 363 | } else if (TileY(tile_start) == TileY(tile_end)) { |
| 364 | direction = AXIS_X; |
| 365 | } else { |
| 366 | return CommandCost(STR_ERROR_START_AND_END_MUST_BE_IN); |
| 367 | } |
nothing calls this directly
no test coverage detected