Changeset - r8083:8cd2123a0c7c
[Not reviewed]
master
0 27 1
smatz - 16 years ago 2007-12-16 15:38:51
smatz@openttd.org
(svn r11644) -Codechange: merge some functions from tunnel_map.h and bridge_map.h into tunnelbridge_map.h
28 files changed with 245 insertions and 241 deletions:
0 comments (0 inline, 0 general)
projects/openttd.vcproj
Show inline comments
 
@@ -1189,24 +1189,27 @@
 
				RelativePath=".\..\src\town_map.h">
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tree_map.h">
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tunnel_map.cpp">
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tunnel_map.h">
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tunnelbridge_map.h">
 
			</File>
 
			<File
 
				RelativePath=".\..\src\unmovable_map.h">
 
			</File>
 
			<File
 
				RelativePath=".\..\src\void_map.h">
 
			</File>
 
			<File
 
				RelativePath=".\..\src\water_map.h">
 
			</File>
 
		</Filter>
 
		<Filter
 
			Name="Misc"
 
			Filter="">
projects/openttd_vs80.vcproj
Show inline comments
 
@@ -1807,24 +1807,28 @@
 
				RelativePath=".\..\src\tree_map.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tunnel_map.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tunnel_map.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tunnelbridge_map.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\unmovable_map.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\void_map.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\water_map.h"
 
				>
 
			</File>
 
		</Filter>
projects/openttd_vs90.vcproj
Show inline comments
 
@@ -1804,24 +1804,28 @@
 
				RelativePath=".\..\src\tree_map.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tunnel_map.cpp"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tunnel_map.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\tunnelbridge_map.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\unmovable_map.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\void_map.h"
 
				>
 
			</File>
 
			<File
 
				RelativePath=".\..\src\water_map.h"
 
				>
 
			</File>
 
		</Filter>
source.list
Show inline comments
 
@@ -364,24 +364,25 @@ newgrf_townname.cpp
 
bridge_map.cpp
 
bridge_map.h
 
clear_map.h
 
industry_map.h
 
rail_map.h
 
road_map.cpp
 
road_map.h
 
station_map.h
 
town_map.h
 
tree_map.h
 
tunnel_map.cpp
 
tunnel_map.h
 
tunnelbridge_map.h
 
unmovable_map.h
 
void_map.h
 
water_map.h
 

	
 
# Misc
 
misc/array.hpp
 
misc/autocopyptr.hpp
 
misc/autoptr.hpp
 
misc/binaryheap.hpp
 
misc/blob.hpp
 
misc/countedptr.hpp
 
misc/crc32.hpp
src/ai/default/default.cpp
Show inline comments
 
@@ -19,26 +19,28 @@
 
#include "../../command.h"
 
#include "../../town.h"
 
#include "../../industry.h"
 
#include "../../station.h"
 
#include "../../pathfind.h"
 
#include "../../economy.h"
 
#include "../../airport.h"
 
#include "../../depot.h"
 
#include "../../variables.h"
 
#include "../../bridge.h"
 
#include "../../date.h"
 
#include "../../helpers.hpp"
 
#include "../../tunnelbridge_map.h"
 
#include "default.h"
 

	
 

	
 
// remove some day perhaps?
 
static uint _ai_service_interval;
 

	
 
typedef void AiStateAction(Player *p);
 

	
 
enum {
 
	AIS_0                            =  0,
 
	AIS_1                            =  1,
 
	AIS_VEH_LOOP                     =  2,
 
	AIS_VEH_CHECK_REPLACE_VEHICLE    =  3,
 
	AIS_VEH_DO_REPLACE_VEHICLE       =  4,
 
	AIS_WANT_NEW_ROUTE               =  5,
 
@@ -2224,25 +2226,25 @@ static bool AiRemoveTileAndGoForward(Pla
 
	TileIndex tilenew;
 

	
 
	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
		if (IsTunnel(tile)) {
 
			// Clear the tunnel and continue at the other side of it.
 
			if (CmdFailed(DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR)))
 
				return false;
 
			p->ai.cur_tile_a = TILE_MASK(_build_tunnel_endtile - TileOffsByDiagDir(p->ai.cur_dir_a));
 
			return true;
 
		} 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 & 1)) return false;
 
			if (DiagDirToAxis(GetTunnelBridgeDirection(tile)) != (p->ai.cur_dir_a & 1)) return false;
 

	
 
			tile = GetOtherBridgeEnd(tile);
 

	
 
			tilenew = TILE_MASK(tile - TileOffsByDiagDir(p->ai.cur_dir_a));
 
			// And clear the bridge.
 
			if (CmdFailed(DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR)))
 
				return false;
 
			p->ai.cur_tile_a = tilenew;
 
			return true;
 
		}
 
	}
 

	
 
@@ -3724,31 +3726,31 @@ pos_3:
 

	
 
			DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
 
			DoCommand(
 
				TILE_MASK(tile + TileOffsByDiagDir(dir)),
 
				DiagDirToRoadBits(ReverseDiagDir(dir)),
 
				0,
 
				DC_EXEC,
 
				CMD_REMOVE_ROAD);
 
		}
 
	} else if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
		if (!IsTileOwner(tile, _current_player) ||
 
				!IsBridge(tile) ||
 
				GetBridgeTransportType(tile) != TRANSPORT_RAIL) {
 
				GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) {
 
			return;
 
		}
 

	
 
		rails = TRACK_BIT_NONE;
 

	
 
		switch (GetBridgeRampDirection(tile)) {
 
		switch (GetTunnelBridgeDirection(tile)) {
 
			default:
 
			case DIAGDIR_NE: goto pos_2;
 
			case DIAGDIR_SE: goto pos_3;
 
			case DIAGDIR_SW: goto pos_0;
 
			case DIAGDIR_NW: goto pos_1;
 
		}
 
	}
 
}
 

	
 
static void AiStateRemoveTrack(Player *p)
 
{
 
	/* Was 1000 for standard 8x8 maps. */
src/ai/trolly/pathfinder.cpp
Show inline comments
 
@@ -3,26 +3,28 @@
 
#include "../../stdafx.h"
 
#include "../../openttd.h"
 
#include "../../bridge_map.h"
 
#include "../../debug.h"
 
#include "../../functions.h"
 
#include "../../map.h"
 
#include "../../tile.h"
 
#include "../../command.h"
 
#include "trolly.h"
 
#include "../../depot.h"
 
#include "../../tunnel_map.h"
 
#include "../../bridge.h"
 
#include "../../tunnelbridge_map.h"
 
#include "../ai.h"
 

	
 

	
 
#define TEST_STATION_NO_DIR 0xFF
 

	
 
// Tests if a station can be build on the given spot
 
// TODO: make it train compatible
 
static bool TestCanBuildStationHere(TileIndex tile, byte dir)
 
{
 
	Player *p = GetPlayer(_current_player);
 

	
 
	if (dir == TEST_STATION_NO_DIR) {
 
		CommandCost ret;
 
		// TODO: currently we only allow spots that can be access from al 4 directions...
 
		//  should be fixed!!!
 
@@ -35,26 +37,26 @@ static bool TestCanBuildStationHere(Tile
 

	
 
	// return true if command succeeded, so the inverse of CmdFailed()
 
	return CmdSucceeded(AiNew_Build_Station(p, p->ainew.tbt, tile, 1, 1, dir, DC_QUERY_COST));
 
}
 

	
 

	
 
static bool IsRoad(TileIndex tile)
 
{
 
	return
 
		// MP_ROAD, but not a road depot?
 
		(IsTileType(tile, MP_ROAD) && !IsTileDepotType(tile, TRANSPORT_ROAD)) ||
 
		(IsTileType(tile, MP_TUNNELBRIDGE) && (
 
			(IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_ROAD) ||
 
			(IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_ROAD)
 
			(IsTunnel(tile) && GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD) ||
 
			(IsBridge(tile) && GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD)
 
		));
 
}
 

	
 

	
 
// Checks if a tile 'a' is between the tiles 'b' and 'c'
 
#define TILES_BETWEEN(a, b, c) (TileX(a) >= TileX(b) && TileX(a) <= TileX(c) && TileY(a) >= TileY(b) && TileY(a) <= TileY(c))
 

	
 

	
 
// Check if the current tile is in our end-area
 
static int32 AyStar_AiPathFinder_EndNodeCheck(AyStar *aystar, OpenListNode *current)
 
{
 
	const Ai_PathFinderInfo* PathFinderInfo = (Ai_PathFinderInfo*)aystar->user_target;
 
@@ -226,27 +228,27 @@ static void AyStar_AiPathFinder_GetNeigh
 
		TileIndex ctile = current->path.node.tile; // Current tile
 
		TileIndex atile = ctile + TileOffsByDiagDir(i); // Adjacent tile
 

	
 
		if (TileX(atile) > 1 && TileX(atile) < MapMaxX() - 1 &&
 
				TileY(atile) > 1 && TileY(atile) < MapMaxY() - 1) {
 
			// We also directly test if the current tile can connect to this tile..
 
			//  We do this simply by just building the tile!
 

	
 
			// If the next step is a bridge, we have to enter it the right way
 
			if (!PathFinderInfo->rail_or_road && IsRoad(atile)) {
 
				if (IsTileType(atile, MP_TUNNELBRIDGE)) {
 
					if (IsTunnel(atile)) {
 
						if (GetTunnelDirection(atile) != i) continue;
 
						if (GetTunnelBridgeDirection(atile) != i) continue;
 
					} else {
 
						if (GetBridgeRampDirection(atile) != i) continue;
 
						if (GetTunnelBridgeDirection(atile) != i) continue;
 
					}
 
				}
 
			}
 

	
 
			if ((AI_PATHFINDER_FLAG_BRIDGE & current->path.node.user_data[0]) != 0 ||
 
					(AI_PATHFINDER_FLAG_TUNNEL & current->path.node.user_data[0]) != 0) {
 
				// We are a bridge/tunnel, how cool!!
 
				//  This means we can only point forward.. get the direction from the user_data
 
				if ((uint)i != (current->path.node.user_data[0] >> 8)) continue;
 
			}
 
			dir = 0;
 

	
src/bridge_map.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file bridge_map.cpp Map accessor functions for bridges. */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
#include "bridge.h"
 
#include "variables.h"
 
#include "landscape.h"
 
#include "tunnelbridge_map.h"
 

	
 

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

	
 
	dir = ReverseDiagDir(dir);
 
	do {
 
		tile += delta;
 
	} while (!IsBridgeTile(tile) || GetBridgeRampDirection(tile) != dir);
 
	} while (!IsBridgeTile(tile) || GetTunnelBridgeDirection(tile) != dir);
 

	
 
	return tile;
 
}
 

	
 

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

	
 

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

	
 

	
 
TileIndex GetOtherBridgeEnd(TileIndex tile)
 
{
 
	assert(IsBridgeTile(tile));
 
	return GetBridgeEnd(tile, GetBridgeRampDirection(tile));
 
	return GetBridgeEnd(tile, GetTunnelBridgeDirection(tile));
 
}
 

	
 
uint GetBridgeHeight(TileIndex t)
 
{
 
	uint h;
 
	Slope tileh = GetTileSlope(t, &h);
 
	Foundation f = GetBridgeFoundation(tileh, DiagDirToAxis(GetBridgeRampDirection(t)));
 
	Foundation f = GetBridgeFoundation(tileh, DiagDirToAxis(GetTunnelBridgeDirection(t)));
 

	
 
	/* one height level extra for the ramp */
 
	return h + TILE_HEIGHT + ApplyFoundationToSlope(f, &tileh);
 
}
src/bridge_map.h
Show inline comments
 
@@ -55,102 +55,48 @@ static inline bool MayHaveBridgeAbove(Ti
 
/**
 
 * checks if a bridge is set above the ground of this tile
 
 * @param t The tile to analyze
 
 * @pre MayHaveBridgeAbove(t)
 
 * @return true if a bridge is detected above
 
 */
 
static inline bool IsBridgeAbove(TileIndex t)
 
{
 
	assert(MayHaveBridgeAbove(t));
 
	return GB(_m[t].m6, 6, 2) != 0;
 
}
 

	
 

	
 
/**
 
 * Determines the type of bridge on a tile
 
 * @param t The tile to analyze
 
 * @pre IsBridgeTile(t)
 
 * @return The bridge type
 
 */
 
static inline uint GetBridgeType(TileIndex t)
 
{
 
	assert(IsBridgeTile(t));
 
	return GB(_m[t].m2, 4, 4);
 
}
 

	
 

	
 
/**
 
 * Get the direction pointing onto the bridge
 
 * @param t The tile to analyze
 
 * @pre IsBridgeTile(t)
 
 * @return the above mentionned direction
 
 */
 
static inline DiagDirection GetBridgeRampDirection(TileIndex t)
 
{
 
	assert(IsBridgeTile(t));
 
	return (DiagDirection)GB(_m[t].m5, 0, 2);
 
}
 

	
 

	
 
/**
 
 * Get the axis of the bridge that goes over the tile. Not the axis or the ramp.
 
 * @param t The tile to analyze
 
 * @pre IsBridgeAbove(t)
 
 * @return the above mentioned axis
 
 */
 
static inline Axis GetBridgeAxis(TileIndex t)
 
{
 
	assert(IsBridgeAbove(t));
 
	return (Axis)(GB(_m[t].m6, 6, 2) - 1);
 
}
 

	
 

	
 
/**
 
 * Get the transport type of the bridge's ramp.
 
 * @param t The ramp tile to analyze
 
 * @pre IsBridgeTile(t)
 
 * @return the transport type of the bridge
 
 */
 
static inline TransportType GetBridgeTransportType(TileIndex t)
 
{
 
	assert(IsBridgeTile(t));
 
	return (TransportType)GB(_m[t].m5, 2, 2);
 
}
 

	
 

	
 
/**
 
 * Does the bridge ramp lie in a snow or desert area?
 
 * @param t The ramp tile to analyze
 
 * @pre IsBridgeTile(t)
 
 * @return true if and only if in a snow or desert area
 
 */
 
static inline bool HasBridgeSnowOrDesert(TileIndex t)
 
{
 
	assert(IsBridgeTile(t));
 
	return HasBit(_m[t].m4, 7);
 
}
 

	
 

	
 
/**
 
 * Sets whether the bridge ramp lies in a snow or desert area.
 
 * @param t              The ramp tile to set (un)make a snow/desert area
 
 * @param snow_or_desert Make (true) or unmake the tile a snow/desert area
 
 * @pre IsBridgeTile(t)
 
 */
 
static inline void SetBridgeSnowOrDesert(TileIndex t, bool snow_or_desert)
 
{
 
	assert(IsBridgeTile(t));
 
	SB(_m[t].m4, 7, 1, snow_or_desert);
 
}
 

	
 
/**
 
 * Finds the end of a bridge in the specified direction starting at a middle tile
 
 * @param t the bridge tile to find the bridge ramp for
 
 * @param d the direction to search in
 
 */
 
TileIndex GetBridgeEnd(TileIndex t, DiagDirection d);
 

	
 
/**
 
 * Finds the northern end of a bridge starting at a middle tile
 
 * @param t the bridge tile to find the bridge ramp for
 
 */
 
TileIndex GetNorthernBridgeEnd(TileIndex t);
 
@@ -178,25 +124,24 @@ uint GetBridgeHeight(TileIndex tile);
 
/**
 
 * Remove the bridge over the given axis.
 
 * @param t the tile to remove the bridge from
 
 * @param a the axis of the bridge to remove
 
 * @pre MayHaveBridgeAbove(t)
 
 */
 
static inline void ClearSingleBridgeMiddle(TileIndex t, Axis a)
 
{
 
	assert(MayHaveBridgeAbove(t));
 
	ClrBit(_m[t].m6, 6 + a);
 
}
 

	
 

	
 
/**
 
 * Removes bridges from the given, that is bridges along the X and Y axis.
 
 * @param t the tile to remove the bridge from
 
 * @pre MayHaveBridgeAbove(t)
 
 */
 
static inline void ClearBridgeMiddle(TileIndex t)
 
{
 
	ClearSingleBridgeMiddle(t, AXIS_X);
 
	ClearSingleBridgeMiddle(t, AXIS_Y);
 
}
 

	
 
/**
src/elrail.cpp
Show inline comments
 
@@ -57,24 +57,26 @@
 
#include "debug.h"
 
#include "tunnel_map.h"
 
#include "road_map.h"
 
#include "bridge_map.h"
 
#include "bridge.h"
 
#include "rail_map.h"
 
#include "table/sprites.h"
 
#include "table/elrail_data.h"
 
#include "vehicle.h"
 
#include "train.h"
 
#include "gui.h"
 
#include "transparency.h"
 
#include "tunnelbridge_map.h"
 

	
 

	
 
static inline TLG GetTLG(TileIndex t)
 
{
 
	return (TLG)((HasBit(TileX(t), 0) << 1) + HasBit(TileY(t), 0));
 
}
 

	
 
/** Finds which Rail Bits are present on a given tile. For bridge tiles,
 
 * returns track bits under the bridge
 
 */
 
static TrackBits GetRailTrackBitsUniversal(TileIndex t, byte *override)
 
{
 
	switch (GetTileType(t)) {
 
@@ -84,32 +86,32 @@ static TrackBits GetRailTrackBitsUnivers
 
				case RAIL_TILE_NORMAL: case RAIL_TILE_SIGNALS:
 
					return GetTrackBits(t);
 
				case RAIL_TILE_WAYPOINT:
 
					return GetRailWaypointBits(t);
 
				default:
 
					return TRACK_BIT_NONE;
 
			}
 
			break;
 

	
 
		case MP_TUNNELBRIDGE:
 
			if (IsTunnel(t)) {
 
				if (GetRailType(t) != RAILTYPE_ELECTRIC) return TRACK_BIT_NONE;
 
				if (override != NULL) *override = 1 << GetTunnelDirection(t);
 
				return AxisToTrackBits(DiagDirToAxis(GetTunnelDirection(t)));
 
				if (override != NULL) *override = 1 << GetTunnelBridgeDirection(t);
 
				return AxisToTrackBits(DiagDirToAxis(GetTunnelBridgeDirection(t)));
 
			} else {
 
				if (GetRailType(t) != RAILTYPE_ELECTRIC) return TRACK_BIT_NONE;
 
				if (override != NULL && DistanceMax(t, GetOtherBridgeEnd(t)) > 1) {
 
					*override = 1 << GetBridgeRampDirection(t);
 
					*override = 1 << GetTunnelBridgeDirection(t);
 
				}
 
				return AxisToTrackBits(DiagDirToAxis(GetBridgeRampDirection(t)));
 
				return AxisToTrackBits(DiagDirToAxis(GetTunnelBridgeDirection(t)));
 
			}
 

	
 
		case MP_ROAD:
 
			if (GetRoadTileType(t) != ROAD_TILE_CROSSING) return TRACK_BIT_NONE;
 
			if (GetRailType(t) != RAILTYPE_ELECTRIC) return TRACK_BIT_NONE;
 
			return GetCrossingRailBits(t);
 

	
 
		case MP_STATION:
 
			if (!IsRailwayStation(t)) return TRACK_BIT_NONE;
 
			if (GetRailType(t) != RAILTYPE_ELECTRIC) return TRACK_BIT_NONE;
 
			if (!IsStationTileElectrifiable(t)) return TRACK_BIT_NONE;
 
			return TrackToTrackBits(GetRailStationTrack(t));
 
@@ -122,25 +124,25 @@ static TrackBits GetRailTrackBitsUnivers
 
/** Corrects the tileh for certain tile types. Returns an effective tileh for the track on the tile.
 
 * @param tile The tile to analyse
 
 * @param *tileh the tileh
 
 */
 
static void AdjustTileh(TileIndex tile, Slope *tileh)
 
{
 
	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
		if (IsTunnel(tile)) {
 
			*tileh = SLOPE_STEEP; // XXX - Hack to make tunnel entrances to always have a pylon
 
		} else if (*tileh != SLOPE_FLAT) {
 
			*tileh = SLOPE_FLAT;
 
		} else {
 
			switch (GetBridgeRampDirection(tile)) {
 
			switch (GetTunnelBridgeDirection(tile)) {
 
				case DIAGDIR_NE: *tileh = SLOPE_NE; break;
 
				case DIAGDIR_SE: *tileh = SLOPE_SE; break;
 
				case DIAGDIR_SW: *tileh = SLOPE_SW; break;
 
				case DIAGDIR_NW: *tileh = SLOPE_NW; break;
 
				default: NOT_REACHED();
 
			}
 
		}
 
	}
 
}
 

	
 
/**
 
 * Returns the Z position of a Pylon Control Point.
 
@@ -179,25 +181,25 @@ static byte GetPCPElevation(TileIndex ti
 
void DrawCatenaryOnTunnel(const TileInfo *ti)
 
{
 
	/* xmin, ymin, xmax + 1, ymax + 1 of BB */
 
	static const int _tunnel_wire_BB[4][4] = {
 
		{ 0, 1, 16, 15 }, // NE
 
		{ 1, 0, 15, 16 }, // SE
 
		{ 0, 1, 16, 15 }, // SW
 
		{ 1, 0, 15, 16 }, // NW
 
	};
 

	
 
	if ((GetRailType(ti->tile) != RAILTYPE_ELECTRIC) || _patches.disable_elrails) return;
 

	
 
	DiagDirection dir = GetTunnelDirection(ti->tile);
 
	DiagDirection dir = GetTunnelBridgeDirection(ti->tile);
 

	
 
	const SortableSpriteStruct *sss = &CatenarySpriteData_Tunnel[dir];
 
	const int *BB_data = _tunnel_wire_BB[dir];
 
	AddSortableSpriteToDraw(
 
		sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset,
 
		BB_data[2] - sss->x_offset, BB_data[3] - sss->y_offset, BB_Z_SEPARATOR - sss->z_offset + 1,
 
		GetTileZ(ti->tile) + sss->z_offset,
 
		IsTransparencySet(TO_BUILDINGS),
 
		BB_data[0] - sss->x_offset, BB_data[1] - sss->y_offset, BB_Z_SEPARATOR - sss->z_offset
 
	);
 
}
 

	
 
@@ -238,42 +240,42 @@ static void DrawCatenaryRailway(const Ti
 

	
 
	AdjustTileh(ti->tile, &tileh[TS_HOME]);
 

	
 
	for (i = DIAGDIR_NE; i < DIAGDIR_END; i++) {
 
		TileIndex neighbour = ti->tile + TileOffsByDiagDir(i);
 
		Foundation foundation = FOUNDATION_NONE;
 
		int k;
 

	
 
		/* Here's one of the main headaches. GetTileSlope does not correct for possibly
 
		 * existing foundataions, so we do have to do that manually later on.*/
 
		tileh[TS_NEIGHBOUR] = GetTileSlope(neighbour, NULL);
 
		trackconfig[TS_NEIGHBOUR] = GetRailTrackBitsUniversal(neighbour, NULL);
 
		if (IsTunnelTile(neighbour) && i != GetTunnelDirection(neighbour)) trackconfig[TS_NEIGHBOUR] = TRACK_BIT_NONE;
 
		if (IsTunnelTile(neighbour) && i != GetTunnelBridgeDirection(neighbour)) trackconfig[TS_NEIGHBOUR] = TRACK_BIT_NONE;
 

	
 
		/* If the neighboured tile does not smoothly connect to the current tile (because of a foundation),
 
		 * we have to draw all pillars on the current tile. */
 
		if (GetPCPElevation(ti->tile, i) != GetPCPElevation(neighbour, ReverseDiagDir(i))) trackconfig[TS_NEIGHBOUR] = TRACK_BIT_NONE;
 

	
 
		isflat[TS_NEIGHBOUR] = ((trackconfig[TS_NEIGHBOUR] & (TRACK_BIT_HORZ | TRACK_BIT_VERT)) != 0);
 

	
 
		PPPpreferred[i] = 0xFF; // We start with preferring everything (end-of-line in any direction)
 
		PPPallowed[i] = AllowedPPPonPCP[i];
 

	
 
		/* We cycle through all the existing tracks at a PCP and see what
 
		 * PPPs we want to have, or may not have at all */
 
		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) &&
 
			    GetBridgeRampDirection(neighbour) == ReverseDiagDir(i)) {
 
			    GetTunnelBridgeDirection(neighbour) == ReverseDiagDir(i)) {
 
				continue;
 
			}
 

	
 
			/* We check whether the track in question (k) is present in the tile
 
			 * (TrackSourceTile) */
 
			if (HasBit(trackconfig[TrackSourceTile[i][k]], TracksAtPCP[i][k])) {
 
				/* track found, if track is in the neighbour tile, adjust the number
 
				 * of the PCP for preferred/allowed determination*/
 
				DiagDirection PCPpos = (TrackSourceTile[i][k] == TS_HOME) ? i : ReverseDiagDir(i);
 
				SetBit(PCPstatus, i); // This PCP is in use
 

	
 
				PPPpreferred[i] &= PreferredPPPofTrackAtPCP[TracksAtPCP[i][k]][PCPpos];
 
@@ -282,25 +284,25 @@ static void DrawCatenaryRailway(const Ti
 
		}
 

	
 
		/* Deactivate all PPPs if PCP is not used */
 
		PPPpreferred[i] *= HasBit(PCPstatus, i);
 
		PPPallowed[i] *= HasBit(PCPstatus, i);
 

	
 
		/* A station is always "flat", so adjust the tileh accordingly */
 
		if (IsTileType(neighbour, MP_STATION)) tileh[TS_NEIGHBOUR] = SLOPE_FLAT;
 

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

	
 
		ApplyFoundationToSlope(foundation, &tileh[TS_NEIGHBOUR]);
 

	
 
	/* Half tile slopes coincide only with horizontal/vertical track.
 
	 * Faking a flat slope results in the correct sprites on positions. */
 
		if (IsHalftileSlope(tileh[TS_NEIGHBOUR])) tileh[TS_NEIGHBOUR] = SLOPE_FLAT;
 

	
 
		AdjustTileh(neighbour, &tileh[TS_NEIGHBOUR]);
 

	
 
		/* If we have a straight (and level) track, we want a pylon only every 2 tiles
 
		 * Delete the PCP if this is the case. */
 
@@ -434,25 +436,25 @@ static void DrawCatenaryOnBridge(const T
 
		uint y = ti->y + y_pcp_offsets[PCPpos] + y_ppp_offsets[PPPpos];
 
		AddSortableSpriteToDraw(pylon_sprites[PPPpos], PAL_NONE, x, y, 1, 1, BB_HEIGHT_UNDER_BRIDGE, height, IsTransparencySet(TO_BUILDINGS), -1, -1);
 
	}
 
}
 

	
 
void DrawCatenary(const TileInfo *ti)
 
{
 
	if (_patches.disable_elrails) return;
 

	
 
	if (MayHaveBridgeAbove(ti->tile) && IsBridgeAbove(ti->tile)) {
 
		TileIndex head = GetNorthernBridgeEnd(ti->tile);
 

	
 
		if (GetBridgeTransportType(head) == TRANSPORT_RAIL && GetRailType(head) == RAILTYPE_ELECTRIC) {
 
		if (GetTunnelBridgeTransportType(head) == TRANSPORT_RAIL && GetRailType(head) == RAILTYPE_ELECTRIC) {
 
			DrawCatenaryOnBridge(ti);
 
		}
 
	}
 

	
 
	switch (GetTileType(ti->tile)) {
 
		case MP_RAILWAY:
 
			if (IsRailDepot(ti->tile)) {
 
				const SortableSpriteStruct *sss = &CatenarySpriteData_Depot[GetRailDepotDirection(ti->tile)];
 

	
 
				/* This wire is not visible with the default depot sprites */
 
				AddSortableSpriteToDraw(
 
					sss->image, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset,
src/npf.cpp
Show inline comments
 
@@ -10,24 +10,25 @@
 
#include "landscape.h"
 
#include "npf.h"
 
#include "aystar.h"
 
#include "macros.h"
 
#include "pathfind.h"
 
#include "station.h"
 
#include "station_map.h"
 
#include "tile.h"
 
#include "depot.h"
 
#include "tunnel_map.h"
 
#include "network/network.h"
 
#include "water_map.h"
 
#include "tunnelbridge_map.h"
 

	
 
static AyStar _npf_aystar;
 

	
 
/* The cost of each trackdir. A diagonal piece is the full NPF_TILE_LENGTH,
 
 * the shorter piece is sqrt(2)/2*NPF_TILE_LENGTH =~ 0.7071
 
 */
 
#define NPF_STRAIGHT_LENGTH (uint)(NPF_TILE_LENGTH * STRAIGHT_TRACK_LENGTH)
 
static const uint _trackdir_length[TRACKDIR_END] = {
 
	NPF_TILE_LENGTH, NPF_TILE_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH,
 
	0, 0,
 
	NPF_TILE_LENGTH, NPF_TILE_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH, NPF_STRAIGHT_LENGTH
 
};
 
@@ -161,25 +162,25 @@ static void NPFFillTrackdirChoice(AyStar
 
		/* We've already made the decision, so just save our parent's decision */
 
		current->user_data[NPF_TRACKDIR_CHOICE] = parent->path.node.user_data[NPF_TRACKDIR_CHOICE];
 
	}
 
}
 

	
 
/* Will return the cost of the tunnel. If it is an entry, it will return the
 
 * cost of that tile. If the tile is an exit, it will return the tunnel length
 
 * including the exit tile. Requires that this is a Tunnel tile */
 
static uint NPFTunnelCost(AyStarNode* current)
 
{
 
	DiagDirection exitdir = TrackdirToExitdir((Trackdir)current->direction);
 
	TileIndex tile = current->tile;
 
	if (GetTunnelDirection(tile) == ReverseDiagDir(exitdir)) {
 
	if (GetTunnelBridgeDirection(tile) == ReverseDiagDir(exitdir)) {
 
		/* We just popped out if this tunnel, since were
 
		 * facing the tunnel exit */
 
		FindLengthOfTunnelResult flotr;
 
		flotr = FindLengthOfTunnel(tile, ReverseDiagDir(exitdir));
 
		return flotr.length * NPF_TILE_LENGTH;
 
		/* @todo: Penalty for tunnels? */
 
	} else {
 
		/* We are entering the tunnel, the enter tile is just a
 
		 * straight track */
 
		return NPF_TILE_LENGTH;
 
	}
 
}
 
@@ -471,26 +472,26 @@ static bool VehicleMayEnterTile(Owner ow
 
	}
 

	
 
	switch (GetTileType(tile)) {
 
		case MP_ROAD:
 
			/* rail-road crossing : are we looking at the railway part? */
 
			if (IsLevelCrossing(tile) &&
 
					DiagDirToAxis(enterdir) != GetCrossingRoadAxis(tile)) {
 
				return IsTileOwner(tile, owner); /* Railway needs owner check, while the street is public */
 
			}
 
			break;
 

	
 
		case MP_TUNNELBRIDGE:
 
			if ((IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_RAIL) ||
 
					(IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL)) {
 
			if ((IsTunnel(tile) && GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) ||
 
					(IsBridge(tile) && GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL)) {
 
				return IsTileOwner(tile, owner);
 
			}
 
			break;
 

	
 
		default:
 
			break;
 
	}
 

	
 
	return true; // no need to check
 
}
 

	
 

	
 
@@ -524,31 +525,31 @@ static void NPFFollowTrack(AyStar* aysta
 
	TileIndex dst_tile = INVALID_TILE;
 
	int i;
 
	uint32 ts;
 
	TrackdirBits trackdirbits;
 
	TransportType type = (TransportType)aystar->user_data[NPF_TYPE];
 
	uint subtype = aystar->user_data[NPF_SUB_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);
 

	
 
	/* Find dest tile */
 
	if (IsTunnelTile(src_tile) && GetTunnelDirection(src_tile) == src_exitdir) {
 
	if (IsTunnelTile(src_tile) && GetTunnelBridgeDirection(src_tile) == src_exitdir) {
 
		/* This is a tunnel. We know this tunnel is our type,
 
		 * 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) {
 
	} else if (IsBridgeTile(src_tile) && GetTunnelBridgeDirection(src_tile) == src_exitdir) {
 
		dst_tile = GetOtherBridgeEnd(src_tile);
 
		override_dst_check = true;
 
	} else if (type != TRANSPORT_WATER && (IsStandardRoadStopTile(src_tile) || IsTileDepotType(src_tile, type))) {
 
		/* This is a road station (non drive-through) 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
 
		 * do this here. */
 

	
 
		DiagDirection exitdir;
 
		/* Find out the exit direction first */
 
		if (IsRoadStopTile(src_tile)) {
 
			exitdir = GetRoadStopDir(src_tile);
 
		} else { // Train or road depot
 
@@ -583,27 +584,27 @@ static void NPFFollowTrack(AyStar* aysta
 
	if (dst_tile == INVALID_TILE) {
 
		/* We reached the border of the map */
 
		/* TODO Nicer control flow for this */
 
		return;
 
	}
 

	
 
	/* 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 (!override_dst_check) {
 
		if (IsTileType(dst_tile, MP_TUNNELBRIDGE)) {
 
			if (IsTunnel(dst_tile)) {
 
				if (GetTunnelDirection(dst_tile) != src_exitdir) return;
 
				if (GetTunnelBridgeDirection(dst_tile) != src_exitdir) return;
 
			} else {
 
				if (GetBridgeRampDirection(dst_tile) != src_exitdir) return;
 
				if (GetTunnelBridgeDirection(dst_tile) != src_exitdir) return;
 
			}
 
		}
 
	}
 

	
 
	/* check correct rail type (mono, maglev, etc) */
 
	if (type == TRANSPORT_RAIL) {
 
		RailType dst_type = GetTileRailType(dst_tile);
 
		if (!HasBit(aystar->user_data[NPF_RAILTYPES], dst_type))
 
			return;
 
	}
 

	
 
	/* Check the owner of the tile */
src/openttd.cpp
Show inline comments
 
@@ -68,24 +68,25 @@
 
#include "sound/sound_driver.hpp"
 
#include "music/music_driver.hpp"
 
#include "video/video_driver.hpp"
 

	
 
#include "bridge_map.h"
 
#include "clear_map.h"
 
#include "rail_map.h"
 
#include "road_map.h"
 
#include "water_map.h"
 
#include "industry_map.h"
 
#include "unmovable_map.h"
 
#include "tree_map.h"
 
#include "tunnelbridge_map.h"
 

	
 
#include <stdarg.h>
 

	
 
void CallLandscapeTick();
 
void IncreaseDate();
 
void DoPaletteAnimations();
 
void MusicLoop();
 
void ResetMusic();
 

	
 
extern void SetDifficultyLevel(int mode, GameOptions *gm_opt);
 
extern Player* DoStartupNewPlayer(bool is_ai);
 
extern void ShowOSErrorBox(const char *buf);
 
@@ -1630,25 +1631,25 @@ bool AfterLoadGame()
 
						case ROAD_TILE_DEPOT:    break;
 
					}
 
					SetRoadTypes(t, ROADTYPES_ROAD);
 
					break;
 

	
 
				case MP_STATION:
 
					if (IsRoadStop(t)) SetRoadTypes(t, ROADTYPES_ROAD);
 
					break;
 

	
 
				case MP_TUNNELBRIDGE:
 
					/* Middle part of "old" bridges */
 
					if (old_bridge && IsBridgeTile(t) && HasBit(_m[t].m5, 6)) break;
 
					if ((IsTunnel(t) ? GetTunnelTransportType(t) : (old_bridge ? (TransportType)GB(_m[t].m5, 1, 2) : GetBridgeTransportType(t))) == TRANSPORT_ROAD) {
 
					if ((IsTunnel(t) ? GetTunnelBridgeTransportType(t) : (old_bridge ? (TransportType)GB(_m[t].m5, 1, 2) : GetTunnelBridgeTransportType(t))) == TRANSPORT_ROAD) {
 
						SetRoadTypes(t, ROADTYPES_ROAD);
 
					}
 
					break;
 

	
 
				default: break;
 
			}
 
		}
 
	}
 

	
 
	if (CheckSavegameVersion(42)) {
 
		Vehicle* v;
 

	
 
@@ -1690,25 +1691,25 @@ bool AfterLoadGame()
 
					uint north_south = GB(_m[t].m5, 5, 1);
 
					DiagDirection dir = ReverseDiagDir(XYNSToDiagDir(axis, north_south));
 
					TransportType type = (TransportType)GB(_m[t].m5, 1, 2);
 

	
 
					_m[t].m5 = 1 << 7 | type << 2 | dir;
 
				}
 
			}
 
		}
 

	
 
		FOR_ALL_VEHICLES(v) {
 
			if (v->type != VEH_TRAIN && v->type != VEH_ROAD) continue;
 
			if (IsBridgeTile(v->tile)) {
 
				DiagDirection dir = GetBridgeRampDirection(v->tile);
 
				DiagDirection dir = GetTunnelBridgeDirection(v->tile);
 

	
 
				if (dir != DirToDiagDir(v->direction)) continue;
 
				switch (dir) {
 
					default: NOT_REACHED();
 
					case DIAGDIR_NE: if ((v->x_pos & 0xF) !=  0)            continue; break;
 
					case DIAGDIR_SE: if ((v->y_pos & 0xF) != TILE_SIZE - 1) continue; break;
 
					case DIAGDIR_SW: if ((v->x_pos & 0xF) != TILE_SIZE - 1) continue; break;
 
					case DIAGDIR_NW: if ((v->y_pos & 0xF) !=  0)            continue; break;
 
				}
 
			} else if (v->z_pos > GetSlopeZ(v->x_pos, v->y_pos)) {
 
				v->tile = GetNorthernBridgeEnd(v->tile);
 
			} else {
 
@@ -1748,29 +1749,29 @@ bool AfterLoadGame()
 
						SetRailType(t, UpdateRailType(GetRailType(t), min_rail));
 
					}
 
					break;
 

	
 
				case MP_STATION:
 
					if (IsRailwayStation(t)) {
 
						SetRailType(t, UpdateRailType(GetRailType(t), min_rail));
 
					}
 
					break;
 

	
 
				case MP_TUNNELBRIDGE:
 
					if (IsTunnel(t)) {
 
						if (GetTunnelTransportType(t) == TRANSPORT_RAIL) {
 
						if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) {
 
							SetRailType(t, UpdateRailType(GetRailType(t), min_rail));
 
						}
 
					} else {
 
						if (GetBridgeTransportType(t) == TRANSPORT_RAIL) {
 
						if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) {
 
							SetRailType(t, UpdateRailType(GetRailType(t), min_rail));
 
						}
 
					}
 
					break;
 

	
 
				default:
 
					break;
 
			}
 
		}
 

	
 
		FOR_ALL_VEHICLES(v) {
 
			if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) TrainConsistChanged(v);
src/pathfind.cpp
Show inline comments
 
@@ -8,24 +8,25 @@
 
#include "station_map.h"
 
#include "depot.h"
 
#include "functions.h"
 
#include "landscape.h"
 
#include "map.h"
 
#include "tile.h"
 
#include "pathfind.h"
 
#include "rail.h"
 
#include "debug.h"
 
#include "tunnel_map.h"
 
#include "variables.h"
 
#include "depot.h"
 
#include "tunnelbridge_map.h"
 

	
 
/* remember which tiles we have already visited so we don't visit them again. */
 
static bool TPFSetTileBit(TrackPathFinder *tpf, TileIndex tile, int dir)
 
{
 
	uint hash, val, offs;
 
	TrackPathFinderLink *link, *new_link;
 
	uint bits = 1 << dir;
 

	
 
	if (tpf->disable_tile_hash)
 
		return true;
 

	
 
	hash = PATHFIND_HASH_TILE(tile);
 
@@ -201,25 +202,25 @@ FindLengthOfTunnelResult FindLengthOfTun
 
	TileIndexDiff delta = TileOffsByDiagDir(dir);
 
	uint z = GetTileZ(tile);
 
	FindLengthOfTunnelResult flotr;
 

	
 
	flotr.length = 0;
 

	
 
	dir = ReverseDiagDir(dir);
 
	do {
 
		flotr.length++;
 
		tile += delta;
 
	} while(
 
		!IsTunnelTile(tile) ||
 
		GetTunnelDirection(tile) != dir ||
 
		GetTunnelBridgeDirection(tile) != dir ||
 
		GetTileZ(tile) != z
 
	);
 

	
 
	flotr.tile = tile;
 
	return flotr;
 
}
 

	
 
static const uint16 _tpfmode1_and[4] = { 0x1009, 0x16, 0x520, 0x2A00 };
 

	
 
static uint SkipToEndOfTunnel(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction)
 
{
 
	FindLengthOfTunnelResult flotr;
 
@@ -251,31 +252,31 @@ static inline void TPFMode1_NormalCase(T
 
	if (tpf->tracktype == TRANSPORT_ROAD) {
 
		/* road stops and depots now have a track (r4419)
 
		 * don't enter road stop from the back */
 
		if (IsStandardRoadStopTile(tile) && ReverseDiagDir(GetRoadStopDir(tile)) != direction) return;
 
		/* don't enter road depot from the back */
 
		if (IsTileDepotType(tile, TRANSPORT_ROAD) && ReverseDiagDir(GetRoadDepotDirection(tile)) != direction) return;
 
	}
 

	
 
	/* Check if the new tile is a tunnel or bridge head and that the direction
 
	 * and transport type match */
 
	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
		if (IsTunnel(tile)) {
 
			if (GetTunnelDirection(tile) != direction ||
 
					GetTunnelTransportType(tile) != tpf->tracktype) {
 
			if (GetTunnelBridgeDirection(tile) != direction ||
 
					GetTunnelBridgeTransportType(tile) != tpf->tracktype) {
 
				return;
 
			}
 
		} else if (IsBridge(tile)) {
 
			if (GetBridgeRampDirection(tile) != direction ||
 
					GetBridgeTransportType(tile) != tpf->tracktype) {
 
			if (GetTunnelBridgeDirection(tile) != direction ||
 
					GetTunnelBridgeTransportType(tile) != tpf->tracktype) {
 
				return;
 
			}
 
		}
 
	}
 

	
 
	tpf->rd.cur_length++;
 

	
 
	uint bits = GetTileTrackStatus(tile, tpf->tracktype, tpf->sub_type);
 

	
 
	if ((byte)bits != tpf->var2) {
 
		bits &= _tpfmode1_and[direction];
 
		bits |= bits >> 8;
 
@@ -298,41 +299,41 @@ static inline void TPFMode1_NormalCase(T
 
				tpf->rd = rd;
 
			} while (bits != 0);
 
		}
 
	}
 
}
 

	
 
static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection direction)
 
{
 
	TileIndex tile_org = tile;
 

	
 
	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
		if (IsTunnel(tile)) {
 
			if (GetTunnelTransportType(tile) != tpf->tracktype) {
 
			if (GetTunnelBridgeTransportType(tile) != tpf->tracktype) {
 
				return;
 
			}
 
			/* Only skip through the tunnel if heading inwards. We can
 
			 * be headed outwards if our starting position was in a
 
			 * tunnel and we're pathfinding backwards */
 
			if (GetTunnelDirection(tile) == direction) {
 
			if (GetTunnelBridgeDirection(tile) == direction) {
 
				tile = SkipToEndOfTunnel(tpf, tile, direction);
 
			} else if (GetTunnelDirection(tile) != ReverseDiagDir(direction)) {
 
			} else if (GetTunnelBridgeDirection(tile) != ReverseDiagDir(direction)) {
 
				/* We don't support moving through the sides of a tunnel
 
				 * entrance :-) */
 
				return;
 
			}
 
		} else {
 
			TileIndex tile_end;
 
			if (GetBridgeRampDirection(tile) != direction ||
 
					GetBridgeTransportType(tile) != tpf->tracktype) {
 
			if (GetTunnelBridgeDirection(tile) != direction ||
 
					GetTunnelBridgeTransportType(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 += TileOffsByDiagDir(direction);
 
@@ -713,48 +714,48 @@ static void NTPEnum(NewTrackPathFinder* 
 
callback_and_continue:
 
		if (tpf->enum_proc(tile, tpf->userdata, si.first_track, si.cur_length))
 
			return;
 

	
 
		assert(si.track <= 13);
 
		direction = _tpf_new_direction[si.track];
 

	
 
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 (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
			if (IsTunnel(tile)) {
 
				if (GetTunnelDirection(tile) != ReverseDiagDir(direction)) {
 
				if (GetTunnelBridgeDirection(tile) != ReverseDiagDir(direction)) {
 
					FindLengthOfTunnelResult flotr;
 

	
 
					/* We are not just driving out of the tunnel */
 
					if (GetTunnelDirection(tile) != direction ||
 
							GetTunnelTransportType(tile) != tpf->tracktype) {
 
					if (GetTunnelBridgeDirection(tile) != direction ||
 
							GetTunnelBridgeTransportType(tile) != tpf->tracktype) {
 
						/* We are not driving into the tunnel, or it is an invalid tunnel */
 
						continue;
 
					}
 
					if (!HasBit(tpf->railtypes, GetRailType(tile))) {
 
						bits = TRACK_BIT_NONE;
 
						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)) {
 
				if (GetTunnelBridgeDirection(tile) != ReverseDiagDir(direction)) {
 
					/* We are not just leaving the bridge */
 
					if (GetBridgeRampDirection(tile) != direction ||
 
							GetBridgeTransportType(tile) != tpf->tracktype) {
 
					if (GetTunnelBridgeDirection(tile) != direction ||
 
							GetTunnelBridgeTransportType(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;
 
			}
 
		}
 

	
 
		/* This is a special loop used to go through
 
		 * a rail net and find the first intersection */
src/rail.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file rail.cpp */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
#include "rail.h"
 
#include "station_map.h"
 
#include "tunnel_map.h"
 
#include "tunnelbridge_map.h"
 

	
 

	
 
/* XXX: Below 3 tables store duplicate data. Maybe remove some? */
 
/* Maps a trackdir to the bit that stores its status in the map arrays, in the
 
 * direction along with the trackdir */
 
extern const byte _signal_along_trackdir[] = {
 
	0x8, 0x8, 0x8, 0x2, 0x4, 0x1, 0, 0,
 
	0x4, 0x4, 0x4, 0x1, 0x8, 0x2
 
};
 

	
 
/* Maps a trackdir to the bit that stores its status in the map arrays, in the
 
 * direction against the trackdir */
 
extern const byte _signal_against_trackdir[] = {
 
@@ -122,23 +124,23 @@ RailType GetTileRailType(TileIndex tile)
 

	
 
		case MP_ROAD:
 
			/* rail/road crossing */
 
			if (IsLevelCrossing(tile)) return GetRailType(tile);
 
			break;
 

	
 
		case MP_STATION:
 
			if (IsRailwayStationTile(tile)) return GetRailType(tile);
 
			break;
 

	
 
		case MP_TUNNELBRIDGE:
 
			if (IsTunnel(tile)) {
 
				if (GetTunnelTransportType(tile) == TRANSPORT_RAIL) return GetRailType(tile);
 
				if (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) return GetRailType(tile);
 
			} else {
 
				if (GetBridgeTransportType(tile) == TRANSPORT_RAIL) return GetRailType(tile);
 
				if (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) return GetRailType(tile);
 
			}
 
			break;
 

	
 
		default:
 
			break;
 
	}
 
	return INVALID_RAILTYPE;
 
}
src/rail_cmd.cpp
Show inline comments
 
@@ -33,24 +33,26 @@
 
#include "rail.h"
 
#include "railtypes.h" // include table for railtypes
 
#include "newgrf.h"
 
#include "yapf/yapf.h"
 
#include "newgrf_engine.h"
 
#include "newgrf_callbacks.h"
 
#include "newgrf_station.h"
 
#include "train.h"
 
#include "misc/autoptr.hpp"
 
#include "autoslope.h"
 
#include "transparency.h"
 
#include "water.h"
 
#include "tunnelbridge_map.h"
 

	
 

	
 
const byte _track_sloped_sprites[14] = {
 
	14, 15, 22, 13,
 
	 0, 21, 17, 12,
 
	23,  0, 18, 20,
 
	19, 16
 
};
 

	
 

	
 
/*         4
 
 *     ---------
 
 *    |\       /|
 
@@ -918,30 +920,30 @@ static bool CheckSignalAutoFill(TileInde
 
			}
 
			return true;
 

	
 
		case MP_ROAD:
 
			if (!IsLevelCrossing(tile)) return false;
 
			signal_ctr += 2;
 
			return true;
 

	
 
		case MP_TUNNELBRIDGE: {
 
			TileIndex orig_tile = tile;
 
			/* Skip to end of tunnel or bridge */
 
			if (IsBridge(tile)) {
 
				if (GetBridgeTransportType(tile) != TRANSPORT_RAIL) return false;
 
				if (GetBridgeRampDirection(tile) != TrackdirToExitdir(trackdir)) return false;
 
				if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) return false;
 
				if (GetTunnelBridgeDirection(tile) != TrackdirToExitdir(trackdir)) return false;
 
				tile = GetOtherBridgeEnd(tile);
 
			} else {
 
				if (GetTunnelTransportType(tile) != TRANSPORT_RAIL) return false;
 
				if (GetTunnelDirection(tile) != TrackdirToExitdir(trackdir)) return false;
 
				if (GetTunnelBridgeTransportType(tile) != TRANSPORT_RAIL) return false;
 
				if (GetTunnelBridgeDirection(tile) != TrackdirToExitdir(trackdir)) return false;
 
				tile = GetOtherTunnelEnd(tile);
 
			}
 
			signal_ctr += 2 + DistanceMax(orig_tile, tile) * 2;
 
			return true;
 
		}
 

	
 
		default: return false;
 
	}
 
}
 

	
 
/** Build many signals by dragging; AutoSignals
 
 * @param tile start tile of drag
src/rail_gui.cpp
Show inline comments
 
@@ -23,24 +23,26 @@
 
#include "waypoint.h"
 
#include "debug.h"
 
#include "variables.h"
 
#include "newgrf_callbacks.h"
 
#include "newgrf_station.h"
 
#include "train.h"
 

	
 
#include "bridge_map.h"
 
#include "rail_map.h"
 
#include "road_map.h"
 
#include "station_map.h"
 
#include "tunnel_map.h"
 
#include "tunnelbridge_map.h"
 

	
 

	
 
static RailType _cur_railtype;
 
static bool _remove_button_clicked;
 
static DiagDirection _build_depot_direction;
 
static byte _waypoint_count = 1;
 
static byte _cur_waypoint_type;
 
static bool _convert_signal_button; // convert signal button in the signal GUI pressed
 
static SignalVariant _cur_signal_variant; // set the signal variant (for signal GUI)
 
static SignalType _cur_signal_type; // set the signal type (for signal GUI)
 

	
 
static struct {
 
	byte orientation;
 
@@ -1514,26 +1516,26 @@ void SetDefaultRailGui()
 

	
 
	extern RailType _last_built_railtype;
 
	RailType rt = (RailType)_patches.default_rail_type;
 
	if (rt >= RAILTYPE_END) {
 
		if (rt == RAILTYPE_END + 2) {
 
			/* Find the most used rail type */
 
			RailType count[RAILTYPE_END];
 
			memset(count, 0, sizeof(count));
 
			for (TileIndex t = 0; t < MapSize(); t++) {
 
				if (IsTileType(t, MP_RAILWAY) ||
 
						IsLevelCrossingTile(t) ||
 
						IsRailwayStationTile(t) ||
 
						(IsTunnelTile(t) && GetTunnelTransportType(t) == TRANSPORT_RAIL) ||
 
						(IsBridgeTile(t) && GetBridgeTransportType(t) == TRANSPORT_RAIL)
 
						(IsTunnelTile(t) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) ||
 
						(IsBridgeTile(t) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL)
 
						) {
 
					count[GetRailType(t)]++;
 
				}
 
			}
 

	
 
			rt = RAILTYPE_RAIL;
 
			for (RailType r = RAILTYPE_ELECTRIC; r < RAILTYPE_END; r++) {
 
				if (count[r] >= count[rt]) rt = r;
 
			}
 

	
 
			/* No rail, just get the first available one */
 
			if (count[rt] == 0) rt = RAILTYPE_END;
src/road_cmd.cpp
Show inline comments
 
@@ -25,24 +25,26 @@
 
#include "player.h"
 
#include "town.h"
 
#include "gfx.h"
 
#include "sound.h"
 
#include "yapf/yapf.h"
 
#include "depot.h"
 
#include "newgrf.h"
 
#include "station_map.h"
 
#include "tunnel_map.h"
 
#include "misc/autoptr.hpp"
 
#include "autoslope.h"
 
#include "transparency.h"
 
#include "tunnelbridge_map.h"
 

	
 

	
 
#define M(x) (1 << (x))
 
/* Level crossings may only be built on these slopes */
 
static const uint32 VALID_LEVEL_CROSSING_SLOPES = (M(SLOPE_SEN) | M(SLOPE_ENW) | M(SLOPE_NWS) | M(SLOPE_NS) | M(SLOPE_WSE) | M(SLOPE_EW) | M(SLOPE_FLAT));
 
#undef M
 

	
 
bool CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, bool *edge_road, RoadType rt)
 
{
 
	RoadBits present;
 
	RoadBits n;
 
	*edge_road = true;
 

	
 
@@ -124,28 +126,28 @@ CommandCost CmdRemoveRoad(TileIndex tile
 
			if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
 
			break;
 

	
 
		case MP_STATION:
 
			if (!IsDriveThroughStopTile(tile)) return CMD_ERROR;
 
			if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
 
			break;
 

	
 
		case MP_TUNNELBRIDGE:
 
			{
 
				TileIndex endtile;
 
				if (IsTunnel(tile)) {
 
					if (GetTunnelTransportType(tile) != TRANSPORT_ROAD) return CMD_ERROR;
 
					if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) return CMD_ERROR;
 
					endtile = GetOtherTunnelEnd(tile);
 
				} else {
 
					if (GetBridgeTransportType(tile) != TRANSPORT_ROAD) return CMD_ERROR;
 
					if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) return CMD_ERROR;
 
					endtile = GetOtherBridgeEnd(tile);
 
				}
 

	
 
				if (GetVehicleTunnelBridge(tile, endtile) != NULL) return CMD_ERROR;
 
			} break;
 

	
 
		default:
 
			return CMD_ERROR;
 
	}
 

	
 
	RoadBits pieces = Extract<RoadBits, 0>(p1);
 
	RoadTypes rts = GetRoadTypes(tile);
 
@@ -166,25 +168,25 @@ CommandCost CmdRemoveRoad(TileIndex tile
 
		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
			TileIndex other_end = IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile);
 
			/* Pay for *every* tile of the bridge or tunnel */
 
			cost.AddCost((DistanceManhattan(IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile), tile) + 1) * _price.remove_road);
 
			if (flags & DC_EXEC) {
 
				SetRoadTypes(other_end, GetRoadTypes(other_end) & ~RoadTypeToRoadTypes(rt));
 
				SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt));
 

	
 
				/* Mark tiles diry that have been repaved */
 
				MarkTileDirtyByTile(tile);
 
				MarkTileDirtyByTile(other_end);
 
				if (IsBridge(tile)) {
 
					TileIndexDiff delta = TileOffsByDiagDir(GetBridgeRampDirection(tile));
 
					TileIndexDiff delta = TileOffsByDiagDir(GetTunnelBridgeDirection(tile));
 

	
 
					for (TileIndex t = tile + delta; t != other_end; t += delta) MarkTileDirtyByTile(t);
 
				}
 
			}
 
		} else {
 
			cost.AddCost(_price.remove_road);
 
			if (flags & DC_EXEC) {
 
				SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt));
 
				MarkTileDirtyByTile(tile);
 
			}
 
		}
 
		return CommandCost(cost);
 
@@ -505,28 +507,28 @@ CommandCost CmdBuildRoad(TileIndex tile,
 

	
 
		case MP_STATION:
 
			if (!IsDriveThroughStopTile(tile)) return CMD_ERROR;
 
			if (HasBit(GetRoadTypes(tile), rt)) return_cmd_error(STR_1007_ALREADY_BUILT);
 
			/* Don't allow "upgrading" the roadstop when vehicles are already driving on it */
 
			if (!EnsureNoVehicleOnGround(tile)) return CMD_ERROR;
 
			break;
 

	
 
		case MP_TUNNELBRIDGE:
 
			{
 
				TileIndex endtile;
 
				if (IsTunnel(tile)) {
 
					if (GetTunnelTransportType(tile) != TRANSPORT_ROAD) return CMD_ERROR;
 
					if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) return CMD_ERROR;
 
					endtile = GetOtherTunnelEnd(tile);
 
				} else {
 
					if (GetBridgeTransportType(tile) != TRANSPORT_ROAD) return CMD_ERROR;
 
					if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) return CMD_ERROR;
 
					endtile = GetOtherBridgeEnd(tile);
 
				}
 
				if (HasBit(GetRoadTypes(tile), rt)) return_cmd_error(STR_1007_ALREADY_BUILT);
 
				/* Don't allow "upgrading" the bridge/tunnel when vehicles are already driving on it */
 
				if (GetVehicleTunnelBridge(tile, endtile) != NULL) return CMD_ERROR;
 
			} break;
 

	
 
		default:
 
do_clear:;
 
			ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
			if (CmdFailed(ret)) return ret;
 
			cost.AddCost(ret);
 
@@ -567,25 +569,25 @@ do_clear:;
 
			} break;
 

	
 
			case MP_TUNNELBRIDGE: {
 
				TileIndex other_end = IsTunnel(tile) ? GetOtherTunnelEnd(tile) : GetOtherBridgeEnd(tile);
 

	
 
				SetRoadTypes(other_end, GetRoadTypes(other_end) | RoadTypeToRoadTypes(rt));
 
				SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt));
 

	
 
				/* Mark tiles diry that have been repaved */
 
				MarkTileDirtyByTile(other_end);
 
				MarkTileDirtyByTile(tile);
 
				if (IsBridge(tile)) {
 
					TileIndexDiff delta = TileOffsByDiagDir(GetBridgeRampDirection(tile));
 
					TileIndexDiff delta = TileOffsByDiagDir(GetTunnelBridgeDirection(tile));
 

	
 
					for (TileIndex t = tile + delta; t != other_end; t += delta) MarkTileDirtyByTile(t);
 
				}
 
			} break;
 

	
 
			case MP_STATION:
 
				SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt));
 
				break;
 

	
 
			default:
 
				MakeRoadNormal(tile, pieces, RoadTypeToRoadTypes(rt), p2, _current_player, _current_player, _current_player);
 
				break;
 
@@ -682,30 +684,30 @@ CommandCost CmdBuildLongRoad(TileIndex e
 
		if (tile == end_tile && !HasBit(p2, 1)) bits &= ROAD_NW | ROAD_NE;
 
		if (tile == start_tile && HasBit(p2, 0)) bits &= ROAD_SE | ROAD_SW;
 

	
 
		ret = DoCommand(tile, drd << 6 | rt << 4 | bits, 0, flags, CMD_BUILD_ROAD);
 
		if (CmdFailed(ret)) {
 
			if (_error_message != STR_1007_ALREADY_BUILT) return CMD_ERROR;
 
			_error_message = INVALID_STRING_ID;
 
		} else {
 
			had_success = true;
 
			/* Only pay for the upgrade on one side of the bridges and tunnels */
 
			if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
				if (IsBridge(tile)) {
 
					if ((!had_bridge || GetBridgeRampDirection(tile) == DIAGDIR_SE || GetBridgeRampDirection(tile) == DIAGDIR_SW)) {
 
					if ((!had_bridge || GetTunnelBridgeDirection(tile) == DIAGDIR_SE || GetTunnelBridgeDirection(tile) == DIAGDIR_SW)) {
 
						cost.AddCost(ret);
 
					}
 
					had_bridge = true;
 
				} else {
 
					if ((!had_tunnel || GetTunnelDirection(tile) == DIAGDIR_SE || GetTunnelDirection(tile) == DIAGDIR_SW)) {
 
					if ((!had_tunnel || GetTunnelBridgeDirection(tile) == DIAGDIR_SE || GetTunnelBridgeDirection(tile) == DIAGDIR_SW)) {
 
						cost.AddCost(ret);
 
					}
 
					had_tunnel = true;
 
				}
 
			} else {
 
				cost.AddCost(ret);
 
			}
 
		}
 

	
 
		if (tile == end_tile) break;
 

	
 
		tile += HasBit(p2, 2) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
src/road_map.cpp
Show inline comments
 
@@ -3,51 +3,52 @@
 
/** @file road_map.cpp */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
#include "functions.h"
 
#include "landscape.h"
 
#include "road_map.h"
 
#include "station.h"
 
#include "tunnel_map.h"
 
#include "station_map.h"
 
#include "depot.h"
 
#include "tunnelbridge_map.h"
 

	
 

	
 
RoadBits GetAnyRoadBits(TileIndex tile, RoadType rt)
 
{
 
	if (!HasBit(GetRoadTypes(tile), rt)) return ROAD_NONE;
 

	
 
	switch (GetTileType(tile)) {
 
		case MP_ROAD:
 
			switch (GetRoadTileType(tile)) {
 
				default:
 
				case ROAD_TILE_NORMAL:   return GetRoadBits(tile, rt);
 
				case ROAD_TILE_CROSSING: return GetCrossingRoadBits(tile);
 
				case ROAD_TILE_DEPOT:    return DiagDirToRoadBits(GetRoadDepotDirection(tile));
 
			}
 

	
 
		case MP_STATION:
 
			if (!IsRoadStopTile(tile)) return ROAD_NONE;
 
			if (IsDriveThroughStopTile(tile)) return (GetRoadStopDir(tile) == DIAGDIR_NE) ? ROAD_X : ROAD_Y;
 
			return DiagDirToRoadBits(GetRoadStopDir(tile));
 

	
 
		case MP_TUNNELBRIDGE:
 
			if (IsTunnel(tile)) {
 
				if (GetTunnelTransportType(tile) != TRANSPORT_ROAD) return ROAD_NONE;
 
				return DiagDirToRoadBits(ReverseDiagDir(GetTunnelDirection(tile)));
 
				if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) return ROAD_NONE;
 
				return DiagDirToRoadBits(ReverseDiagDir(GetTunnelBridgeDirection(tile)));
 
			} else {
 
				if (GetBridgeTransportType(tile) != TRANSPORT_ROAD) return ROAD_NONE;
 
				return DiagDirToRoadBits(ReverseDiagDir(GetBridgeRampDirection(tile)));
 
				if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) return ROAD_NONE;
 
				return DiagDirToRoadBits(ReverseDiagDir(GetTunnelBridgeDirection(tile)));
 
			}
 

	
 
		default: return ROAD_NONE;
 
	}
 
}
 

	
 

	
 
TrackBits GetAnyRoadTrackBits(TileIndex tile, RoadType rt)
 
{
 
	uint32 r;
 

	
 
	/* Don't allow local authorities to build roads through road depots or road stops. */
src/roadveh_cmd.cpp
Show inline comments
 
@@ -28,24 +28,26 @@
 
#include "bridge.h"
 
#include "tunnel_map.h"
 
#include "bridge_map.h"
 
#include "vehicle_gui.h"
 
#include "articulated_vehicles.h"
 
#include "newgrf_callbacks.h"
 
#include "newgrf_engine.h"
 
#include "newgrf_text.h"
 
#include "newgrf_sound.h"
 
#include "yapf/yapf.h"
 
#include "date.h"
 
#include "cargotype.h"
 
#include "tunnelbridge_map.h"
 

	
 

	
 
static const uint16 _roadveh_images[63] = {
 
	0xCD4, 0xCDC, 0xCE4, 0xCEC, 0xCF4, 0xCFC, 0xD0C, 0xD14,
 
	0xD24, 0xD1C, 0xD2C, 0xD04, 0xD1C, 0xD24, 0xD6C, 0xD74,
 
	0xD7C, 0xC14, 0xC1C, 0xC24, 0xC2C, 0xC34, 0xC3C, 0xC4C,
 
	0xC54, 0xC64, 0xC5C, 0xC6C, 0xC44, 0xC5C, 0xC64, 0xCAC,
 
	0xCB4, 0xCBC, 0xD94, 0xD9C, 0xDA4, 0xDAC, 0xDB4, 0xDBC,
 
	0xDCC, 0xDD4, 0xDE4, 0xDDC, 0xDEC, 0xDC4, 0xDDC, 0xDE4,
 
	0xE2C, 0xE34, 0xE3C, 0xC14, 0xC1C, 0xC2C, 0xC3C, 0xC4C,
 
	0xC5C, 0xC64, 0xC6C, 0xC74, 0xC84, 0xC94, 0xCA4
 
};
 

	
 
@@ -540,26 +542,26 @@ CommandCost CmdTurnRoadVeh(TileIndex til
 
	if (v->vehstatus & VS_STOPPED ||
 
			v->vehstatus & VS_CRASHED ||
 
			v->breakdown_ctr != 0 ||
 
			v->u.road.overtaking != 0 ||
 
			v->u.road.state == RVSB_WORMHOLE ||
 
			v->IsInDepot() ||
 
			v->cur_speed < 5) {
 
		return CMD_ERROR;
 
	}
 

	
 
	if (IsTileType(v->tile, MP_ROAD) && GetRoadTileType(v->tile) == ROAD_TILE_NORMAL && GetDisallowedRoadDirections(v->tile) != DRD_NONE) 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 (IsTunnelTile(v->tile) && DirToDiagDir(v->direction) == GetTunnelBridgeDirection(v->tile)) return CMD_ERROR;
 
	if (IsBridgeTile(v->tile) && DirToDiagDir(v->direction) == GetTunnelBridgeDirection(v->tile)) return CMD_ERROR;
 

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

	
 
	return CommandCost();
 
}
 

	
 

	
 
void RoadVehicle::MarkDirty()
 
{
 
	for (Vehicle *v = this; v != NULL; v = v->Next()) {
 
		v->cur_image = v->GetImage(v->direction);
 
		MarkAllViewportsDirty(v->left_coord, v->top_coord, v->right_coord + 1, v->bottom_coord + 1);
 
@@ -1397,27 +1399,27 @@ static Trackdir FollowPreviousRoadVehicl
 
		/* If the previous vehicle is on the same tile as this vehicle is
 
		 * then it must have reversed. */
 
		return _road_reverse_table[entry_dir];
 
	}
 

	
 
	byte prev_state = prev->u.road.state;
 
	Trackdir dir;
 

	
 
	if (prev_state == RVSB_WORMHOLE || prev_state == RVSB_IN_DEPOT) {
 
		DiagDirection diag_dir = INVALID_DIAGDIR;
 

	
 
		if (IsTunnelTile(tile)) {
 
			diag_dir = GetTunnelDirection(tile);
 
			diag_dir = GetTunnelBridgeDirection(tile);
 
		} else if (IsBridgeTile(tile)) {
 
			diag_dir = GetBridgeRampDirection(tile);
 
			diag_dir = GetTunnelBridgeDirection(tile);
 
		} else if (IsTileType(tile, MP_ROAD) && GetRoadTileType(tile) == ROAD_TILE_DEPOT) {
 
			diag_dir = ReverseDiagDir(GetRoadDepotDirection(tile));
 
		}
 

	
 
		if (diag_dir == INVALID_DIAGDIR) return INVALID_TRACKDIR;
 
		dir = DiagdirToDiagTrackdir(diag_dir);
 
	} else if (HasBit(prev_state, RVS_IN_DT_ROAD_STOP)) {
 
		dir = (Trackdir)(prev_state & RVSB_ROAD_STOP_TRACKDIR_MASK);
 
	} else if (prev_state < TRACKDIR_END) {
 
		if (already_reversed && prev->tile != tile) {
 
			/*
 
			 * The vehicle has reversed, but did not go straight back.
src/smallmap_gui.cpp
Show inline comments
 
@@ -19,24 +19,26 @@
 
#include "gui.h"
 
#include "tree_map.h"
 
#include "tunnel_map.h"
 
#include "window.h"
 
#include "gfx.h"
 
#include "viewport.h"
 
#include "player.h"
 
#include "vehicle.h"
 
#include "town.h"
 
#include "sound.h"
 
#include "variables.h"
 
#include "blitter/factory.hpp"
 
#include "tunnelbridge_map.h"
 

	
 

	
 
static const Widget _smallmap_widgets[] = {
 
{  WWT_CLOSEBOX,   RESIZE_NONE,    13,     0,    10,     0,    13, STR_00C5,                STR_018B_CLOSE_WINDOW},
 
{   WWT_CAPTION,  RESIZE_RIGHT,    13,    11,   337,     0,    13, STR_00B0_MAP,            STR_018C_WINDOW_TITLE_DRAG_THIS},
 
{ WWT_STICKYBOX,     RESIZE_LR,    13,   338,   349,     0,    13, 0x0,                     STR_STICKY_BUTTON},
 
{     WWT_PANEL,     RESIZE_RB,    13,     0,   349,    14,   157, 0x0,                     STR_NULL},
 
{     WWT_INSET,     RESIZE_RB,    13,     2,   347,    16,   155, 0x0,                     STR_NULL},
 
{    WWT_IMGBTN,   RESIZE_LRTB,    13,   284,   305,   158,   179, SPR_IMG_SHOW_COUNTOURS,  STR_0191_SHOW_LAND_CONTOURS_ON_MAP},
 
{    WWT_IMGBTN,   RESIZE_LRTB,    13,   306,   327,   158,   179, SPR_IMG_SHOW_VEHICLES,   STR_0192_SHOW_VEHICLES_ON_MAP},
 
{    WWT_IMGBTN,   RESIZE_LRTB,    13,   328,   349,   158,   179, SPR_IMG_INDUSTRY,        STR_0193_SHOW_INDUSTRIES_ON_MAP},
 
{    WWT_IMGBTN,   RESIZE_LRTB,    13,   284,   307,   180,   201, SPR_IMG_SHOW_ROUTES,     STR_0194_SHOW_TRANSPORT_ROUTES_ON},
 
{    WWT_IMGBTN,   RESIZE_LRTB,    13,   306,   327,   180,   201, SPR_IMG_PLANTTREES,      STR_0195_SHOW_VEGETATION_ON_MAP},
 
@@ -331,27 +333,27 @@ static void DrawSmallMapStuff(void *dst,
 
	} while (xc++, yc++, dst = blitter->MoveTo(dst, pitch, 0), --reps != 0);
 
}
 

	
 

	
 
static inline TileType GetEffectiveTileType(TileIndex tile)
 
{
 
	TileType t = GetTileType(tile);
 

	
 
	if (t == MP_TUNNELBRIDGE) {
 
		TransportType tt;
 

	
 
		if (IsTunnel(tile)) {
 
			tt = GetTunnelTransportType(tile);
 
			tt = GetTunnelBridgeTransportType(tile);
 
		} else {
 
			tt = GetBridgeTransportType(tile);
 
			tt = GetTunnelBridgeTransportType(tile);
 
		}
 
		switch (tt) {
 
			case TRANSPORT_RAIL: t = MP_RAILWAY; break;
 
			case TRANSPORT_ROAD: t = MP_ROAD;    break;
 
			default:             t = MP_WATER;   break;
 
		}
 
	}
 
	return t;
 
}
 

	
 
/**
 
 * Return the color a tile would be displayed with in the small map in mode "Contour".
src/town_cmd.cpp
Show inline comments
 
@@ -35,24 +35,26 @@
 
#include "date.h"
 
#include "table/town_land.h"
 
#include "genworld.h"
 
#include "newgrf.h"
 
#include "newgrf_callbacks.h"
 
#include "newgrf_house.h"
 
#include "newgrf_commons.h"
 
#include "newgrf_townname.h"
 
#include "misc/autoptr.hpp"
 
#include "autoslope.h"
 
#include "waypoint.h"
 
#include "transparency.h"
 
#include "tunnelbridge_map.h"
 

	
 

	
 
/* Initialize the town-pool */
 
DEFINE_OLD_POOL_GENERIC(Town, Town)
 

	
 
Town::Town(TileIndex tile)
 
{
 
	if (tile != 0) _total_towns++;
 
	this->xy = tile;
 
}
 

	
 
Town::~Town()
 
{
 
@@ -1053,27 +1055,27 @@ static void GrowTownInTile(TileIndex *ti
 
				break;
 

	
 
			case TL_BETTER_ROADS:
 
			case TL_ORIGINAL:
 
				rcmd = DiagDirToRoadBits(ReverseDiagDir(target_dir));
 
				break;
 
		}
 
	} else {
 
		bool allow_house = false; // Value which decides if we want to construct a house
 

	
 
		/* Reached a tunnel/bridge? Then continue at the other side of it. */
 
		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
			if (IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_ROAD) {
 
			if (IsTunnel(tile) && GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD) {
 
				*tile_ptr = GetOtherTunnelEnd(tile);
 
			} else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_ROAD) {
 
			} else if (IsBridge(tile) && GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD) {
 
				*tile_ptr = GetOtherBridgeEnd(tile);
 
			}
 
			return;
 
		}
 

	
 
		/* Possibly extend the road in a direction.
 
		 * Randomize a direction and if it has a road, bail out. */
 
		target_dir = RandomDiagDir();
 
		if (cur_rb & DiagDirToRoadBits(target_dir)) return;
 

	
 
		/* This is the tile we will reach if we extend to this direction. */
 
		TileIndex house_tile = TileAddByDiagDir(tile, target_dir); // position of a possible house
src/train_cmd.cpp
Show inline comments
 
@@ -33,24 +33,26 @@
 
#include "train.h"
 
#include "bridge.h"
 
#include "newgrf_callbacks.h"
 
#include "newgrf_engine.h"
 
#include "newgrf_sound.h"
 
#include "newgrf_text.h"
 
#include "direction.h"
 
#include "yapf/yapf.h"
 
#include "date.h"
 
#include "cargotype.h"
 
#include "group.h"
 
#include "table/sprites.h"
 
#include "tunnelbridge_map.h"
 

	
 

	
 
static bool TrainCheckIfLineEnds(Vehicle *v);
 
static void TrainController(Vehicle *v, bool update_image);
 

	
 
static const byte _vehicle_initial_x_fract[4] = {10, 8, 4,  8};
 
static const byte _vehicle_initial_y_fract[4] = { 8, 4, 8, 10};
 
static const TrackBits _state_dir_table[4] = { TRACK_BIT_RIGHT, TRACK_BIT_LOWER, TRACK_BIT_LEFT, TRACK_BIT_UPPER };
 

	
 

	
 
/** Return the cargo weight multiplier to use for a rail vehicle
 
 * @param cargo Cargo type to get multiplier for
 
 * @return Cargo weight multiplier
 
@@ -3048,25 +3050,25 @@ static void DeleteLastWagon(Vehicle *v)
 
	if (v->u.rail.track != TRACK_BIT_DEPOT && v->u.rail.track != TRACK_BIT_WORMHOLE)
 
		SetSignalsOnBothDir(v->tile, FIND_FIRST_BIT(v->u.rail.track));
 

	
 
	/* Check if the wagon was on a road/rail-crossing and disable it if no
 
	 * others are on it */
 
	DisableTrainCrossing(v->tile);
 

	
 
	if (v->u.rail.track == TRACK_BIT_WORMHOLE) { // inside a tunnel / bridge
 
		TileIndex endtile = IsTunnel(v->tile) ? GetOtherTunnelEnd(v->tile) : GetOtherBridgeEnd(v->tile);
 

	
 
		if (GetVehicleTunnelBridge(v->tile, endtile) != NULL) return; // tunnel / bridge is busy
 

	
 
		DiagDirection dir = IsTunnel(v->tile) ? GetTunnelDirection(v->tile) : GetBridgeRampDirection(v->tile);
 
		DiagDirection dir = IsTunnel(v->tile) ? GetTunnelBridgeDirection(v->tile) : GetTunnelBridgeDirection(v->tile);
 

	
 
		/* v->direction is "random", so it cannot be used to determine the direction of the track */
 
		UpdateSignalsOnSegment(v->tile, dir);
 
		UpdateSignalsOnSegment(endtile, ReverseDiagDir(dir));
 
	}
 
}
 

	
 
static void ChangeTrainDirRandomly(Vehicle *v)
 
{
 
	static const DirDiff delta[] = {
 
		DIRDIFF_45LEFT, DIRDIFF_SAME, DIRDIFF_SAME, DIRDIFF_45RIGHT
 
	};
 
@@ -3165,25 +3167,25 @@ static bool TrainCheckIfLineEnds(Vehicle
 
		uint16 break_speed = _breakdown_speeds[GB(~t, 4, 4)];
 
		if (break_speed < v->cur_speed) v->cur_speed = break_speed;
 
	} else {
 
		v->vehstatus &= ~VS_TRAIN_SLOWING;
 
	}
 

	
 
	if (v->u.rail.track == TRACK_BIT_WORMHOLE) return true; // exit if inside a tunnel
 
	if (v->u.rail.track == TRACK_BIT_DEPOT) return true; // exit if inside a depot
 

	
 
	TileIndex tile = v->tile;
 

	
 
	if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
		DiagDirection dir = IsTunnel(tile) ? GetTunnelDirection(tile) : GetBridgeRampDirection(tile);
 
		DiagDirection dir = IsTunnel(tile) ? GetTunnelBridgeDirection(tile) : GetTunnelBridgeDirection(tile);
 
		if (DiagDirToDir(dir) == v->direction) return true;
 
	}
 

	
 
	// depot?
 
	/* XXX -- When enabled, this makes it possible to crash trains of others
 
	     (by building a depot right against a station) */
 
/*	if (IsTileType(tile, MP_RAILWAY) && GetRailTileType(tile) == RAIL_TILE_DEPOT_WAYPOINT)
 
		return true;*/
 

	
 
	/* Determine the non-diagonal direction in which we will exit this tile */
 
	DiagDirection dir = DirToDiagDir(v->direction);
 
	if (!(v->direction & 1) && v->u.rail.track != _state_dir_table[dir]) {
src/tunnel_map.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file tunnel_map.cpp */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "tile.h"
 
#include "tunnel_map.h"
 
#include "tunnelbridge_map.h"
 

	
 

	
 
/**
 
 * Gets the other end of the tunnel. Where a vehicle would reappear when it
 
 * enters at the given tile.
 
 * @param tile the tile to search from.
 
 * @return the tile of the other end of the tunnel.
 
 */
 
TileIndex GetOtherTunnelEnd(TileIndex tile)
 
{
 
	DiagDirection dir = GetTunnelDirection(tile);
 
	DiagDirection dir = GetTunnelBridgeDirection(tile);
 
	TileIndexDiff delta = TileOffsByDiagDir(dir);
 
	uint z = GetTileZ(tile);
 

	
 
	dir = ReverseDiagDir(dir);
 
	do {
 
		tile += delta;
 
	} while (
 
		!IsTunnelTile(tile) ||
 
		GetTunnelDirection(tile) != dir ||
 
		GetTunnelBridgeDirection(tile) != dir ||
 
		GetTileZ(tile) != z
 
	);
 

	
 
	return tile;
 
}
 

	
 

	
 
/**
 
 * Is there a tunnel in the way in the given direction?
 
 * @param tile the tile to search from.
 
 * @param z    the 'z' to search on.
 
 * @param dir  the direction to start searching to.
 
@@ -43,25 +45,25 @@ bool IsTunnelInWayDir(TileIndex tile, ui
 
{
 
	TileIndexDiff delta = TileOffsByDiagDir(dir);
 
	uint height;
 

	
 
	do {
 
		tile -= delta;
 
		height = GetTileZ(tile);
 
	} while (z < height);
 

	
 
	return
 
		z == height &&
 
		IsTunnelTile(tile) &&
 
		GetTunnelDirection(tile) == dir;
 
		GetTunnelBridgeDirection(tile) == dir;
 
}
 

	
 
/**
 
 * Is there a tunnel in the way in any direction?
 
 * @param tile the tile to search from.
 
 * @param z the 'z' to search on.
 
 * @return true if and only if there is a tunnel.
 
 */
 
bool IsTunnelInWay(TileIndex tile, uint z)
 
{
 
	return
 
		IsTunnelInWayDir(tile, z, (TileX(tile) > (MapMaxX() / 2)) ? DIAGDIR_NE : DIAGDIR_SW) ||
src/tunnel_map.h
Show inline comments
 
@@ -2,103 +2,51 @@
 

	
 
/** @file tunnel_map.h */
 

	
 
#ifndef TUNNEL_MAP_H
 
#define TUNNEL_MAP_H
 

	
 
#include "direction.h"
 
#include "macros.h"
 
#include "map.h"
 
#include "rail.h"
 
#include "road.h"
 

	
 

	
 
/**
 
 * Is this a tunnel (entrance)?
 
 * @param t the tile that might be a tunnel
 
 * @pre IsTileType(t, MP_TUNNELBRIDGE)
 
 * @return true if and only if this tile is a tunnel (entrance)
 
 */
 
static inline bool IsTunnel(TileIndex t)
 
{
 
	assert(IsTileType(t, MP_TUNNELBRIDGE));
 
	return !HasBit(_m[t].m5, 7);
 
}
 

	
 

	
 
/**
 
 * Is this a tunnel (entrance)?
 
 * @param t the tile that might be a tunnel
 
 * @return true if and only if this tile is a tunnel (entrance)
 
 */
 
static inline bool IsTunnelTile(TileIndex t)
 
{
 
	return IsTileType(t, MP_TUNNELBRIDGE) && IsTunnel(t);
 
}
 

	
 
/**
 
 * Gets the direction facing out of the tunnel
 
 * @param t the tile to get the tunnel facing direction of
 
 * @pre IsTunnelTile(t)
 
 * @return the direction the tunnel is facing
 
 */
 
static inline DiagDirection GetTunnelDirection(TileIndex t)
 
{
 
	assert(IsTunnelTile(t));
 
	return (DiagDirection)GB(_m[t].m5, 0, 2);
 
}
 

	
 
/**
 
 * Gets the transport type of the tunnel (road or rail)
 
 * @param t the tunnel entrance tile to get the type of
 
 * @pre IsTunnelTile(t)
 
 * @return the transport type in the tunnel
 
 */
 
static inline TransportType GetTunnelTransportType(TileIndex t)
 
{
 
	assert(IsTunnelTile(t));
 
	return (TransportType)GB(_m[t].m5, 2, 2);
 
}
 

	
 
/**
 
 * Is this tunnel entrance in a snowy or desert area?
 
 * @param t the tunnel entrance tile
 
 * @pre IsTunnelTile(t)
 
 * @return true if and only if the tunnel entrance is in a snowy/desert area
 
 */
 
static inline bool HasTunnelSnowOrDesert(TileIndex t)
 
{
 
	assert(IsTunnelTile(t));
 
	return HasBit(_m[t].m4, 7);
 
}
 

	
 
/**
 
 * Places this tunnel entrance in a snowy or desert area,
 
 * or takes it out of there.
 
 * @param t the tunnel entrance tile
 
 * @param snow_or_desert is the entrance in snow or desert (true), when
 
 *                       not in snow and not in desert false
 
 * @pre IsTunnelTile(t)
 
 */
 
static inline void SetTunnelSnowOrDesert(TileIndex t, bool snow_or_desert)
 
{
 
	assert(IsTunnelTile(t));
 
	SB(_m[t].m4, 7, 1, snow_or_desert);
 
}
 

	
 

	
 
TileIndex GetOtherTunnelEnd(TileIndex);
 
bool IsTunnelInWay(TileIndex, uint z);
 
bool IsTunnelInWayDir(TileIndex tile, uint z, DiagDirection dir);
 

	
 

	
 
/**
 
 * Makes a road tunnel entrance
 
 * @param t the entrance of the tunnel
 
 * @param o the owner of the entrance
 
 * @param d the direction facing out of the tunnel
 
 * @param r the road type used in the tunnel
 
 */
 
static inline void MakeRoadTunnel(TileIndex t, Owner o, DiagDirection d, RoadTypes r)
 
{
 
	SetTileType(t, MP_TUNNELBRIDGE);
 
	SetTileOwner(t, o);
 
	_m[t].m2 = 0;
src/tunnelbridge_cmd.cpp
Show inline comments
 
@@ -25,26 +25,27 @@
 
#include "player.h"
 
#include "town.h"
 
#include "sound.h"
 
#include "variables.h"
 
#include "bridge.h"
 
#include "train.h"
 
#include "water_map.h"
 
#include "yapf/yapf.h"
 
#include "date.h"
 
#include "newgrf_sound.h"
 
#include "autoslope.h"
 
#include "transparency.h"
 
#include "tunnelbridge_map.h"
 
#include "table/bridge_land.h"
 

	
 
#include "table/bridge_land.h"
 

	
 
const Bridge orig_bridge[] = {
 
/*
 
	     year of availablity
 
	     |  minimum length
 
	     |  |   maximum length
 
	     |  |   |    price
 
	     |  |   |    |    maximum speed
 
	     |  |   |    |    |  sprite to use in GUI                string with description
 
	     |  |   |    |    |  |                                   |                            */
 
	{    0, 0, 16,  80,  32, 0xA24, PAL_NONE                  , STR_5012_WOODEN             , NULL, 0 },
 
	{    0, 0,  2, 112,  48, 0xA26, PALETTE_TO_STRUCT_RED     , STR_5013_CONCRETE           , NULL, 0 },
 
@@ -257,25 +258,25 @@ CommandCost CmdBuildBridge(TileIndex end
 
	if (IsSteepSlope(tileh_end)) z_end += TILE_HEIGHT;
 
	if (HasBit(BRIDGE_FULL_LEVELED_FOUNDATION, tileh_end)) z_end += TILE_HEIGHT;
 

	
 
	if (z_start != z_end) return_cmd_error(STR_BRIDGEHEADS_NOT_SAME_HEIGHT);
 

	
 
	allow_on_slopes = (!_is_old_ai_player
 
	                   && _patches.build_on_slopes);
 

	
 
	TransportType transport_type = railtype == INVALID_RAILTYPE ? TRANSPORT_ROAD : TRANSPORT_RAIL;
 

	
 
	if (IsBridgeTile(tile_start) && IsBridgeTile(tile_end) &&
 
			GetOtherBridgeEnd(tile_start) == tile_end &&
 
			GetBridgeTransportType(tile_start) == transport_type) {
 
			GetTunnelBridgeTransportType(tile_start) == transport_type) {
 
		/* Replace a current bridge. */
 

	
 
		/* If this is a railway bridge, make sure the railtypes match. */
 
		if (transport_type == TRANSPORT_RAIL && GetRailType(tile_start) != railtype) {
 
			return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 
		}
 

	
 
		/* Do not replace town bridges with lower speed bridges. */
 
		if (!(flags & DC_QUERY_COST) && IsTileOwner(tile_start, OWNER_TOWN) &&
 
				_bridge[bridge_type].speed < _bridge[GetBridgeType(tile_start)].speed) {
 
			Town *t = ClosestTownFromTile(tile_start, UINT_MAX);
 

	
 
@@ -382,25 +383,25 @@ CommandCost CmdBuildBridge(TileIndex end
 

	
 
			case MP_RAILWAY:
 
				if (!IsPlainRailTile(tile)) goto not_valid_below;
 
				break;
 

	
 
			case MP_ROAD:
 
				if (GetRoadTileType(tile) == ROAD_TILE_DEPOT) goto not_valid_below;
 
				break;
 

	
 
			case MP_TUNNELBRIDGE:
 
				if (IsTunnel(tile)) break;
 
				if (replace_bridge) break;
 
				if (direction == DiagDirToAxis(GetBridgeRampDirection(tile))) goto not_valid_below;
 
				if (direction == DiagDirToAxis(GetTunnelBridgeDirection(tile))) goto not_valid_below;
 
				if (z_start < GetBridgeHeight(tile)) goto not_valid_below;
 
				break;
 

	
 
			case MP_UNMOVABLE:
 
				if (!IsOwnedLand(tile)) goto not_valid_below;
 
				break;
 

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

	
 
			default:
 
@@ -593,25 +594,25 @@ static CommandCost DoClearTunnel(TileInd
 

	
 
		/* Check if you are allowed to remove the tunnel owned by a town
 
		 * Removal depends on difficulty settings */
 
		if (!CheckforTownRating(flags, t, TUNNELBRIDGE_REMOVE)) {
 
			SetDParam(0, t->index);
 
			return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES);
 
		}
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		/* We first need to request the direction before calling DoClearSquare
 
		 *  else the direction is always 0.. dah!! ;) */
 
		DiagDirection dir = GetTunnelDirection(tile);
 
		DiagDirection dir = GetTunnelBridgeDirection(tile);
 
		Track track;
 

	
 
		/* Adjust the town's player rating. Do this before removing the tile owner info. */
 
		if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR)
 
			ChangeTownRating(t, RATING_TUNNEL_BRIDGE_DOWN_STEP, RATING_TUNNEL_BRIDGE_MINIMUM);
 

	
 
		DoClearSquare(tile);
 
		DoClearSquare(endtile);
 
		UpdateSignalsOnSegment(tile, ReverseDiagDir(dir));
 
		UpdateSignalsOnSegment(endtile, dir);
 
		track = AxisToTrack(DiagDirToAxis(dir));
 
		YapfNotifyTrackLayoutChange(tile, track);
 
@@ -627,25 +628,25 @@ static CommandCost DoClearBridge(TileInd
 
	TileIndexDiff delta;
 
	TileIndex endtile;
 
	Town *t = NULL;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	if (!CheckAllowRemoveTunnelBridge(tile)) return CMD_ERROR;
 

	
 
	endtile = GetOtherBridgeEnd(tile);
 

	
 
	if (GetVehicleTunnelBridge(tile, endtile) != NULL) return CMD_ERROR;
 

	
 
	direction = GetBridgeRampDirection(tile);
 
	direction = GetTunnelBridgeDirection(tile);
 
	delta = TileOffsByDiagDir(direction);
 

	
 
	if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR) {
 
		t = ClosestTownFromTile(tile, (uint)-1); // town penalty rating
 

	
 
		/* Check if you are allowed to remove the bridge owned by a town
 
		 * Removal depends on difficulty settings */
 
		if (!CheckforTownRating(flags, t, TUNNELBRIDGE_REMOVE)) {
 
			SetDParam(0, t->index);
 
			return_cmd_error(STR_2009_LOCAL_AUTHORITY_REFUSES);
 
		}
 
	}
 
@@ -692,65 +693,65 @@ static CommandCost ClearTile_TunnelBridg
 
/**
 
 * Switches the rail type for a tunnel or a bridgehead. As the railtype
 
 * on the bridge are determined by the one of the bridgehead, this
 
 * functions converts the railtype on the entire bridge.
 
 * @param tile        The tile on which the railtype is to be convert.
 
 * @param totype      The railtype we want to convert to
 
 * @param exec        Switches between test and execute mode
 
 * @return            The cost and state of the operation
 
 * @retval CMD_ERROR  An error occured during the operation.
 
 */
 
CommandCost DoConvertTunnelBridgeRail(TileIndex tile, RailType totype, bool exec)
 
{
 
	if (IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_RAIL) {
 
	if (IsTunnel(tile) && GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) {
 
		TileIndex endtile = GetOtherTunnelEnd(tile);
 

	
 
		/* If not coverting rail <-> el. rail, any vehicle cannot be in tunnel */
 
		if (!IsCompatibleRail(GetRailType(tile), totype) &&
 
				GetVehicleTunnelBridge(tile, endtile) != NULL) {
 
			return CMD_ERROR;
 
		}
 

	
 
		if (exec) {
 
			SetRailType(tile, totype);
 
			SetRailType(endtile, totype);
 
			MarkTileDirtyByTile(tile);
 
			MarkTileDirtyByTile(endtile);
 

	
 
			Track track = AxisToTrack(DiagDirToAxis(GetTunnelDirection(tile)));
 
			Track track = AxisToTrack(DiagDirToAxis(GetTunnelBridgeDirection(tile)));
 

	
 
			YapfNotifyTrackLayoutChange(tile, track);
 
			YapfNotifyTrackLayoutChange(endtile, track);
 

	
 
			VehicleFromPos(tile, NULL, &UpdateTrainPowerProc);
 
			VehicleFromPos(endtile, NULL, &UpdateTrainPowerProc);
 
		}
 

	
 
		return CommandCost((DistanceManhattan(tile, endtile) + 1) * RailConvertCost(GetRailType(tile), totype));
 
	} else if (IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
 
	} else if (IsBridge(tile) && GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) {
 
		TileIndex endtile = GetOtherBridgeEnd(tile);
 

	
 
		if (!IsCompatibleRail(GetRailType(tile), totype) &&
 
				GetVehicleTunnelBridge(tile, endtile) != NULL) {
 
			return CMD_ERROR;
 
		}
 

	
 
		if (exec) {
 
			SetRailType(tile, totype);
 
			SetRailType(endtile, totype);
 
			MarkTileDirtyByTile(tile);
 
			MarkTileDirtyByTile(endtile);
 

	
 
			Track track = AxisToTrack(DiagDirToAxis(GetBridgeRampDirection(tile)));
 
			TileIndexDiff delta = TileOffsByDiagDir(GetBridgeRampDirection(tile));
 
			Track track = AxisToTrack(DiagDirToAxis(GetTunnelBridgeDirection(tile)));
 
			TileIndexDiff delta = TileOffsByDiagDir(GetTunnelBridgeDirection(tile));
 

	
 
			YapfNotifyTrackLayoutChange(tile, track);
 
			YapfNotifyTrackLayoutChange(endtile, track);
 

	
 
			VehicleFromPos(tile, NULL, &UpdateTrainPowerProc);
 
			VehicleFromPos(endtile, NULL, &UpdateTrainPowerProc);
 

	
 
			for (tile += delta; tile != endtile; tile += delta) {
 
				MarkTileDirtyByTile(tile); // TODO encapsulate this into a function
 
			}
 
		}
 

	
 
@@ -885,40 +886,40 @@ static void DrawTile_TunnelBridge(TileIn
 
		 *   1    3                  2 = SpriteCombine of tunnel-roof and catenary (tram & elrail)
 
		 *
 
		 */
 

	
 
		static const int _tunnel_BB[4][12] = {
 
			/*  tunnnel-roof  |  Z-separator  | tram-catenary
 
			 * w  h  bb_x bb_y| x   y   w   h |bb_x bb_y w h */
 
			{  1,  0, -15, -14,  0, 15, 16,  1, 0, 1, 16, 15 }, // NE
 
			{  0,  1, -14, -15, 15,  0,  1, 16, 1, 0, 15, 16 }, // SE
 
			{  1,  0, -15, -14,  0, 15, 16,  1, 0, 1, 16, 15 }, // SW
 
			{  0,  1, -14, -15, 15,  0,  1, 16, 1, 0, 15, 16 }, // NW
 
		};
 
		const int *BB_data = _tunnel_BB[GetTunnelDirection(ti->tile)];
 
		const int *BB_data = _tunnel_BB[GetTunnelBridgeDirection(ti->tile)];
 

	
 
		bool catenary = false;
 

	
 
		if (GetTunnelTransportType(ti->tile) == TRANSPORT_RAIL) {
 
		if (GetTunnelBridgeTransportType(ti->tile) == TRANSPORT_RAIL) {
 
			image = GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.tunnel;
 
		} else {
 
			image = SPR_TUNNEL_ENTRY_REAR_ROAD;
 
		}
 

	
 
		if (HasTunnelSnowOrDesert(ti->tile)) image += 32;
 
		if (HasTunnelBridgeSnowOrDesert(ti->tile)) image += 32;
 

	
 
		image += GetTunnelDirection(ti->tile) * 2;
 
		image += GetTunnelBridgeDirection(ti->tile) * 2;
 
		DrawGroundSprite(image, PAL_NONE);
 
		if (GetTunnelTransportType(ti->tile) == TRANSPORT_ROAD) {
 
			DiagDirection dir = GetTunnelDirection(ti->tile);
 
		if (GetTunnelBridgeTransportType(ti->tile) == TRANSPORT_ROAD) {
 
			DiagDirection dir = GetTunnelBridgeDirection(ti->tile);
 
			RoadTypes rts = GetRoadTypes(ti->tile);
 

	
 
			if (HasBit(rts, ROADTYPE_TRAM)) {
 
				static const SpriteID tunnel_sprites[2][4] = { { 28, 78, 79, 27 }, {  5, 76, 77,  4 } };
 

	
 
				DrawGroundSprite(SPR_TRAMWAY_BASE + tunnel_sprites[rts - ROADTYPES_TRAM][dir], PAL_NONE);
 

	
 
				catenary = true;
 
				StartSpriteCombine();
 
				AddSortableSpriteToDraw(SPR_TRAMWAY_TUNNEL_WIRES + dir, PAL_NONE, ti->x, ti->y, BB_data[10], BB_data[11], TILE_HEIGHT, ti->z, IsTransparencySet(TO_BUILDINGS), BB_data[8], BB_data[9], BB_Z_SEPARATOR);
 
			}
 
		} else if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) {
 
@@ -932,69 +933,69 @@ static void DrawTile_TunnelBridge(TileIn
 
		AddSortableSpriteToDraw(image + 1, PAL_NONE, ti->x + TILE_SIZE - 1, ti->y + TILE_SIZE - 1, BB_data[0], BB_data[1], TILE_HEIGHT, ti->z, false, BB_data[2], BB_data[3], BB_Z_SEPARATOR);
 

	
 
		if (catenary) EndSpriteCombine();
 

	
 
		/* Add helper BB for sprite sorting, that separate the tunnel from things beside of it */
 
		AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, ti->x             , ti->y             , BB_data[6], BB_data[7], TILE_HEIGHT, ti->z);
 
		AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, ti->x + BB_data[4], ti->y + BB_data[5], BB_data[6], BB_data[7], TILE_HEIGHT, ti->z);
 

	
 
		DrawBridgeMiddle(ti);
 
	} else if (IsBridge(ti->tile)) { // XXX is this necessary?
 
		const PalSpriteID *psid;
 
		int base_offset;
 
		bool ice = HasBridgeSnowOrDesert(ti->tile);
 
		bool ice = HasTunnelBridgeSnowOrDesert(ti->tile);
 

	
 
		if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL) {
 
		if (GetTunnelBridgeTransportType(ti->tile) == TRANSPORT_RAIL) {
 
			base_offset = GetRailTypeInfo(GetRailType(ti->tile))->bridge_offset;
 
			assert(base_offset != 8); // This one is used for roads
 
		} else {
 
			base_offset = 8;
 
		}
 

	
 
		/* as the lower 3 bits are used for other stuff, make sure they are clear */
 
		assert( (base_offset & 0x07) == 0x00);
 

	
 
		DrawFoundation(ti, GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile))));
 
		DrawFoundation(ti, GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetTunnelBridgeDirection(ti->tile))));
 

	
 
		/* HACK Wizardry to convert the bridge ramp direction into a sprite offset */
 
		base_offset += (6 - GetBridgeRampDirection(ti->tile)) % 4;
 
		base_offset += (6 - GetTunnelBridgeDirection(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 */
 
		psid = &GetBridgeSpriteTable(GetBridgeType(ti->tile), 6)[base_offset];
 

	
 
		if (!ice) {
 
			DrawClearLandTile(ti, 3);
 
		} else {
 
			DrawGroundSprite(SPR_FLAT_SNOWY_TILE + _tileh_to_sprite[ti->tileh], PAL_NONE);
 
		}
 

	
 
		/* draw ramp */
 

	
 
		/* Draw Trambits as SpriteCombine */
 
		if (GetBridgeTransportType(ti->tile) == TRANSPORT_ROAD) StartSpriteCombine();
 
		if (GetTunnelBridgeTransportType(ti->tile) == TRANSPORT_ROAD) StartSpriteCombine();
 

	
 
		/* HACK set the height of the BB of a sloped ramp to 1 so a vehicle on
 
		 * it doesn't disappear behind it
 
		 */
 
		AddSortableSpriteToDraw(
 
			psid->sprite, psid->pal, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 0 : 8, ti->z, IsTransparencySet(TO_BRIDGES)
 
		);
 

	
 
		if (GetBridgeTransportType(ti->tile) == TRANSPORT_ROAD) {
 
		if (GetTunnelBridgeTransportType(ti->tile) == TRANSPORT_ROAD) {
 
			RoadTypes rts = GetRoadTypes(ti->tile);
 

	
 
			if (HasBit(rts, ROADTYPE_TRAM)) {
 
				uint offset = GetBridgeRampDirection(ti->tile);
 
				uint offset = GetTunnelBridgeDirection(ti->tile);
 
				uint z = ti->z;
 
				if (ti->tileh != SLOPE_FLAT) {
 
					offset = (offset + 1) & 1;
 
					z += TILE_HEIGHT;
 
				} else {
 
					offset += 2;
 
				}
 
				/* DrawBridgeTramBits() calls EndSpriteCombine() and StartSpriteCombine() */
 
				DrawBridgeTramBits(ti->x, ti->y, z, offset, HasBit(rts, ROADTYPE_ROAD));
 
			}
 
			EndSpriteCombine();
 
		} else if (GetRailType(ti->tile) == RAILTYPE_ELECTRIC) {
 
@@ -1075,78 +1076,78 @@ void DrawBridgeMiddle(const TileInfo* ti
 
	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) {
 
	if (GetTunnelBridgeTransportType(rampsouth) == TRANSPORT_RAIL) {
 
		base_offset = GetRailTypeInfo(GetRailType(rampsouth))->bridge_offset;
 
	} else {
 
		base_offset = 8;
 
	}
 

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

	
 
	x = ti->x;
 
	y = ti->y;
 
	uint bridge_z = GetBridgeHeight(rampsouth);
 
	z = bridge_z - BRIDGE_Z_START;
 

	
 
	/* Add a bounding box, that separates the bridge from things below it. */
 
	AddSortableSpriteToDraw(SPR_EMPTY_BOUNDING_BOX, PAL_NONE, x, y, 16, 16, 1, bridge_z - TILE_HEIGHT + BB_Z_SEPARATOR);
 

	
 
	/* Draw Trambits as SpriteCombine */
 
	if (GetBridgeTransportType(rampsouth) == TRANSPORT_ROAD) StartSpriteCombine();
 
	if (GetTunnelBridgeTransportType(rampsouth) == TRANSPORT_ROAD) StartSpriteCombine();
 

	
 
	/* Draw floor and far part of bridge*/
 
	if (axis == AXIS_X) {
 
		AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 16, 1, 0x28, z, IsTransparencySet(TO_BRIDGES), 0, 0, BRIDGE_Z_START);
 
	} else {
 
		AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 1, 16, 0x28, z, IsTransparencySet(TO_BRIDGES), 0, 0, BRIDGE_Z_START);
 
	}
 

	
 
	psid++;
 

	
 
	if (GetBridgeTransportType(rampsouth) == TRANSPORT_ROAD) {
 
	if (GetTunnelBridgeTransportType(rampsouth) == TRANSPORT_ROAD) {
 
		RoadTypes rts = GetRoadTypes(rampsouth);
 

	
 
		if (HasBit(rts, ROADTYPE_TRAM)) {
 
			/* DrawBridgeTramBits() calls EndSpriteCombine() and StartSpriteCombine() */
 
			DrawBridgeTramBits(x, y, bridge_z, axis ^ 1, HasBit(rts, ROADTYPE_ROAD));
 
		} else {
 
			EndSpriteCombine();
 
			StartSpriteCombine();
 
		}
 
	} else if (GetRailType(rampsouth) == RAILTYPE_ELECTRIC) {
 
		DrawCatenary(ti);
 
	}
 

	
 
	/* draw roof, the component of the bridge which is logically between the vehicle and the camera */
 
	if (axis == AXIS_X) {
 
		y += 12;
 
		if (psid->sprite & SPRITE_MASK) AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 16, 4, 0x28, z, IsTransparencySet(TO_BRIDGES), 0, 3, BRIDGE_Z_START);
 
	} else {
 
		x += 12;
 
		if (psid->sprite & SPRITE_MASK) AddSortableSpriteToDraw(psid->sprite, psid->pal, x, y, 4, 16, 0x28, z, IsTransparencySet(TO_BRIDGES), 3, 0, BRIDGE_Z_START);
 
	}
 

	
 
	/* Draw TramFront as SpriteCombine */
 
	if (GetBridgeTransportType(rampsouth) == TRANSPORT_ROAD) EndSpriteCombine();
 
	if (GetTunnelBridgeTransportType(rampsouth) == TRANSPORT_ROAD) EndSpriteCombine();
 

	
 
	psid++;
 
	if (ti->z + 5 == z) {
 
		/* draw poles below for small bridges */
 
		if (psid->sprite != 0) {
 
			SpriteID image = psid->sprite;
 
			SpriteID pal   = psid->pal;
 
			if (IsTransparencySet(TO_BRIDGES)) {
 
				SetBit(image, PALETTE_MODIFIER_TRANSPARENT);
 
				pal = PALETTE_TO_TRANSPARENT;
 
			}
 

	
 
@@ -1159,30 +1160,30 @@ void DrawBridgeMiddle(const TileInfo* ti
 
}
 

	
 

	
 
static uint GetSlopeZ_TunnelBridge(TileIndex tile, uint x, uint y)
 
{
 
	uint z;
 
	Slope tileh = GetTileSlope(tile, &z);
 

	
 
	x &= 0xF;
 
	y &= 0xF;
 

	
 
	if (IsTunnel(tile)) {
 
		uint pos = (DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? y : x);
 
		uint pos = (DiagDirToAxis(GetTunnelBridgeDirection(tile)) == AXIS_X ? y : x);
 

	
 
		/* In the tunnel entrance? */
 
		if (5 <= pos && pos <= 10) return z;
 
	} else {
 
		DiagDirection dir = GetBridgeRampDirection(tile);
 
		DiagDirection dir = GetTunnelBridgeDirection(tile);
 
		uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x);
 

	
 
		z += ApplyFoundationToSlope(GetBridgeFoundation(tileh, DiagDirToAxis(dir)), &tileh);
 

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

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

	
 
			switch (dir) {
 
				default: NOT_REACHED();
 
@@ -1191,25 +1192,25 @@ static uint GetSlopeZ_TunnelBridge(TileI
 
				case DIAGDIR_SW: delta = x / 2; break;
 
				case DIAGDIR_NW: delta = (TILE_SIZE - 1 - y) / 2; break;
 
			}
 
			return z + 1 + delta;
 
		}
 
	}
 

	
 
	return z + GetPartialZ(x, y, tileh);
 
}
 

	
 
static Foundation GetFoundation_TunnelBridge(TileIndex tile, Slope tileh)
 
{
 
	return IsTunnel(tile) ? FOUNDATION_NONE : GetBridgeFoundation(tileh, DiagDirToAxis(GetBridgeRampDirection(tile)));
 
	return IsTunnel(tile) ? FOUNDATION_NONE : GetBridgeFoundation(tileh, DiagDirToAxis(GetTunnelBridgeDirection(tile)));
 
}
 

	
 

	
 
static void GetAcceptedCargo_TunnelBridge(TileIndex tile, AcceptedCargo ac)
 
{
 
	/* not used */
 
}
 

	
 
static const StringID _bridge_tile_str[(MAX_BRIDGES + 3) + (MAX_BRIDGES + 3)] = {
 
	STR_501F_WOODEN_RAIL_BRIDGE,
 
	STR_5020_CONCRETE_RAIL_BRIDGE,
 
	STR_501C_STEEL_GIRDER_RAIL_BRIDGE,
 
@@ -1235,98 +1236,98 @@ static const StringID _bridge_tile_str[(
 
	STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE,
 
	STR_5023_STEEL_CANTILEVER_ROAD_BRIDGE,
 
	STR_5022_STEEL_GIRDER_ROAD_BRIDGE,
 
	STR_5028_TUBULAR_ROAD_BRIDGE,
 
	STR_5028_TUBULAR_ROAD_BRIDGE,
 
	STR_5028_TUBULAR_ROAD_BRIDGE,
 
	0, 0, 0,
 
};
 

	
 
static void GetTileDesc_TunnelBridge(TileIndex tile, TileDesc *td)
 
{
 
	if (IsTunnel(tile)) {
 
		td->str = (GetTunnelTransportType(tile) == TRANSPORT_RAIL) ?
 
		td->str = (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) ?
 
			STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL;
 
	} else {
 
		td->str = _bridge_tile_str[GetBridgeTransportType(tile) << 4 | GetBridgeType(tile)];
 
		td->str = _bridge_tile_str[GetTunnelBridgeTransportType(tile) << 4 | GetBridgeType(tile)];
 
	}
 
	td->owner = GetTileOwner(tile);
 
}
 

	
 

	
 
static void AnimateTile_TunnelBridge(TileIndex tile)
 
{
 
	/* not used */
 
}
 

	
 
static void TileLoop_TunnelBridge(TileIndex tile)
 
{
 
	bool snow_or_desert = IsTunnelTile(tile) ? HasTunnelSnowOrDesert(tile) : HasBridgeSnowOrDesert(tile);
 
	bool snow_or_desert = IsTunnelTile(tile) ? HasTunnelBridgeSnowOrDesert(tile) : HasTunnelBridgeSnowOrDesert(tile);
 
	switch (_opt.landscape) {
 
		case LT_ARCTIC:
 
			if (snow_or_desert != (GetTileZ(tile) > GetSnowLine())) {
 
				if (IsTunnelTile(tile)) {
 
					SetTunnelSnowOrDesert(tile, !snow_or_desert);
 
					SetTunnelBridgeSnowOrDesert(tile, !snow_or_desert);
 
				} else {
 
					SetBridgeSnowOrDesert(tile, !snow_or_desert);
 
					SetTunnelBridgeSnowOrDesert(tile, !snow_or_desert);
 
				}
 
				MarkTileDirtyByTile(tile);
 
			}
 
			break;
 

	
 
		case LT_TROPIC:
 
			if (GetTropicZone(tile) == TROPICZONE_DESERT && !snow_or_desert) {
 
				if (IsTunnelTile(tile)) {
 
					SetTunnelSnowOrDesert(tile, true);
 
					SetTunnelBridgeSnowOrDesert(tile, true);
 
				} else {
 
					SetBridgeSnowOrDesert(tile, true);
 
					SetTunnelBridgeSnowOrDesert(tile, true);
 
				}
 
				MarkTileDirtyByTile(tile);
 
			}
 
			break;
 
	}
 
}
 

	
 
static void ClickTile_TunnelBridge(TileIndex tile)
 
{
 
	/* not used */
 
}
 

	
 

	
 
static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode, uint sub_mode)
 
{
 
	if (IsTunnel(tile)) {
 
		if (GetTunnelTransportType(tile) != mode) return 0;
 
		if (GetTunnelTransportType(tile) == TRANSPORT_ROAD && (GetRoadTypes(tile) & sub_mode) == 0) return 0;
 
		return AxisToTrackBits(DiagDirToAxis(GetTunnelDirection(tile))) * 0x101;
 
		if (GetTunnelBridgeTransportType(tile) != mode) return 0;
 
		if (GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD && (GetRoadTypes(tile) & sub_mode) == 0) return 0;
 
		return AxisToTrackBits(DiagDirToAxis(GetTunnelBridgeDirection(tile))) * 0x101;
 
	} else {
 
		if (GetBridgeTransportType(tile) != mode) return 0;
 
		if (GetBridgeTransportType(tile) == TRANSPORT_ROAD && (GetRoadTypes(tile) & sub_mode) == 0) return 0;
 
		return AxisToTrackBits(DiagDirToAxis(GetBridgeRampDirection(tile))) * 0x101;
 
		if (GetTunnelBridgeTransportType(tile) != mode) return 0;
 
		if (GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD && (GetRoadTypes(tile) & sub_mode) == 0) return 0;
 
		return AxisToTrackBits(DiagDirToAxis(GetTunnelBridgeDirection(tile))) * 0x101;
 
	}
 
}
 

	
 
static void ChangeTileOwner_TunnelBridge(TileIndex tile, PlayerID old_player, PlayerID new_player)
 
{
 
	if (!IsTileOwner(tile, old_player)) return;
 

	
 
	if (new_player != PLAYER_SPECTATOR) {
 
		SetTileOwner(tile, new_player);
 
	} else {
 
		if (CmdFailed(DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR))) {
 
			/* When clearing the bridge/tunnel failed there are still vehicles on/in
 
			 * the bridge/tunnel. As all *our* vehicles are already removed, they
 
			 * must be of another owner. Therefor this must be a road bridge/tunnel.
 
			 * In that case we can safely reassign the ownership to OWNER_NONE. */
 
			assert((IsTunnel(tile) ? GetTunnelTransportType(tile) : GetBridgeTransportType(tile)) == TRANSPORT_ROAD);
 
			assert((IsTunnel(tile) ? GetTunnelBridgeTransportType(tile) : GetTunnelBridgeTransportType(tile)) == TRANSPORT_ROAD);
 
			SetTileOwner(tile, OWNER_NONE);
 
		}
 
	}
 
}
 

	
 

	
 
static const byte _tunnel_fractcoord_1[4]    = {0x8E, 0x18, 0x81, 0xE8};
 
static const byte _tunnel_fractcoord_2[4]    = {0x81, 0x98, 0x87, 0x38};
 
static const byte _tunnel_fractcoord_3[4]    = {0x82, 0x88, 0x86, 0x48};
 
static const byte _exit_tunnel_track[4]      = {1, 2, 1, 2};
 

	
 
/** Get the trackdir of the exit of a tunnel */
 
@@ -1345,25 +1346,25 @@ static uint32 VehicleEnter_TunnelBridge(
 
	int z = GetSlopeZ(x, y) - v->z_pos;
 

	
 
	if (abs(z) > 2) return VETSB_CANNOT_ENTER;
 

	
 
	if (IsTunnel(tile)) {
 
		byte fc;
 
		DiagDirection dir;
 
		DiagDirection vdir;
 

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

	
 
			dir = GetTunnelDirection(tile);
 
			dir = GetTunnelBridgeDirection(tile);
 
			vdir = DirToDiagDir(v->direction);
 

	
 
			if (v->u.rail.track != TRACK_BIT_WORMHOLE && dir == vdir) {
 
				if (IsFrontEngine(v) && fc == _tunnel_fractcoord_1[dir]) {
 
					if (!PlayVehicleSound(v, VSE_TUNNEL) && RailVehInfo(v->engine_type)->engclass == 0) {
 
						SndPlayVehicleFx(SND_05_TRAIN_THROUGH_TUNNEL, v);
 
					}
 
					return VETSB_CONTINUE;
 
				}
 
				if (fc == _tunnel_fractcoord_2[dir]) {
 
					v->tile = tile;
 
					v->u.rail.track = TRACK_BIT_WORMHOLE;
 
@@ -1373,25 +1374,25 @@ static uint32 VehicleEnter_TunnelBridge(
 
			}
 

	
 
			if (dir == ReverseDiagDir(vdir) && fc == _tunnel_fractcoord_3[dir] && z == 0) {
 
				/* We're at the tunnel exit ?? */
 
				v->tile = tile;
 
				v->u.rail.track = (TrackBits)_exit_tunnel_track[dir];
 
				assert(v->u.rail.track);
 
				v->vehstatus &= ~VS_HIDDEN;
 
				return VETSB_ENTERED_WORMHOLE;
 
			}
 
		} else if (v->type == VEH_ROAD) {
 
			fc = (x & 0xF) + (y << 4);
 
			dir = GetTunnelDirection(tile);
 
			dir = GetTunnelBridgeDirection(tile);
 
			vdir = DirToDiagDir(v->direction);
 

	
 
			/* Enter tunnel? */
 
			if (v->u.road.state != RVSB_WORMHOLE && dir == vdir) {
 
				if (fc == _tunnel_fractcoord_4[dir] ||
 
						fc == _tunnel_fractcoord_5[dir]) {
 
					v->tile = tile;
 
					v->u.road.state = RVSB_WORMHOLE;
 
					v->vehstatus |= VS_HIDDEN;
 
					return VETSB_ENTERED_WORMHOLE;
 
				} else {
 
					return VETSB_CONTINUE;
 
@@ -1413,25 +1414,25 @@ static uint32 VehicleEnter_TunnelBridge(
 
		}
 
	} else if (IsBridge(tile)) { // XXX is this necessary?
 
		DiagDirection dir;
 

	
 
		if (v->IsPrimaryVehicle()) {
 
			/* 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);
 
		dir = GetTunnelBridgeDirection(tile);
 
		if (DirToDiagDir(v->direction) == dir) {
 
			switch (dir) {
 
				default: NOT_REACHED();
 
				case DIAGDIR_NE: if ((x & 0xF) != 0)             return VETSB_CONTINUE; break;
 
				case DIAGDIR_SE: if ((y & 0xF) != TILE_SIZE - 1) return VETSB_CONTINUE; break;
 
				case DIAGDIR_SW: if ((x & 0xF) != TILE_SIZE - 1) return VETSB_CONTINUE; break;
 
				case DIAGDIR_NW: if ((y & 0xF) != 0)             return VETSB_CONTINUE; break;
 
			}
 
			if (v->type == VEH_TRAIN) {
 
				v->u.rail.track = TRACK_BIT_WORMHOLE;
 
				ClrBit(v->u.rail.flags, VRF_GOINGUP);
 
				ClrBit(v->u.rail.flags, VRF_GOINGDOWN);
 
@@ -1453,25 +1454,25 @@ static uint32 VehicleEnter_TunnelBridge(
 
					return VETSB_ENTERED_WORMHOLE;
 
				}
 
			}
 
			return VETSB_CONTINUE;
 
		}
 
	}
 
	return VETSB_CONTINUE;
 
}
 

	
 
static CommandCost TerraformTile_TunnelBridge(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
 
{
 
	if (_patches.build_on_slopes && AutoslopeEnabled() && IsBridge(tile)) {
 
		DiagDirection direction = GetBridgeRampDirection(tile);
 
		DiagDirection direction = GetTunnelBridgeDirection(tile);
 
		Axis axis = DiagDirToAxis(direction);
 
		CommandCost res;
 

	
 
		/* Check if new slope is valid for bridges in general (so we can savely call GetBridgeFoundation()) */
 
		if ((direction == DIAGDIR_NW) || (direction == DIAGDIR_NE)) {
 
			res = CheckBridgeSlopeSouth(axis, tileh_new);
 
		} else {
 
			res = CheckBridgeSlopeNorth(axis, tileh_new);
 
		}
 

	
 
		if (!CmdFailed(res)) {
 
			uint z_old;
src/tunnelbridge_map.h
Show inline comments
 
new file 100644
 
/* $Id$ */
 

	
 
/** @file tunnelbridge_map.h Functions that have tunnels and bridges in common */
 

	
 
#ifndef TUNNELBRIDGE_MAP_H
 
#define TUNNELBRIDGE_MAP_H
 

	
 
#include "direction.h"            /* DiagDirection */
 
#include "core/bitmath_func.hpp"  /* GB, HasBit, SB */
 
#include "map.h"                  /* Tile, TileIndex */
 
#include "tile.h"                 /* TileType, IsTileType */
 
#include "openttd.h"              /* TransportType */
 

	
 

	
 
/**
 
 * Tunnel: Get the direction facing out of the tunnel
 
 * Bridge: Get the direction pointing onto the bridge
 
 * @param t The tile to analyze
 
 * @pre IsTileType(t, MP_TUNNELBRIDGE)
 
 * @return the above mentionned direction
 
 */
 
static inline DiagDirection GetTunnelBridgeDirection(TileIndex t)
 
{
 
	assert(IsTileType(t, MP_TUNNELBRIDGE));
 
	return (DiagDirection)GB(_m[t].m5, 0, 2);
 
}
 

	
 
/**
 
 * Tunnel: Get the transport type of the tunnel (road or rail)
 
 * Bridge: Get the transport type of the bridge's ramp
 
 * @param t The tile to analyze
 
 * @pre IsTileType(t, MP_TUNNELBRIDGE)
 
 * @return the transport type in the tunnel/bridge
 
 */
 
static inline TransportType GetTunnelBridgeTransportType(TileIndex t)
 
{
 
	assert(IsTileType(t, MP_TUNNELBRIDGE));
 
	return (TransportType)GB(_m[t].m5, 2, 2);
 
}
 

	
 
/**
 
 * Tunnel: Is this tunnel entrance in a snowy or desert area?
 
 * Bridge: Does the bridge ramp lie in a snow or desert area?
 
 * @param t The tile to analyze
 
 * @pre IsTileType(t, MP_TUNNELBRIDGE)
 
 * @return true if and only if the tile is in a snowy/desert area
 
 */
 
static inline bool HasTunnelBridgeSnowOrDesert(TileIndex t)
 
{
 
	assert(IsTileType(t, MP_TUNNELBRIDGE));
 
	return HasBit(_m[t].m4, 7);
 
}
 

	
 
/**
 
 * Tunnel: Places this tunnel entrance in a snowy or desert area, or takes it out of there.
 
 * Bridge: Sets whether the bridge ramp lies in a snow or desert area.
 
 * @param t the tunnel entrance / bridge ramp tile
 
 * @param snow_or_desert is the entrance/ramp in snow or desert (true), when
 
 *                       not in snow and not in desert false
 
 * @pre IsTileType(t, MP_TUNNELBRIDGE)
 
 */
 
static inline void SetTunnelBridgeSnowOrDesert(TileIndex t, bool snow_or_desert)
 
{
 
	assert(IsTileType(t, MP_TUNNELBRIDGE));
 
	SB(_m[t].m4, 7, 1, snow_or_desert);
 
}
 

	
 
#endif /* TUNNELBRIDGE_MAP_H */
src/yapf/follow_track.hpp
Show inline comments
 
@@ -69,39 +69,39 @@ struct CFollowTrackT : public FollowTrac
 
		return true;
 
	}
 

	
 
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);
 
			DiagDirection tunnel_enterdir = GetTunnelBridgeDirection(m_old_tile);
 
			if (tunnel_enterdir == m_exitdir) {
 
				// we are entering the tunnel
 
				FindLengthOfTunnelResult flotr = FindLengthOfTunnel(m_old_tile, m_exitdir);
 
				m_new_tile = flotr.tile;
 
				m_is_tunnel = true;
 
				m_tiles_skipped = flotr.length - 1;
 
				return;
 
			}
 
			assert(ReverseDiagDir(tunnel_enterdir) == m_exitdir);
 
		}
 

	
 
		// extra handling for bridge ramp in our direction
 
		if (IsBridgeTile(m_old_tile)) {
 
			DiagDirection bridge_enterdir = GetBridgeRampDirection(m_old_tile);
 
			DiagDirection bridge_enterdir = GetTunnelBridgeDirection(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
 
@@ -199,33 +199,33 @@ protected:
 
			RailType rail_type = GetTileRailType(m_new_tile);
 
			if (!HasBit(m_veh->u.rail.compatible_railtypes, rail_type)) {
 
				// incompatible rail type
 
				m_err = EC_RAIL_TYPE;
 
				return false;
 
			}
 
		}
 

	
 
		// tunnel holes and bridge ramps can be entered only from proper direction
 
		if (!IsWaterTT() && IsTileType(m_new_tile, MP_TUNNELBRIDGE)) {
 
			if (IsTunnel(m_new_tile)) {
 
				if (!m_is_tunnel) {
 
					DiagDirection tunnel_enterdir = GetTunnelDirection(m_new_tile);
 
					DiagDirection tunnel_enterdir = GetTunnelBridgeDirection(m_new_tile);
 
					if (tunnel_enterdir != m_exitdir) {
 
						m_err = EC_NO_WAY;
 
						return false;
 
					}
 
				}
 
			} else if (IsBridge(m_new_tile)) {
 
				if (!m_is_bridge) {
 
					DiagDirection ramp_enderdir = GetBridgeRampDirection(m_new_tile);
 
					DiagDirection ramp_enderdir = GetTunnelBridgeDirection(m_new_tile);
 
					if (ramp_enderdir != m_exitdir) {
 
						m_err = EC_NO_WAY;
 
						return false;
 
					}
 
				}
 
			}
 
		}
 

	
 
		// special handling for rail stations - get to the end of platform
 
		if (IsRailTT() && m_is_station) {
 
			// entered railway station
 
			// get platform length
src/yapf/yapf.hpp
Show inline comments
 
@@ -3,24 +3,25 @@
 
#ifndef  YAPF_HPP
 
#define  YAPF_HPP
 

	
 

	
 

	
 
#include "track_dir.hpp"
 

	
 
#include "../vehicle.h"
 
#include "../depot.h"
 
#include "../road_map.h"
 
#include "../tunnel_map.h"
 
#include "../bridge_map.h"
 
#include "../tunnelbridge_map.h"
 
#include "../bridge.h"
 
#include "../station.h"
 
#include "../station_map.h"
 
#include "../date.h"
 
#include "../functions.h"
 
#include "../landscape.h"
 
#include "yapf.h"
 
#include "../pathfind.h"
 
#include "../waypoint.h"
 
#include "../debug.h"
 

	
 
extern Patches _patches_newgame;
src/yapf/yapf_costbase.hpp
Show inline comments
 
@@ -2,25 +2,25 @@
 

	
 
#ifndef  YAPF_COSTBASE_HPP
 
#define  YAPF_COSTBASE_HPP
 

	
 
struct CYapfCostBase {
 
	static const TrackdirBits   c_upwards_slopes[16];
 

	
 
	FORCEINLINE static bool stSlopeCost(TileIndex tile, Trackdir td)
 
	{
 
		if (IsDiagonalTrackdir(td)) {
 
			if (IsBridgeTile(tile)) {
 
				// it is bridge ramp, check if we are entering the bridge
 
				if (GetBridgeRampDirection(tile) != TrackdirToExitdir(td)) return false; // no, we are living it, no penalty
 
				if (GetTunnelBridgeDirection(tile) != TrackdirToExitdir(td)) return false; // no, we are living it, no penalty
 
				// we are entering the bridge
 
				// if the tile slope is downwards, then bridge ramp has not upward slope
 
				uint tile_slope = GetTileSlope(tile, NULL) & 0x0F;
 
				if ((c_upwards_slopes[tile_slope] & TrackdirToTrackdirBits(ReverseTrackdir(td))) != 0) return false; // tile under ramp goes down, no penalty
 
				// tile under ramp isn't going down, so ramp must go up
 
				return true;
 
			} else {
 
				// not bridge ramp
 
				if (IsTunnelTile(tile)) return false; // tunnel entry/exit doesn't slope
 
				uint tile_slope = GetTileSlope(tile, NULL) & 0x0F;
 
				if ((c_upwards_slopes[tile_slope] & TrackdirToTrackdirBits(td)) != 0) return true; // slopes uphill => apply penalty
 
			}
0 comments (0 inline, 0 general)