Changeset - r3933:400e9c30928e
[Not reviewed]
master
0 33 0
celestar - 18 years ago 2006-06-02 13:05:41
celestar@openttd.org
(svn r5070) Merged the bridge branch
-Feature: Bridges can now be placed above:
Any railway track combination (excluding depots and waypoints)
Any road combination (excluding depots)
Clear tiles (duh), including fields
Tunnel entrances
Bridge heads

Thanks to Tron for idea and implementation, KUDr for the yapf synchronization and many others for hours of testing

There are still a number of visual problems remaining, especially when electric railways are on or under the bridge.
DO NOT REPORT THOSE BUGS FOR THE TIME BEING please.
33 files changed with 767 insertions and 972 deletions:
0 comments (0 inline, 0 general)
BUGS
Show inline comments
 
/* $Id */
 
/* $Id$ */
 

	
 
KNOWN BUGS / PROBLEMS:
 

	
 
bridges:
 
Graphical problems, especially in conjunction with signals and catenary
 

	
 
electrified rails:
 
Normal and elrail depots look the same. Use 'X' (transparent buildings)
 
   to distinguish between them
 
Missing curors / icons for construction (currently using the conventional ones)
 

	
ai/default/default.c
Show inline comments
 
@@ -2158,9 +2158,7 @@ static bool AiRemoveTileAndGoForward(Pla
 
				return false;
 
			p->ai.cur_tile_a = TILE_MASK(_build_tunnel_endtile - TileOffsByDir(p->ai.cur_dir_a));
 
			return true;
 
		}
 

	
 
		if (IsBridgeRamp(tile)) {
 
		} else {
 
			// Check if the bridge points in the right direction.
 
			// This is not really needed the first place AiRemoveTileAndGoForward is called.
 
			if (DiagDirToAxis(GetBridgeRampDirection(tile)) != (p->ai.cur_dir_a & 1U)) return false;
 
@@ -3692,7 +3690,6 @@ pos_3:
 
	} else if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
		if (!IsTileOwner(tile, _current_player) ||
 
				!IsBridge(tile) ||
 
				!IsBridgeRamp(tile) ||
 
				GetBridgeTransportType(tile) != TRANSPORT_RAIL) {
 
			return;
 
		}
bridge.h
Show inline comments
 
@@ -27,5 +27,6 @@ extern const Bridge orig_bridge[MAX_BRID
 
extern Bridge _bridge[MAX_BRIDGES];
 

	
 
uint GetBridgeFoundation(Slope tileh, Axis axis);
 
uint SetSpeedLimitOnBridge(Vehicle *);
 

	
 
#endif /* BRIDGE_H */
bridge_map.c
Show inline comments
 
@@ -3,22 +3,25 @@
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
#include "variables.h"
 

	
 

	
 
TileIndex GetBridgeEnd(TileIndex tile, DiagDirection dir)
 
{
 
	TileIndexDiff delta = TileOffsByDir(dir);
 

	
 
	assert(DiagDirToAxis(dir) == GetBridgeAxis(tile));
 

	
 
	do {
 
		tile += delta;
 
	} while (!IsBridgeRamp(tile));
 
	do { tile += delta; } while (IsBridgeAbove(tile) && IsBridgeOfAxis(tile, DiagDirToAxis(dir)));
 

	
 
	return tile;
 
}
 

	
 

	
 
TileIndex GetNorthernBridgeEnd(TileIndex t)
 
{
 
	return GetBridgeEnd(t, ReverseDiagDir(AxisToDiagDir(GetBridgeAxis(t))));
 
}
 

	
 

	
 
TileIndex GetSouthernBridgeEnd(TileIndex t)
 
{
 
	return GetBridgeEnd(t, AxisToDiagDir(GetBridgeAxis(t)));
 
@@ -27,11 +30,25 @@ TileIndex GetSouthernBridgeEnd(TileIndex
 

	
 
TileIndex GetOtherBridgeEnd(TileIndex tile)
 
{
 
	TileIndexDiff delta = TileOffsByDir(GetBridgeRampDirection(tile));
 
	assert(IsBridgeTile(tile));
 
	return GetBridgeEnd(tile, GetBridgeRampDirection(tile));
 
}
 

	
 
uint GetBridgeHeight(TileIndex tile, Axis a)
 
{
 
	uint h, f;
 
	uint tileh = GetTileSlope(tile, &h);
 

	
 
	f = GetBridgeFoundation(tileh, a);
 

	
 
	do {
 
		tile += delta;
 
	} while (!IsBridgeRamp(tile));
 
	if (f) {
 
		if (f < 15) {
 
			h += TILE_HEIGHT;
 
			tileh = SLOPE_FLAT;
 
		} else {
 
			tileh = _inclined_tileh[f - 15];
 
		}
 
	}
 

	
 
	return tile;
 
	return h + TILE_HEIGHT;
 
}
bridge_map.h
Show inline comments
 
@@ -11,6 +11,9 @@
 
#include "tile.h"
 

	
 

	
 
void DrawBridgeMiddle(const TileInfo* ti); // XXX
 

	
 

	
 
static inline bool IsBridge(TileIndex t)
 
{
 
	assert(IsTileType(t, MP_TUNNELBRIDGE));
 
@@ -23,28 +26,38 @@ static inline bool IsBridgeTile(TileInde
 
}
 

	
 

	
 
static inline bool IsBridgeRamp(TileIndex t)
 
static inline bool MayHaveBridgeAbove(TileIndex t)
 
{
 
	assert(IsBridgeTile(t));
 
	return !HASBIT(_m[t].m5, 6);
 
}
 

	
 
static inline bool IsBridgeMiddle(TileIndex t)
 
{
 
	assert(IsBridgeTile(t));
 
	return HASBIT(_m[t].m5, 6);
 
	return
 
		IsTileType(t, MP_CLEAR) ||
 
		IsTileType(t, MP_RAILWAY) ||
 
		IsTileType(t, MP_STREET) ||
 
		IsTileType(t, MP_WATER) ||
 
		IsTileType(t, MP_TUNNELBRIDGE);
 
}
 

	
 

	
 
/**
 
 * Determines which piece of a bridge is contained in the current tile
 
 * @param tile The tile to analyze
 
 * @return the piece
 
 */
 
static inline uint GetBridgePiece(TileIndex t)
 
static inline bool IsXBridgeAbove(TileIndex t)
 
{
 
	assert(MayHaveBridgeAbove(t));
 
	return GB(_m[t].extra, 6, 1) != 0;
 
}
 

	
 
static inline bool IsYBridgeAbove(TileIndex t)
 
{
 
	assert(IsBridgeMiddle(t));
 
	return GB(_m[t].m2, 0, 4);
 
	assert(MayHaveBridgeAbove(t));
 
	return GB(_m[t].extra, 7, 1) != 0;
 
}
 

	
 
static inline bool IsBridgeOfAxis(TileIndex t, Axis a)
 
{
 
	if (a == AXIS_X) return IsXBridgeAbove(t);
 
	return IsYBridgeAbove(t);
 
}
 

	
 
static inline bool IsBridgeAbove(TileIndex t)
 
{
 
	return (IsXBridgeAbove(t) || IsYBridgeAbove(t));
 
}
 

	
 

	
 
@@ -65,7 +78,6 @@ static inline uint GetBridgeType(TileInd
 
 */
 
static inline DiagDirection GetBridgeRampDirection(TileIndex t)
 
{
 
	assert(IsBridgeRamp(t));
 
	/* Heavy wizardry to convert the X/Y (bit 0) + N/S (bit 5) encoding of
 
	 * bridges to a DiagDirection
 
	 */
 
@@ -75,8 +87,9 @@ static inline DiagDirection GetBridgeRam
 

	
 
static inline Axis GetBridgeAxis(TileIndex t)
 
{
 
	assert(IsBridgeMiddle(t));
 
	return (Axis)GB(_m[t].m5, 0, 1);
 
	static const Axis BridgeAxis[] = {AXIS_END, AXIS_X, AXIS_Y, AXIS_END};
 
	assert(IsBridgeAbove(t));
 
	return BridgeAxis[GB(_m[t].extra, 6, 2)];
 
}
 

	
 

	
 
@@ -87,50 +100,17 @@ static inline TransportType GetBridgeTra
 
}
 

	
 

	
 
static inline bool IsClearUnderBridge(TileIndex t)
 
{
 
	assert(IsBridgeMiddle(t));
 
	return GB(_m[t].m5, 3, 3) == 0;
 
}
 

	
 
static inline bool IsWaterUnderBridge(TileIndex t)
 
{
 
	assert(IsBridgeMiddle(t));
 
	return GB(_m[t].m5, 3, 3) == 1;
 
}
 

	
 

	
 
static inline bool IsTransportUnderBridge(TileIndex t)
 
{
 
	assert(IsBridgeMiddle(t));
 
	return HASBIT(_m[t].m5, 5);
 
}
 

	
 
static inline TransportType GetTransportTypeUnderBridge(TileIndex t)
 
{
 
	assert(IsTransportUnderBridge(t));
 
	return (TransportType)GB(_m[t].m5, 3, 2);
 
}
 

	
 
static inline RoadBits GetRoadBitsUnderBridge(TileIndex t)
 
{
 
	assert(GetTransportTypeUnderBridge(t) == TRANSPORT_ROAD);
 
	return GetBridgeAxis(t) == AXIS_X ? ROAD_Y : ROAD_X;
 
}
 

	
 
static inline TrackBits GetRailBitsUnderBridge(TileIndex t)
 
{
 
	assert(GetTransportTypeUnderBridge(t) == TRANSPORT_RAIL);
 
	return GetBridgeAxis(t) == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X;
 
}
 

	
 

	
 
/**
 
 * Finds the end of a bridge in the specified direction starting at a middle tile
 
 */
 
TileIndex GetBridgeEnd(TileIndex, DiagDirection);
 

	
 
/**
 
 * Finds the northern end of a bridge starting at a middle tile
 
 */
 
TileIndex GetNorthernBridgeEnd(TileIndex t);
 

	
 
/**
 
 * Finds the southern end of a bridge starting at a middle tile
 
 */
 
TileIndex GetSouthernBridgeEnd(TileIndex t);
 
@@ -141,38 +121,26 @@ TileIndex GetSouthernBridgeEnd(TileIndex
 
 */
 
TileIndex GetOtherBridgeEnd(TileIndex);
 

	
 
uint GetBridgeHeight(TileIndex t);
 
uint GetBridgeHeight(TileIndex tile, Axis a);
 
uint GetBridgeFoundation(Slope tileh, Axis axis);
 

	
 
static inline void SetClearUnderBridge(TileIndex t)
 
static inline void ClearSingleBridgeMiddle(TileIndex t, Axis a)
 
{
 
	assert(IsBridgeMiddle(t));
 
	SetTileOwner(t, OWNER_NONE);
 
	SB(_m[t].m5, 3, 3, 0 << 2 | 0);
 
	SB(_m[t].m3, 0, 4, 0);
 
	assert(MayHaveBridgeAbove(t));
 
	CLRBIT(_m[t].extra, 6 + a);
 
}
 

	
 
static inline void SetWaterUnderBridge(TileIndex t)
 

	
 
static inline void ClearBridgeMiddle(TileIndex t)
 
{
 
	assert(IsBridgeMiddle(t));
 
	SetTileOwner(t, OWNER_WATER);
 
	SB(_m[t].m5, 3, 3, 0 << 2 | 1);
 
	SB(_m[t].m3, 0, 4, 0);
 
	ClearSingleBridgeMiddle(t, AXIS_X);
 
	ClearSingleBridgeMiddle(t, AXIS_Y);
 
}
 

	
 
static inline void SetRailUnderBridge(TileIndex t, Owner o, RailType r)
 
static inline void SetBridgeMiddle(TileIndex t, Axis a)
 
{
 
	assert(IsBridgeMiddle(t));
 
	SetTileOwner(t, o);
 
	SB(_m[t].m5, 3, 3, 1 << 2 | TRANSPORT_RAIL);
 
	SB(_m[t].m3, 0, 4, r);
 
}
 

	
 
static inline void SetRoadUnderBridge(TileIndex t, Owner o)
 
{
 
	assert(IsBridgeMiddle(t));
 
	SetTileOwner(t, o);
 
	SB(_m[t].m5, 3, 3, 1 << 2 | TRANSPORT_ROAD);
 
	SB(_m[t].m3, 0, 4, 0);
 
	assert(MayHaveBridgeAbove(t));
 
	SETBIT(_m[t].extra, 6 + a);
 
}
 

	
 

	
 
@@ -200,26 +168,4 @@ static inline void MakeRailBridgeRamp(Ti
 
}
 

	
 

	
 
static inline void MakeBridgeMiddle(TileIndex t, uint bridgetype, uint piece, Axis a, TransportType tt)
 
{
 
	SetTileType(t, MP_TUNNELBRIDGE);
 
	SetTileOwner(t, OWNER_NONE);
 
	_m[t].m2 = bridgetype << 4 | piece;
 
	_m[t].m3 = 0;
 
	_m[t].m4 = 0;
 
	_m[t].m5 = 1 << 7 | 1 << 6 | 0 << 5 | 0 << 3 | tt << 1 | a;
 
}
 

	
 
static inline void MakeRoadBridgeMiddle(TileIndex t, uint bridgetype, uint piece, Axis a)
 
{
 
	MakeBridgeMiddle(t, bridgetype, piece, a, TRANSPORT_ROAD);
 
}
 

	
 
static inline void MakeRailBridgeMiddle(TileIndex t, uint bridgetype, uint piece, Axis a, RailType r)
 
{
 
	MakeBridgeMiddle(t, bridgetype, piece, a, TRANSPORT_RAIL);
 
	SB(_m[t].m3, 4, 4, r);
 
}
 

	
 

	
 
#endif
clear_cmd.c
Show inline comments
 
@@ -11,6 +11,7 @@
 
#include "viewport.h"
 
#include "command.h"
 
#include "tunnel_map.h"
 
#include "bridge_map.h"
 
#include "variables.h"
 
#include "table/sprites.h"
 
#include "unmovable_map.h"
 
@@ -259,6 +260,14 @@ int32 CmdTerraformLand(TileIndex tile, u
 
				} else return_cmd_error(STR_5800_OBJECT_IN_THE_WAY);
 
			}
 

	
 
			if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) {
 
				byte height = GetBridgeHeight(GetNorthernBridgeEnd(tile), GetBridgeAxis(tile));
 

	
 
				height /= TILE_HEIGHT;
 

	
 
				if (a >= height || b >= height || c >= height || d >= height) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 
			}
 

	
 
			if (direction == -1 && IsTunnelInWay(tile, min)) return_cmd_error(STR_1002_EXCAVATION_WOULD_DAMAGE);
 

	
 
			_terraform_err_tile = 0;
 
@@ -501,6 +510,7 @@ static void DrawTile_Clear(TileInfo *ti)
 
	}
 

	
 
	DrawClearLandFence(ti);
 
	DrawBridgeMiddle(ti);
 
}
 

	
 
static uint GetSlopeZ_Clear(const TileInfo* ti)
elrail.c
Show inline comments
 
@@ -91,18 +91,10 @@ static TrackBits GetRailTrackBitsUnivers
 
				return DiagDirToAxis(GetTunnelDirection(t)) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y;
 
			} else {
 
				if (GetRailType(t) != RAILTYPE_ELECTRIC) return 0;
 
				if (IsBridgeMiddle(t)) {
 
					if (IsTransportUnderBridge(t) &&
 
						GetTransportTypeUnderBridge(t) == TRANSPORT_RAIL) {
 
						return GetRailBitsUnderBridge(t);
 
					} else {
 
						return 0;
 
					}
 
				} else {
 
					if (override != NULL && DistanceMax(t, GetOtherBridgeEnd(t)) > 1) *override = 1 << GetBridgeRampDirection(t);
 

	
 
					return DiagDirToAxis(GetBridgeRampDirection(t)) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y;
 
				if (override != NULL && DistanceMax(t, GetOtherBridgeEnd(t)) > 1) {
 
					*override = 1 << GetBridgeRampDirection(t);
 
				}
 
				return DiagDirToAxis(GetBridgeRampDirection(t)) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y;
 
			}
 
		case MP_STREET:
 
			if (GetRoadTileType(t) != ROAD_TILE_CROSSING) return 0;
 
@@ -125,7 +117,7 @@ static TrackBits GetRailTrackBitsUnivers
 
static void AdjustTileh(TileIndex tile, Slope* tileh)
 
{
 
	if (IsTunnelTile(tile)) *tileh = SLOPE_FLAT;
 
	if (IsBridgeTile(tile) && IsBridgeRamp(tile)) {
 
	if (IsBridgeTile(tile)) {
 
		if (*tileh != SLOPE_FLAT) {
 
			*tileh = SLOPE_FLAT;
 
		} else {
 
@@ -193,9 +185,10 @@ static void DrawCatenaryRailway(const Ti
 
		for (k = 0; k < NUM_TRACKS_AT_PCP; k++) {
 
			/* Next to us, we have a bridge head, don't worry about that one, if it shows away from us */
 
			if (TrackSourceTile[i][k] == TS_NEIGHBOUR &&
 
			    IsBridgeTile(neighbour) && IsBridgeRamp(neighbour) &&
 
			    GetBridgeRampDirection(neighbour) == ReverseDiagDir(i)
 
			   ) continue;
 
			    IsBridgeTile(neighbour) &&
 
			    GetBridgeRampDirection(neighbour) == ReverseDiagDir(i)) {
 
				continue;
 
			}
 

	
 
			/* We check whether the track in question (k) is present in the tile
 
			   (TrackSourceTile) */
 
@@ -219,7 +212,7 @@ static void DrawCatenaryRailway(const Ti
 

	
 
		/* Read the foundataions if they are present, and adjust the tileh */
 
		if (IsTileType(neighbour, MP_RAILWAY)) foundation = GetRailFoundation(tileh[TS_NEIGHBOUR], trackconfig[TS_NEIGHBOUR]);
 
		if (IsBridgeTile(neighbour) && IsBridgeRamp(neighbour)) {
 
		if (IsBridgeTile(neighbour)) {
 
			foundation = GetBridgeFoundation(tileh[TS_NEIGHBOUR], DiagDirToAxis(GetBridgeRampDirection(neighbour)));
 
		}
 

	
 
@@ -247,6 +240,14 @@ static void DrawCatenaryRailway(const Ti
 
		   Remove those (simply by ANDing with allowed, since these markers are never allowed) */
 
		if ( (PPPallowed[i] & PPPpreferred[i]) != 0) PPPallowed[i] &= PPPpreferred[i];
 

	
 
		if (MayHaveBridgeAbove(ti->tile) && IsBridgeAbove(ti->tile)) {
 
			Track bridgetrack = GetBridgeAxis(ti->tile) == AXIS_X ? TRACK_X : TRACK_Y;
 
			uint height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile), GetBridgeAxis(ti->tile));
 

	
 
			if ((height <= TilePixelHeight(ti->tile) + TILE_HEIGHT) &&
 
			(i == PCPpositions[bridgetrack][0] || i == PCPpositions[bridgetrack][1])) SETBIT(OverridePCP, i);
 
		}
 

	
 
		if (PPPallowed[i] != 0 && HASBIT(PCPstatus, i) && !HASBIT(OverridePCP, i)) {
 
			for (k = 0; k < DIR_END; k++) {
 
				byte temp = PPPorder[i][GetTLG(ti->tile)][k];
 
@@ -279,12 +280,11 @@ static void DrawCatenaryRailway(const Ti
 
			const SortableSpriteStruct *sss;
 
			int tileh_selector = !(tileh[TS_HOME] % 3) * tileh[TS_HOME] / 3; /* tileh for the slopes, 0 otherwise */
 

	
 
			if ( /* We are not drawing a wire under a low bridge */
 
					IsBridgeTile(ti->tile) &&
 
					IsBridgeMiddle(ti->tile) &&
 
					!(_display_opt & DO_TRANS_BUILDINGS) &&
 
					GetBridgeHeight(ti->tile) <= TilePixelHeight(ti->tile)
 
			   ) return;
 
			if (MayHaveBridgeAbove(ti->tile) && IsBridgeAbove(ti->tile) && !(_display_opt & DO_TRANS_BUILDINGS)) {
 
				uint height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile), GetBridgeAxis(ti->tile));
 

	
 
				if (height <= TilePixelHeight(ti->tile) + TILE_HEIGHT) return;
 
			}
 

	
 
			assert(PCPconfig != 0); /* We have a pylon on neither end of the wire, that doesn't work (since we have no sprites for that) */
 
			assert(!IsSteepSlope(tileh[TS_HOME]));
 
@@ -320,30 +320,37 @@ static void DrawCatenaryOnBridge(const T
 
	}
 

	
 
	AddSortableSpriteToDraw( sss->image, ti->x + sss->x_offset, ti->y + sss->y_offset,
 
			sss->x_size, sss->y_size, sss->z_size, GetBridgeHeight(ti->tile) + sss->z_offset + 8);
 
			sss->x_size, sss->y_size, sss->z_size, GetBridgeHeight(end, axis) + sss->z_offset);
 

	
 
	/* Finished with wires, draw pylons */
 
	/* every other tile needs a pylon on the northern end */
 
	if (num % 2) {
 
		if (axis == AXIS_X) {
 
			AddSortableSpriteToDraw( pylons_bridge[0 + HASBIT(tlg, 0)], ti->x, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, GetBridgeHeight(ti->tile) + TILE_HEIGHT);
 
			AddSortableSpriteToDraw( pylons_bridge[0 + HASBIT(tlg, 0)], ti->x, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, GetBridgeHeight(end, axis));
 
		} else {
 
			AddSortableSpriteToDraw( pylons_bridge[2 + HASBIT(tlg, 1)], ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y, 1, 1, 10, GetBridgeHeight(ti->tile) + TILE_HEIGHT);
 
			AddSortableSpriteToDraw( pylons_bridge[2 + HASBIT(tlg, 1)], ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y, 1, 1, 10, GetBridgeHeight(end, axis));
 
		}
 
	}
 

	
 
	/* need a pylon on the southern end of the bridge */
 
	if (DistanceMax(ti->tile, start) == length) {
 
		if (axis == AXIS_X) {
 
			AddSortableSpriteToDraw( pylons_bridge[0 + HASBIT(tlg, 0)], ti->x + 16, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, GetBridgeHeight(ti->tile) + TILE_HEIGHT);
 
			AddSortableSpriteToDraw( pylons_bridge[0 + HASBIT(tlg, 0)], ti->x + 16, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, GetBridgeHeight(end, axis));
 
		} else {
 
			AddSortableSpriteToDraw( pylons_bridge[2 + HASBIT(tlg, 1)], ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y + 16, 1, 1, 10, GetBridgeHeight(ti->tile) + TILE_HEIGHT);
 
			AddSortableSpriteToDraw( pylons_bridge[2 + HASBIT(tlg, 1)], ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y + 16, 1, 1, 10, GetBridgeHeight(end, axis));
 
		}
 
	}
 
}
 

	
 
void DrawCatenary(const TileInfo *ti)
 
{
 
	if (MayHaveBridgeAbove(ti->tile) && IsBridgeAbove(ti->tile)) {
 
		TileIndex head = GetNorthernBridgeEnd(ti->tile);
 

	
 
		if (GetBridgeTransportType(head) == TRANSPORT_RAIL && GetRailType(head) == RAILTYPE_ELECTRIC) {
 
			DrawCatenaryOnBridge(ti);
 
		}
 
	}
 
	switch (GetTileType(ti->tile)) {
 
		case MP_RAILWAY:
 
			if (GetRailTileType(ti->tile) == RAIL_TILE_DEPOT_WAYPOINT && GetRailTileSubtype(ti->tile) == RAIL_SUBTYPE_DEPOT) {
 
@@ -354,9 +361,8 @@ void DrawCatenary(const TileInfo *ti)
 
			}
 
			/* Fall through */
 
		case MP_TUNNELBRIDGE:
 
			if (IsBridgeTile(ti->tile) && IsBridgeMiddle(ti->tile) && GetRailTypeOnBridge(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenaryOnBridge(ti);
 
			/* Fall further */
 
		case MP_STREET: case MP_STATION:
 
		case MP_STREET:
 
		case MP_STATION:
 
			DrawCatenaryRailway(ti);
 
			break;
 
		default:
landscape.c
Show inline comments
 
@@ -2,6 +2,7 @@
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
#include "clear_map.h"
 
#include "functions.h"
 
#include "map.h"
 
@@ -387,6 +388,8 @@ void InitializeLandscape(void)
 
		for (x = 0; x < maxx; x++) {
 
			MakeClear(sizex * y + x, CLEAR_GRASS, 3);
 
			SetTileHeight(sizex * y + x, 0);
 
			_m[sizex * y + x].extra = 0;
 
			ClearBridgeMiddle(sizex * y + x);
 
		}
 
		MakeVoid(sizex * y + x);
 
	}
misc.c
Show inline comments
 
@@ -859,16 +859,26 @@ static void Load_MAPE(void)
 
	uint size = MapSize();
 
	uint i;
 

	
 
	for (i = 0; i != size;) {
 
		uint8 buf[1024];
 
		uint j;
 
	if (CheckSavegameVersion(29)) {
 
		for (i = 0; i != size;) {
 
			uint8 buf[1024];
 
			uint j;
 

	
 
		SlArray(buf, lengthof(buf), SLE_UINT8);
 
		for (j = 0; j != lengthof(buf); j++) {
 
			_m[i++].extra = GB(buf[j], 0, 2);
 
			_m[i++].extra = GB(buf[j], 2, 2);
 
			_m[i++].extra = GB(buf[j], 4, 2);
 
			_m[i++].extra = GB(buf[j], 6, 2);
 
			SlArray(buf, lengthof(buf), SLE_UINT8);
 
			for (j = 0; j != lengthof(buf); j++) {
 
				_m[i++].extra = GB(buf[j], 0, 2);
 
				_m[i++].extra = GB(buf[j], 2, 2);
 
				_m[i++].extra = GB(buf[j], 4, 2);
 
				_m[i++].extra = GB(buf[j], 6, 2);
 
			}
 
		}
 
	} else {
 
		for (i = 0; i != size;) {
 
			byte buf[4096];
 
			uint j;
 

	
 
			SlArray(buf, lengthof(buf), SLE_UINT8);
 
			for (j = 0; j != lengthof(buf); j++) _m[i++].extra = buf[j];
 
		}
 
	}
 
}
 
@@ -878,17 +888,12 @@ static void Save_MAPE(void)
 
	uint size = MapSize();
 
	uint i;
 

	
 
	SlSetLength(size / 4);
 
	SlSetLength(size);
 
	for (i = 0; i != size;) {
 
		uint8 buf[1024];
 
		uint8 buf[4096];
 
		uint j;
 

	
 
		for (j = 0; j != lengthof(buf); j++) {
 
			buf[j]  = _m[i++].extra << 0;
 
			buf[j] |= _m[i++].extra << 2;
 
			buf[j] |= _m[i++].extra << 4;
 
			buf[j] |= _m[i++].extra << 6;
 
		}
 
		for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].extra;
 
		SlArray(buf, lengthof(buf), SLE_UINT8);
 
	}
 
}
npf.c
Show inline comments
 
@@ -479,17 +479,7 @@ static bool VehicleMayEnterTile(Owner ow
 

	
 
		case MP_TUNNELBRIDGE:
 
			if ((IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_RAIL) ||
 
					(IsBridge(tile) && (
 
						(
 
							IsBridgeRamp(tile) &&
 
							GetBridgeTransportType(tile) == TRANSPORT_RAIL
 
						) || (
 
							IsBridgeMiddle(tile) &&
 
							IsTransportUnderBridge(tile) &&
 
							GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL &&
 
							GetBridgeAxis(tile) != DiagDirToAxis(enterdir)
 
						)
 
					))) {
 
					(IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL)) {
 
				return IsTileOwner(tile, owner);
 
			}
 
			break;
 
@@ -516,6 +506,7 @@ static void NPFFollowTrack(AyStar* aysta
 
	int i;
 
	TrackdirBits trackdirbits, ts;
 
	TransportType type = aystar->user_data[NPF_TYPE];
 
	bool override_dst_check = false;
 
	/* Initialize to 0, so we can jump out (return) somewhere an have no neighbours */
 
	aystar->num_neighbours = 0;
 
	DEBUG(npf, 4)("Expanding: (%d, %d, %d) [%d]", TileX(src_tile), TileY(src_tile), src_trackdir, src_tile);
 
@@ -526,6 +517,10 @@ static void NPFFollowTrack(AyStar* aysta
 
		 * otherwise we wouldn't have got here. It is also facing us,
 
		 * so we should skip it's body */
 
		dst_tile = GetOtherTunnelEnd(src_tile);
 
		override_dst_check = true;
 
	} else if (IsBridgeTile(src_tile) && GetBridgeRampDirection(src_tile) == src_exitdir) {
 
		dst_tile = GetOtherBridgeEnd(src_tile);
 
		override_dst_check = true;
 
	} else if (type != TRANSPORT_WATER && (IsRoadStopTile(src_tile) || IsTileDepotType(src_tile, type))) {
 
		/* This is a road station or a train or road depot. We can enter and exit
 
		 * those from one side only. Trackdirs don't support that (yet), so we'll
 
@@ -573,8 +568,14 @@ static void NPFFollowTrack(AyStar* aysta
 
	/* I can't enter a tunnel entry/exit tile from a tile above the tunnel. Note
 
	 * that I can enter the tunnel from a tile below the tunnel entrance. This
 
	 * solves the problem of vehicles wanting to drive off a tunnel entrance */
 
	if (IsTunnelTile(dst_tile) && GetTileZ(dst_tile) < GetTileZ(src_tile)) {
 
		return;
 
	if (!override_dst_check) {
 
		if (IsTileType(dst_tile, MP_TUNNELBRIDGE)) {
 
			if (IsTunnel(dst_tile)) {
 
				if (GetTunnelDirection(dst_tile) != src_exitdir) return;
 
			} else {
 
				if (GetBridgeRampDirection(dst_tile) != src_exitdir) return;
 
			}
 
		}
 
	}
 

	
 
	/* check correct rail type (mono, maglev, etc) */
openttd.c
Show inline comments
 
@@ -49,6 +49,12 @@
 
#include "yapf/yapf.h"
 
#include "settings.h"
 

	
 
#include "bridge_map.h"
 
#include "clear_map.h"
 
#include "rail_map.h"
 
#include "road_map.h"
 
#include "water_map.h"
 

	
 
#include <stdarg.h>
 

	
 
void GenerateWorld(int mode, uint size_x, uint size_y);
 
@@ -1256,6 +1262,72 @@ bool AfterLoadGame(void)
 
		}
 
	}
 

	
 
	if (CheckSavegameVersion(29)) {
 
		TileIndex map_end = MapSize();
 
		TileIndex tile;
 
		Vehicle* v;
 

	
 
		for (tile = 0; tile != map_end; tile++) {
 
			if (MayHaveBridgeAbove(tile)) ClearBridgeMiddle(tile);
 
			if (IsTileType(tile, MP_TUNNELBRIDGE) &&
 
					_m[tile].m5 & 0x80 && // bridge
 
					_m[tile].m5 & 0x40) { // middle part
 
				Axis axis = (Axis)GB(_m[tile].m5, 0, 1);
 

	
 
				if (_m[tile].m5 & 0x20) { // transport route under bridge?
 
					if (GB(_m[tile].m5, 3, 2) == TRANSPORT_RAIL) {
 
						MakeRailNormal(
 
							tile,
 
							GetTileOwner(tile),
 
							axis == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X,
 
							GetRailType(tile)
 
						);
 
					} else {
 
						uint town = IsTileOwner(tile, OWNER_TOWN) ? ClosestTownFromTile(tile, (uint)-1)->index : 0;
 

	
 
						MakeRoadNormal(
 
							tile,
 
							GetTileOwner(tile),
 
							axis == AXIS_X ? ROAD_Y : ROAD_X,
 
							town
 
						);
 
					}
 
				} else {
 
					if (GB(_m[tile].m5, 3, 2) == 0) {
 
						MakeClear(tile, CLEAR_GRASS, 3);
 
					} else {
 
						MakeWater(tile);
 
					}
 
				}
 
				SetBridgeMiddle(tile, axis);
 
			}
 
		}
 

	
 
		FOR_ALL_VEHICLES(v) {
 
			if (v->type != VEH_Train && v->type != VEH_Road) continue;
 
			if (IsBridgeTile(v->tile)) {
 
				DiagDirection dir = GetBridgeRampDirection(v->tile);
 

	
 
				if (dir != DirToDiagDir(v->direction)) continue;
 
				switch (dir) {
 
					default:
 
					case DIAGDIR_NE: if ((v->x_pos & 0xF) !=  0) continue;
 
					case DIAGDIR_SE: if ((v->y_pos & 0xF) != 15) continue;
 
					case DIAGDIR_SW: if ((v->x_pos & 0xF) != 15) continue;
 
					case DIAGDIR_NW: if ((v->y_pos & 0xF) !=  0) continue;
 
				}
 
			} else if (v->z_pos <= GetSlopeZ(v->x_pos, v->y_pos)) {
 
				continue;
 
			}
 
			if (!IsBridgeTile(v->tile)) v->tile = GetNorthernBridgeEnd(v->tile);
 
			if (v->type == VEH_Train) {
 
				v->u.rail.track = 0x40;
 
			} else {
 
				v->u.road.state = 0xFF;
 
			}
 
		}
 
	}
 

	
 
	/* Elrails got added in rev 24 */
 
	if (CheckSavegameVersion(24)) {
 
		Vehicle* v;
 
@@ -1306,15 +1378,6 @@ bool AfterLoadGame(void)
 
						}
 
					} else {
 
						if (GetBridgeTransportType(t) == TRANSPORT_RAIL) {
 
							if (IsBridgeRamp(t)) {
 
								SetRailType(t, UpdateRailType(GetRailType(t), min_rail));
 
							} else {
 
								SetRailTypeOnBridge(t, UpdateRailType(GetRailTypeOnBridge(t), min_rail));
 
							}
 
						}
 
						if (IsBridgeMiddle(t) &&
 
								IsTransportUnderBridge(t) &&
 
								GetTransportTypeUnderBridge(t) == TRANSPORT_RAIL) {
 
							SetRailType(t, UpdateRailType(GetRailType(t), min_rail));
 
						}
 
					}
pathfind.c
Show inline comments
 
@@ -256,21 +256,27 @@ static void TPFMode1(TrackPathFinder* tp
 
	RememberData rd;
 
	TileIndex tile_org = tile;
 

	
 
	// check if the old tile can be left at that direction
 
	if (tpf->tracktype == TRANSPORT_ROAD) {
 
		// road stops and depots now have a track (r4419)
 
		// don't enter road stop from the back
 
		if (IsRoadStopTile(tile) && GetRoadStopDir(tile) != direction) return;
 
		// don't enter road depot from the back
 
		if (IsTileDepotType(tile, TRANSPORT_ROAD) && GetRoadDepotDirection(tile) != direction) return;
 
	}
 

	
 
	if (IsTunnelTile(tile)) {
 
		if (GetTunnelDirection(tile) != direction ||
 
				GetTunnelTransportType(tile) != tpf->tracktype) {
 
			return;
 
	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
		if (IsTunnel(tile)) {
 
			if (GetTunnelDirection(tile) != direction ||
 
					GetTunnelTransportType(tile) != tpf->tracktype) {
 
				return;
 
			}
 
			tile = SkipToEndOfTunnel(tpf, tile, direction);
 
		} else {
 
			TileIndex tile_end;
 
			if (GetBridgeRampDirection(tile) != direction ||
 
					GetBridgeTransportType(tile) != tpf->tracktype) {
 
				return;
 
			}
 
			//fprintf(stderr, "%s: Planning over bridge\n", __func__);
 
			// TODO doesn't work - WHAT doesn't work?
 
			TPFSetTileBit(tpf, tile, 14);
 
			tile_end = GetOtherBridgeEnd(tile);
 
			tpf->rd.cur_length += DistanceManhattan(tile, tile_end);
 
			tile = tile_end;
 
			TPFSetTileBit(tpf, tile, 14);
 
		}
 
		tile = SkipToEndOfTunnel(tpf, tile, direction);
 
	}
 
	tile += TileOffsByDir(direction);
 

	
 
@@ -281,11 +287,7 @@ static void TPFMode1(TrackPathFinder* tp
 

	
 
		if (IsTileType(tile_org, MP_RAILWAY) || IsTileType(tile_org, MP_STATION) || IsTileType(tile_org, MP_TUNNELBRIDGE))
 
			if (IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_STATION) || IsTileType(tile, MP_TUNNELBRIDGE))
 
				/* Check if we are on a bridge (middle parts don't have an owner */
 
				if (!IsBridgeTile(tile) || !IsBridgeMiddle(tile))
 
					if (!IsBridgeTile(tile_org) || !IsBridgeMiddle(tile_org))
 
						if (GetTileOwner(tile_org) != GetTileOwner(tile))
 
							return;
 
				if (GetTileOwner(tile_org) != GetTileOwner(tile)) return;
 
	}
 

	
 
	// check if the new tile can be entered from that direction
 
@@ -673,7 +675,6 @@ static void NTPEnum(NewTrackPathFinder* 
 
	uint track;
 
	TileIndex tile_org;
 
	StackedItem si;
 
	FindLengthOfTunnelResult flotr;
 
	int estimation;
 

	
 

	
 
@@ -711,22 +712,40 @@ callback_and_continue:
 
start_at:
 
		// If the tile is the entry tile of a tunnel, and we're not going out of the tunnel,
 
		//   need to find the exit of the tunnel.
 
		if (IsTunnelTile(tile) &&
 
				GetTunnelDirection(tile) != ReverseDiagDir(direction)) {
 
			/* We are not just driving out of the tunnel */
 
			if (GetTunnelDirection(tile) != direction ||
 
					GetTunnelTransportType(tile) != tpf->tracktype) {
 
				// We are not driving into the tunnel, or it is an invalid tunnel
 
				continue;
 
		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
			if (IsTunnel(tile)) {
 
				if (GetTunnelDirection(tile) != ReverseDiagDir(direction)) {
 
					FindLengthOfTunnelResult flotr;
 

	
 
					/* We are not just driving out of the tunnel */
 
					if (GetTunnelDirection(tile) != direction ||
 
							GetTunnelTransportType(tile) != tpf->tracktype) {
 
						// We are not driving into the tunnel, or it is an invalid tunnel
 
						continue;
 
					}
 
					if (!HASBIT(tpf->railtypes, GetRailType(tile))) {
 
						bits = 0;
 
						break;
 
					}
 
					flotr = FindLengthOfTunnel(tile, direction);
 
					si.cur_length += flotr.length * DIAG_FACTOR;
 
					tile = flotr.tile;
 
					// tile now points to the exit tile of the tunnel
 
				}
 
			} else {
 
				TileIndex tile_end;
 
				if (GetBridgeRampDirection(tile) != ReverseDiagDir(direction)) {
 
					// We are not just leaving the bridge
 
					if (GetBridgeRampDirection(tile) != direction ||
 
							GetBridgeTransportType(tile) != tpf->tracktype) {
 
						// Not entering the bridge or not compatible
 
						continue;
 
					}
 
				}
 
				tile_end = GetOtherBridgeEnd(tile);
 
				si.cur_length += DistanceManhattan(tile, tile_end) * DIAG_FACTOR;
 
				tile = tile_end;
 
			}
 
			if (!HASBIT(tpf->railtypes, GetRailType(tile))) {
 
				bits = 0;
 
				break;
 
			}
 
			flotr = FindLengthOfTunnel(tile, direction);
 
			si.cur_length += flotr.length * DIAG_FACTOR;
 
			tile = flotr.tile;
 
			// tile now points to the exit tile of the tunnel
 
		}
 

	
 
		// This is a special loop used to go through
 
@@ -754,13 +773,9 @@ start_at:
 
				// Check that the tile contains exactly one track
 
				if (bits == 0 || KILL_FIRST_BIT(bits) != 0) break;
 

	
 
				/* Check the rail type only if the train is *NOT* on top of
 
				 * a bridge. */
 
				if (!(IsBridgeTile(tile) && IsBridgeMiddle(tile) && GetBridgeAxis(tile) == DiagDirToAxis(direction))) {
 
					if (IsTileType(tile, MP_STREET) ? !HASBIT(tpf->railtypes, GetRailTypeCrossing(tile)) : !HASBIT(tpf->railtypes, GetRailType(tile))) {
 
						bits = 0;
 
						break;
 
					}
 
				if (IsTileType(tile, MP_STREET) ? !HASBIT(tpf->railtypes, GetRailTypeCrossing(tile)) : !HASBIT(tpf->railtypes, GetRailType(tile))) {
 
					bits = 0;
 
					break;
 
				}
 

	
 
				///////////////////
rail.c
Show inline comments
 
@@ -104,7 +104,6 @@ const Trackdir _dir_to_diag_trackdir[] =
 

	
 
RailType GetTileRailType(TileIndex tile, Trackdir trackdir)
 
{
 
	DiagDirection exitdir = TrackdirToExitdir(trackdir);
 
	switch (GetTileType(tile)) {
 
		case MP_RAILWAY:
 
			return GetRailType(tile);
 
@@ -124,21 +123,8 @@ RailType GetTileRailType(TileIndex tile,
 
					return GetRailType(tile);
 
				}
 
			} else {
 
				if (IsBridgeRamp(tile)) {
 
					if (GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
 
						return GetRailType(tile);
 
					}
 
				} else {
 
					if (GetBridgeAxis(tile) == DiagDirToAxis(exitdir)) {
 
						if (GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
 
							return GetRailTypeOnBridge(tile);
 
						}
 
					} else {
 
						if (IsTransportUnderBridge(tile) &&
 
								GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL) {
 
							return GetRailType(tile);
 
						}
 
					}
 
				if (GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
 
					return GetRailType(tile);
 
				}
 
			}
 
			break;
rail_cmd.c
Show inline comments
 
@@ -231,29 +231,6 @@ int32 CmdBuildSingleRail(TileIndex tile,
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	switch (GetTileType(tile)) {
 
		case MP_TUNNELBRIDGE:
 
			if (!IsBridge(tile) ||
 
					!IsBridgeMiddle(tile) ||
 
					(GetBridgeAxis(tile) == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X) != 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, p1);
 
			} 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)) {
 
@@ -341,20 +318,6 @@ int32 CmdRemoveSingleRail(TileIndex tile
 
	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 ||
 
@@ -591,6 +554,8 @@ int32 CmdBuildTrainDepot(TileIndex tile,
 
	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;
 

	
 
@@ -1416,6 +1381,7 @@ static void DrawTile_Track(TileInfo *ti)
 
			);
 
		}
 
	}
 
	DrawBridgeMiddle(ti);
 
}
 

	
 
void DrawTrainDepotSprite(int x, int y, int image, RailType railtype)
 
@@ -1525,19 +1491,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 + (v->u.rail.track << 8))) return v;
 
@@ -1553,15 +1511,18 @@ static bool SignalVehicleCheck(TileIndex
 
	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)
 

	
 
@@ -1571,9 +1532,9 @@ static bool SignalVehicleCheck(TileIndex
 
		// 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;
 
		for (; tile != end; tile += TileOffsByDir(direction)) {
 
			if (VehicleFromPos(tile, &dest, SignalVehicleCheckProc) != NULL)
 
				return true;
rail_map.h
Show inline comments
 
@@ -81,11 +81,6 @@ static inline RailType GetRailTypeCrossi
 
	return (RailType)GB(_m[t].m4, 0, 4);
 
}
 

	
 
static inline RailType GetRailTypeOnBridge(TileIndex t)
 
{
 
	return (RailType)GB(_m[t].m3, 4, 4);
 
}
 

	
 
static inline void SetRailType(TileIndex t, RailType r)
 
{
 
	SB(_m[t].m3, 0, 4, r);
 
@@ -97,11 +92,6 @@ static inline void SetRailTypeCrossing(T
 
	SB(_m[t].m4, 0, 4, r);
 
}
 

	
 
static inline void SetRailTypeOnBridge(TileIndex t, RailType r)
 
{
 
	SB(_m[t].m3, 4, 4, r);
 
}
 

	
 

	
 
/** These are used to specify a single track.
 
 * Can be translated to a trackbit with TrackToTrackbit */
road_cmd.c
Show inline comments
 
@@ -108,97 +108,70 @@ int32 CmdRemoveRoad(TileIndex tile, uint
 
	if (p1 >> 4) return CMD_ERROR;
 
	pieces = p1;
 

	
 
	if (!IsTileType(tile, MP_STREET) && !IsTileType(tile, MP_TUNNELBRIDGE)) return CMD_ERROR;
 
	if (!IsTileType(tile, MP_STREET)) return CMD_ERROR;
 

	
 
	owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile);
 

	
 
	if (owner == OWNER_TOWN && _game_mode != GM_EDITOR) {
 
		if (IsTileType(tile, MP_TUNNELBRIDGE)) { // index of town is not saved for bridge (no space)
 
			t = ClosestTownFromTile(tile, _patches.dist_local_authority);
 
		} else {
 
			t = GetTownByTile(tile);
 
		}
 
		t = GetTownByTile(tile);
 
	} else {
 
		t = NULL;
 
	}
 

	
 
	if (!CheckAllowRemoveRoad(tile, pieces, &edge_road)) return CMD_ERROR;
 

	
 
	switch (GetTileType(tile)) {
 
		case MP_TUNNELBRIDGE:
 
			if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
 
	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
 

	
 
	// check if you're allowed to remove the street owned by a town
 
	// removal allowance depends on difficulty setting
 
	if (!CheckforTownRating(flags, t, ROAD_REMOVE)) return CMD_ERROR;
 

	
 
	switch (GetRoadTileType(tile)) {
 
		case ROAD_TILE_NORMAL: {
 
			RoadBits present = GetRoadBits(tile);
 
			RoadBits c = pieces;
 

	
 
			if (GetTileSlope(tile, NULL) != SLOPE_FLAT  &&
 
					(present == ROAD_Y || present == ROAD_X)) {
 
				c |= (c & 0xC) >> 2;
 
				c |= (c & 0x3) << 2;
 
			}
 

	
 
			if (!IsBridge(tile) ||
 
					!IsBridgeMiddle(tile) ||
 
					!IsTransportUnderBridge(tile) ||
 
					GetTransportTypeUnderBridge(tile) != TRANSPORT_ROAD ||
 
					(pieces & ComplementRoadBits(GetRoadBitsUnderBridge(tile))) != 0) {
 
			// limit the bits to delete to the existing bits.
 
			c &= present;
 
			if (c == 0) return CMD_ERROR;
 

	
 
			if (flags & DC_EXEC) {
 
				ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
 

	
 
				present ^= c;
 
				if (present == 0) {
 
					DoClearSquare(tile);
 
				} else {
 
					SetRoadBits(tile, present);
 
					MarkTileDirtyByTile(tile);
 
				}
 
			}
 
			return CountRoadBits(c) * _price.remove_road;
 
		}
 

	
 
		case ROAD_TILE_CROSSING: {
 
			if (pieces & ComplementRoadBits(GetCrossingRoadBits(tile))) {
 
				return CMD_ERROR;
 
			}
 

	
 
			if (flags & DC_EXEC) {
 
				ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
 
				SetClearUnderBridge(tile);
 

	
 
				MakeRailNormal(tile, GetTileOwner(tile), GetCrossingRailBits(tile), GetRailTypeCrossing(tile));
 
				MarkTileDirtyByTile(tile);
 
			}
 
			return _price.remove_road * 2;
 

	
 
		case MP_STREET:
 
			if (!EnsureNoVehicle(tile)) return CMD_ERROR;
 

	
 
			// check if you're allowed to remove the street owned by a town
 
			// removal allowance depends on difficulty setting
 
			if (!CheckforTownRating(flags, t, ROAD_REMOVE)) return CMD_ERROR;
 

	
 
			switch (GetRoadTileType(tile)) {
 
				case ROAD_TILE_NORMAL: {
 
					RoadBits present = GetRoadBits(tile);
 
					RoadBits c = pieces;
 

	
 
					if (GetTileSlope(tile, NULL) != SLOPE_FLAT &&
 
							(present == ROAD_Y || present == ROAD_X)) {
 
						c |= (c & 0xC) >> 2;
 
						c |= (c & 0x3) << 2;
 
					}
 

	
 
					// limit the bits to delete to the existing bits.
 
					c &= present;
 
					if (c == 0) return CMD_ERROR;
 

	
 
					if (flags & DC_EXEC) {
 
						ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
 
		}
 

	
 
						present ^= c;
 
						if (present == 0) {
 
							DoClearSquare(tile);
 
						} else {
 
							SetRoadBits(tile, present);
 
							MarkTileDirtyByTile(tile);
 
						}
 
					}
 
					return CountRoadBits(c) * _price.remove_road;
 
				}
 

	
 
				case ROAD_TILE_CROSSING: {
 
					if (pieces & ComplementRoadBits(GetCrossingRoadBits(tile))) {
 
						return CMD_ERROR;
 
					}
 

	
 
					if (flags & DC_EXEC) {
 
						ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
 

	
 
						MakeRailNormal(tile, GetTileOwner(tile), GetCrossingRailBits(tile), GetRailTypeCrossing(tile));
 
						MarkTileDirtyByTile(tile);
 
					}
 
					return _price.remove_road * 2;
 
				}
 

	
 
				default:
 
				case ROAD_TILE_DEPOT:
 
					return CMD_ERROR;
 
			}
 

	
 
		default: return CMD_ERROR;
 
		case ROAD_TILE_DEPOT:
 
		default:
 
			return CMD_ERROR;
 
	}
 
}
 

	
 
@@ -348,37 +321,6 @@ int32 CmdBuildRoad(TileIndex tile, uint3
 
			return _price.build_road * 2;
 
		}
 

	
 
		case MP_TUNNELBRIDGE:
 
			/* check for flat land */
 
			if (IsSteepSlope(tileh)) {
 
				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 
			}
 

	
 
			if (!IsBridge(tile) || !IsBridgeMiddle(tile)) goto do_clear;
 

	
 
			/* only allow roads pertendicular to bridge */
 
			if ((pieces & (GetBridgeAxis(tile) == AXIS_X ? ROAD_X : ROAD_Y)) != 0) {
 
				goto do_clear;
 
			}
 

	
 
			/* check if clear land under bridge */
 
			if (IsTransportUnderBridge(tile)) {
 
				switch (GetTransportTypeUnderBridge(tile)) {
 
					case TRANSPORT_ROAD: return_cmd_error(STR_1007_ALREADY_BUILT);
 
					default: return_cmd_error(STR_1008_MUST_REMOVE_RAILROAD_TRACK);
 
				}
 
			} else {
 
				if (IsWaterUnderBridge(tile)) {
 
					return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
 
				}
 
			}
 

	
 
			if (flags & DC_EXEC) {
 
				SetRoadUnderBridge(tile, _current_player);
 
				MarkTileDirtyByTile(tile);
 
			}
 
			return _price.build_road * 2;
 

	
 
		default:
 
do_clear:;
 
			ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
@@ -575,6 +517,8 @@ int32 CmdBuildRoadDepot(TileIndex tile, 
 
	cost = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
	if (CmdFailed(cost)) return CMD_ERROR;
 

	
 
	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 

	
 
	dep = AllocateDepot();
 
	if (dep == NULL) return CMD_ERROR;
 

	
 
@@ -798,6 +742,7 @@ static void DrawTile_Road(TileInfo *ti)
 
			break;
 
		}
 
	}
 
	DrawBridgeMiddle(ti);
 
}
 

	
 
void DrawRoadDepotSprite(int x, int y, int image)
road_map.c
Show inline comments
 
@@ -27,22 +27,12 @@ RoadBits GetAnyRoadBits(TileIndex tile)
 
			return DiagDirToRoadBits(GetRoadStopDir(tile));
 

	
 
		case MP_TUNNELBRIDGE:
 
			if (IsBridge(tile)) {
 
				if (IsBridgeMiddle(tile)) {
 
					if (!IsTransportUnderBridge(tile) ||
 
							GetBridgeTransportType(tile) != TRANSPORT_ROAD) {
 
						return 0;
 
					}
 
					return GetRoadBitsUnderBridge(tile);
 
				} else {
 
					// ending
 
					if (GetBridgeTransportType(tile) != TRANSPORT_ROAD) return 0;
 
					return DiagDirToRoadBits(ReverseDiagDir(GetBridgeRampDirection(tile)));
 
				}
 
			} else {
 
				// tunnel
 
			if (IsTunnel(tile)) {
 
				if (GetTunnelTransportType(tile) != TRANSPORT_ROAD) return 0;
 
				return DiagDirToRoadBits(ReverseDiagDir(GetTunnelDirection(tile)));
 
			} else {
 
				if (GetBridgeTransportType(tile) != TRANSPORT_ROAD) return 0;
 
				return DiagDirToRoadBits(ReverseDiagDir(GetBridgeRampDirection(tile)));
 
			}
 

	
 
		default: return 0;
roadveh_cmd.c
Show inline comments
 
@@ -20,7 +20,9 @@
 
#include "player.h"
 
#include "sound.h"
 
#include "depot.h"
 
#include "bridge.h"
 
#include "tunnel_map.h"
 
#include "bridge_map.h"
 
#include "vehicle_gui.h"
 
#include "newgrf_engine.h"
 
#include "yapf/yapf.h"
 
@@ -313,8 +315,6 @@ static const Depot* FindClosestRoadDepot
 
{
 
	TileIndex tile = v->tile;
 

	
 
	if (v->u.road.state == 255) tile = GetVehicleOutOfTunnelTile(v);
 

	
 
	if (_patches.yapf.road_use_yapf) {
 
		Depot* ret = YapfFindNearestRoadDepot(v);
 
		return ret;
 
@@ -411,14 +411,19 @@ int32 CmdTurnRoadVeh(TileIndex tile, uin
 

	
 
	if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (v->vehstatus & (VS_HIDDEN | VS_STOPPED) ||
 
	if (v->vehstatus & VS_STOPPED ||
 
			v->u.road.crashed_ctr != 0 ||
 
			v->breakdown_ctr != 0 ||
 
			v->u.road.overtaking != 0 ||
 
			v->u.road.state == 255 ||
 
			v->u.road.state == 254 ||
 
			v->cur_speed < 5) {
 
		return CMD_ERROR;
 
	}
 

	
 
	if (IsTunnelTile(v->tile) && DirToDiagDir(v->direction) == GetTunnelDirection(v->tile)) return CMD_ERROR;
 
	if (IsBridgeTile(v->tile) && DirToDiagDir(v->direction) == GetBridgeRampDirection(v->tile)) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) v->u.road.reverse_ctr = 180;
 

	
 
	return 0;
 
@@ -485,11 +490,9 @@ static byte SetRoadVehPosition(Vehicle *
 
	byte new_z, old_z;
 

	
 
	// need this hint so it returns the right z coordinate on bridges.
 
	_get_z_hint = v->z_pos;
 
	v->x_pos = x;
 
	v->y_pos = y;
 
	new_z = GetSlopeZ(x, y);
 
	_get_z_hint = 0;
 

	
 
	old_z = v->z_pos;
 
	v->z_pos = new_z;
 
@@ -824,6 +827,7 @@ static bool RoadVehAccelerate(Vehicle *v
 

	
 
	// Clamp
 
	spd = min(spd, v->max_speed);
 
	if (v->u.road.state == 255) spd = min(spd, SetSpeedLimitOnBridge(v));
 

	
 
	//updates statusbar only if speed have changed to save CPU time
 
	if (spd != v->cur_speed) {
 
@@ -1285,8 +1289,7 @@ static void RoadVehController(Vehicle *v
 
			return;
 
		}
 

	
 
		if (IsTunnelTile(gp.new_tile) &&
 
				VehicleEnterTile(v, gp.new_tile, gp.x, gp.y) & 4) {
 
		if ((IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) && VehicleEnterTile(v, gp.new_tile, gp.x, gp.y) & 4) {
 
			//new_dir = RoadGetNewDirection(v, gp.x, gp.y)
 
			v->cur_image = GetRoadVehImage(v, v->direction);
 
			UpdateRoadVehDeltaXY(v);
 
@@ -1297,6 +1300,7 @@ static void RoadVehController(Vehicle *v
 
		v->x_pos = gp.x;
 
		v->y_pos = gp.y;
 
		VehiclePositionChanged(v);
 
		if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v);
 
		return;
 
	}
 

	
saveload.c
Show inline comments
 
@@ -30,7 +30,7 @@
 
#include "variables.h"
 
#include <setjmp.h>
 

	
 
const uint16 SAVEGAME_VERSION = 28;
 
const uint16 SAVEGAME_VERSION = 29;
 
uint16 _sl_version;       /// the major savegame version identifier
 
byte   _sl_minor_version; /// the minor savegame version, DO NOT USE!
 

	
station_cmd.c
Show inline comments
 
@@ -5,6 +5,7 @@
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
#include "debug.h"
 
#include "functions.h"
 
#include "station_map.h"
 
@@ -782,6 +783,10 @@ int32 CheckFlatLandBelow(TileIndex tile,
 
	int flat_z;
 

	
 
	BEGIN_TILE_LOOP(tile_cur, w, h, tile)
 
		if (MayHaveBridgeAbove(tile_cur) && IsBridgeAbove(tile_cur)) {
 
			return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 
		}
 

	
 
		if (!EnsureNoVehicle(tile_cur)) return CMD_ERROR;
 

	
 
		tileh = GetTileSlope(tile_cur, &z);
table/sprites.h
Show inline comments
 
@@ -708,6 +708,27 @@ enum Sprites {
 
	SPR_BTTUB_X_RAIL_REAR_BEG   = 2569,
 
	SPR_BTTUB_X_RAIL_REAR_MID   = 2570,
 
	SPR_BTTUB_X_RAIL_REAR_END   = 2571,
 
	SPR_BTTUB_Y_RAIL_REAR_BEG   = 2572,
 
	SPR_BTTUB_Y_RAIL_REAR_MID   = 2573,
 
	SPR_BTTUB_Y_RAIL_REAR_END   = 2574,
 
	SPR_BTTUB_X_ROAD_REAR_BEG   = 2575,
 
	SPR_BTTUB_X_ROAD_REAR_MID   = 2576,
 
	SPR_BTTUB_X_ROAD_REAR_END   = 2577,
 
	SPR_BTTUB_Y_ROAD_REAR_BEG   = 2578,
 
	SPR_BTTUB_Y_ROAD_REAR_MID   = 2579,
 
	SPR_BTTUB_Y_ROAD_REAR_END   = 2580,
 
	SPR_BTTUB_X_MONO_REAR_BEG   = 2581,
 
	SPR_BTTUB_X_MONO_REAR_MID   = 2582,
 
	SPR_BTTUB_X_MONO_REAR_END   = 2583,
 
	SPR_BTTUB_Y_MONO_REAR_BEG   = 2584,
 
	SPR_BTTUB_Y_MONO_REAR_MID   = 2585,
 
	SPR_BTTUB_Y_MONO_REAR_END   = 2586,
 
	SPR_BTTUB_X_MGLV_REAR_BEG   = 2587,
 
	SPR_BTTUB_X_MGLV_REAR_MID   = 2588,
 
	SPR_BTTUB_X_MGLV_REAR_END   = 2589,
 
	SPR_BTTUB_Y_MGLV_REAR_BEG   = 2590,
 
	SPR_BTTUB_Y_MGLV_REAR_MID   = 2591,
 
	SPR_BTTUB_Y_MGLV_REAR_END   = 2592,
 

	
 

	
 
	/* ramps (for all bridges except wood and tubular?)*/
terraform_gui.c
Show inline comments
 
@@ -2,6 +2,7 @@
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
#include "clear_map.h"
 
#include "table/sprites.h"
 
#include "table/strings.h"
 
@@ -81,11 +82,20 @@ static void GenerateRockyArea(TileIndex 
 
	size_y = (ey - sy) + 1;
 

	
 
	BEGIN_TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) {
 
		if (IsTileType(tile, MP_CLEAR) || IsTileType(tile, MP_TREES)) {
 
			MakeClear(tile, CLEAR_ROCKS, 3);
 
			MarkTileDirtyByTile(tile);
 
			success = true;
 
		switch (GetTileType(tile)) {
 
			case MP_CLEAR:
 
				MakeClear(tile, CLEAR_ROCKS, 3);
 
				break;
 

	
 
			case MP_TREES:
 
				MakeClear(tile, CLEAR_ROCKS, 3);
 
				ClearBridgeMiddle(tile);
 
				break;
 

	
 
			default: continue;
 
		}
 
		MarkTileDirtyByTile(tile);
 
		success = true;
 
	} END_TILE_LOOP(tile, size_x, size_y, 0);
 

	
 
	if (success) SndPlayTileFx(SND_1F_SPLAT, end);
town_cmd.c
Show inline comments
 
@@ -26,6 +26,7 @@
 
#include "water_map.h"
 
#include "variables.h"
 
#include "bridge.h"
 
#include "bridge_map.h"
 
#include "table/town_land.h"
 

	
 
enum {
 
@@ -1093,6 +1094,8 @@ static bool CheckBuildHouseMode(TileInde
 
	slope = GetTileSlope(tile, NULL);
 
	if (IsSteepSlope(slope)) return false;
 

	
 
	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return false;
 

	
 
	b = 0;
 
	if ((slope != SLOPE_FLAT && ~slope & _masks[mode])) b = ~b;
 
	if ((tileh != SLOPE_FLAT && ~tileh & _masks[mode+4])) b = ~b;
 
@@ -1136,6 +1139,8 @@ static bool CheckFree2x2Area(TileIndex t
 

	
 
		if (GetTileSlope(tile, NULL) != SLOPE_FLAT) return false;
 

	
 
		if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return false;
 

	
 
		if (CmdFailed(DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER | DC_FORCETEST, CMD_LANDSCAPE_CLEAR)))
 
			return false;
 
	}
 
@@ -1270,6 +1275,7 @@ static bool BuildTownHouse(Town *t, Tile
 
	// make sure it's possible
 
	if (!EnsureNoVehicle(tile)) return false;
 
	if (IsSteepSlope(GetTileSlope(tile, NULL))) return false;
 
	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return false;
 

	
 
	r = DoCommand(tile, 0, 0, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR);
 
	if (CmdFailed(r)) return false;
train_cmd.c
Show inline comments
 
@@ -25,6 +25,7 @@
 
#include "waypoint.h"
 
#include "vehicle_gui.h"
 
#include "train.h"
 
#include "bridge.h"
 
#include "newgrf_callbacks.h"
 
#include "newgrf_engine.h"
 
#include "newgrf_text.h"
 
@@ -91,10 +92,7 @@ void TrainPowerChanged(Vehicle* v)
 
		/* Power is not added for articulated parts */
 
		if (IsArticulatedPart(u)) continue;
 

	
 
		if (IsBridgeTile(u->tile) && IsBridgeMiddle(u->tile) && DiagDirToAxis(DirToDiagDir(u->direction)) == GetBridgeAxis(u->tile)) {
 
			if (!HasPowerOnRail(u->u.rail.railtype, GetRailTypeOnBridge(u->tile))) engine_has_power = false;
 
			if (!HasPowerOnRail(v->u.rail.railtype, GetRailTypeOnBridge(u->tile))) wagon_has_power = false;
 
		} else if (IsLevelCrossingTile(u->tile)) {
 
		if (IsLevelCrossingTile(u->tile)) {
 
			if (!HasPowerOnRail(u->u.rail.railtype, GetRailTypeCrossing(u->tile)))	engine_has_power = false;
 
			if (!HasPowerOnRail(v->u.rail.railtype, GetRailTypeCrossing(u->tile)))	wagon_has_power = false;
 
		} else {
 
@@ -1529,13 +1527,14 @@ static void ReverseTrainSwapVeh(Vehicle 
 
		UpdateVarsAfterSwap(a);
 
		UpdateVarsAfterSwap(b);
 

	
 
		VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
 
		VehicleEnterTile(b, b->tile, b->x_pos, b->y_pos);
 
		/* call the proper EnterTile function unless we are in a wormhole */
 
		if (!(a->u.rail.track & 0x40)) VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
 
		if (!(b->u.rail.track & 0x40)) VehicleEnterTile(b, b->tile, b->x_pos, b->y_pos);
 
	} else {
 
		if (!(a->u.rail.track & 0x80)) a->direction = ReverseDir(a->direction);
 
		UpdateVarsAfterSwap(a);
 

	
 
		VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
 
		if (!(a->u.rail.track & 0x40)) VehicleEnterTile(a, a->tile, a->x_pos, a->y_pos);
 
	}
 

	
 
	/* Update train's power incase tiles were different rail type */
 
@@ -1848,8 +1847,6 @@ static TrainFindDepotData FindClosestTra
 
		return tfdd;
 
	}
 

	
 
	if (v->u.rail.track == 0x40) tile = GetVehicleOutOfTunnelTile(v);
 

	
 
	if (_patches.yapf.rail_use_yapf) {
 
		bool found = YapfFindNearestRailDepotTwoWay(v, max_distance, NPF_INFINITE_PENALTY, &tfdd.tile, &tfdd.reverse);
 
		tfdd.best_length = found ? max_distance / 2 : -1; // some fake distance or NOT_FOUND
 
@@ -2567,9 +2564,7 @@ static byte AfterSetTrainPos(Vehicle *v,
 
	byte new_z, old_z;
 

	
 
	// need this hint so it returns the right z coordinate on bridges.
 
	_get_z_hint = v->z_pos;
 
	new_z = GetSlopeZ(v->x_pos, v->y_pos);
 
	_get_z_hint = 0;
 

	
 
	old_z = v->z_pos;
 
	v->z_pos = new_z;
 
@@ -2645,13 +2640,6 @@ static bool CheckCompatibleRail(const Ve
 
			// normal tracks, jump to owner check
 
			break;
 

	
 
		case MP_TUNNELBRIDGE:
 
			if (IsBridge(tile) && IsBridgeMiddle(tile)) {
 
				// is train going over the bridge?
 
				if (v->z_pos > GetTileMaxZ(tile)) return true;
 
			}
 
			break;
 

	
 
		case MP_STREET:
 
			// tracks over roads, do owner check of tracks
 
			return
 
@@ -2992,15 +2980,16 @@ static void TrainController(Vehicle *v)
 
				v->direction = chosen_dir;
 
			}
 
		} else {
 
			/* in tunnel */
 
			/* in tunnel on on a bridge */
 
			GetNewVehiclePos(v, &gp);
 

	
 
			// Check if to exit the tunnel...
 
			if (!IsTunnelTile(gp.new_tile) ||
 
					!(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y)&0x4) ) {
 
			SetSpeedLimitOnBridge(v);
 

	
 
			if (!(IsTunnelTile(gp.new_tile) || IsBridgeTile(gp.new_tile)) || !(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y) & 0x4)) {
 
				v->x_pos = gp.x;
 
				v->y_pos = gp.y;
 
				VehiclePositionChanged(v);
 
				if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v);
 
				continue;
 
			}
 
		}
 
@@ -3097,7 +3086,7 @@ static void DeleteLastWagon(Vehicle *v)
 
	 * others are on it */
 
	DisableTrainCrossing(v->tile);
 

	
 
	if (v->u.rail.track == 0x40) { // inside a tunnel
 
	if ( (v->u.rail.track == 0x40 && v->vehstatus & VS_HIDDEN) ) { // inside a tunnel
 
		TileIndex endtile = CheckTunnelBusy(v->tile, NULL);
 

	
 
		if (endtile == INVALID_TILE) return; // tunnel is busy (error returned)
 
@@ -3128,15 +3117,16 @@ static void ChangeTrainDirRandomly(Vehic
 
	};
 

	
 
	do {
 
		//I need to buffer the train direction
 
		if (!(v->u.rail.track & 0x40)) {
 
		/* We don't need to twist around vehicles if they're not visible */
 
		if (!(v->vehstatus & VS_HIDDEN)) {
 
			v->direction = ChangeDir(v->direction, delta[GB(Random(), 0, 2)]);
 
		}
 
		if (!(v->vehstatus & VS_HIDDEN)) {
 
			BeginVehicleMove(v);
 
			UpdateTrainDeltaXY(v, v->direction);
 
			v->cur_image = GetTrainImage(v, v->direction);
 
			AfterSetTrainPos(v, false);
 
			/* Refrain from updating the z position of the vehicle when on
 
			   a bridge, because AfterSetTrainPos will put the vehicle under
 
			   the bridge in that case */
 
			if (!(v->u.rail.track & 0x40)) AfterSetTrainPos(v, false);
 
		}
 
	} while ((v = v->next) != NULL);
 
}
 
@@ -3147,7 +3137,7 @@ static void HandleCrashedTrain(Vehicle *
 
	uint32 r;
 
	Vehicle *u;
 

	
 
	if (state == 4 && v->u.rail.track != 0x40) {
 
	if (state == 4 && !(v->u.rail.track & VS_HIDDEN)) {
 
		CreateEffectVehicleRel(v, 4, 4, 8, EV_EXPLOSION_LARGE);
 
	}
 

	
 
@@ -3234,10 +3224,15 @@ static bool TrainCheckIfLineEnds(Vehicle
 

	
 
	tile = v->tile;
 

	
 
	// tunnel entrance?
 
	if (IsTunnelTile(tile) &&
 
			DiagDirToDir(GetTunnelDirection(tile)) == v->direction) {
 
		return true;
 
	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
		DiagDirection dir;
 

	
 
		if (IsTunnel(tile)) {
 
			dir = GetTunnelDirection(tile);
 
		} else {
 
			dir = GetBridgeRampDirection(tile);
 
		}
 
		if (DiagDirToDir(dir) == v->direction) return true;
 
	}
 

	
 
	// depot?
tree_cmd.c
Show inline comments
 
@@ -2,6 +2,7 @@
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
#include "clear_map.h"
 
#include "table/strings.h"
 
#include "table/sprites.h"
 
@@ -68,6 +69,7 @@ static void DoPlaceMoreTrees(TileIndex t
 

	
 
		if (dist <= 13 &&
 
				IsTileType(cur_tile, MP_CLEAR) &&
 
				!IsBridgeAbove(cur_tile) &&
 
				!IsClearGround(cur_tile, CLEAR_FIELDS) &&
 
				!IsClearGround(cur_tile, CLEAR_ROCKS)) {
 
			PlaceTree(cur_tile, r);
 
@@ -92,6 +94,7 @@ void PlaceTreesRandomly(void)
 
		uint32 r = Random();
 
		TileIndex tile = RandomTileSeed(r);
 
		if (IsTileType(tile, MP_CLEAR) &&
 
				!IsBridgeAbove(tile) &&
 
				!IsClearGround(tile, CLEAR_FIELDS) &&
 
				!IsClearGround(tile, CLEAR_ROCKS)) {
 
			PlaceTree(tile, r);
 
@@ -105,7 +108,9 @@ void PlaceTreesRandomly(void)
 
		do {
 
			uint32 r = Random();
 
			TileIndex tile = RandomTileSeed(r);
 
			if (IsTileType(tile, MP_CLEAR) && GetTropicZone(tile) == TROPICZONE_RAINFOREST) {
 
			if (IsTileType(tile, MP_CLEAR) &&
 
					!IsBridgeAbove(tile) &&
 
					GetTropicZone(tile) == TROPICZONE_RAINFOREST) {
 
				PlaceTree(tile, r);
 
			}
 
		} while (--i);
 
@@ -175,7 +180,8 @@ int32 CmdPlantTree(TileIndex tile, uint3
 
					break;
 

	
 
				case MP_CLEAR:
 
					if (!IsTileOwner(tile, OWNER_NONE)) {
 
					if (!IsTileOwner(tile, OWNER_NONE) ||
 
							IsBridgeAbove(tile)) {
 
						msg = STR_2804_SITE_UNSUITABLE;
 
						continue;
 
					}
 
@@ -480,7 +486,7 @@ static void TileLoop_Trees(TileIndex til
 

	
 
						tile += ToTileIndexDiff(_tileloop_trees_dir[Random() & 7]);
 

	
 
						if (!IsTileType(tile, MP_CLEAR)) return;
 
						if (!IsTileType(tile, MP_CLEAR) || IsBridgeAbove(tile)) return;
 

	
 
						switch (GetClearGround(tile)) {
 
							case CLEAR_GRASS:
 
@@ -513,6 +519,7 @@ static void TileLoop_Trees(TileIndex til
 
					case TREE_GROUND_ROUGH: MakeClear(tile, CLEAR_ROUGH, 3); break;
 
					default: MakeClear(tile, CLEAR_SNOW, GetTreeDensity(tile)); break;
 
				}
 
				ClearBridgeMiddle(tile);
 
			}
 
			break;
 

	
 
@@ -535,6 +542,7 @@ void OnTick_Trees(void)
 
	if (_opt.landscape == LT_DESERT &&
 
			(r = Random(), tile = RandomTileSeed(r), GetTropicZone(tile) == TROPICZONE_RAINFOREST) &&
 
			IsTileType(tile, MP_CLEAR) &&
 
			!IsBridgeAbove(tile) &&
 
			(ct = GetClearGround(tile), ct == CLEAR_GRASS || ct == CLEAR_ROUGH) &&
 
			(tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TREE_INVALID) {
 
		MakeTree(tile, tree, 0, 0, ct == CLEAR_ROUGH ? TREE_GROUND_ROUGH : TREE_GROUND_GRASS, 0);
 
@@ -547,6 +555,7 @@ void OnTick_Trees(void)
 
	r = Random();
 
	tile = TILE_MASK(r);
 
	if (IsTileType(tile, MP_CLEAR) &&
 
			!IsBridgeAbove(tile) &&
 
			(ct = GetClearGround(tile), ct == CLEAR_GRASS || ct == CLEAR_ROUGH || ct == CLEAR_SNOW) &&
 
			(tree = GetRandomTreeType(tile, GB(r, 24, 8))) != TREE_INVALID) {
 
		switch (ct) {
tunnelbridge_cmd.c
Show inline comments
 
@@ -30,11 +30,6 @@
 

	
 
#include "table/bridge_land.h"
 

	
 
extern const byte _track_sloped_sprites[14];
 
extern const SpriteID _water_shore_sprites[15];
 

	
 
extern void DrawCanalWater(TileIndex tile);
 

	
 
const Bridge orig_bridge[] = {
 
/*
 
	   year of availablity
 
@@ -197,7 +192,6 @@ int32 CmdBuildBridge(TileIndex end_tile,
 
	TileIndex tile;
 
	TileIndexDiff delta;
 
	uint bridge_len;
 
	uint odd_middle_part;
 
	Axis direction;
 
	uint i;
 
	int32 cost, terraformcost, ret;
 
@@ -289,6 +283,26 @@ int32 CmdBuildBridge(TileIndex end_tile,
 
		return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 
	cost += terraformcost;
 

	
 
	{
 
		TileIndex Heads[] = {tile_start, tile_end};
 
		int i;
 

	
 
		for (i = 0; i < 2; i++) {
 
			if (MayHaveBridgeAbove(Heads[i])) {
 
				if (IsBridgeAbove(Heads[i])) {
 
					TileIndex north_head = GetNorthernBridgeEnd(Heads[i]);
 
					int z1, z2;
 

	
 
					if (direction == GetBridgeAxis(Heads[i])) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 

	
 
					z1 = GetBridgeHeight(north_head, GetBridgeAxis(Heads[i]));
 
					z2 = GetBridgeHeight(Heads[i], direction);
 

	
 
					if (z1 == z2) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 
				}
 
			}
 
		}
 
	}
 

	
 
	/* do the drill? */
 
	if (flags & DC_EXEC) {
 
@@ -305,47 +319,42 @@ int32 CmdBuildBridge(TileIndex end_tile,
 
		MarkTileDirtyByTile(tile_end);
 
	}
 

	
 
	// position of middle part of the odd bridge (larger than MAX(i) otherwise)
 
	odd_middle_part = (bridge_len % 2) ? (bridge_len / 2) : bridge_len;
 

	
 
	tile = tile_start;
 
	delta = (direction == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
 
	for (i = 0; i != bridge_len; i++) {
 
		TransportType transport_under;
 
		Owner owner_under = OWNER_NONE;
 
		RailType rail_under = INVALID_RAILTYPE;
 
		uint z;
 

	
 
		tile += delta;
 

	
 
		if (GetTileSlope(tile, &z) != SLOPE_FLAT && z >= z_start) {
 
			return_cmd_error(STR_5009_LEVEL_LAND_OR_WATER_REQUIRED);
 
		if (GetTileSlope(tile, &z) != SLOPE_FLAT && z >= z_start) return_cmd_error(STR_5009_LEVEL_LAND_OR_WATER_REQUIRED);
 

	
 
		if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) {
 
			/* Disallow crossing bridges for the time being */
 
			return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 
		}
 

	
 
		switch (GetTileType(tile)) {
 
			case MP_WATER:
 
				if (!EnsureNoVehicle(tile)) return_cmd_error(STR_980E_SHIP_IN_THE_WAY);
 
				if (!(IsWater(tile) || IsCoast(tile))) goto not_valid_below;
 
				transport_under = TRANSPORT_WATER;
 
				break;
 

	
 
			case MP_RAILWAY:
 
				if (GetRailTileType(tile) != RAIL_TILE_NORMAL ||
 
						GetTrackBits(tile) != (direction == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X)) {
 
					goto not_valid_below;
 
				}
 
				transport_under = TRANSPORT_RAIL;
 
				owner_under = GetTileOwner(tile);
 
				rail_under = GetRailType(tile);
 
				if (!IsPlainRailTile(tile)) goto not_valid_below;
 
				break;
 

	
 
			case MP_STREET:
 
				if (GetRoadTileType(tile) != ROAD_TILE_NORMAL ||
 
						GetRoadBits(tile) != (direction == AXIS_X ? ROAD_Y : ROAD_X)) {
 
					goto not_valid_below;
 
				}
 
				transport_under = TRANSPORT_ROAD;
 
				owner_under = GetTileOwner(tile);
 
				if (GetRoadTileType(tile) != ROAD_TILE_NORMAL) goto not_valid_below;
 
				break;
 

	
 
			case MP_TUNNELBRIDGE:
 
				if (IsTunnel(tile)) break;
 
				if (direction == DiagDirToAxis(GetBridgeRampDirection(tile))) goto not_valid_below;
 
				if (GetBridgeHeight(tile_start, direction) == GetBridgeHeight(tile, DiagDirToAxis(GetBridgeRampDirection(tile)))) goto not_valid_below;
 
				break;
 

	
 
			case MP_CLEAR:
 
				if (IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 
				break;
 

	
 
			default:
 
@@ -354,50 +363,11 @@ not_valid_below:;
 
				ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
				if (CmdFailed(ret)) return ret;
 
				cost += ret;
 
				transport_under = INVALID_TRANSPORT;
 
				break;
 
		}
 

	
 
		if (flags & DC_EXEC) {
 
			uint piece;
 

	
 
			//bridges pieces sequence (middle parts)
 
			// bridge len 1: 0
 
			// bridge len 2: 0 1
 
			// bridge len 3: 0 4 1
 
			// bridge len 4: 0 2 3 1
 
			// bridge len 5: 0 2 5 3 1
 
			// bridge len 6: 0 2 3 2 3 1
 
			// bridge len 7: 0 2 3 4 2 3 1
 
			// #0 - always as first, #1 - always as last (if len>1)
 
			// #2,#3 are to pair in order
 
			// for odd bridges: #5 is going in the bridge middle if on even position, #4 on odd (counting from 0)
 

	
 
			if (i == 0) { // first tile
 
				piece = 0;
 
			} else if (i == bridge_len - 1) { // last tile
 
				piece = 1;
 
			} else if (i == odd_middle_part) { // we are on the middle of odd bridge: #5 on even pos, #4 on odd
 
				piece = 5 - (i % 2);
 
			} else {
 
					// generate #2 and #3 in turns [i%2==0], after the middle of odd bridge
 
					// this sequence swaps [... XOR (i>odd_middle_part)],
 
					// for even bridges XOR does not apply as odd_middle_part==bridge_len
 
					piece = 2 + ((i % 2 == 0) ^ (i > odd_middle_part));
 
			}
 

	
 
			if (transport == TRANSPORT_RAIL) {
 
				MakeRailBridgeMiddle(tile, bridge_type, piece, direction, railtype);
 
			} else {
 
				MakeRoadBridgeMiddle(tile, bridge_type, piece, direction);
 
			}
 
			switch (transport_under) {
 
				case TRANSPORT_RAIL:  SetRailUnderBridge(tile, owner_under, rail_under); break;
 
				case TRANSPORT_ROAD:  SetRoadUnderBridge(tile, owner_under); break;
 
				case TRANSPORT_WATER: SetWaterUnderBridge(tile); break;
 
				default:              SetClearUnderBridge(tile); break;
 
			}
 

	
 
			SetBridgeMiddle(tile, direction);
 
			MarkTileDirtyByTile(tile);
 
		}
 
	}
 
@@ -582,7 +552,7 @@ static int32 DoClearTunnel(TileIndex til
 
	return _price.clear_tunnel * (length + 1);
 
}
 

	
 

	
 
#if 0
 
static uint GetBridgeHeightRamp(TileIndex t)
 
{
 
	/* Return the height there (the height of the NORTH CORNER)
 
@@ -590,6 +560,7 @@ static uint GetBridgeHeightRamp(TileInde
 
	 * the z coordinate is 1 height level too low. Compensate for that */
 
	return TilePixelHeight(t) + (GetTileSlope(t, NULL) == SLOPE_WSE ? TILE_HEIGHT : 0);
 
}
 
#endif
 

	
 

	
 
static int32 DoClearBridge(TileIndex tile, uint32 flags)
 
@@ -597,47 +568,10 @@ static int32 DoClearBridge(TileIndex til
 
	DiagDirection direction;
 
	TileIndexDiff delta;
 
	TileIndex endtile;
 
	Vehicle *v;
 
	Town *t;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	if (IsBridgeMiddle(tile)) {
 
		if (IsTransportUnderBridge(tile)) {
 
			/* delete transport route under the bridge */
 
			int32 cost;
 

	
 
			// check if we own the tile below the bridge..
 
			if (_current_player != OWNER_WATER && (!CheckTileOwnership(tile) || !EnsureNoVehicleOnGround(tile)))
 
				return CMD_ERROR;
 

	
 
			if (GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL) {
 
				cost = _price.remove_rail;
 
			} else {
 
				cost = _price.remove_road * 2;
 
			}
 

	
 
			if (flags & DC_EXEC) {
 
				SetClearUnderBridge(tile);
 
				MarkTileDirtyByTile(tile);
 
			}
 
			return cost;
 
		} else if (IsWaterUnderBridge(tile) && TilePixelHeight(tile) != 0) {
 
			/* delete canal under bridge */
 

	
 
			// check for vehicles under bridge
 
			if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
 

	
 
			if (flags & DC_EXEC) {
 
				SetClearUnderBridge(tile);
 
				MarkTileDirtyByTile(tile);
 
			}
 
			return _price.clear_water;
 
		}
 

	
 
		tile = GetSouthernBridgeEnd(tile);
 
	}
 

	
 
	// floods, scenario editor can always destroy bridges
 
	if (_current_player != OWNER_WATER && _game_mode != GM_EDITOR && !CheckTileOwnership(tile)) {
 
		if (!(_patches.extra_dynamite || _cheats.magic_bulldozer.value) || !IsTileOwner(tile, OWNER_TOWN))
 
@@ -651,18 +585,6 @@ static int32 DoClearBridge(TileIndex til
 
	direction = GetBridgeRampDirection(tile);
 
	delta = TileOffsByDir(direction);
 

	
 
	/*	Make sure there's no vehicle on the bridge
 
			Omit tile and endtile, since these are already checked, thus solving the problem
 
			of bridges over water, or higher bridges, where z is not increased, eg level bridge
 
	*/
 
	/* Bridges on slopes might have their Z-value offset..correct this */
 
	v = FindVehicleBetween(
 
		tile    + delta,
 
		endtile - delta,
 
		GetBridgeHeightRamp(tile) + TILE_HEIGHT
 
	);
 
	if (v != NULL) return_cmd_error(VehicleInTheWayErrMsg(v));
 

	
 
	t = ClosestTownFromTile(tile, (uint)-1); //needed for town rating penalty
 
	// check if you're allowed to remove the bridge owned by a town.
 
	// removal allowal depends on difficulty settings
 
@@ -681,26 +603,8 @@ static int32 DoClearBridge(TileIndex til
 
		DoClearSquare(tile);
 
		DoClearSquare(endtile);
 
		for (c = tile + delta; c != endtile; c += delta) {
 
			if (IsTransportUnderBridge(c)) {
 
				if (GetTransportTypeUnderBridge(c) == TRANSPORT_RAIL) {
 
					MakeRailNormal(c, GetTileOwner(c), GetRailBitsUnderBridge(c), GetRailType(c));
 
				} else {
 
					uint town = IsTileOwner(c, OWNER_TOWN) ? ClosestTownFromTile(c, (uint)-1)->index : 0;
 
					MakeRoadNormal(c, GetTileOwner(c), GetRoadBitsUnderBridge(c), town);
 
				}
 
				MarkTileDirtyByTile(c);
 
			} else {
 
				if (IsClearUnderBridge(c)) {
 
					DoClearSquare(c);
 
				} else {
 
					if (GetTileSlope(c, NULL) == SLOPE_FLAT) {
 
						MakeWater(c);
 
					} else {
 
						MakeShore(c);
 
					}
 
					MarkTileDirtyByTile(c);
 
				}
 
			}
 
			ClearBridgeMiddle(c);
 
			MarkTileDirtyByTile(c);
 
		}
 

	
 
		UpdateSignalsOnSegment(tile, ReverseDiagDir(direction));
 
@@ -753,29 +657,7 @@ int32 DoConvertTunnelBridgeRail(TileInde
 
			YapfNotifyTrackLayoutChange(endtile, endtrack);
 
		}
 
		return (length + 1) * (_price.build_rail >> 1);
 
	} else if (IsBridge(tile) &&
 
			IsBridgeMiddle(tile) &&
 
			IsTransportUnderBridge(tile) &&
 
			GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL) {
 
		// only check for train under bridge
 
		if (!CheckTileOwnership(tile) || !EnsureNoVehicleOnGround(tile))
 
			return CMD_ERROR;
 

	
 
		if (GetRailType(tile) == totype) return CMD_ERROR;
 

	
 
		if (exec) {
 
			TrackBits tracks;
 
			SetRailType(tile, totype);
 
			MarkTileDirtyByTile(tile);
 

	
 
			// notify YAPF about the track layout change
 
			for (tracks = GetRailBitsUnderBridge(tile); tracks != TRACK_BIT_NONE; tracks = KILL_FIRST_BIT(tracks))
 
				YapfNotifyTrackLayoutChange(tile, FIND_FIRST_BIT(tracks));
 
		}
 
		return _price.build_rail >> 1;
 
	} else if (IsBridge(tile) && IsBridgeRamp(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
 
		TileIndexDiff delta;
 
		int32 cost;
 
	} else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
 
		uint z = TilePixelHeight(tile);
 

	
 
		z += TILE_HEIGHT;
 
@@ -796,53 +678,29 @@ int32 DoConvertTunnelBridgeRail(TileInde
 
		if (GetRailType(tile) == totype) return CMD_ERROR;
 

	
 
		if (exec) {
 
			Track track, endtrack;
 
			TileIndexDiff delta;
 

	
 
			SetRailType(tile, totype);
 
			SetRailType(endtile, totype);
 
			MarkTileDirtyByTile(tile);
 
			MarkTileDirtyByTile(endtile);
 

	
 
			// notify YAPF about the track layout change
 
			track = TrackdirToTrack(DiagdirToDiagTrackdir(GetBridgeRampDirection(tile)));
 
			endtrack = TrackdirToTrack(DiagdirToDiagTrackdir(GetBridgeRampDirection(endtile)));
 
			YapfNotifyTrackLayoutChange(tile, track);
 
			YapfNotifyTrackLayoutChange(endtile, endtrack);
 
		}
 
		cost = 2 * (_price.build_rail >> 1);
 
		delta = TileOffsByDir(GetBridgeRampDirection(tile));
 
		for (tile += delta; tile != endtile; tile += delta) {
 
			if (exec) {
 
				SetRailTypeOnBridge(tile, totype);
 
				MarkTileDirtyByTile(tile);
 
			delta = TileOffsByDir(GetBridgeRampDirection(tile));
 
			for (tile += delta; tile != endtile; tile += delta) {
 
				MarkTileDirtyByTile(tile); // TODO encapsulate this into a function
 
			}
 
			cost += _price.build_rail >> 1;
 
		}
 

	
 
		return cost;
 
		return (DistanceManhattan(tile, endtile) + 1) * (_price.build_rail >> 1);
 
	} else
 
		return CMD_ERROR;
 
}
 

	
 

	
 
// fast routine for getting the height of a middle bridge tile. 'tile' MUST be a middle bridge tile.
 
uint GetBridgeHeight(TileIndex t)
 
{
 
	return GetBridgeHeightRamp(GetSouthernBridgeEnd(t));
 
}
 

	
 
static const byte _bridge_foundations[2][16] = {
 
// 0 1  2  3  4 5 6 7  8 9 10 11 12 13 14 15
 
	{0,16,18,3,20,5,0,7,22,0,10,11,12,13,14},
 
	{0,15,17,0,19,5,6,7,21,9,10,11, 0,13,14},
 
};
 

	
 
extern const byte _road_sloped_sprites[14];
 

	
 
static void DrawBridgePillars(PalSpriteID image, const TileInfo *ti, int x, int y, int z)
 
static void DrawBridgePillars(PalSpriteID image, const TileInfo* ti, Axis axis, uint type, int x, int y, int z)
 
{
 
	if (image != 0) {
 
		Axis axis = GetBridgeAxis(ti->tile);
 
		bool drawfarpillar = !HASBIT(GetBridgeFlags(GetBridgeType(ti->tile)), 0);
 
		bool drawfarpillar = !HASBIT(GetBridgeFlags(type), 0);
 
		int back_height, front_height;
 
		int i = z;
 
		const byte *p;
 
@@ -905,17 +763,11 @@ uint GetBridgeFoundation(Slope tileh, Ax
 
  * <li>Bit 2: Set if the bridge head is sloped</li>
 
  * <li>Bit 3 and more: Railtype Specific subset</li>
 
  * </ul>
 
  * For middle parts:
 
  * <ul><li>Bits 0-1: need to be 0</li>
 
  * <li>Bit 2: direction</li>
 
  * <li>Bit 3 and above: Railtype Specific subset</li>
 
  * </ul>
 
  * Please note that in this code, "roads" are treated as railtype 1, whilst the real railtypes are 0, 2 and 3
 
  */
 
static void DrawTile_TunnelBridge(TileInfo *ti)
 
{
 
	uint32 image;
 
	const PalSpriteID *b;
 
	bool ice = _m[ti->tile].m4 & 0x80;
 

	
 
	if (IsTunnel(ti->tile)) {
 
@@ -932,19 +784,12 @@ static void DrawTile_TunnelBridge(TileIn
 
		if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
 

	
 
		AddSortableSpriteToDraw(image+1, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, 1, 1, 8, (byte)ti->z);
 
		DrawBridgeMiddle(ti);
 
	} else if (IsBridge(ti->tile)) { // XXX is this necessary?
 
		int base_offset;
 

	
 
		if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL) {
 
			RailType rt;
 

	
 
			if (IsBridgeRamp(ti->tile)) {
 
				rt = GetRailType(ti->tile);
 
			} else {
 
				rt = GetRailTypeOnBridge(ti->tile);
 
			}
 

	
 
			base_offset = GetRailTypeInfo(rt)->bridge_offset;
 
			base_offset = GetRailTypeInfo(GetRailType(ti->tile))->bridge_offset;
 
			assert(base_offset != 8); /* This one is used for roads */
 
		} else {
 
			base_offset = 8;
 
@@ -953,124 +798,152 @@ static void DrawTile_TunnelBridge(TileIn
 
		/* as the lower 3 bits are used for other stuff, make sure they are clear */
 
		assert( (base_offset & 0x07) == 0x00);
 

	
 
		if (IsBridgeRamp(ti->tile)) {
 
			if (!HASBIT(BRIDGE_NO_FOUNDATION, ti->tileh)) {
 
				int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile)));
 
				if (f) DrawFoundation(ti, f);
 
			}
 
		if (!HASBIT(BRIDGE_NO_FOUNDATION, ti->tileh)) {
 
			int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile)));
 
			if (f) DrawFoundation(ti, f);
 
		}
 

	
 
			// HACK Wizardry to convert the bridge ramp direction into a sprite offset
 
			base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4;
 
		// HACK Wizardry to convert the bridge ramp direction into a sprite offset
 
		base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4;
 

	
 
			if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
 

	
 
			/* Table number 6 always refers to the bridge heads for any bridge type */
 
			image = GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset];
 
		if (ti->tileh == SLOPE_FLAT) base_offset += 4; // sloped bridge head
 

	
 
			if (!ice) {
 
				DrawClearLandTile(ti, 3);
 
			} else {
 
				DrawGroundSprite(SPR_FLAT_SNOWY_TILE + _tileh_to_sprite[ti->tileh]);
 
			}
 
		/* Table number 6 always refers to the bridge heads for any bridge type */
 
		image = GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset];
 

	
 
			if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
 

	
 
			// draw ramp
 
			if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
 
			AddSortableSpriteToDraw(image, ti->x, ti->y, 16, 16, 7, ti->z);
 
		if (!ice) {
 
			DrawClearLandTile(ti, 3);
 
		} else {
 
			// bridge middle part.
 
			Axis axis = GetBridgeAxis(ti->tile);
 
			uint z;
 
			int x,y;
 
			DrawGroundSprite(SPR_FLAT_SNOWY_TILE + _tileh_to_sprite[ti->tileh]);
 
		}
 

	
 
			if (IsTransportUnderBridge(ti->tile)) {
 
				uint f = _bridge_foundations[axis][ti->tileh];
 
		if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
 

	
 
				if (f != 0) DrawFoundation(ti, f);
 

	
 
				if (GetTransportTypeUnderBridge(ti->tile) == TRANSPORT_RAIL) {
 
					const RailtypeInfo* rti = GetRailTypeInfo(GetRailType(ti->tile));
 
		// draw ramp
 
		if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
 
		AddSortableSpriteToDraw(image, ti->x, ti->y, 16, 16, 7, ti->z);
 

	
 
					if (ti->tileh == SLOPE_FLAT) {
 
						image = (axis == AXIS_X ? SPR_RAIL_TRACK_Y : SPR_RAIL_TRACK_X);
 
					} else {
 
						image = SPR_RAIL_TRACK_Y + _track_sloped_sprites[ti->tileh - 1];
 
					}
 
					image += rti->total_offset;
 
					if (ice) image += rti->snow_offset;
 
				} else {
 
					if (ti->tileh == SLOPE_FLAT) {
 
						image = (axis == AXIS_X ? SPR_ROAD_Y : SPR_ROAD_X);
 
					} else {
 
						image = _road_sloped_sprites[ti->tileh - 1] + 0x53F;
 
					}
 
					if (ice) image += 19;
 
				}
 
				DrawGroundSprite(image);
 
			} else {
 
				if (IsClearUnderBridge(ti->tile)) {
 
					image = (ice ? SPR_FLAT_SNOWY_TILE : SPR_FLAT_GRASS_TILE);
 
					DrawGroundSprite(image + _tileh_to_sprite[ti->tileh]);
 
				} else {
 
					if (ti->tileh == SLOPE_FLAT) {
 
						DrawGroundSprite(SPR_FLAT_WATER_TILE);
 
						if (ti->z != 0) DrawCanalWater(ti->tile);
 
					} else {
 
						DrawGroundSprite(_water_shore_sprites[ti->tileh]);
 
					}
 
				}
 
			}
 
		DrawBridgeMiddle(ti);
 
	}
 
}
 

	
 
			if (axis != AXIS_X) base_offset += 4;
 

	
 
			/*  base_offset needs to be 0 due to the structure of the sprite table see table/bridge_land.h */
 
			assert( (base_offset & 0x03) == 0x00);
 
			// get bridge sprites
 
			b = GetBridgeSpriteTable(GetBridgeType(ti->tile), GetBridgePiece(ti->tile)) + base_offset;
 

	
 
			z = GetBridgeHeight(ti->tile) + 5;
 

	
 
			// draw rail or road component
 
			image = b[0];
 
			if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
 
			if (axis == AXIS_X) {
 
				AddSortableSpriteToDraw(image, ti->x, ti->y, 16, 11, 1, z);
 
			} else {
 
				AddSortableSpriteToDraw(image, ti->x, ti->y, 11, 16, 1, z);
 
			}
 

	
 
			x = ti->x;
 
			y = ti->y;
 
			image = b[1];
 
			if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
 

	
 
			// draw roof, the component of the bridge which is logically between the vehicle and the camera
 
			if (axis == AXIS_X) {
 
				y += 12;
 
				if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, x, y, 16, 1, 0x28, z);
 
			} else {
 
				x += 12;
 
				if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, x, y, 1, 16, 0x28, z);
 
			}
 

	
 
			if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC || GetRailTypeOnBridge(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
 

	
 
			if (ti->z + 5 == z) {
 
				// draw poles below for small bridges
 
				image = b[2];
 
				if (image != 0) {
 
					if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
 
					DrawGroundSpriteAt(image, x, y, z);
 
				}
 
			} else if (_patches.bridge_pillars) {
 
				// draw pillars below for high bridges
 
				DrawBridgePillars(b[2], ti, x, y, z);
 
			}
 
		}
 
//bridges pieces sequence (middle parts)
 
// bridge len 1: 0
 
// bridge len 2: 0 1
 
// bridge len 3: 0 4 1
 
// bridge len 4: 0 2 3 1
 
// bridge len 5: 0 2 5 3 1
 
// bridge len 6: 0 2 3 2 3 1
 
// bridge len 7: 0 2 3 4 2 3 1
 
// #0 - always as first, #1 - always as last (if len>1)
 
// #2,#3 are to pair in order
 
// for odd bridges: #5 is going in the bridge middle if on even position, #4 on odd (counting from 0)
 
static uint CalcBridgePiece(uint north, uint south)
 
{
 
	if (north == 1) {
 
		return 0;
 
	} else if (south == 1) {
 
		return 1;
 
	} else if (north < south) {
 
		return north & 1 ? 3 : 2;
 
	} else if (north > south) {
 
		return south & 1 ? 2 : 3;
 
	} else {
 
		return north & 1 ? 5 : 4;
 
	}
 
}
 

	
 
void DrawBridgeMiddle(const TileInfo* ti)
 
{
 
	const PalSpriteID* b;
 
	PalSpriteID image;
 
	uint base_offset;
 
	TileIndex rampnorth;
 
	TileIndex rampsouth;
 
	Axis axis;
 
	uint piece;
 
	uint type;
 
	int x;
 
	int y;
 
	uint z;
 

	
 
	if (!IsBridgeAbove(ti->tile)) return;
 

	
 
	rampnorth = GetNorthernBridgeEnd(ti->tile);
 
	rampsouth = GetSouthernBridgeEnd(ti->tile);
 

	
 
	axis = GetBridgeAxis(ti->tile);
 
	piece = CalcBridgePiece(
 
		DistanceManhattan(ti->tile, rampnorth),
 
		DistanceManhattan(ti->tile, rampsouth)
 
	);
 
	type = GetBridgeType(rampsouth);
 

	
 
	if (GetBridgeTransportType(rampsouth) == TRANSPORT_RAIL) {
 
		base_offset = GetRailTypeInfo(GetRailType(rampsouth))->bridge_offset;
 
	} else {
 
		base_offset = 8;
 
	}
 

	
 
	b = base_offset + GetBridgeSpriteTable(type, piece);
 
	if (axis != AXIS_X) b += 4;
 

	
 
	x = ti->x;
 
	y = ti->y;
 
	z = GetBridgeHeight(rampsouth, axis) - 3;
 

	
 
	image = b[0];
 
	if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
 
	if (axis == AXIS_X) {
 
		AddSortableSpriteToDraw(image, x, y, 16, 11, 1, z);
 
	} else {
 
		AddSortableSpriteToDraw(image, x, y, 11, 16, 1, z);
 
	}
 

	
 
	image = b[1];
 
	if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
 

	
 
	// draw roof, the component of the bridge which is logically between the vehicle and the camera
 
	if (axis == AXIS_X) {
 
		y += 12;
 
		if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, x, y, 16, 1, 0x28, z);
 
	} else {
 
		x += 12;
 
		if (image & SPRITE_MASK) AddSortableSpriteToDraw(image, x, y, 1, 16, 0x28, z);
 
	}
 

	
 
	if (GetRailType(rampsouth) == RAILTYPE_ELECTRIC) DrawCatenary(ti);
 

	
 
	if (ti->z + 5 == z) {
 
		// draw poles below for small bridges
 
		image = b[2];
 
		if (image != 0) {
 
			if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
 
			DrawGroundSpriteAt(image, x, y, z);
 
		}
 
	} else if (_patches.bridge_pillars) {
 
		// draw pillars below for high bridges
 
		DrawBridgePillars(b[2], ti, axis, type, x, y, z);
 
	}
 
}
 

	
 

	
 
uint SetSpeedLimitOnBridge(Vehicle *v)
 
{
 
	uint bridge_speed;
 
	if (v->vehstatus & VS_HIDDEN) return v->max_speed; /* in tunnel */
 

	
 
	bridge_speed = _bridge[GetBridgeType(v->tile)].speed;
 

	
 
	if (v->type == VEH_Road) bridge_speed *= 2; /* XXX give vehicles proper speeds */
 

	
 
	if (v->cur_speed > bridge_speed) v->cur_speed = bridge_speed;
 
	return bridge_speed;
 
}
 

	
 

	
 

	
 
static uint GetSlopeZ_TunnelBridge(const TileInfo* ti)
 
{
 
	TileIndex tile = ti->tile;
 
@@ -1085,44 +958,30 @@ static uint GetSlopeZ_TunnelBridge(const
 
		// In the tunnel entrance?
 
		if (5 <= pos && pos <= 10) return z;
 
	} else {
 
		if (IsBridgeRamp(tile)) {
 
			DiagDirection dir = GetBridgeRampDirection(tile);
 
			uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x);
 
		DiagDirection dir = GetBridgeRampDirection(tile);
 
		uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x);
 

	
 
			// On the bridge ramp?
 
			if (5 <= pos && pos <= 10) {
 
				uint delta;
 
		// On the bridge ramp?
 
		if (5 <= pos && pos <= 10) {
 
			uint delta;
 

	
 
				if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT;
 
			if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + TILE_HEIGHT;
 

	
 
				if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) z += TILE_HEIGHT;
 
				switch (dir) {
 
					default:
 
					case DIAGDIR_NE: delta = (TILE_SIZE - 1 - x) / 2; break;
 
					case DIAGDIR_SE: delta = y / 2; break;
 
					case DIAGDIR_SW: delta = x / 2; break;
 
					case DIAGDIR_NW: delta = (TILE_SIZE - 1 - y) / 2; break;
 
				}
 
				return z + 1 + delta;
 
			} else {
 
				uint f = GetBridgeFoundation(tileh, DiagDirToAxis(dir));
 
			if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) z += TILE_HEIGHT;
 
			switch (dir) {
 
				default:
 
				case DIAGDIR_NE: delta = (TILE_SIZE - 1 - x) / 2; break;
 
				case DIAGDIR_SE: delta = y / 2; break;
 
				case DIAGDIR_SW: delta = x / 2; break;
 
				case DIAGDIR_NW: delta = (TILE_SIZE - 1 - y) / 2; break;
 
			}
 
			return z + 1 + delta;
 
		} else {
 
			uint f = GetBridgeFoundation(tileh, DiagDirToAxis(dir));
 

	
 
				if (f != 0) {
 
					if (f < 15) return z + TILE_HEIGHT;
 
					tileh = _inclined_tileh[f - 15];
 
				}
 
			}
 
		} else {
 
			// HACK on the bridge?
 
			if (_get_z_hint >= z + TILE_HEIGHT + (tileh == SLOPE_FLAT ? 0 : TILE_HEIGHT)) return _get_z_hint;
 

	
 
			if (IsTransportUnderBridge(tile)) {
 
				uint f = _bridge_foundations[GetBridgeAxis(tile)][tileh];
 

	
 
				if (f != 0) {
 
					if (f < 15) return z + TILE_HEIGHT;
 
					tileh = _inclined_tileh[f - 15];
 
				}
 
			if (f != 0) {
 
				if (f < 15) return z + TILE_HEIGHT;
 
				tileh = _inclined_tileh[f - 15];
 
			}
 
		}
 
	}
 
@@ -1181,9 +1040,6 @@ static void GetTileDesc_TunnelBridge(Til
 
			STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL;
 
	} else {
 
		td->str = _bridge_tile_str[GetBridgeTransportType(tile) << 4 | GetBridgeType(tile)];
 

	
 
		// the owner is stored at the end of the bridge
 
		if (IsBridgeMiddle(tile)) tile = GetSouthernBridgeEnd(tile);
 
	}
 
	td->owner = GetTileOwner(tile);
 
}
 
@@ -1218,10 +1074,6 @@ static void TileLoop_TunnelBridge(TileIn
 
			}
 
			break;
 
	}
 

	
 
	if (IsBridge(tile) && IsBridgeMiddle(tile) && IsWaterUnderBridge(tile)) {
 
		TileLoop_Water(tile);
 
	}
 
}
 

	
 
static void ClickTile_TunnelBridge(TileIndex tile)
 
@@ -1232,37 +1084,13 @@ static void ClickTile_TunnelBridge(TileI
 

	
 
static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode)
 
{
 
	uint32 result;
 

	
 
	if (IsTunnel(tile)) {
 
		if (GetTunnelTransportType(tile) == mode) {
 
			return DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? 0x101 : 0x202;
 
		}
 
	} else if (IsBridge(tile)) { // XXX is this necessary?
 
		if (IsBridgeRamp(tile)) {
 
			if (GetBridgeTransportType(tile) != mode) return 0;
 
			return (DiagDirToAxis(GetBridgeRampDirection(tile)) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y) * 0x101;
 
		} else {
 
			result = 0;
 
			if (GetBridgeTransportType(tile) == mode) {
 
				result = (GetBridgeAxis(tile) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y) * 0x101;
 
			}
 
			if (IsTransportUnderBridge(tile)) {
 
				if (GetTransportTypeUnderBridge(tile) != mode) return result;
 
			} else {
 
				if (IsClearUnderBridge(tile)) {
 
					return result;
 
				} else {
 
					if (mode != TRANSPORT_WATER) return result;
 
				}
 
			}
 
			/* If we've not returned yet, there is a compatible
 
			 * transport or water beneath, so we can add it to
 
			 * result */
 
			/* Why is this xor'd ? Can't it just be or'd? */
 
			result ^= (GetBridgeAxis(tile) == AXIS_X ? 0x202 : 0x101);
 
		}
 
		return result;
 
		if (GetBridgeTransportType(tile) != mode) return 0;
 
		return (DiagDirToAxis(GetBridgeRampDirection(tile)) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y) * 0x101;
 
	} else {
 
		assert(0); /* This should never occur */
 
	}
 
@@ -1276,16 +1104,7 @@ static void ChangeTileOwner_TunnelBridge
 
	if (new_player != OWNER_SPECTATOR) {
 
		SetTileOwner(tile, new_player);
 
	}	else {
 
		if (IsBridge(tile) && IsBridgeMiddle(tile) && IsTransportUnderBridge(tile)) {
 
			// the stuff BELOW the middle part is owned by the deleted player.
 
			if (GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL) {
 
				SetClearUnderBridge(tile);
 
			} else {
 
				SetTileOwner(tile, OWNER_NONE);
 
			}
 
		} else {
 
			DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
 
		}
 
		DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
 
	}
 
}
 

	
 
@@ -1305,14 +1124,15 @@ static const byte _tunnel_fractcoord_7[4
 

	
 
static uint32 VehicleEnter_TunnelBridge(Vehicle *v, TileIndex tile, int x, int y)
 
{
 
	int z = GetSlopeZ(x, y) - v->z_pos;
 

	
 
	if (myabs(z) > 2) return 8;
 

	
 
	if (IsTunnel(tile)) {
 
		int z = GetSlopeZ(x, y) - v->z_pos;
 
		byte fc;
 
		DiagDirection dir;
 
		DiagDirection vdir;
 

	
 
		if (myabs(z) > 2) return 8;
 

	
 
		if (v->type == VEH_Train) {
 
			fc = (x & 0xF) + (y << 4);
 

	
 
@@ -1373,30 +1193,53 @@ static uint32 VehicleEnter_TunnelBridge(
 
			}
 
		}
 
	} else if (IsBridge(tile)) { // XXX is this necessary?
 
		DiagDirection dir;
 

	
 
		if (v->type == VEH_Road || (v->type == VEH_Train && IsFrontEngine(v))) {
 
			if (IsBridgeRamp(tile) || v->z_pos > GetTileMaxZ(tile)) {
 
				/* modify speed of vehicle */
 
				uint16 spd = _bridge[GetBridgeType(tile)].speed;
 
				if (v->type == VEH_Road) spd *= 2;
 
				if (v->cur_speed > spd) v->cur_speed = spd;
 
			/* modify speed of vehicle */
 
			uint16 spd = _bridge[GetBridgeType(tile)].speed;
 

	
 
			if (v->type == VEH_Road) spd *= 2;
 
			if (v->cur_speed > spd) v->cur_speed = spd;
 
		}
 

	
 
		dir = GetBridgeRampDirection(tile);
 
		if (DirToDiagDir(v->direction) == dir) {
 
			switch (dir) {
 
				default:
 
				case DIAGDIR_NE: if ((x & 0xF) != 0)             return 0; break;
 
				case DIAGDIR_SE: if ((y & 0xF) != TILE_SIZE - 1) return 0; break;
 
				case DIAGDIR_SW: if ((x & 0xF) != TILE_SIZE - 1) return 0; break;
 
				case DIAGDIR_NW: if ((y & 0xF) != 0)             return 0; break;
 
			}
 
			if (v->type == VEH_Train) {
 
				v->u.rail.track = 0x40;
 
				CLRBIT(v->u.rail.flags, VRF_GOINGUP);
 
				CLRBIT(v->u.rail.flags, VRF_GOINGDOWN);
 
			} else {
 
				v->u.road.state = 0xFF;
 
			}
 
			return 4;
 
		} else if (DirToDiagDir(v->direction) == ReverseDiagDir(dir)) {
 
			v->tile = tile;
 
			if (v->type == VEH_Train) {
 
				if (v->u.rail.track == 0x40) {
 
					v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? 1 : 2);
 
					return 4;
 
				}
 
			} else {
 
				if (v->u.road.state == 0xFF) {
 
					v->u.road.state = _road_exit_tunnel_state[dir];
 
					v->u.road.frame = 0;
 
					return 4;
 
				}
 
			}
 
			return 0;
 
		}
 
	}
 
	return 0;
 
}
 

	
 
TileIndex GetVehicleOutOfTunnelTile(const Vehicle *v)
 
{
 
	TileIndex tile;
 
	TileIndexDiff delta = (v->direction & 2) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
 
	byte z = v->z_pos;
 

	
 
	for (tile = v->tile;; tile += delta) {
 
		if (IsTunnelTile(tile) && GetTileZ(tile) == z) break;
 
	}
 
	return tile;
 
}
 

	
 
const TileTypeProcs _tile_type_tunnelbridge_procs = {
 
	DrawTile_TunnelBridge,					/* draw_tile_proc */
 
	GetSlopeZ_TunnelBridge,					/* get_slope_z_proc */
variables.h
Show inline comments
 
@@ -309,7 +309,6 @@ VARDEF bool _exit_game;
 
VARDEF SmallFiosItem _file_to_saveload;
 
VARDEF byte _make_screenshot;
 

	
 
VARDEF byte _get_z_hint; // used as a hint to getslopez to return the right height at a bridge.
 

	
 
VARDEF char *_newgrf_files[32];
 

	
vehicle.h
Show inline comments
 
@@ -286,7 +286,6 @@ uint32 VehicleEnterTile(Vehicle *v, Tile
 

	
 
StringID VehicleInTheWayErrMsg(const Vehicle* v);
 
Vehicle *FindVehicleBetween(TileIndex from, TileIndex to, byte z);
 
TileIndex GetVehicleOutOfTunnelTile(const Vehicle *v);
 

	
 
bool UpdateSignalsOnSegment(TileIndex tile, DiagDirection direction);
 
void SetSignalsOnBothDir(TileIndex tile, byte track);
water_cmd.c
Show inline comments
 
@@ -20,7 +20,7 @@
 
#include "train.h"
 
#include "water_map.h"
 

	
 
const SpriteID _water_shore_sprites[15] = {
 
static const SpriteID _water_shore_sprites[] = {
 
	0,
 
	SPR_SHORE_TILEH_1,
 
	SPR_SHORE_TILEH_2,
 
@@ -65,6 +65,8 @@ int32 CmdBuildShipDepot(TileIndex tile, 
 
	if (!IsClearWaterTile(tile) || !IsClearWaterTile(tile2))
 
		return_cmd_error(STR_3801_MUST_BE_BUILT_ON_WATER);
 

	
 
	if (IsBridgeAbove(tile) || IsBridgeAbove(tile2)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 

	
 
	ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
	if (CmdFailed(ret)) return CMD_ERROR;
 
	ret = DoCommand(tile2, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
@@ -139,6 +141,8 @@ static int32 DoBuildShiplift(TileIndex t
 
		return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 
	}
 

	
 
	if (IsBridgeAbove(tile) || IsBridgeAbove(tile - delta) || IsBridgeAbove(tile + delta)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 

	
 
	if (flags & DC_EXEC) {
 
		MakeLock(tile, dir);
 
		MarkTileDirtyByTile(tile);
 
@@ -227,6 +231,8 @@ int32 CmdBuildCanal(TileIndex tile, uint
 

	
 
	cost = 0;
 
	BEGIN_TILE_LOOP(tile, size_x, size_y, TileXY(sx, sy)) {
 
		int32 ret;
 

	
 
		if (GetTileSlope(tile, NULL) != SLOPE_FLAT) {
 
			return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 
		}
 
@@ -234,26 +240,12 @@ int32 CmdBuildCanal(TileIndex tile, uint
 
		// can't make water of water!
 
		if (IsTileType(tile, MP_WATER)) continue;
 

	
 
		/* is middle piece of a bridge? */
 
		if (IsBridgeTile(tile) && IsBridgeMiddle(tile)) {
 
			if (IsTransportUnderBridge(tile)) {
 
				return_cmd_error(STR_5800_OBJECT_IN_THE_WAY);
 
			}
 

	
 
			if (IsWaterUnderBridge(tile)) return_cmd_error(STR_1007_ALREADY_BUILT);
 

	
 
			if (flags & DC_EXEC) SetWaterUnderBridge(tile);
 
		} else {
 
			/* no bridge, try to clear it. */
 
			int32 ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 

	
 
			if (CmdFailed(ret)) return ret;
 
			cost += ret;
 

	
 
			if (flags & DC_EXEC) MakeWater(tile);
 
		}
 
		ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
		if (CmdFailed(ret)) return ret;
 
		cost += ret;
 

	
 
		if (flags & DC_EXEC) {
 
			MakeWater(tile);
 
			MarkTileDirtyByTile(tile);
 
			MarkTilesAroundDirty(tile);
 
		}
 
@@ -336,17 +328,9 @@ static int32 ClearTile_Water(TileIndex t
 
static bool IsWateredTile(TileIndex tile)
 
{
 
	switch (GetTileType(tile)) {
 
		case MP_WATER:
 
			return !IsCoast(tile);
 

	
 
		case MP_STATION:
 
			return IsOilRig(tile) || IsDock(tile) || IsBuoy_(tile);
 

	
 
		case MP_TUNNELBRIDGE:
 
			return IsBridge(tile) && IsBridgeMiddle(tile) && IsWaterUnderBridge(tile);
 

	
 
		default:
 
			return false;
 
		case MP_WATER:   return !IsCoast(tile);
 
		case MP_STATION: return IsOilRig(tile) || IsDock(tile) || IsBuoy_(tile);
 
		default:         return false;
 
	}
 
}
 

	
 
@@ -422,11 +406,13 @@ static void DrawTile_Water(TileInfo *ti)
 
		case WATER_CLEAR:
 
			DrawGroundSprite(SPR_FLAT_WATER_TILE);
 
			if (ti->z != 0) DrawCanalWater(ti->tile);
 
			DrawBridgeMiddle(ti);
 
			break;
 

	
 
		case WATER_COAST:
 
			assert(!IsSteepSlope(ti->tileh));
 
			DrawGroundSprite(_water_shore_sprites[ti->tileh]);
 
			DrawBridgeMiddle(ti);
 
			break;
 

	
 
		case WATER_LOCK: {
 
@@ -536,27 +522,10 @@ static void TileLoopWaterHelper(TileInde
 
				}
 
				break;
 

	
 
			case MP_TUNNELBRIDGE:
 
				if (IsBridge(target) && IsBridgeMiddle(target) && IsClearUnderBridge(target)) {
 
					SetWaterUnderBridge(target);
 
					MarkTileDirtyByTile(target);
 
				}
 
				break;
 

	
 
			default:
 
				break;
 
		}
 
	} else {
 
		if (IsBridgeTile(target) && IsBridgeMiddle(target)) {
 
			if (IsWaterUnderBridge(target) ||
 
					(IsTransportUnderBridge(target) && GetTransportTypeUnderBridge(target) == TRANSPORT_WATER)) { // XXX does this happen at all?
 
				return;
 
			}
 
			SetWaterUnderBridge(target);
 
			MarkTileDirtyByTile(target);
 
			return;
 
		}
 

	
 
		_current_player = OWNER_WATER;
 
		{
 
			Vehicle *v = FindVehicleOnTileZ(target, 0);
waypoint.c
Show inline comments
 
@@ -9,6 +9,7 @@
 
#include "map.h"
 
#include "order.h"
 
#include "rail_map.h"
 
#include "bridge_map.h"
 
#include "saveload.h"
 
#include "station.h"
 
#include "tile.h"
 
@@ -201,6 +202,8 @@ int32 CmdBuildTrainWaypoint(TileIndex ti
 
			return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 
	}
 

	
 
	if (MayHaveBridgeAbove(tile) && IsBridgeAbove(tile)) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 

	
 
	/* Check if there is an already existing, deleted, waypoint close to us that we can reuse. */
 
	wp = FindDeletedWaypointCloseTo(tile);
 
	if (wp == NULL) {
yapf/follow_track.hpp
Show inline comments
 
@@ -27,7 +27,7 @@ struct CFollowTrackT : public FollowTrac
 
		m_new_tile = INVALID_TILE;
 
		m_new_td_bits = TRACKDIR_BIT_NONE;
 
		m_exitdir = INVALID_DIAGDIR;
 
		m_is_station = m_is_tunnel = false;
 
		m_is_station = m_is_bridge = m_is_tunnel = false;
 
		m_tiles_skipped = 0;
 
	}
 

	
 
@@ -60,6 +60,9 @@ protected:
 
	/** Follow the m_exitdir from m_old_tile and fill m_new_tile and m_tiles_skipped */
 
	FORCEINLINE void FollowTileExit()
 
	{
 
		m_is_station = m_is_bridge = m_is_tunnel = false;
 
		m_tiles_skipped = 0;
 

	
 
		// extra handling for tunnels in our direction
 
		if (IsTunnelTile(m_old_tile)) {
 
			DiagDirection tunnel_enterdir = GetTunnelDirection(m_old_tile);
 
@@ -73,11 +76,22 @@ protected:
 
			}
 
			assert(ReverseDiagDir(tunnel_enterdir) == m_exitdir);
 
		}
 
		// not a tunnel or station
 
		m_is_tunnel = false;
 
		m_tiles_skipped = 0;
 

	
 
		// normal or station tile
 
		// extra handling for bridge ramp in our direction
 
		if (IsBridgeTile(m_old_tile)) {
 
			DiagDirection bridge_enterdir = GetBridgeRampDirection(m_old_tile);
 
			if (bridge_enterdir == m_exitdir) {
 
				// we are entering the bridge ramp
 
				m_new_tile = GetOtherBridgeEnd(m_old_tile);
 
				uint32 bridge_length = GetBridgeLength(m_old_tile, m_new_tile);
 
				m_tiles_skipped = bridge_length;
 
				m_is_bridge = true;
 
				return;
 
			}
 
			assert(ReverseDiagDir(bridge_enterdir) == m_exitdir);
 
		}
 

	
 
		// normal or station tile, do one step
 
		TileIndexDiff diff = TileOffsByDir(m_exitdir);
 
		m_new_tile = TILE_ADD(m_old_tile, diff);
 

	
 
@@ -148,22 +162,7 @@ protected:
 
		// rail transport is possible only on tiles with the same owner as vehicle
 
		if (IsRailTT() && GetTileOwner(m_new_tile) != m_veh->owner) {
 
			// different owner
 
			if (IsBridgeTile(m_new_tile)) {
 
				if (IsBridgeMiddle(m_new_tile)) {
 
						// bridge middle has no owner - tile is owned by the owner of the under-bridge track
 
					if (GetBridgeAxis(m_new_tile) != DiagDirToAxis(m_exitdir)) {
 
						// so it must be under bridge track (and wrong owner)
 
						return false;
 
					}
 
					// in the middle of the bridge - when we came here, it should be ok
 
				} else {
 
					// different owner, on the bridge ramp
 
					return false;
 
				}
 
			} else {
 
				// different owner, not a bridge
 
				return false;
 
			}
 
			return false;
 
		}
 

	
 
		// rail transport is possible only on compatible rail types
 
@@ -224,20 +223,10 @@ public:
 
		int max_speed = INT_MAX; // no limit
 

	
 
		// for now we handle only on-bridge speed limit
 
		if (IsBridgeTile(m_old_tile) && !IsWaterTT() && IsDiagonalTrackdir(m_old_td)) {
 
			bool is_on_bridge = true;
 
			if (IsBridgeMiddle(m_old_tile)) {
 
				// get track axis
 
				Axis track_axis = DiagDirToAxis(TrackdirToExitdir(m_old_td));
 
				// get under-bridge axis
 
				Axis bridge_axis =  GetBridgeAxis(m_old_tile);
 
				if (track_axis != bridge_axis) is_on_bridge = false;
 
			}
 
			if (is_on_bridge) {
 
				int spd = _bridge[GetBridgeType(m_old_tile)].speed;
 
				if (IsRoadTT()) spd *= 2;
 
				if (max_speed > spd) max_speed = spd;
 
			}
 
		if (!IsWaterTT() && IsBridgeTile(m_old_tile)) {
 
			int spd = _bridge[GetBridgeType(m_old_tile)].speed;
 
			if (IsRoadTT()) spd *= 2;
 
			if (max_speed > spd) max_speed = spd;
 
		}
 

	
 
		// if min speed was requested, return it
yapf/yapf.h
Show inline comments
 
@@ -34,9 +34,9 @@ typedef struct FollowTrack_t
 
	Trackdir      m_old_td;
 
	TileIndex     m_new_tile;
 
	TrackdirBits  m_new_td_bits;
 
//	TrackdirBits  m_red_td_bits;
 
	DiagDirection m_exitdir;
 
	bool          m_is_tunnel;
 
	bool          m_is_bridge;
 
	bool          m_is_station;
 
	int           m_tiles_skipped;
 
} FollowTrack_t;
yapf/yapf_road.cpp
Show inline comments
 
@@ -423,7 +423,9 @@ uint YapfRoadVehDistanceToTile(const Veh
 
Depot* YapfFindNearestRoadDepot(const Vehicle *v)
 
{
 
	TileIndex tile = v->tile;
 
#if 0 /* NOT NEEDED, function does/did nothing */
 
	if (v->u.road.state == 255) tile = GetVehicleOutOfTunnelTile(v);
 
#endif
 
	Trackdir trackdir = GetVehicleTrackdir(v);
 
	if ((GetTileTrackStatus(tile, TRANSPORT_ROAD) & TrackdirToTrackdirBits(trackdir)) == 0)
 
		return NULL;
0 comments (0 inline, 0 general)