mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r24503) -Change [FS#5228]: When building long roads or tramways, only build the roadbits at the beginning and the end if they can connect to something.
This commit is contained in:
parent
771511c60e
commit
55dccee02f
|
@ -785,18 +785,33 @@ do_clear:;
|
|||
return cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a road or tram connection can be found when building a new road or tram.
|
||||
* @param tile Tile at which the road being built will end.
|
||||
* @param rt Roadtype of the road being built.
|
||||
* @param dir Direction that the road is following.
|
||||
* @return True if the next tile at dir direction is suitable for being connected directly by a second roadbit at the end of the road being built.
|
||||
*/
|
||||
static bool CanConnectToRoad(TileIndex tile, RoadType rt, DiagDirection dir)
|
||||
{
|
||||
RoadBits bits = GetAnyRoadBits(tile + TileOffsByDiagDir(dir), rt, false);
|
||||
return (bits & DiagDirToRoadBits(ReverseDiagDir(dir)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a long piece of road.
|
||||
* @param start_tile start tile of drag (the building cost will appear over this tile)
|
||||
* @param flags operation to perform
|
||||
* @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)
|
||||
* - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1). Only used if bit 6 is set or if we are building a single tile
|
||||
* - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2). Only used if bit 6 is set or if we are building a single tile
|
||||
* - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4)
|
||||
* - p2 = (bit 3 + 4) - road type
|
||||
* - p2 = (bit 5) - set road direction
|
||||
* - p2 = (bit 6) - 0 = build up to an obstacle, 1 = fail if an obstacle is found (used for AIs).
|
||||
* - p2 = (bit 6) - defines two different behaviors for this command:
|
||||
* - 0 = Build up to an obstacle. Do not build the first and last roadbits unless they can be connected to something, or if we are building a single tile
|
||||
* - 1 = Fail if an obstacle is found. Always take into account bit 0 and 1. This behavior is used for scripts
|
||||
* @param text unused
|
||||
* @return the cost of this operation or an error
|
||||
*/
|
||||
|
@ -837,19 +852,31 @@ CommandCost CmdBuildLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p
|
|||
bool had_bridge = false;
|
||||
bool had_tunnel = false;
|
||||
bool had_success = false;
|
||||
bool is_ai = HasBit(p2, 6);
|
||||
|
||||
/* Start tile is the first tile clicked by the user. */
|
||||
for (;;) {
|
||||
RoadBits bits = AxisToRoadBits(axis);
|
||||
|
||||
/* 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);
|
||||
/* Determine which road parts should be built. */
|
||||
if (!is_ai && start_tile != end_tile) {
|
||||
/* Only build the first and last roadbit if they can connect to something. */
|
||||
if (tile == end_tile && !CanConnectToRoad(tile, rt, dir)) {
|
||||
bits = DiagDirToRoadBits(ReverseDiagDir(dir));
|
||||
} else if (tile == start_tile && !CanConnectToRoad(tile, rt, ReverseDiagDir(dir))) {
|
||||
bits = DiagDirToRoadBits(dir);
|
||||
}
|
||||
} else {
|
||||
/* 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);
|
||||
}
|
||||
|
||||
CommandCost ret = DoCommand(tile, drd << 6 | rt << 4 | bits, 0, flags, CMD_BUILD_ROAD);
|
||||
if (ret.Failed()) {
|
||||
last_error = ret;
|
||||
if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT) {
|
||||
if (HasBit(p2, 6)) return last_error;
|
||||
if (is_ai) return last_error;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue