forked from mirror/OpenTTD
(svn r7573) -Merged the bridge branch. Allows to build bridges of arbitrary rail/road combinations (including signals)
This commit is contained in:
77
rail_cmd.c
77
rail_cmd.c
@@ -247,36 +247,13 @@ int32 CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
||||
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
||||
|
||||
switch (GetTileType(tile)) {
|
||||
case MP_TUNNELBRIDGE:
|
||||
if (!IsBridge(tile) ||
|
||||
!IsBridgeMiddle(tile) ||
|
||||
AxisToTrackBits(OtherAxis(GetBridgeAxis(tile))) != trackbit) {
|
||||
// Get detailed error message
|
||||
return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
||||
}
|
||||
|
||||
if (IsClearUnderBridge(tile)) {
|
||||
ret = CheckRailSlope(tileh, trackbit, 0, tile);
|
||||
if (CmdFailed(ret)) return ret;
|
||||
cost += ret;
|
||||
|
||||
if (flags & DC_EXEC) SetRailUnderBridge(tile, _current_player, railtype);
|
||||
} else if (IsTransportUnderBridge(tile) &&
|
||||
GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL) {
|
||||
return_cmd_error(STR_1007_ALREADY_BUILT);
|
||||
} else {
|
||||
// Get detailed error message
|
||||
return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
||||
}
|
||||
break;
|
||||
|
||||
case MP_RAILWAY:
|
||||
if (!CheckTrackCombination(tile, trackbit, flags) ||
|
||||
!EnsureNoVehicle(tile)) {
|
||||
return CMD_ERROR;
|
||||
}
|
||||
if (!IsTileOwner(tile, _current_player) ||
|
||||
!IsCompatibleRail(GetRailType(tile), railtype)) {
|
||||
GetRailType(tile) != railtype) {
|
||||
// Get detailed error message
|
||||
return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
|
||||
}
|
||||
@@ -366,20 +343,6 @@ int32 CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
||||
SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
|
||||
|
||||
switch (GetTileType(tile)) {
|
||||
case MP_TUNNELBRIDGE:
|
||||
if (!IsBridge(tile) ||
|
||||
!IsBridgeMiddle(tile) ||
|
||||
!IsTransportUnderBridge(tile) ||
|
||||
GetTransportTypeUnderBridge(tile) != TRANSPORT_RAIL ||
|
||||
GetRailBitsUnderBridge(tile) != trackbit ||
|
||||
(_current_player != OWNER_WATER && !CheckTileOwnership(tile)) ||
|
||||
!EnsureNoVehicleOnGround(tile)) {
|
||||
return CMD_ERROR;
|
||||
}
|
||||
|
||||
if (flags & DC_EXEC) SetClearUnderBridge(tile);
|
||||
break;
|
||||
|
||||
case MP_STREET: {
|
||||
if (!IsLevelCrossing(tile) ||
|
||||
GetCrossingRailBits(tile) != trackbit ||
|
||||
@@ -617,6 +580,8 @@ int32 CmdBuildTrainDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
|
||||
if (CmdFailed(ret)) return CMD_ERROR;
|
||||
cost = ret;
|
||||
|
||||
if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
|
||||
|
||||
d = AllocateDepot();
|
||||
if (d == NULL) return CMD_ERROR;
|
||||
|
||||
@@ -1414,6 +1379,7 @@ default_waypoint:
|
||||
);
|
||||
}
|
||||
}
|
||||
DrawBridgeMiddle(ti);
|
||||
}
|
||||
|
||||
|
||||
@@ -1513,19 +1479,11 @@ typedef struct SignalVehicleCheckStruct {
|
||||
static void *SignalVehicleCheckProc(Vehicle *v, void *data)
|
||||
{
|
||||
const SignalVehicleCheckStruct* dest = data;
|
||||
TileIndex tile;
|
||||
|
||||
if (v->type != VEH_Train) return NULL;
|
||||
|
||||
/* Find the tile outside the tunnel, for signalling */
|
||||
if (v->u.rail.track == 0x40) {
|
||||
tile = GetVehicleOutOfTunnelTile(v);
|
||||
} else {
|
||||
tile = v->tile;
|
||||
}
|
||||
|
||||
/* Wrong tile, or no train? Not a match */
|
||||
if (tile != dest->tile) return NULL;
|
||||
if (v->tile != dest->tile) return NULL;
|
||||
|
||||
/* Are we on the same piece of track? */
|
||||
if (dest->track & v->u.rail.track * 0x101) return v;
|
||||
@@ -1541,15 +1499,18 @@ static bool SignalVehicleCheck(TileIndex tile, uint track)
|
||||
dest.tile = tile;
|
||||
dest.track = track;
|
||||
|
||||
/** @todo "Hackish" fix for the tunnel problems. This is needed because a tunnel
|
||||
* is some kind of invisible black hole, and there is some special magic going
|
||||
* on in there. This 'workaround' can be removed once the maprewrite is done.
|
||||
*/
|
||||
if (IsTunnelTile(tile)) {
|
||||
// It is a tunnel we're checking, we need to do some special stuff
|
||||
// because VehicleFromPos will not find the vihicle otherwise
|
||||
TileIndex end = GetOtherTunnelEnd(tile);
|
||||
DiagDirection direction = GetTunnelDirection(tile);
|
||||
/* Locate vehicles in tunnels or on bridges */
|
||||
if (IsTunnelTile(tile) || IsBridgeTile(tile)) {
|
||||
TileIndex end;
|
||||
DiagDirection direction;
|
||||
|
||||
if (IsTunnelTile(tile)) {
|
||||
end = GetOtherTunnelEnd(tile);
|
||||
direction = GetTunnelDirection(tile);
|
||||
} else {
|
||||
end = GetOtherBridgeEnd(tile);
|
||||
direction = GetBridgeRampDirection(tile);
|
||||
}
|
||||
|
||||
dest.track = 1 << (direction & 1); // get the trackbit the vehicle would have if it has not entered the tunnel yet (ie is still visible)
|
||||
|
||||
@@ -1559,9 +1520,9 @@ static bool SignalVehicleCheck(TileIndex tile, uint track)
|
||||
// check for a vehicle with that trackdir on the end tile of the tunnel
|
||||
if (VehicleFromPos(end, &dest, SignalVehicleCheckProc) != NULL) return true;
|
||||
|
||||
// now check all tiles from start to end for a "hidden" vehicle
|
||||
// now check all tiles from start to end for a warping vehicle
|
||||
// NOTE: the hashes for tiles may overlap, so this could maybe be optimised a bit by not checking every tile?
|
||||
dest.track = 0x40; // trackbit for vehicles "hidden" inside a tunnel
|
||||
dest.track = 0x40; //Vehicle inside a tunnel or on a bridge
|
||||
for (; tile != end; tile += TileOffsByDiagDir(direction)) {
|
||||
if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL)
|
||||
return true;
|
||||
|
Reference in New Issue
Block a user