From c390e8f00efe2036432dd2d5e7a07b5333952e66 Mon Sep 17 00:00:00 2001 From: rubidium Date: Thu, 14 Jan 2010 23:05:07 +0000 Subject: (svn r18803) -Feature [FS#3318]: make building (long) roads work like building rail; build upon the first obstruction instead of failing totally. Patch by Terkhen. --- src/road_cmd.cpp | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'src/road_cmd.cpp') diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 0dd465871..1a151f33a 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -697,9 +697,9 @@ do_clear:; } /** Build a long piece of road. - * @param end_tile end tile of drag + * @param start_tile start tile of drag (the building cost will appear over this tile) * @param flags operation to perform - * @param p1 start tile of drag + * @param p1 end tile of drag * @param p2 various bitstuffed elements * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1) * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2) @@ -709,7 +709,7 @@ do_clear:; * @param text unused * @return the cost of this operation or an error */ -CommandCost CmdBuildLongRoad(TileIndex end_tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +CommandCost CmdBuildLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { CommandCost cost(EXPENSES_CONSTRUCTION); bool had_bridge = false; @@ -721,7 +721,7 @@ CommandCost CmdBuildLongRoad(TileIndex end_tile, DoCommandFlag flags, uint32 p1, if (p1 >= MapSize()) return CMD_ERROR; - TileIndex start_tile = p1; + TileIndex end_tile = p1; RoadType rt = (RoadType)GB(p2, 3, 2); if (!IsValidRoadType(rt) || !ValParamRoadType(rt)) return CMD_ERROR; @@ -730,12 +730,12 @@ CommandCost CmdBuildLongRoad(TileIndex end_tile, DoCommandFlag flags, uint32 p1, if (axis == AXIS_X && TileY(start_tile) != TileY(end_tile)) return CMD_ERROR; // x-axis if (axis == AXIS_Y && TileX(start_tile) != TileX(end_tile)) return CMD_ERROR; // y-axis - /* Swap start and ending tile, also the half-tile drag var (bit 0 and 1) */ + DiagDirection dir = AxisToDiagDir(axis); + + /* Swap direction, also the half-tile drag var (bit 0 and 1) */ if (start_tile > end_tile || (start_tile == end_tile && HasBit(p2, 0))) { - TileIndex t = start_tile; - start_tile = end_tile; - end_tile = t; - p2 ^= IsInsideMM(p2 & 3, 1, 3) ? 3 : 0; + dir = ReverseDiagDir(dir); + p2 ^= 3; drd = DRD_SOUTHBOUND; } @@ -747,28 +747,29 @@ CommandCost CmdBuildLongRoad(TileIndex end_tile, DoCommandFlag flags, uint32 p1, if (!HasBit(p2, 5)) drd = DRD_NONE; TileIndex tile = start_tile; - /* Start tile is the small number. */ + /* Start tile is the first tile clicked by the user. */ for (;;) { RoadBits bits = AxisToRoadBits(axis); - if (tile == end_tile && !HasBit(p2, 1)) bits &= ROAD_NW | ROAD_NE; - if (tile == start_tile && HasBit(p2, 0)) bits &= ROAD_SE | ROAD_SW; + /* Road parts only have to be built at the start tile or at the end tile. */ + if (tile == end_tile && !HasBit(p2, 1)) bits &= DiagDirToRoadBits(ReverseDiagDir(dir)); + if (tile == start_tile && HasBit(p2, 0)) bits &= DiagDirToRoadBits(dir); _error_message = INVALID_STRING_ID; CommandCost ret = DoCommand(tile, drd << 6 | rt << 4 | bits, 0, flags, CMD_BUILD_ROAD); if (CmdFailed(ret)) { - if (_error_message != STR_ERROR_ALREADY_BUILT) return CMD_ERROR; + if (_error_message != STR_ERROR_ALREADY_BUILT) break; } else { had_success = true; /* Only pay for the upgrade on one side of the bridges and tunnels */ if (IsTileType(tile, MP_TUNNELBRIDGE)) { if (IsBridge(tile)) { - if ((!had_bridge || GetTunnelBridgeDirection(tile) == DIAGDIR_SE || GetTunnelBridgeDirection(tile) == DIAGDIR_SW)) { + if ((!had_bridge || GetTunnelBridgeDirection(tile) == dir)) { cost.AddCost(ret); } had_bridge = true; } else { // IsTunnel(tile) - if ((!had_tunnel || GetTunnelBridgeDirection(tile) == DIAGDIR_SE || GetTunnelBridgeDirection(tile) == DIAGDIR_SW)) { + if ((!had_tunnel || GetTunnelBridgeDirection(tile) == dir)) { cost.AddCost(ret); } had_tunnel = true; @@ -780,7 +781,7 @@ CommandCost CmdBuildLongRoad(TileIndex end_tile, DoCommandFlag flags, uint32 p1, if (tile == end_tile) break; - tile += (axis == AXIS_Y) ? TileDiffXY(0, 1) : TileDiffXY(1, 0); + tile += TileOffsByDiagDir(dir); } return !had_success ? CMD_ERROR : cost; -- cgit v1.2.3-54-g00ecf