bridge_map.h
author KUDr
Sun, 31 Dec 2006 23:48:04 +0000
branchcustombridgeheads
changeset 5618 a7db50b9f817
parent 5601 51f241d43769
child 5632 025c3b25f1fd
permissions -rw-r--r--
(svn r7710) [cbh] - Fix: [YAPF] one more assert fixed. Call from the TrainController() added by (r7705) has broken YAPF because it was called when vehicle was already on the next tile (with cbh choice). Before it was always called before the train entered tile with choice.
/* $Id$ */

#ifndef BRIDGE_MAP_H
#define BRIDGE_MAP_H

#include "direction.h"
#include "macros.h"
#include "map.h"
#include "rail.h"
#include "road_map.h"
#include "tile.h"


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

#define M(x) (1 << (x))
enum {
	// foundation, whole tile is leveled up --> 3 corners raised
	BRIDGE_FULL_LEVELED_FOUNDATION = M(SLOPE_WSE) | M(SLOPE_NWS) | M(SLOPE_ENW) | M(SLOPE_SEN),
	// foundation, tile is partly leveled up --> 1 corner raised
	BRIDGE_PARTLY_LEVELED_FOUNDATION = M(SLOPE_W) | M(SLOPE_S) | M(SLOPE_E) | M(SLOPE_N),
	// no foundations (X,Y direction)
	BRIDGE_NO_FOUNDATION = M(SLOPE_FLAT) | M(SLOPE_SW) | M(SLOPE_SE) | M(SLOPE_NW) | M(SLOPE_NE),
	BRIDGE_HORZ_RAMP = (BRIDGE_PARTLY_LEVELED_FOUNDATION | BRIDGE_NO_FOUNDATION) & ~M(SLOPE_FLAT)
};
#undef M


static inline bool IsBridgeTile(TileIndex t)
{
	return IsTileType(t, MP_STREET_BRIDGE) || IsTileType(t, MP_RAILWAY_BRIDGE);
}

static inline bool MayHaveBridgeAbove(TileIndex t)
{
	return
		IsTileType(t, MP_CLEAR) ||
		IsTileType(t, MP_RAILWAY) ||
		IsTileType(t, MP_STREET) ||
		IsTileType(t, MP_WATER) ||
		IsTileType(t, MP_TUNNEL) ||
		IsTileType(t, MP_STREET_BRIDGE) ||
		IsTileType(t, MP_RAILWAY_BRIDGE) ||
		IsTileType(t, MP_UNMOVABLE);
}


static inline bool IsBridgeAbove(TileIndex t)
{
	assert(MayHaveBridgeAbove(t));
	return GB(_m[t].extra, 6, 2) != 0;
}


/**
 * Determines the type of bridge on a tile
 * @param tile The tile to analyze
 * @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
 */
static inline DiagDirection GetBridgeRampDirection(TileIndex t)
{
	assert(IsBridgeTile(t));
	return (DiagDirection)GB(_m[t].m4, 5, 2);
}


static inline Axis GetBridgeAxis(TileIndex t)
{
	assert(IsBridgeAbove(t));
	return (Axis)(GB(_m[t].extra, 6, 2) - 1);
}


static inline TransportType GetBridgeTransportType(TileIndex t)
{
	assert(IsBridgeTile(t));
	if (IsTileType(t, MP_STREET_BRIDGE)) return TRANSPORT_ROAD;

	return TRANSPORT_RAIL;
}


static inline bool HasBridgeSnowOrDesert(TileIndex t)
{
	assert(IsBridgeTile(t));
	return HASBIT(_m[t].m4, 7);
}


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
 */
TileIndex GetBridgeEnd(TileIndex, DiagDirection);

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

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


/**
 * Starting at one bridge end finds the other bridge end
 */
TileIndex GetOtherBridgeEnd(TileIndex);

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

static inline void ClearSingleBridgeMiddle(TileIndex t, Axis a)
{
	assert(MayHaveBridgeAbove(t));
	CLRBIT(_m[t].extra, 6 + a);
}


static inline void ClearBridgeMiddle(TileIndex t)
{
	ClearSingleBridgeMiddle(t, AXIS_X);
	ClearSingleBridgeMiddle(t, AXIS_Y);
}

static inline void SetBridgeMiddle(TileIndex t, Axis a)
{
	assert(MayHaveBridgeAbove(t));
	SETBIT(_m[t].extra, 6 + a);
}


static inline void MakeBridgeRamp(TileIndex t, Owner o, uint bridgetype, DiagDirection d, TransportType tt)
{
	SetTileOwner(t, o);
	_m[t].m2 = bridgetype << 4;
	_m[t].m4 = d << 5;
	_m[t].m5 = 0;
}

static inline void MakeRoadBridgeRamp(TileIndex t, Owner o, uint bridgetype, DiagDirection d)
{
	MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_ROAD);
	SetTileType(t, MP_STREET_BRIDGE);
	_m[t].m3 = 0;
}

static inline void MakeRailBridgeRamp(TileIndex t, Owner o, uint bridgetype, DiagDirection d, RailType r)
{
	MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_RAIL);
	SetTileType(t, MP_RAILWAY_BRIDGE);
	_m[t].m3 = r;
	_m[t].m5 = DiagDirToAxis(d) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y;
}


#endif /* BRIDGE_MAP_H */