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

Function CmdBuildRoad

src/road_cmd.cpp:599–928  ·  view source on GitHub ↗

* Build a piece of road. * @param flags operation to perform * @param tile tile where to build road * @param pieces road pieces to build (RoadBits) * @param rt road type * @param toggle_drd disallowed directions to toggle * @param town_id the town that is building the road (TownID::Invalid() if not applicable) * @return the cost of this operation or an error */

Source from the content-addressed store, hash-verified

597 * @return the cost of this operation or an error
598 */
599CommandCost CmdBuildRoad(DoCommandFlags flags, TileIndex tile, RoadBits pieces, RoadType rt, DisallowedRoadDirections toggle_drd, TownID town_id)
600{
601 CompanyID company = _current_company;
602 CommandCost cost(EXPENSES_CONSTRUCTION);
603
604 RoadBits existing = ROAD_NONE;
605 RoadBits other_bits = ROAD_NONE;
606
607 /* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero
608 * if a non-company is building the road */
609 if ((Company::IsValidID(company) && town_id != TownID::Invalid()) || (company == OWNER_TOWN && !Town::IsValidID(town_id)) || (company == OWNER_DEITY && town_id != TownID::Invalid())) return CMD_ERROR;
610 if (company != OWNER_TOWN) {
611 const Town *town = CalcClosestTownFromTile(tile);
612 town_id = (town != nullptr) ? town->index : TownID::Invalid();
613
614 if (company == OWNER_DEITY) {
615 company = OWNER_TOWN;
616
617 /* If we are not within a town, we are not owned by the town */
618 if (town == nullptr || DistanceSquare(tile, town->xy) > town->cache.squared_town_zone_radius[to_underlying(HouseZone::TownEdge)]) {
619 company = OWNER_NONE;
620 }
621 }
622 }
623
624 /* do not allow building 'zero' road bits, code wouldn't handle it */
625 if (pieces == ROAD_NONE || !IsValidRoadBits(pieces) || !IsValidDisallowedRoadDirections(toggle_drd)) return CMD_ERROR;
626 if (!ValParamRoadType(rt)) return CMD_ERROR;
627
628 Slope tileh = GetTileSlope(tile);
629 RoadTramType rtt = GetRoadTramType(rt);
630
631 bool need_to_clear = false;
632 switch (GetTileType(tile)) {
633 case MP_ROAD:
634 switch (GetRoadTileType(tile)) {
635 case RoadTileType::Normal: {
636 if (HasRoadWorks(tile)) return CommandCost(STR_ERROR_ROAD_WORKS_IN_PROGRESS);
637
638 other_bits = GetRoadBits(tile, OtherRoadTramType(rtt));
639 if (!HasTileRoadType(tile, rtt)) break;
640
641 existing = GetRoadBits(tile, rtt);
642 bool crossing = !IsStraightRoad(existing | pieces);
643 if (rtt == RTT_ROAD && (GetDisallowedRoadDirections(tile) != DRD_NONE || toggle_drd != DRD_NONE) && crossing) {
644 /* Junctions cannot be one-way */
645 return CommandCost(STR_ERROR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION);
646 }
647 if ((existing & pieces) == pieces) {
648 /* We only want to set the (dis)allowed road directions */
649 if (toggle_drd != DRD_NONE && rtt == RTT_ROAD) {
650 Owner owner = GetRoadOwner(tile, rtt);
651 if (owner != OWNER_NONE) {
652 CommandCost ret = CheckOwnership(owner, tile);
653 if (ret.Failed()) return ret;
654 }
655
656 DisallowedRoadDirections dis_existing = GetDisallowedRoadDirections(tile);

Callers

nothing calls this directly

Calls 15

InvalidFunction · 0.85
CalcClosestTownFromTileFunction · 0.85
DistanceSquareFunction · 0.85
to_underlyingFunction · 0.85
IsValidRoadBitsFunction · 0.85
ValParamRoadTypeFunction · 0.85
GetTileSlopeFunction · 0.85
GetRoadTramTypeFunction · 0.85
GetTileTypeFunction · 0.85
GetRoadTileTypeFunction · 0.85
HasRoadWorksFunction · 0.85

Tested by

no test coverage detected