Changeset - r3234:e8dbbce03288
[Not reviewed]
master
0 13 0
tron - 19 years ago 2006-03-16 15:16:27
tron@openttd.org
(svn r3907) Replace many bridge related direct map accesses with calls to shiny new functions and mark some strange constructs with XXX
13 files changed with 215 insertions and 168 deletions:
0 comments (0 inline, 0 general)
ai/default/default.c
Show inline comments
 
@@ -2157,8 +2157,7 @@ static bool AiRemoveTileAndGoForward(Pla
 
			return true;
 
		}
 

	
 
		if (!(_m[tile].m5 & 0x40)) {
 

	
 
		if (IsBridgeRamp(tile)) {
 
			// Check if the bridge points in the right direction.
 
			// This is not really needed the first place AiRemoveTileAndGoForward is called.
 
			if (DiagDirToAxis(GetBridgeRampDirection(tile)) != (p->ai.cur_dir_a & 1U)) return false;
 
@@ -3669,8 +3668,12 @@ pos_3:
 
				CMD_REMOVE_ROAD);
 
		}
 
	} else if (IsTileType(tile, MP_TUNNELBRIDGE)) {
 
		if (!IsTileOwner(tile, _current_player) || (_m[tile].m5 & 0xC6) != 0x80)
 
		if (!IsTileOwner(tile, _current_player) ||
 
				!IsBridge(tile) ||
 
				!IsBridgeRamp(tile) ||
 
				GetBridgeTransportType(tile) != TRANSPORT_RAIL) {
 
			return;
 
		}
 

	
 
		m5 = 0;
 

	
ai/trolly/pathfinder.c
Show inline comments
 
@@ -2,6 +2,7 @@
 

	
 
#include "../../stdafx.h"
 
#include "../../openttd.h"
 
#include "../../bridge_map.h"
 
#include "../../debug.h"
 
#include "../../functions.h"
 
#include "../../map.h"
 
@@ -44,8 +45,7 @@ static bool IsRoad(TileIndex tile)
 
		(IsTileType(tile, MP_STREET) && !IsTileDepotType(tile, TRANSPORT_ROAD)) ||
 
		(IsTileType(tile, MP_TUNNELBRIDGE) && (
 
			(IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_ROAD) ||
 
			// road bridge?
 
			((_m[tile].m5 & 0x80) != 0 && (_m[tile].m5 & 0x2) == 0x2)
 
			(IsBridge(tile) && GetBridgeTransportType(tile) == TRANSPORT_ROAD)
 
		));
 
}
 

	
 
@@ -234,7 +234,7 @@ static void AyStar_AiPathFinder_GetNeigh
 
					if (IsTunnel(atile)) {
 
						if (GetTunnelDirection(atile) != i) continue;
 
					} else {
 
						if ((_m[atile].m5 & 1U) != DiagDirToAxis(i)) continue;
 
						if (GetBridgeRampDirection(atile) != i) continue;
 
					}
 
				}
 
			}
bridge_map.h
Show inline comments
 
@@ -7,9 +7,21 @@
 
#include "macros.h"
 
#include "map.h"
 
#include "rail.h"
 
#include "road_map.h"
 
#include "tile.h"
 

	
 

	
 
static inline bool IsBridge(TileIndex t)
 
{
 
	return HASBIT(_m[t].m5, 7);
 
}
 

	
 
static inline bool IsBridgeTile(TileIndex t)
 
{
 
	return IsTileType(t, MP_TUNNELBRIDGE) && IsBridge(t);
 
}
 

	
 

	
 
static inline bool IsBridgeRamp(TileIndex t)
 
{
 
	return !HASBIT(_m[t].m5, 6);
 
@@ -61,6 +73,12 @@ static inline Axis GetBridgeAxis(TileInd
 
}
 

	
 

	
 
static inline TransportType GetBridgeTransportType(TileIndex t)
 
{
 
	return (TransportType)GB(_m[t].m5, 1, 2);
 
}
 

	
 

	
 
static inline bool IsClearUnderBridge(TileIndex t)
 
{
 
	return GB(_m[t].m5, 3, 3) == 0;
 
@@ -82,6 +100,16 @@ static inline TransportType GetTransport
 
	return (TransportType)GB(_m[t].m5, 3, 2);
 
}
 

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

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

	
 

	
 
/**
 
 * Finds the end of a bridge in the specified direction starting at a middle tile
npf.c
Show inline comments
 
@@ -2,6 +2,7 @@
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
#include "debug.h"
 
#include "functions.h"
 
#include "npf.h"
 
@@ -484,8 +485,10 @@ static bool VehicleMayEnterTile(Owner ow
 
			/* if we were on a railway middle part, we are now at a railway bridge ending */
 
#endif
 
			if ((IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_RAIL) ||
 
					(_m[tile].m5 & 0xC6) == 0x80 || /* railway bridge ending */
 
					((_m[tile].m5 & 0xF8) == 0xE0 && GB(_m[tile].m5, 0, 1) != (enterdir & 0x1))) { /* railway under bridge */
 
					(IsBridge(tile) && (
 
						(IsBridgeRamp(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) ||
 
						(IsBridgeMiddle(tile) && IsTransportUnderBridge(tile) && GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL)
 
					))) {
 
				return IsTileOwner(tile, owner);
 
			}
 
			break;
pathfind.c
Show inline comments
 
@@ -2,6 +2,7 @@
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
#include "functions.h"
 
#include "map.h"
 
#include "tile.h"
 
@@ -137,11 +138,18 @@ static void TPFMode2(TrackPathFinder* tp
 

	
 
	/* XXX: Mode 2 is currently only used for ships, why is this code here? */
 
	if (tpf->tracktype == TRANSPORT_RAIL) {
 
		if (IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_STATION) || IsTileType(tile, MP_TUNNELBRIDGE)) {
 
			owner = GetTileOwner(tile);
 
			/* Check if we are on the middle of a bridge (has no owner) */
 
			if (IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5 & 0xC0) == 0xC0)
 
				owner = -1;
 
		switch (GetTileType(tile)) {
 
			case MP_TUNNELBRIDGE:
 
				// bridge middle has no owner
 
				if (IsBridge(tile) && IsBridgeMiddle(tile)) break;
 
				/* FALLTHROUGH */
 

	
 
			case MP_RAILWAY:
 
			case MP_STATION:
 
				owner = GetTileOwner(tile);
 
				break;
 

	
 
			default: break; // XXX can this occur?
 
		}
 
	}
 

	
 
@@ -152,11 +160,19 @@ static void TPFMode2(TrackPathFinder* tp
 

	
 
	/* Check in case of rail if the owner is the same */
 
	if (tpf->tracktype == TRANSPORT_RAIL) {
 
		if (IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_STATION) || IsTileType(tile, MP_TUNNELBRIDGE))
 
			/* Check if we are on the middle of a bridge (has no owner) */
 
			if (!IsTileType(tile, MP_TUNNELBRIDGE) || (_m[tile].m5 & 0xC0) != 0xC0)
 
				if (owner != -1 && !IsTileOwner(tile, owner))
 
					return;
 
		switch (GetTileType(tile)) {
 
			case MP_TUNNELBRIDGE:
 
				// bridge middle has no owner
 
				if (IsBridge(tile) && IsBridgeMiddle(tile)) break;
 
				/* FALLTHROUGH */
 

	
 
			case MP_RAILWAY:
 
			case MP_STATION:
 
				if (owner != -1 && !IsTileOwner(tile, owner)) return;
 
				break;
 

	
 
			default: break; // XXX can this occur?
 
		}
 
	}
 

	
 
	if (++tpf->rd.cur_length > 50)
 
@@ -296,8 +312,8 @@ static void TPFMode1(TrackPathFinder* tp
 
		if (IsTileType(tile_org, MP_RAILWAY) || IsTileType(tile_org, MP_STATION) || IsTileType(tile_org, MP_TUNNELBRIDGE))
 
			if (IsTileType(tile, MP_RAILWAY) || IsTileType(tile, MP_STATION) || IsTileType(tile, MP_TUNNELBRIDGE))
 
				/* Check if we are on a bridge (middle parts don't have an owner */
 
				if (!IsTileType(tile, MP_TUNNELBRIDGE) || (_m[tile].m5 & 0xC0) != 0xC0)
 
					if (!IsTileType(tile_org, MP_TUNNELBRIDGE) || (_m[tile_org].m5 & 0xC0) != 0xC0)
 
				if (!IsBridgeTile(tile) || !IsBridgeMiddle(tile))
 
					if (!IsBridgeTile(tile_org) || !IsBridgeMiddle(tile_org))
 
						if (GetTileOwner(tile_org) != GetTileOwner(tile))
 
							return;
 
	}
rail.c
Show inline comments
 
@@ -2,6 +2,7 @@
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
#include "rail.h"
 
#include "station.h"
 
#include "tunnel_map.h"
 
@@ -124,18 +125,32 @@ RailType GetTileRailType(TileIndex tile,
 
				type = _m[tile].m3 & RAILTYPE_MASK;
 
			break;
 
		case MP_TUNNELBRIDGE:
 
			if (IsTunnel(tile) && GetTunnelTransportType(tile) == TRANSPORT_RAIL) {
 
				return _m[tile].m3 & RAILTYPE_MASK;
 
			if (IsTunnel(tile)) {
 
				if (GetTunnelTransportType(tile) == TRANSPORT_RAIL) {
 
					return _m[tile].m3 & RAILTYPE_MASK;
 
				}
 
			} else {
 
				if (IsBridgeRamp(tile)) {
 
					if (GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
 
						return _m[tile].m3 & RAILTYPE_MASK;
 
					}
 
				} else {
 
					if (GetBridgeAxis(tile) == DiagDirToAxis(exitdir)) {
 
						if (GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
 
							/* on the bridge */
 
							return (_m[tile].m3 >> 4) & RAILTYPE_MASK;
 
						}
 
					} else {
 
						if (IsTransportUnderBridge(tile) &&
 
								GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL) {
 
							/* under the bridge */
 
							return _m[tile].m3 & RAILTYPE_MASK;
 
						}
 
					}
 
				}
 
			}
 
			/* railway bridge ending */
 
			if ((_m[tile].m5 & 0xC6) == 0x80) type = _m[tile].m3 & RAILTYPE_MASK;
 
			/* on railway bridge */
 
			if ((_m[tile].m5 & 0xC6) == 0xC0 && ((DiagDirection)(_m[tile].m5 & 0x1)) == (exitdir & 0x1))
 
				type = (_m[tile].m3 >> 4) & RAILTYPE_MASK;
 
			/* under bridge (any type) */
 
			if ((_m[tile].m5 & 0xF8) == 0xE0 && (_m[tile].m5 & 0x1U) != (exitdir & 0x1))
 
				type = _m[tile].m3 & RAILTYPE_MASK;
 
			break;
 

	
 
		default:
 
			break;
 
	}
rail_cmd.c
Show inline comments
 
@@ -288,27 +288,25 @@ int32 CmdBuildSingleRail(int x, int y, u
 

	
 
	switch (GetTileType(tile)) {
 
		case MP_TUNNELBRIDGE:
 
			if ((m5 & 0xC0) != 0xC0 || // not bridge middle part?
 
					(m5 & 0x01 ? TRACK_BIT_X : TRACK_BIT_Y) != trackbit) { // wrong direction?
 
			if (!IsBridge(tile) ||
 
					!IsBridgeMiddle(tile) ||
 
					(GetBridgeAxis(tile) == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X) != trackbit) {
 
				// Get detailed error message
 
				return DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
			}
 

	
 
			switch (m5 & 0x38) { // what's under the bridge?
 
				case 0x00: // clear land
 
					ret = CheckRailSlope(tileh, trackbit, 0, tile);
 
					if (CmdFailed(ret)) return ret;
 
					cost += ret;
 
			if (IsClearUnderBridge(tile)) {
 
				ret = CheckRailSlope(tileh, trackbit, 0, tile);
 
				if (CmdFailed(ret)) return ret;
 
				cost += ret;
 

	
 
					if (flags & DC_EXEC) SetRailUnderBridge(tile, _current_player, p1);
 
					break;
 

	
 
				case 0x20: // rail already there
 
					return_cmd_error(STR_1007_ALREADY_BUILT);
 

	
 
				default:
 
					// Get detailed error message
 
					return DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
				if (flags & DC_EXEC) SetRailUnderBridge(tile, _current_player, p1);
 
			} else if (IsTransportUnderBridge(tile) &&
 
					GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL) {
 
				return_cmd_error(STR_1007_ALREADY_BUILT);
 
			} else {
 
				// Get detailed error message
 
				return DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
			}
 
			break;
 

	
 
@@ -411,14 +409,14 @@ int32 CmdRemoveSingleRail(int x, int y, 
 
	switch (GetTileType(tile))
 
	{
 
		case MP_TUNNELBRIDGE:
 
			if (!EnsureNoVehicleZ(tile, TilePixelHeight(tile)))
 
			if (!IsBridge(tile) ||
 
					!IsBridgeMiddle(tile) ||
 
					!IsTransportUnderBridge(tile) ||
 
					GetTransportTypeUnderBridge(tile) != TRANSPORT_RAIL ||
 
					GetRailBitsUnderBridge(tile) != trackbit ||
 
					!EnsureNoVehicleZ(tile, TilePixelHeight(tile))) {
 
				return CMD_ERROR;
 

	
 
			if ((_m[tile].m5 & 0xF8) != 0xE0)
 
				return CMD_ERROR;
 

	
 
			if ((_m[tile].m5 & 1 ? TRACK_BIT_X : TRACK_BIT_Y) != trackbit)
 
				return CMD_ERROR;
 
			}
 

	
 
			if (!(flags & DC_EXEC))
 
				return _price.remove_rail;
road_cmd.c
Show inline comments
 
@@ -129,11 +129,11 @@ int32 CmdRemoveRoad(int x, int y, uint32
 
		case MP_TUNNELBRIDGE:
 
			if (!EnsureNoVehicleZ(tile, TilePixelHeight(tile))) return CMD_ERROR;
 

	
 
			if ((ti.map5 & 0xE9) == 0xE8) {
 
				if (pieces & ROAD_X) return CMD_ERROR;
 
			} else if ((ti.map5 & 0xE9) == 0xE9) {
 
				if (pieces & ROAD_Y) return CMD_ERROR;
 
			} else {
 
			if (!IsBridge(tile) ||
 
					!IsBridgeMiddle(tile) ||
 
					!IsTransportUnderBridge(tile) ||
 
					GetTransportTypeUnderBridge(tile) != TRANSPORT_ROAD ||
 
					(pieces & ComplementRoadBits(GetRoadBitsUnderBridge(tile))) != 0) {
 
				return CMD_ERROR;
 
			}
 

	
 
@@ -357,19 +357,23 @@ int32 CmdBuildRoad(int x, int y, uint32 
 
				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 
			}
 

	
 
			/* is this middle part of a bridge? */
 
			if ((ti.map5 & 0xC0) != 0xC0) goto do_clear;
 
			if (!IsBridge(tile) || !IsBridgeMiddle(tile)) goto do_clear;
 

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

	
 
			/* check if clear land under bridge */
 
			if ((ti.map5 & 0xF8) == 0xE8) { /* road under bridge */
 
				return_cmd_error(STR_1007_ALREADY_BUILT);
 
			} else if ((ti.map5 & 0xE0) == 0xE0) { /* other transport route under bridge */
 
				return_cmd_error(STR_1008_MUST_REMOVE_RAILROAD_TRACK);
 
			} else if ((ti.map5 & 0xF8) == 0xC8) { /* water under bridge */
 
				return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
 
			if (IsTransportUnderBridge(tile)) {
 
				switch (GetTransportTypeUnderBridge(tile)) {
 
					case TRANSPORT_ROAD: return_cmd_error(STR_1007_ALREADY_BUILT);
 
					default: return_cmd_error(STR_1008_MUST_REMOVE_RAILROAD_TRACK);
 
				}
 
			} else {
 
				if (IsWaterUnderBridge(tile)) {
 
					return_cmd_error(STR_3807_CAN_T_BUILD_ON_WATER);
 
				}
 
			}
 

	
 
			/* all checked, can build road now! */
road_map.c
Show inline comments
 
@@ -25,15 +25,16 @@ RoadBits GetAnyRoadBits(TileIndex tile)
 
			return DiagDirToRoadBits(GetRoadStationDir(tile));
 

	
 
		case MP_TUNNELBRIDGE:
 
			if (_m[tile].m5 & 0x80) {
 
				// bridge
 
				if (_m[tile].m5 & 0x40) {
 
					// middle part
 
					if ((_m[tile].m5 & 0x38) != 0x28) return 0; // no road under bridge
 
					return _m[tile].m5 & 1 ? ROAD_X : ROAD_Y;
 
			if (IsBridge(tile)) {
 
				if (IsBridgeMiddle(tile)) {
 
					if (!IsTransportUnderBridge(tile) ||
 
							GetBridgeTransportType(tile) != TRANSPORT_ROAD) {
 
						return 0;
 
					}
 
					return GetRoadBitsUnderBridge(tile);
 
				} else {
 
					// ending
 
					if (GB(_m[tile].m5, 1, 2) != TRANSPORT_ROAD) return 0; // not a road bridge
 
					if (GetBridgeTransportType(tile) != TRANSPORT_ROAD) return 0;
 
					return DiagDirToRoadBits(ReverseDiagDir(GetBridgeRampDirection(tile)));
 
				}
 
			} else {
smallmap_gui.c
Show inline comments
 
@@ -2,6 +2,7 @@
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
#include "clear_map.h"
 
#include "functions.h"
 
#include "spritecache.h"
 
@@ -351,7 +352,7 @@ static inline TileType GetEffectiveTileT
 
		if (IsTunnel(tile)) {
 
			tt = GetTunnelTransportType(tile);
 
		} else {
 
			tt = GB(_m[tile].m5, 1, 2);
 
			tt = GetBridgeTransportType(tile);
 
		}
 
		switch (tt) {
 
			case TRANSPORT_RAIL: t = MP_RAILWAY; break;
train_cmd.c
Show inline comments
 
@@ -2,6 +2,7 @@
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "bridge_map.h"
 
#include "debug.h"
 
#include "functions.h"
 
#include "gui.h"
 
@@ -2545,7 +2546,7 @@ static bool CheckCompatibleRail(const Ve
 
			break;
 

	
 
		case MP_TUNNELBRIDGE:
 
			if ((_m[tile].m5 & 0xC0) == 0xC0) { // is bridge middle part?
 
			if (IsBridge(tile) && IsBridgeMiddle(tile)) {
 
				uint height;
 
				uint tileh = GetTileSlope(tile, &height);
 

	
tunnelbridge_cmd.c
Show inline comments
 
@@ -670,22 +670,18 @@ static int32 DoClearBridge(TileIndex til
 
		DoClearSquare(tile);
 
		DoClearSquare(endtile);
 
		for (c = tile + delta; c != endtile; c += delta) {
 
			if (_m[c].m5 & 0x20) {
 
				// transport under bridge
 
				if (GB(_m[c].m5, 3, 2) == TRANSPORT_RAIL) {
 
					MakeRailNormal(c, GetTileOwner(c), _m[c].m5 & 1 ? TRACK_BIT_X : TRACK_BIT_Y, GB(_m[c].m3, 0, 3));
 
			if (IsTransportUnderBridge(c)) {
 
				if (GetTransportTypeUnderBridge(c) == TRANSPORT_RAIL) {
 
					MakeRailNormal(c, GetTileOwner(c), GetRailBitsUnderBridge(c), GB(_m[c].m3, 0, 3));
 
				} else {
 
					uint town = IsTileOwner(c, OWNER_TOWN) ? ClosestTownFromTile(c, (uint)-1)->index : 0;
 
					MakeRoadNormal(c, GetTileOwner(c), _m[c].m5 & 1 ? ROAD_X : ROAD_Y, town);
 
					MakeRoadNormal(c, GetTileOwner(c), GetRoadBitsUnderBridge(c), town);
 
				}
 
				MarkTileDirtyByTile(c);
 
			} else {
 
				// clear under bridge
 
				if (GB(_m[c].m5, 3, 2) == 0) {
 
					// grass under bridge
 
				if (IsClearUnderBridge(c)) {
 
					DoClearSquare(c);
 
				} else {
 
					// water under bridge
 
					if (GetTileSlope(c, NULL) == 0) {
 
						MakeWater(c);
 
					} else {
 
@@ -705,12 +701,10 @@ static int32 DoClearBridge(TileIndex til
 

	
 
static int32 ClearTile_TunnelBridge(TileIndex tile, byte flags)
 
{
 
	byte m5 = _m[tile].m5;
 

	
 
	if (IsTunnel(tile)) {
 
		if (flags & DC_AUTO) return_cmd_error(STR_5006_MUST_DEMOLISH_TUNNEL_FIRST);
 
		return DoClearTunnel(tile, flags);
 
	} else if (m5 & 0x80) {
 
	} else if (IsBridge(tile)) { // XXX Is this necessary?
 
		if (flags & DC_AUTO) return_cmd_error(STR_5007_MUST_DEMOLISH_BRIDGE_FIRST);
 
		return DoClearBridge(tile, flags);
 
	}
 
@@ -739,8 +733,10 @@ int32 DoConvertTunnelBridgeRail(TileInde
 
			MarkTileDirtyByTile(endtile);
 
		}
 
		return (length + 1) * (_price.build_rail >> 1);
 
	} else if ((_m[tile].m5 & 0xF8) == 0xE0) {
 
		// bridge middle part with rail below
 
	} else if (IsBridge(tile) &&
 
			IsBridgeMiddle(tile) &&
 
			IsTransportUnderBridge(tile) &&
 
			GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL) {
 
		// only check for train under bridge
 
		if (!CheckTileOwnership(tile) || !EnsureNoVehicleZ(tile, TilePixelHeight(tile)))
 
			return CMD_ERROR;
 
@@ -753,7 +749,7 @@ int32 DoConvertTunnelBridgeRail(TileInde
 
			MarkTileDirtyByTile(tile);
 
		}
 
		return _price.build_rail >> 1;
 
	} else if ((_m[tile].m5 & 0xC6) == 0x80) {
 
	} else if (IsBridge(tile) && IsBridgeRamp(tile) && GetBridgeTransportType(tile) == TRANSPORT_RAIL) {
 
		TileIndexDiff delta;
 
		int32 cost;
 
		uint z = TilePixelHeight(tile);
 
@@ -762,7 +758,6 @@ int32 DoConvertTunnelBridgeRail(TileInde
 

	
 
		if (!CheckTileOwnership(tile)) return CMD_ERROR;
 

	
 
		// railway bridge
 
		endtile = GetOtherBridgeEnd(tile);
 
		// Make sure there's no vehicle on the bridge
 
		v = FindVehicleBetween(tile, endtile, z);
 
@@ -821,6 +816,7 @@ extern const byte _road_sloped_sprites[1
 

	
 
static void DrawBridgePillars(const TileInfo *ti, int x, int y, int z)
 
{
 
	Axis axis = GetBridgeAxis(ti->tile);
 
	const PalSpriteID *b;
 
	PalSpriteID image;
 
	int piece;
 
@@ -830,7 +826,7 @@ static void DrawBridgePillars(const Tile
 
	// Draw first piece
 
	// (necessary for cantilever bridges)
 

	
 
	image = b[12 + GB(ti->map5, 0, 1)];
 
	image = b[axis == AXIS_X ? 12 : 13];
 
	piece = GetBridgePiece(ti->tile);
 

	
 
	if (image != 0 && piece != 0) {
 
@@ -838,7 +834,7 @@ static void DrawBridgePillars(const Tile
 
		DrawGroundSpriteAt(image, x, y, z);
 
	}
 

	
 
	image = b[GB(ti->map5, 0, 1) * 6 + piece];
 
	image = b[piece + (axis == AXIS_X ? 0 : 6)];
 

	
 
	if (image != 0) {
 
		int back_height, front_height, i=z;
 
@@ -853,7 +849,7 @@ static void DrawBridgePillars(const Tile
 

	
 
		if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
 

	
 
		p = _tileh_bits[(image & 1) * 2 + (ti->map5&0x01)];
 
		p = _tileh_bits[(image & 1) * 2 + (axis == AXIS_X ? 0 : 1)];
 
		front_height = ti->z + ((ti->tileh & p[0])?8:0);
 
		back_height = ti->z + ((ti->tileh & p[1])?8:0);
 

	
 
@@ -920,7 +916,6 @@ static void DrawTile_TunnelBridge(TileIn
 
	const PalSpriteID *b;
 
	bool ice = _m[ti->tile].m4 & 0x80;
 

	
 
	// draw tunnel?
 
	if (IsTunnel(ti->tile)) {
 
		if (GetTunnelTransportType(ti->tile) == TRANSPORT_RAIL) {
 
			image = GetRailTypeInfo(GB(_m[ti->tile].m3, 0, 4))->base_sprites.tunnel;
 
@@ -934,30 +929,30 @@ static void DrawTile_TunnelBridge(TileIn
 
		DrawGroundSprite(image);
 

	
 
		AddSortableSpriteToDraw(image+1, ti->x + 15, ti->y + 15, 1, 1, 8, (byte)ti->z);
 
	// draw bridge?
 
	} else if (ti->map5 & 0x80) {
 
		RailType rt;
 
	} else if (IsBridge(ti->tile)) { // XXX is this necessary?
 
		int base_offset;
 

	
 
		if (HASBIT(ti->map5, 1)) { /* This is a road bridge */
 
			base_offset = 8;
 
		} else { /* Rail bridge */
 
			if (HASBIT(ti->map5, 6)) { /* The bits we need depend on the fact whether it is a bridge head or not */
 
		if (GetBridgeTransportType(ti->tile) == TRANSPORT_RAIL) {
 
			RailType rt;
 

	
 
			if (IsBridgeRamp(ti->tile)) {
 
				rt = GB(_m[ti->tile].m3, 0, 3);
 
			} else {
 
				rt = GB(_m[ti->tile].m3, 4, 3);
 
			} else {
 
				rt = GB(_m[ti->tile].m3, 0, 3);
 
			}
 

	
 
			base_offset = GetRailTypeInfo(rt)->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);
 

	
 
		if (!(ti->map5 & 0x40)) {	// bridge ramps
 
		if (IsBridgeRamp(ti->tile)) {
 
			if (!(BRIDGE_NO_FOUNDATION & (1 << ti->tileh))) {	// no foundations for 0, 3, 6, 9, 12
 
				int f = GetBridgeFoundation(ti->tileh, ti->map5 & 0x1);	// pass direction
 
				int f = GetBridgeFoundation(ti->tileh, DiagDirToAxis(GetBridgeRampDirection(ti->tile)));
 
				if (f) DrawFoundation(ti, f);
 
			}
 

	
 
@@ -1002,7 +997,6 @@ static void DrawTile_TunnelBridge(TileIn
 
					image += rti->total_offset;
 
					if (ice) image += rti->snow_offset;
 
				} else {
 
					// road
 
					if (ti->tileh == 0) {
 
						image = (axis == AXIS_X ? SPR_ROAD_Y : SPR_ROAD_X);
 
					} else {
 
@@ -1037,12 +1031,11 @@ static void DrawTile_TunnelBridge(TileIn
 
			// draw rail or road component
 
			image = b[0];
 
			if (_display_opt & DO_TRANS_BUILDINGS) MAKE_TRANSPARENT(image);
 
			AddSortableSpriteToDraw(
 
				image, ti->x, ti->y,
 
				axis == AXIS_X ? 16 : 11,
 
				axis == AXIS_X ? 11 : 16,
 
				1, z
 
			);
 
			if (axis == AXIS_X) {
 
				AddSortableSpriteToDraw(image, ti->x, ti->y, 16, 11, 1, z);
 
			} else {
 
				AddSortableSpriteToDraw(image, ti->x, ti->y, 11, 16, 1, z);
 
			}
 

	
 
			x = ti->x;
 
			y = ti->y;
 
@@ -1081,17 +1074,15 @@ static uint GetSlopeZ_TunnelBridge(const
 
	uint tileh = ti->tileh;
 

	
 
	// swap directions if Y tunnel/bridge to let the code handle the X case only.
 
	if (ti->map5 & 1) uintswap(x,y);
 
	if (ti->map5 & 1) uintswap(x,y); // XXX bogus: it could be a tunnel, bridge ramp or bridge middle tile
 

	
 
	// to the side of the tunnel/bridge?
 
	if (IS_INT_INSIDE(y, 5, 10+1)) {
 
		// tunnel?
 
		if ((ti->map5 & 0xF0) == 0) return z;
 
		if (IsTunnel(ti->tile)) return z;
 

	
 
		// bridge?
 
		if (ti->map5 & 0x80) {
 
			// bridge ending?
 
			if (!(ti->map5 & 0x40)) {
 
		if (IsBridge(ti->tile)) {
 
			if (IsBridgeRamp(ti->tile)) {
 
				if (BRIDGE_FULL_LEVELED_FOUNDATION & (1 << tileh)) // 7, 11, 13, 14
 
					z += 8;
 

	
 
@@ -1105,8 +1096,6 @@ static uint GetSlopeZ_TunnelBridge(const
 
					// ramp in opposite dir
 
					return z + ((x ^ 0xF) >> 1);
 
				}
 

	
 
			// bridge middle part
 
			} else {
 
				// build on slopes?
 
				if (tileh != 0) z += 8;
 
@@ -1119,8 +1108,9 @@ static uint GetSlopeZ_TunnelBridge(const
 

	
 
				// in the shared area, assume that we're below the bridge, cause otherwise the hint would've caught it.
 
				// if rail or road below then it means it's possibly build on slope below the bridge.
 
				if (ti->map5 & 0x20) {
 
					uint f = _bridge_foundations[ti->map5 & 1][tileh];
 
				if (IsTransportUnderBridge(ti->tile)) {
 
					uint f = _bridge_foundations[GetBridgeAxis(ti->tile)][tileh];
 

	
 
					// make sure that the slope is not inclined foundation
 
					if (IS_BYTE_INSIDE(f, 1, 15)) return z;
 

	
 
@@ -1132,11 +1122,10 @@ static uint GetSlopeZ_TunnelBridge(const
 
			}
 
		}
 
	} else {
 
		// if it's a bridge middle with transport route below, then we need to compensate for build on slopes
 
		if ((ti->map5 & (0x80 | 0x40 | 0x20)) == (0x80 | 0x40 | 0x20)) {
 
		if (IsBridge(ti->tile) && IsBridgeMiddle(ti->tile) && IsTransportUnderBridge(ti->tile)) {
 
			uint f;
 
			if (tileh != 0) z += 8;
 
			f = _bridge_foundations[ti->map5 & 1][tileh];
 
			f = _bridge_foundations[GetBridgeAxis(ti->tile)][tileh];
 
			if (IS_BYTE_INSIDE(f, 1, 15)) return z;
 
			if (f != 0) tileh = _inclined_tileh[f - 15];
 
		}
 
@@ -1196,7 +1185,7 @@ static void GetTileDesc_TunnelBridge(Til
 
		td->str = (GetTunnelTransportType(tile) == TRANSPORT_RAIL) ?
 
			STR_5017_RAILROAD_TUNNEL : STR_5018_ROAD_TUNNEL;
 
	} else {
 
		td->str = _bridge_tile_str[GB(_m[tile].m5, 1, 2) << 4 | GetBridgeType(tile)];
 
		td->str = _bridge_tile_str[GetBridgeTransportType(tile) << 4 | GetBridgeType(tile)];
 

	
 
		// the owner is stored at the end of the bridge
 
		if (IsBridgeMiddle(tile)) tile = GetSouthernBridgeEnd(tile);
 
@@ -1235,8 +1224,9 @@ static void TileLoop_TunnelBridge(TileIn
 
			break;
 
	}
 

	
 
	// if it's a bridge with water below, call tileloop_water on it.
 
	if ((_m[tile].m5 & 0xF8) == 0xC8) TileLoop_Water(tile);
 
	if (IsBridge(tile) && IsBridgeMiddle(tile) && IsWaterUnderBridge(tile)) {
 
		TileLoop_Water(tile);
 
	}
 
}
 

	
 
static void ClickTile_TunnelBridge(TileIndex tile)
 
@@ -1248,41 +1238,34 @@ static void ClickTile_TunnelBridge(TileI
 
static uint32 GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode)
 
{
 
	uint32 result;
 
	byte m5 = _m[tile].m5;
 

	
 
	if (IsTunnel(tile)) {
 
		if (GetTunnelTransportType(tile) == mode) {
 
			return DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? 0x101 : 0x202;
 
		}
 
	} else if (m5 & 0x80) {
 
	} else if (IsBridge(tile)) { // XXX is this necessary?
 
		/* This is a bridge */
 
		result = 0;
 
		if (GB(m5, 1, 2) == mode) {
 
		if (GetBridgeTransportType(tile) == mode) {
 
			/* Transport over the bridge is compatible */
 
			result = m5 & 1 ? 0x202 : 0x101;
 
			result = (GetBridgeAxis(tile) == AXIS_X ? 0x101 : 0x202);
 
		}
 
		if (m5 & 0x40) {
 
		if (IsBridgeMiddle(tile)) {
 
			/* Bridge middle part */
 
			if (!(m5 & 0x20)) {
 
				/* Clear ground or water underneath */
 
				if ((m5 & 0x18) != 8) {
 
					/* Clear ground */
 
			if (IsTransportUnderBridge(tile)) {
 
				if (GetTransportTypeUnderBridge(tile) != mode) return result;
 
			} else {
 
				if (IsClearUnderBridge(tile)) {
 
					return result;
 
				} else {
 
					if (mode != TRANSPORT_WATER) return result;
 
				}
 
			} else {
 
				/* Transport underneath */
 
				if (GB(m5, 3, 2) != mode) {
 
					/* Incompatible transport underneath */
 
					return result;
 
				}
 
			}
 
			/* If we've not returned yet, there is a compatible
 
			 * transport or water beneath, so we can add it to
 
			 * result */
 
			/* Why is this xor'd ? Can't it just be or'd? */
 
			result ^= m5 & 1 ? 0x101 : 0x202;
 
			result ^= (GetBridgeAxis(tile) == AXIS_X ? 0x202 : 0x101);
 
		}
 
		return result;
 
	} else {
 
@@ -1298,13 +1281,11 @@ static void ChangeTileOwner_TunnelBridge
 
	if (new_player != OWNER_SPECTATOR) {
 
		SetTileOwner(tile, new_player);
 
	}	else {
 
		if ((_m[tile].m5 & 0xE0) == 0xE0) {
 
		if (IsBridge(tile) && IsBridgeMiddle(tile) && IsTransportUnderBridge(tile)) {
 
			// the stuff BELOW the middle part is owned by the deleted player.
 
			if (!(_m[tile].m5 & (1 << 4 | 1 << 3))) {
 
				// convert railway into grass.
 
			if (GetTransportTypeUnderBridge(tile) == TRANSPORT_RAIL) {
 
				SetClearUnderBridge(tile);
 
			} else {
 
				// for road, change the owner of the road to local authority
 
				SetTileOwner(tile, OWNER_NONE);
 
			}
 
		} else {
 
@@ -1396,13 +1377,13 @@ static uint32 VehicleEnter_TunnelBridge(
 
				return 4;
 
			}
 
		}
 
	} else if (_m[tile].m5 & 0x80) {
 
	} else if (IsBridge(tile)) { // XXX is this necessary?
 
		if (v->type == VEH_Road || (v->type == VEH_Train && IsFrontEngine(v))) {
 
			uint h;
 

	
 
			// Compensate for possible foundation
 
			if (GetTileSlope(tile, &h) != 0) h += 8;
 
			if (!(_m[tile].m5 & 0x40) || // start/end tile of bridge
 
			if (IsBridgeRamp(tile) ||
 
					myabs(h - v->z_pos) > 2) { // high above the ground -> on the bridge
 
				/* modify speed of vehicle */
 
				uint16 spd = _bridge[GetBridgeType(tile)].speed;
water_cmd.c
Show inline comments
 
@@ -241,13 +241,12 @@ int32 CmdBuildCanal(int x, int y, uint32
 
		if (IsTileType(tile, MP_WATER)) continue;
 

	
 
		/* is middle piece of a bridge? */
 
		if (IsTileType(tile, MP_TUNNELBRIDGE) && _m[tile].m5 & 0x40) { /* build under bridge */
 
			if (_m[tile].m5 & 0x20) // transport route under bridge
 
		if (IsBridgeTile(tile) && IsBridgeMiddle(tile)) {
 
			if (IsTransportUnderBridge(tile)) {
 
				return_cmd_error(STR_5800_OBJECT_IN_THE_WAY);
 
			}
 

	
 
			if (_m[tile].m5 & 0x18) { // already water under bridge
 
				return_cmd_error(STR_1007_ALREADY_BUILT);
 
			}
 
			if (IsWaterUnderBridge(tile)) return_cmd_error(STR_1007_ALREADY_BUILT);
 

	
 
			if (flags & DC_EXEC) SetWaterUnderBridge(tile);
 
		} else {
 
@@ -354,8 +353,7 @@ static bool IsWateredTile(TileIndex tile
 
			return !(m5 < 75 || (m5 >= 83 && m5 <= 114));
 

	
 
		case MP_TUNNELBRIDGE:
 
			// true, if tile is middle part of bridge with water underneath
 
			return (m5 & 0xF8) == 0xC8;
 
			return IsBridge(tile) && IsBridgeMiddle(tile) && IsWaterUnderBridge(tile);
 

	
 
		default:
 
			return false;
 
@@ -542,8 +540,7 @@ static void TileLoopWaterHelper(TileInde
 
				break;
 

	
 
			case MP_TUNNELBRIDGE:
 
				// Middle part of bridge with clear land below?
 
				if ((_m[target].m5 & 0xF8) == 0xC0) {
 
				if (IsBridge(target) && IsBridgeMiddle(target) && IsClearUnderBridge(target)) {
 
					SetWaterUnderBridge(target);
 
					MarkTileDirtyByTile(target);
 
				}
 
@@ -553,15 +550,14 @@ static void TileLoopWaterHelper(TileInde
 
				break;
 
		}
 
	} else {
 
		if (IsTileType(target, MP_TUNNELBRIDGE)) {
 
			byte m5 = _m[target].m5;
 
			if ((m5 & 0xF8) == 0xC8 || (m5 & 0xF8) == 0xF0) return;
 

	
 
			if ((m5 & 0xC0) == 0xC0) {
 
				SetWaterUnderBridge(target);
 
				MarkTileDirtyByTile(target);
 
		if (IsBridgeTile(target) && IsBridgeMiddle(target)) {
 
			if (IsWaterUnderBridge(target) ||
 
					(IsTransportUnderBridge(target) && GetTransportTypeUnderBridge(target) == TRANSPORT_WATER)) { // XXX does this happen at all?
 
				return;
 
			}
 
			SetWaterUnderBridge(target);
 
			MarkTileDirtyByTile(target);
 
			return;
 
		}
 

	
 
		_current_player = OWNER_WATER;
0 comments (0 inline, 0 general)