Changeset - r3792:deb3c0493c60
[Not reviewed]
master
0 15 0
rubidium - 18 years ago 2006-05-09 08:17:33
rubidium@openttd.org
(svn r4788) - Codechange: RAILTYPE_{NORMAL,ELECTRIC,...} and RAIL_TYPE_{NORMAL,SIGNAL,...} have nearly the same name, rename RAIL_TYPE_* to RAIL_TILE_* of extra clarity
15 files changed with 55 insertions and 55 deletions:
0 comments (0 inline, 0 general)
ai/default/default.c
Show inline comments
 
@@ -2163,49 +2163,49 @@ static bool AiRemoveTileAndGoForward(Pla
 
			// 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;
 

	
 
			tile = GetOtherBridgeEnd(tile);
 

	
 
			tilenew = TILE_MASK(tile - TileOffsByDir(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;
 
		}
 
	}
 

	
 
	// Find the railtype at the position. Quit if no rail there.
 
	b = GetRailTrackStatus(tile) & _dir_table_3[p->ai.cur_dir_a];
 
	if (b == 0) return false;
 

	
 
	// Convert into a bit position that CMD_REMOVE_SINGLE_RAIL expects.
 
	bit = FindFirstBit(b);
 

	
 
	// Then remove and signals if there are any.
 
	if (IsTileType(tile, MP_RAILWAY) &&
 
			GetRailTileType(tile) == RAIL_TYPE_SIGNALS) {
 
			GetRailTileType(tile) == RAIL_TILE_SIGNALS) {
 
		DoCommand(tile, 0, 0, DC_EXEC, CMD_REMOVE_SIGNALS);
 
	}
 

	
 
	// And also remove the rail.
 
	if (CmdFailed(DoCommand(tile, 0, bit, DC_EXEC, CMD_REMOVE_SINGLE_RAIL)))
 
		return false;
 

	
 
	// Find the direction at the other edge of the rail.
 
	ptr = _ai_table_15[p->ai.cur_dir_a ^ 2];
 
	while (ptr[0] != bit) ptr += 2;
 
	p->ai.cur_dir_a = ptr[1] ^ 2;
 

	
 
	// And then also switch tile.
 
	p->ai.cur_tile_a = TILE_MASK(p->ai.cur_tile_a - TileOffsByDir(p->ai.cur_dir_a));
 

	
 
	return true;
 
}
 

	
 

	
 
static void AiBuildRailDestruct(Player *p)
 
{
 
	// Decrease timeout.
 
	if (!--p->ai.state_counter) {
 
		p->ai.state_mode = 2;
elrail.c
Show inline comments
 
@@ -55,51 +55,51 @@ some that are preferred (because the pyl
 
#include "rail.h"
 
#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"
 

	
 
static inline TLG GetTLG(TileIndex t)
 
{
 
	return (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)) {
 
		case MP_RAILWAY:
 
			if (GetRailType(t) != RAILTYPE_ELECTRIC) return 0;
 
			switch (GetRailTileType(t)) {
 
				case RAIL_TYPE_NORMAL: case RAIL_TYPE_SIGNALS:
 
				case RAIL_TILE_NORMAL: case RAIL_TILE_SIGNALS:
 
					return GetTrackBits(t);
 
				case RAIL_TYPE_DEPOT_WAYPOINT:
 
				case RAIL_TILE_DEPOT_WAYPOINT:
 
					if (GetRailTileSubtype(t) == RAIL_SUBTYPE_WAYPOINT) return GetRailWaypointBits(t);
 
				default:
 
					return 0;
 
			}
 
			break;
 
		case MP_TUNNELBRIDGE:
 
			if (IsTunnel(t)) {
 
				if (GetRailType(t) != RAILTYPE_ELECTRIC) return 0;
 
				if (override != NULL) *override = 1 << GetTunnelDirection(t);
 
				return DiagDirToAxis(GetTunnelDirection(t)) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y;
 
			} else {
 
				if (GetRailType(t) != RAILTYPE_ELECTRIC) return 0;
 
				if (IsBridgeMiddle(t)) {
 
					if (IsTransportUnderBridge(t) &&
 
						GetTransportTypeUnderBridge(t) == TRANSPORT_RAIL) {
 
						return GetRailBitsUnderBridge(t);
 
					} else {
 
						return 0;
 
					}
 
				} else {
 
					if (override != NULL && DistanceMax(t, GetOtherBridgeEnd(t)) > 1) *override = 1 << GetBridgeRampDirection(t);
 

	
 
					return DiagDirToAxis(GetBridgeRampDirection(t)) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y;
 
				}
 
@@ -325,42 +325,42 @@ static void DrawCatenaryOnBridge(const T
 
	/* Finished with wires, draw pylons */
 
	/* every other tile needs a pylon on the northern end */
 
	if (num % 2) {
 
		if (axis == AXIS_X) {
 
			AddSortableSpriteToDraw( pylons_bridge[0 + HASBIT(tlg, 0)], ti->x, ti->y + 4 + 8 * HASBIT(tlg, 0), 1, 1, 10, GetBridgeHeight(ti->tile) + TILE_HEIGHT);
 
		} else {
 
			AddSortableSpriteToDraw( pylons_bridge[2 + HASBIT(tlg, 1)], ti->x + 4 + 8 * HASBIT(tlg, 1), ti->y, 1, 1, 10, GetBridgeHeight(ti->tile) + TILE_HEIGHT);
 
		}
 
	}
 

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

	
 
void DrawCatenary(const TileInfo *ti)
 
{
 
	switch (GetTileType(ti->tile)) {
 
		case MP_RAILWAY:
 
			if (GetRailTileType(ti->tile) == RAIL_TYPE_DEPOT_WAYPOINT && GetRailTileSubtype(ti->tile) == RAIL_SUBTYPE_DEPOT) {
 
			if (GetRailTileType(ti->tile) == RAIL_TILE_DEPOT_WAYPOINT && GetRailTileSubtype(ti->tile) == RAIL_SUBTYPE_DEPOT) {
 
				const SortableSpriteStruct *sss = &CatenarySpriteData[WIRE_DEPOT_SW + ReverseDiagDir(GetRailDepotDirection(ti->tile))];
 
				AddSortableSpriteToDraw( sss->image, ti->x + sss->x_offset, ti->y + sss->y_offset,
 
					sss->x_size, sss->y_size, sss->z_size, GetSlopeZ(ti->x, ti->y) + sss->z_offset);
 
				return;
 
			}
 
			/* Fall through */
 
		case MP_TUNNELBRIDGE:
 
			if (IsBridgeTile(ti->tile) && IsBridgeMiddle(ti->tile) && GetRailTypeOnBridge(ti->tile) == RAILTYPE_ELECTRIC) DrawCatenaryOnBridge(ti);
 
			/* Fall further */
 
		case MP_STREET: case MP_STATION:
 
			DrawCatenaryRailway(ti);
 
			break;
 
		default:
 
			break;
 
	}
 
}
 

	
newgrf_station.c
Show inline comments
 
@@ -232,49 +232,49 @@ uint32 GetPlatformInfo(Axis axis, byte t
 
/* Find the end of a railway station, from the tile, in the direction of delta.
 
 * If check_type is set, we stop if the custom station type changes.
 
 * If check_axis is set, we stop if the station direction changes.
 
 */
 
static TileIndex FindRailStationEnd(TileIndex tile, TileIndexDiff delta, bool check_type, bool check_axis)
 
{
 
	bool waypoint;
 
	byte orig_type = 0;
 
	Axis orig_axis = AXIS_X;
 

	
 
	waypoint = IsTileType(tile, MP_RAILWAY);
 

	
 
	if (waypoint) {
 
		if (check_axis) orig_axis = GetWaypointAxis(tile);
 
	} else {
 
		if (check_type) orig_type = GetCustomStationSpecIndex(tile);
 
		if (check_axis) orig_axis = GetRailStationAxis(tile);
 
	}
 

	
 
	while (true) {
 
		TileIndex new_tile = TILE_ADD(tile, delta);
 

	
 
		if (waypoint) {
 
			if (!IsTileType(new_tile, MP_RAILWAY)) break;
 
			if (GetRailTileType(new_tile) != RAIL_TYPE_DEPOT_WAYPOINT) break;
 
			if (GetRailTileType(new_tile) != RAIL_TILE_DEPOT_WAYPOINT) break;
 
			if (GetRailTileSubtype(new_tile) != RAIL_SUBTYPE_WAYPOINT) break;
 
			if (check_axis && GetWaypointAxis(new_tile) != orig_axis) break;
 
		} else {
 
			if (!IsRailwayStationTile(new_tile)) break;
 
			if (check_type && GetCustomStationSpecIndex(new_tile) != orig_type) break;
 
			if (check_axis && GetRailStationAxis(new_tile) != orig_axis) break;
 
		}
 

	
 
		tile = new_tile;
 
	}
 
	return tile;
 
}
 

	
 

	
 
static uint32 GetPlatformInfoHelper(TileIndex tile, bool check_type, bool check_axis, bool centred)
 
{
 
	int tx = TileX(tile);
 
	int ty = TileY(tile);
 
	int sx = TileX(FindRailStationEnd(tile, TileDiffXY(-1,  0), check_type, check_axis));
 
	int sy = TileY(FindRailStationEnd(tile, TileDiffXY( 0, -1), check_type, check_axis));
 
	int ex = TileX(FindRailStationEnd(tile, TileDiffXY( 1,  0), check_type, check_axis)) + 1;
 
	int ey = TileY(FindRailStationEnd(tile, TileDiffXY( 0,  1), check_type, check_axis)) + 1;
 
	Axis axis = IsTileType(tile, MP_RAILWAY) ? GetWaypointAxis(tile) : GetRailStationAxis(tile);
 

	
npf.c
Show inline comments
 
@@ -604,49 +604,49 @@ static void NPFFollowTrack(AyStar* aysta
 
		 * the back */
 
		ts = TrackdirToTrackdirBits(DiagdirToDiagTrackdir(ReverseDiagDir(exitdir)));
 
	} else {
 
		ts = GetTileTrackStatus(dst_tile, type);
 
	}
 
	trackdirbits = ts & TRACKDIR_BIT_MASK; /* Filter out signal status and the unused bits */
 

	
 
	DEBUG(npf, 4)("Next node: (%d, %d) [%d], possible trackdirs: 0x%X", TileX(dst_tile), TileY(dst_tile), dst_tile, trackdirbits);
 
	/* Select only trackdirs we can reach from our current trackdir */
 
	trackdirbits &= TrackdirReachesTrackdirs(src_trackdir);
 
	if (_patches.forbid_90_deg && (type == TRANSPORT_RAIL || type == TRANSPORT_WATER)) /* Filter out trackdirs that would make 90 deg turns for trains */
 
		trackdirbits &= ~TrackdirCrossesTrackdirs(src_trackdir);
 

	
 
	DEBUG(npf,6)("After filtering: (%d, %d), possible trackdirs: 0x%X", TileX(dst_tile), TileY(dst_tile), trackdirbits);
 

	
 
	i = 0;
 
	/* Enumerate possible track */
 
	while (trackdirbits != 0) {
 
		Trackdir dst_trackdir;
 
		dst_trackdir =  FindFirstBit2x64(trackdirbits);
 
		trackdirbits = KillFirstBit2x64(trackdirbits);
 
		DEBUG(npf, 5)("Expanded into trackdir: %d, remaining trackdirs: 0x%X", dst_trackdir, trackdirbits);
 

	
 
		/* Check for oneway signal against us */
 
		if (IsTileType(dst_tile, MP_RAILWAY) && GetRailTileType(dst_tile) == RAIL_TYPE_SIGNALS) {
 
		if (IsTileType(dst_tile, MP_RAILWAY) && GetRailTileType(dst_tile) == RAIL_TILE_SIGNALS) {
 
			if (HasSignalOnTrackdir(dst_tile, ReverseTrackdir(dst_trackdir)) && !HasSignalOnTrackdir(dst_tile, dst_trackdir))
 
				// if one way signal not pointing towards us, stop going in this direction.
 
				break;
 
		}
 
		{
 
			/* We've found ourselves a neighbour :-) */
 
			AyStarNode* neighbour = &aystar->neighbours[i];
 
			neighbour->tile = dst_tile;
 
			neighbour->direction = dst_trackdir;
 
			/* Save user data */
 
			neighbour->user_data[NPF_NODE_FLAGS] = current->path.node.user_data[NPF_NODE_FLAGS];
 
			NPFFillTrackdirChoice(neighbour, current);
 
		}
 
		i++;
 
	}
 
	aystar->num_neighbours = i;
 
}
 

	
 
/*
 
 * Plan a route to the specified target (which is checked by target_proc),
 
 * from start1 and if not NULL, from start2 as well. The type of transport we
 
 * are checking is in type. reverse_penalty is applied to all routes that
 
 * originate from the second start node.
 
 * When we are looking for one specific target (optionally multiple tiles), we
oldloader.c
Show inline comments
 
@@ -1502,49 +1502,49 @@ static bool LoadOldMain(LoadgameState *l
 

	
 
	DEBUG(oldloader, 4)("[OldLoader] Going to read main chunk..");
 
	/* Load the biggest chunk */
 
	if (!LoadChunk(ls, NULL, main_chunk)) {
 
		DEBUG(oldloader, 0)("[OldLoader] Loading failed!");
 
		return false;
 
	}
 
	DEBUG(oldloader, 4)("[OldLoader] Done. Converting stuff..");
 

	
 
	/* Fix some general stuff */
 
	_opt.landscape = _opt.landscape & 0xF;
 

	
 
	/* Remap some pointers */
 
	_cur_town_ctr      = REMAP_TOWN_IDX(_old_cur_town_ctr);
 

	
 
	/* _old_map3 is changed in _map3_lo and _map3_hi */
 
	for (i = 0; i < OLD_MAP_SIZE; i++) {
 
		_m[i].m3 = _old_map3[i * 2];
 
		_m[i].m4 = _old_map3[i * 2 + 1];
 
	}
 

	
 
	for (i = 0; i < OLD_MAP_SIZE; i ++) {
 
		if (IsTileType(i, MP_RAILWAY)) {
 
			/* We save presignals different from TTDPatch, convert them */
 
			if (GetRailTileType(i) == RAIL_TYPE_SIGNALS) {
 
			if (GetRailTileType(i) == RAIL_TILE_SIGNALS) {
 
				/* This byte is always zero in TTD for this type of tile */
 
				if (_m[i].m4) /* Convert the presignals to our own format */
 
					_m[i].m4 = (_m[i].m4 >> 1) & 7;
 
			}
 
			/* TTDPatch stores PBS things in L6 and all elsewhere; so we'll just
 
			* clear it for ourselves and let OTTD's rebuild PBS itself */
 
			_m[i].m4 &= 0xF; /* Only keep the lower four bits; upper four is PBS */
 
		}
 
	}
 

	
 
	/* Fix the game to be compatible with OpenTTD */
 
	FixOldTowns();
 
	FixOldStations();
 
	FixOldVehicles();
 

	
 
	AddTypeToEngines();
 

	
 
	/* We have a new difficulty setting */
 
	_opt.diff.town_council_tolerance = clamp(_opt.diff_level, 0, 2);
 

	
 
	DEBUG(oldloader, 4)("[OldLoader] Done!");
 
	DEBUG(oldloader, 1)("[OldLoader] TTD(Patch) savegame successfully converted");
 

	
 
	return true;
order_gui.c
Show inline comments
 
@@ -179,49 +179,49 @@ static void DrawOrdersWindow(Window *w)
 
		}
 

	
 
		i++;
 
		order = order->next;
 
	}
 

	
 
	if (i - w->vscroll.pos < w->vscroll.cap) {
 
		str = shared_orders ? STR_END_OF_SHARED_ORDERS : STR_882A_END_OF_ORDERS;
 
		color = (i == WP(w,order_d).sel) ? 0xC : 0x10;
 
		DrawString(2, y, str, color);
 
	}
 
}
 

	
 
static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile)
 
{
 
	Order order;
 
	order.next  = NULL;
 
	order.index = 0;
 

	
 
	// check depot first
 
	if (_patches.gotodepot) {
 
		switch (GetTileType(tile)) {
 
		case MP_RAILWAY:
 
			if (v->type == VEH_Train && IsTileOwner(tile, _local_player)) {
 
				if (GetRailTileType(tile) == RAIL_TYPE_DEPOT_WAYPOINT &&
 
				if (GetRailTileType(tile) == RAIL_TILE_DEPOT_WAYPOINT &&
 
						GetRailTileSubtype(tile) == RAIL_SUBTYPE_DEPOT) {
 
					order.type = OT_GOTO_DEPOT;
 
					order.flags = OF_PART_OF_ORDERS;
 
					order.station = GetDepotByTile(tile)->index;
 
					return order;
 
				}
 
			}
 
			break;
 

	
 
		case MP_STREET:
 
			if (GetRoadType(tile) == ROAD_DEPOT && v->type == VEH_Road && IsTileOwner(tile, _local_player)) {
 
				order.type = OT_GOTO_DEPOT;
 
				order.flags = OF_PART_OF_ORDERS;
 
				order.station = GetDepotByTile(tile)->index;
 
				return order;
 
			}
 
			break;
 

	
 
		case MP_STATION:
 
			if (v->type != VEH_Aircraft) break;
 
			if (IsHangar(tile) && IsTileOwner(tile, _local_player)) {
 
				order.type = OT_GOTO_DEPOT;
 
				order.flags = OF_PART_OF_ORDERS;
 
				order.station = GetStationIndex(tile);
rail.h
Show inline comments
 
@@ -316,64 +316,64 @@ static inline TrackdirBits TrackdirReach
 
static inline TrackdirBits TrackdirCrossesTrackdirs(Trackdir trackdir) {
 
	extern const TrackdirBits _track_crosses_trackdirs[TRACKDIR_END];
 
	return _track_crosses_trackdirs[TrackdirToTrack(trackdir)];
 
}
 

	
 

	
 
/* Checks if a given Track is diagonal */
 
static inline bool IsDiagonalTrack(Track track) { return (track == TRACK_X) || (track == TRACK_Y); }
 

	
 
/* Checks if a given Trackdir is diagonal. */
 
static inline bool IsDiagonalTrackdir(Trackdir trackdir) { return IsDiagonalTrack(TrackdirToTrack(trackdir)); }
 

	
 
/*
 
 * Functions quering signals on tiles.
 
 */
 

	
 
/**
 
 * Checks for the presence of signals (either way) on the given track on the
 
 * given rail tile.
 
 */
 
static inline bool HasSignalOnTrack(TileIndex tile, Track track)
 
{
 
	assert(IsValidTrack(track));
 
	return
 
		GetRailTileType(tile) == RAIL_TYPE_SIGNALS &&
 
		GetRailTileType(tile) == RAIL_TILE_SIGNALS &&
 
		(_m[tile].m3 & SignalOnTrack(track)) != 0;
 
}
 

	
 
/**
 
 * Checks for the presence of signals along the given trackdir on the given
 
 * rail tile.
 
 *
 
 * Along meaning if you are currently driving on the given trackdir, this is
 
 * the signal that is facing us (for which we stop when it's red).
 
 */
 
static inline bool HasSignalOnTrackdir(TileIndex tile, Trackdir trackdir)
 
{
 
	assert (IsValidTrackdir(trackdir));
 
	return
 
		GetRailTileType(tile) == RAIL_TYPE_SIGNALS &&
 
		GetRailTileType(tile) == RAIL_TILE_SIGNALS &&
 
		_m[tile].m3 & SignalAlongTrackdir(trackdir);
 
}
 

	
 
/**
 
 * Gets the state of the signal along the given trackdir.
 
 *
 
 * Along meaning if you are currently driving on the given trackdir, this is
 
 * the signal that is facing us (for which we stop when it's red).
 
 */
 
static inline SignalState GetSignalStateByTrackdir(TileIndex tile, Trackdir trackdir)
 
{
 
	assert(IsValidTrackdir(trackdir));
 
	assert(HasSignalOnTrack(tile, TrackdirToTrack(trackdir)));
 
	return _m[tile].m2 & SignalAlongTrackdir(trackdir) ?
 
		SIGNAL_STATE_GREEN : SIGNAL_STATE_RED;
 
}
 

	
 

	
 
/**
 
 * Return the rail type of tile, or INVALID_RAILTYPE if this is no rail tile.
 
 * Note that there is no check if the given trackdir is actually present on
 
 * the tile!
 
 * The given trackdir is used when there are (could be) multiple rail types on
 
 * one tile.
rail_cmd.c
Show inline comments
 
@@ -56,65 +56,65 @@ void ShowTrainDepotWindow(TileIndex tile
 

	
 

	
 

	
 
/* MAP2 byte:    abcd???? => Signal On? Same coding as map3lo
 
 * MAP3LO byte:  abcd???? => Signal Exists?
 
 *				 a and b are for diagonals, upper and left,
 
 *				 one for each direction. (ie a == NE->SW, b ==
 
 *				 SW->NE, or v.v., I don't know. b and c are
 
 *				 similar for lower and right.
 
 * MAP2 byte:    ????abcd => Type of ground.
 
 * MAP3LO byte:  ????abcd => Type of rail.
 
 * MAP5:         00abcdef => rail
 
 *               01abcdef => rail w/ signals
 
 *               10uuuuuu => unused
 
 *               11uuuudd => rail depot
 
 */
 

	
 
static bool CheckTrackCombination(TileIndex tile, TrackBits to_build, uint flags)
 
{
 
	RailTileType type = GetRailTileType(tile);
 
	TrackBits current; /* The current track layout */
 
	TrackBits future; /* The track layout we want to build */
 
	_error_message = STR_1001_IMPOSSIBLE_TRACK_COMBINATION;
 

	
 
	if (type != RAIL_TYPE_NORMAL && type != RAIL_TYPE_SIGNALS)
 
	if (type != RAIL_TILE_NORMAL && type != RAIL_TILE_SIGNALS)
 
		return false; /* Cannot build anything on depots and checkpoints */
 

	
 
	/* So, we have a tile with tracks on it (and possibly signals). Let's see
 
	 * what tracks first */
 
	current = GetTrackBits(tile);
 
	future = current | to_build;
 

	
 
	/* Are we really building something new? */
 
	if (current == future) {
 
		/* Nothing new is being built */
 
		_error_message = STR_1007_ALREADY_BUILT;
 
		return false;
 
	}
 

	
 
	/* Let's see if we may build this */
 
	if ((flags & DC_NO_RAIL_OVERLAP) || type == RAIL_TYPE_SIGNALS) {
 
	if ((flags & DC_NO_RAIL_OVERLAP) || type == RAIL_TILE_SIGNALS) {
 
		/* If we are not allowed to overlap (flag is on for ai players or we have
 
		 * signals on the tile), check that */
 
		return future == TRACK_BIT_HORZ || future == TRACK_BIT_VERT;
 
	} else {
 
		/* Normally, we may overlap and any combination is valid */
 
		return true;
 
	}
 
}
 

	
 

	
 
const TrackBits _valid_tileh_slopes[2][15] = {
 

	
 
// set of normal ones
 
{
 
	TRACK_BIT_ALL,
 
	TRACK_BIT_RIGHT,
 
	TRACK_BIT_UPPER,
 
	TRACK_BIT_X,
 

	
 
	TRACK_BIT_LEFT,
 
	0,
 
	TRACK_BIT_Y,
 
	TRACK_BIT_LOWER,
 

	
 
@@ -240,49 +240,49 @@ int32 CmdBuildSingleRail(TileIndex tile,
 
				// Get detailed error message
 
				return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
			}
 

	
 
			if (IsClearUnderBridge(tile)) {
 
				ret = CheckRailSlope(tileh, trackbit, 0, tile);
 
				if (CmdFailed(ret)) return ret;
 
				cost += ret;
 

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

	
 
		case MP_RAILWAY:
 
			if (!CheckTrackCombination(tile, trackbit, flags) ||
 
					!EnsureNoVehicle(tile)) {
 
				return CMD_ERROR;
 
			}
 
			if (GetRailTileType(tile) == RAIL_TYPE_DEPOT_WAYPOINT ||
 
			if (GetRailTileType(tile) == RAIL_TILE_DEPOT_WAYPOINT ||
 
					!IsTileOwner(tile, _current_player) ||
 
					GetRailType(tile) != p1) {
 
				// Get detailed error message
 
				return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
			}
 

	
 
			ret = CheckRailSlope(tileh, trackbit, GetTrackBits(tile), tile);
 
			if (CmdFailed(ret)) return ret;
 
			cost += ret;
 

	
 
			if (flags & DC_EXEC) {
 
				SetRailGroundType(tile, RAIL_GROUND_BARREN);
 
				_m[tile].m5 |= trackbit;
 
			}
 
			break;
 

	
 
		case MP_STREET:
 
#define M(x) (1 << (x))
 
			/* Level crossings may only be built on these slopes */
 
			if (!HASBIT(M(SLOPE_SEN) | M(SLOPE_ENW) | M(SLOPE_NWS) | M(SLOPE_NS) | M(SLOPE_WSE) | M(SLOPE_EW) | M(SLOPE_FLAT), tileh)) {
 
				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 
			}
 
#undef M
 

	
 
@@ -645,51 +645,51 @@ int32 CmdBuildSingleSignal(TileIndex til
 
 		TrackBits trackbits = GetTrackBits(tile);
 
		if (KILL_FIRST_BIT(trackbits) != 0 && /* More than one track present */
 
				trackbits != TRACK_BIT_HORZ &&
 
				trackbits != TRACK_BIT_VERT
 
		)
 
			return CMD_ERROR;
 
	}
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	if (!HasSignalOnTrack(tile, track)) {
 
		// build new signals
 
		cost = _price.build_signals;
 
	} else {
 
		if (p2 != 0 && sigvar != GetSignalVariant(tile)) {
 
			// convert signals <-> semaphores
 
			cost = _price.build_signals + _price.remove_signals;
 
		} else {
 
			// it is free to change orientation/pre-exit-combo signals
 
			cost = 0;
 
		}
 
	}
 

	
 
	if (flags & DC_EXEC) {
 
		if (GetRailTileType(tile) != RAIL_TYPE_SIGNALS) {
 
		if (GetRailTileType(tile) != RAIL_TILE_SIGNALS) {
 
			// there are no signals at all on this tile yet
 
			_m[tile].m5 |= RAIL_TYPE_SIGNALS; // change into signals
 
			_m[tile].m5 |= RAIL_TILE_SIGNALS; // change into signals
 
			_m[tile].m2 |= 0xF0;              // all signals are on
 
			_m[tile].m3 &= ~0xF0;          // no signals built by default
 
			SetSignalType(tile, SIGTYPE_NORMAL);
 
			SetSignalVariant(tile, sigvar);
 
		}
 

	
 
		if (p2 == 0) {
 
			if (!HasSignalOnTrack(tile, track)) {
 
				// build new signals
 
				_m[tile].m3 |= SignalOnTrack(track);
 
			} else {
 
				if (pre_signal) {
 
					// cycle between normal -> pre -> exit -> combo -> ...
 
					SignalType type = GetSignalType(tile);
 

	
 
					SetSignalType(tile, type == SIGTYPE_COMBO ? SIGTYPE_NORMAL : type + 1);
 
				} else {
 
					CycleSignalSide(tile, track);
 
				}
 
			}
 
		} else {
 
			/* If CmdBuildManySignals is called with copying signals, just copy the
 
			 * direction of the first signal given as parameter by CmdBuildManySignals */
 
			_m[tile].m3 &= ~SignalOnTrack(track);
 
@@ -723,49 +723,49 @@ static int32 CmdSignalTrackHelper(TileIn
 
	int mode = p2 & 0x1;
 
	Track track = GB(p2, 4, 3);
 
	Trackdir trackdir = TrackToTrackdir(track);
 
	byte semaphores = (HASBIT(p2, 3)) ? 8 : 0;
 
	byte signal_density = (p2 >> 24);
 

	
 
	if (p1 >= MapSize()) return CMD_ERROR;
 
	end_tile = p1;
 
	if (signal_density == 0 || signal_density > 20) return CMD_ERROR;
 

	
 
	if (!IsTileType(tile, MP_RAILWAY)) return CMD_ERROR;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	/* for vertical/horizontal tracks, double the given signals density
 
	* since the original amount will be too dense (shorter tracks) */
 
	if (!IsDiagonalTrack(track))
 
		signal_density *= 2;
 

	
 
	if (CmdFailed(ValidateAutoDrag(&trackdir, tile, end_tile))) return CMD_ERROR;
 

	
 
	track = TrackdirToTrack(trackdir); /* trackdir might have changed, keep track in sync */
 

	
 
	// copy the signal-style of the first rail-piece if existing
 
	if (GetRailTileType(tile) == RAIL_TYPE_SIGNALS && GetTrackBits(tile) != 0) { /* XXX: GetTrackBits check useless? */
 
	if (GetRailTileType(tile) == RAIL_TILE_SIGNALS && GetTrackBits(tile) != 0) { /* XXX: GetTrackBits check useless? */
 
		signals = _m[tile].m3 & SignalOnTrack(track);
 
		if (signals == 0) signals = SignalOnTrack(track); /* Can this actually occur? */
 

	
 
		// copy signal/semaphores style (independent of CTRL)
 
		semaphores = (GetSignalVariant(tile) == SIG_ELECTRIC ? 0 : 8);
 
	} else // no signals exist, drag a two-way signal stretch
 
		signals = SignalOnTrack(track);
 

	
 
	/* signal_ctr         - amount of tiles already processed
 
	 * signals_density    - patch setting to put signal on every Nth tile (double space on |, -- tracks)
 
	 **********
 
	 * trackdir   - trackdir to build with autorail
 
	 * semaphores - semaphores or signals
 
	 * signals    - is there a signal/semaphore on the first tile, copy its style (two-way/single-way)
 
	                and convert all others to semaphore/signal
 
	 * mode       - 1 remove signals, 0 build signals */
 
	signal_ctr = total_cost = 0;
 
	for (;;) {
 
		// only build/remove signals with the specified density
 
		if ((signal_ctr % signal_density) == 0 ) {
 
			ret = DoCommand(tile, TrackdirToTrack(trackdir) | semaphores, signals, flags, (mode == 1) ? CMD_REMOVE_SIGNALS : CMD_BUILD_SIGNALS);
 

	
 
			/* Abort placement for any other error than NOT_SUITABLE_TRACK
 
			 * This includes vehicles on track, competitor's tracks, etc. */
 
@@ -804,49 +804,49 @@ int32 CmdBuildSignalTrack(TileIndex tile
 
 * @param p1 track to remove signal from (Track enum)
 
 */
 
int32 CmdRemoveSingleSignal(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Track track = (Track)(p1 & 0x7);
 

	
 
	if (!ValParamTrackOrientation(track) || !IsTileType(tile, MP_RAILWAY) || !EnsureNoVehicle(tile))
 
		return CMD_ERROR;
 

	
 
	if (!HasSignalOnTrack(tile, track)) // no signals on track?
 
		return CMD_ERROR;
 

	
 
	/* Only water can remove signals from anyone */
 
	if (_current_player != OWNER_WATER && !CheckTileOwnership(tile)) return CMD_ERROR;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	/* Do it? */
 
	if (flags & DC_EXEC) {
 
		_m[tile].m3 &= ~SignalOnTrack(track);
 

	
 
		/* removed last signal from tile? */
 
		if (GB(_m[tile].m3, 4, 4) == 0) {
 
			SB(_m[tile].m2, 4, 4, 0);
 
			SB(_m[tile].m5, 6, 2, RAIL_TYPE_NORMAL >> 6); // XXX >> because the constant is meant for direct application, not use with SB
 
			SB(_m[tile].m5, 6, 2, RAIL_TILE_NORMAL >> 6); // XXX >> because the constant is meant for direct application, not use with SB
 
			SetSignalVariant(tile, SIG_ELECTRIC); // remove any possible semaphores
 
		}
 

	
 
		SetSignalsOnBothDir(tile, track);
 

	
 
		MarkTileDirtyByTile(tile);
 
	}
 

	
 
	return _price.remove_signals;
 
}
 

	
 
/** Remove signals on a stretch of track.
 
 * Stub for the unified signal builder/remover
 
 * @see CmdSignalTrackHelper
 
 */
 
int32 CmdRemoveSignalTrack(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	return CmdSignalTrackHelper(tile, flags, p1, SETBIT(p2, 0));
 
}
 

	
 
typedef int32 DoConvertRailProc(TileIndex tile, RailType totype, bool exec);
 

	
 
static int32 DoConvertRail(TileIndex tile, RailType totype, bool exec)
 
{
 
@@ -936,95 +936,95 @@ static int32 RemoveTrainDepot(TileIndex 
 
		return CMD_ERROR;
 

	
 
	if (!EnsureNoVehicle(tile))
 
		return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		DiagDirection dir = GetRailDepotDirection(tile);
 

	
 
		DoDeleteDepot(tile);
 
		UpdateSignalsOnSegment(tile, dir);
 
	}
 

	
 
	return _price.remove_train_depot;
 
}
 

	
 
static int32 ClearTile_Track(TileIndex tile, byte flags)
 
{
 
	int32 cost;
 
	int32 ret;
 
	byte m5;
 

	
 
	m5 = _m[tile].m5;
 

	
 
	if (flags & DC_AUTO) {
 
		if (GetRailTileType(tile) == RAIL_TYPE_DEPOT_WAYPOINT) {
 
		if (GetRailTileType(tile) == RAIL_TILE_DEPOT_WAYPOINT) {
 
			return_cmd_error(STR_2004_BUILDING_MUST_BE_DEMOLISHED);
 
		}
 

	
 
		if (!IsTileOwner(tile, _current_player))
 
			return_cmd_error(STR_1024_AREA_IS_OWNED_BY_ANOTHER);
 

	
 
		return_cmd_error(STR_1008_MUST_REMOVE_RAILROAD_TRACK);
 
	}
 

	
 
	cost = 0;
 

	
 
	switch (GetRailTileType(tile)) {
 
		/* XXX: Why the fuck do we remove these thow signals first? */
 
		case RAIL_TYPE_SIGNALS:
 
		case RAIL_TILE_SIGNALS:
 
			if (HasSignalOnTrack(tile, TRACK_X)) {
 
				ret = DoCommand(tile, TRACK_X, 0, flags, CMD_REMOVE_SIGNALS);
 
				if (CmdFailed(ret)) return CMD_ERROR;
 
				cost += ret;
 
			}
 
			if (HasSignalOnTrack(tile, TRACK_LOWER)) {
 
				ret = DoCommand(tile, TRACK_LOWER, 0, flags, CMD_REMOVE_SIGNALS);
 
				if (CmdFailed(ret)) return CMD_ERROR;
 
				cost += ret;
 
			}
 

	
 
			m5 &= TRACK_BIT_MASK;
 
			if (!(flags & DC_EXEC)) {
 
				for (; m5 != 0; m5 >>= 1) if (m5 & 1) cost += _price.remove_rail;
 
				return cost;
 
			}
 
			/* FALLTHROUGH */
 

	
 
		case RAIL_TYPE_NORMAL: {
 
		case RAIL_TILE_NORMAL: {
 
			uint i;
 

	
 
			for (i = 0; m5 != 0; i++, m5 >>= 1) {
 
				if (m5 & 1) {
 
					ret = DoCommand(tile, 0, i, flags, CMD_REMOVE_SINGLE_RAIL);
 
					if (CmdFailed(ret)) return CMD_ERROR;
 
					cost += ret;
 
				}
 
			}
 
			return cost;
 
		}
 

	
 
		case RAIL_TYPE_DEPOT_WAYPOINT:
 
		case RAIL_TILE_DEPOT_WAYPOINT:
 
			if (GetRailTileSubtype(tile) == RAIL_SUBTYPE_DEPOT) {
 
				return RemoveTrainDepot(tile, flags);
 
			} else {
 
				return RemoveTrainWaypoint(tile, flags, false);
 
			}
 

	
 
		default:
 
			return CMD_ERROR;
 
	}
 
}
 

	
 
#include "table/track_land.h"
 

	
 
static void DrawSingleSignal(TileIndex tile, byte condition, uint image, uint pos)
 
{
 
	bool side = _opt.road_side & _patches.signal_side;
 
	static const Point SignalPositions[2][12] = {
 
		{      /* Signals on the left side */
 
		/*  LEFT      LEFT      RIGHT     RIGHT     UPPER     UPPER */
 
			{ 8,  5}, {14,  1}, { 1, 14}, { 9, 11}, { 1,  0}, { 3, 10},
 
		/*  LOWER     LOWER     X         X         Y         Y     */
 
			{11,  4}, {14, 14}, {11,  3}, { 4, 13}, { 3,  4}, {11, 13}
 
		}, {   /* Signals on the right side */
 
		/*  LEFT      LEFT      RIGHT     RIGHT     UPPER     UPPER */
 
@@ -1277,57 +1277,57 @@ static void DrawSignals(TileIndex tile, 
 
				MAYBE_DRAW_SIGNAL(3, 0x505, 4);
 
				MAYBE_DRAW_SIGNAL(2, 0x503, 5);
 
			}
 
			if (rails & TRACK_BIT_LOWER) {
 
				MAYBE_DRAW_SIGNAL(1, 0x505, 6);
 
				MAYBE_DRAW_SIGNAL(0, 0x503, 7);
 
			}
 
		} else {
 
			MAYBE_DRAW_SIGNAL(3, 0x4FB, 8);
 
			MAYBE_DRAW_SIGNAL(2, 0x4FD, 9);
 
		}
 
	} else {
 
		MAYBE_DRAW_SIGNAL(3, 0x4FF, 10);
 
		MAYBE_DRAW_SIGNAL(2, 0x501, 11);
 
	}
 
}
 

	
 
static void DrawTile_Track(TileInfo *ti)
 
{
 
	const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile));
 
	PalSpriteID image;
 

	
 
	_drawtile_track_palette = SPRITE_PALETTE(PLAYER_SPRITE_COLOR(GetTileOwner(ti->tile)));
 

	
 
	if (GetRailTileType(ti->tile) != RAIL_TYPE_DEPOT_WAYPOINT) {
 
	if (GetRailTileType(ti->tile) != RAIL_TILE_DEPOT_WAYPOINT) {
 
		TrackBits rails = GetTrackBits(ti->tile);
 

	
 
		DrawTrackBits(ti, rails, false);
 

	
 
		if (_display_opt & DO_FULL_DETAIL) _detailed_track_proc[GetRailGroundType(ti->tile)](ti);
 

	
 
		/* draw signals also? */
 
		if (GetRailTileType(ti->tile) == RAIL_TYPE_SIGNALS) DrawSignals(ti->tile, rails);
 
		if (GetRailTileType(ti->tile) == RAIL_TILE_SIGNALS) DrawSignals(ti->tile, rails);
 

	
 
	} else {
 
		/* draw depots / waypoints */
 
		const DrawTrackSeqStruct *drss;
 
		bool is_depot = GetRailTileSubtype(ti->tile) == RAIL_SUBTYPE_DEPOT;
 

	
 
		if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, ti->tileh);
 

	
 
		if (IsRailWaypoint(ti->tile) && IsCustomWaypoint(ti->tile)) {
 
			// look for customization
 
			byte stat_id = GetWaypointByTile(ti->tile)->stat_id;
 
			const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, stat_id);
 

	
 
			if (statspec != NULL) {
 
				DrawTileSeqStruct const *seq;
 
				// emulate station tile - open with building
 
				uint tile = 2;
 
				const DrawTileSprites *cust;
 
				Station *st = ComposeWaypointStation(ti->tile);
 

	
 
				uint32 relocation = GetCustomStationRelocation(statspec, st, ti->tile);
 

	
 
				if (HASBIT(statspec->callbackmask, CBM_CUSTOM_LAYOUT)) {
 
					uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0, 0, statspec, st, ti->tile);
 
@@ -1696,65 +1696,65 @@ bool UpdateSignalsOnSegment(TileIndex ti
 
	}
 

	
 
	return result != 0;
 
}
 

	
 
void SetSignalsOnBothDir(TileIndex tile, byte track)
 
{
 
	static const DiagDirection _search_dir_1[] = {
 
		DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE
 
	};
 
	static const DiagDirection _search_dir_2[] = {
 
		DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE
 
	};
 

	
 
	UpdateSignalsOnSegment(tile, _search_dir_1[track]);
 
	UpdateSignalsOnSegment(tile, _search_dir_2[track]);
 
}
 

	
 
static uint GetSlopeZ_Track(const TileInfo* ti)
 
{
 
	Slope tileh = ti->tileh;
 
	uint z = ti->z;
 

	
 
	if (tileh == SLOPE_FLAT) return z;
 
	if (GetRailTileType(ti->tile) == RAIL_TYPE_DEPOT_WAYPOINT) {
 
	if (GetRailTileType(ti->tile) == RAIL_TILE_DEPOT_WAYPOINT) {
 
		return z + TILE_HEIGHT;
 
	} else {
 
		uint f = GetRailFoundation(ti->tileh, GetTrackBits(ti->tile));
 

	
 
		if (f != 0) {
 
			if (f < 15) return z + TILE_HEIGHT; // leveled foundation
 
			tileh = _inclined_tileh[f - 15]; // inclined foundation
 
		}
 
		return z + GetPartialZ(ti->x & 0xF, ti->y & 0xF, tileh);
 
	}
 
}
 

	
 
static Slope GetSlopeTileh_Track(TileIndex tile, Slope tileh)
 
{
 
	if (tileh == SLOPE_FLAT) return SLOPE_FLAT;
 
	if (GetRailTileType(tile) == RAIL_TYPE_DEPOT_WAYPOINT) {
 
	if (GetRailTileType(tile) == RAIL_TILE_DEPOT_WAYPOINT) {
 
		return SLOPE_FLAT;
 
	} else {
 
		uint f = GetRailFoundation(tileh, GetTrackBits(tile));
 

	
 
		if (f == 0) return tileh;
 
		if (f < 15) return SLOPE_FLAT; // leveled foundation
 
		return _inclined_tileh[f - 15]; // inclined foundation
 
	}
 
}
 

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

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

	
 
static void TileLoop_Track(TileIndex tile)
 
{
 
	RailGroundType old_ground = GetRailGroundType(tile);
 
	RailGroundType new_ground = old_ground;
 
@@ -1763,49 +1763,49 @@ static void TileLoop_Track(TileIndex til
 
	switch (_opt.landscape) {
 
		case LT_HILLY:
 
			if (GetTileZ(tile) > _opt.snow_line) {
 
				new_ground = RAIL_GROUND_ICE_DESERT;
 
				quick_return = true;
 
			}
 
			break;
 

	
 
		case LT_DESERT:
 
			if (GetTropicZone(tile) == TROPICZONE_DESERT) {
 
				new_ground = RAIL_GROUND_ICE_DESERT;
 
				quick_return = true;
 
			}
 
			break;
 
	}
 

	
 
	if (new_ground != old_ground) {
 
		SetRailGroundType(tile, new_ground);
 
		MarkTileDirtyByTile(tile);
 
	}
 

	
 
	if (quick_return) return;
 

	
 
	// Don't continue tile loop for depots
 
	if (GetRailTileType(tile) == RAIL_TYPE_DEPOT_WAYPOINT) return;
 
	if (GetRailTileType(tile) == RAIL_TILE_DEPOT_WAYPOINT) return;
 

	
 
	new_ground = RAIL_GROUND_GRASS;
 

	
 
	if (old_ground != RAIL_GROUND_BARREN) { /* wait until bottom is green */
 
		/* determine direction of fence */
 
		TrackBits rail = GetTrackBits(tile);
 

	
 
		switch (rail) {
 
			case TRACK_BIT_UPPER: new_ground = RAIL_GROUND_FENCE_HORIZ1; break;
 
			case TRACK_BIT_LOWER: new_ground = RAIL_GROUND_FENCE_HORIZ2; break;
 
			case TRACK_BIT_LEFT:  new_ground = RAIL_GROUND_FENCE_VERT1;  break;
 
			case TRACK_BIT_RIGHT: new_ground = RAIL_GROUND_FENCE_VERT2;  break;
 

	
 
			default: {
 
				PlayerID owner = GetTileOwner(tile);
 

	
 
				if (rail == (TRACK_BIT_LOWER | TRACK_BIT_RIGHT) || (
 
							(rail & TRACK_BIT_3WAY_NW) == 0 &&
 
							(rail & TRACK_BIT_X)
 
						)) {
 
					TileIndex n = tile + TileDiffXY(0, -1);
 
					TrackBits nrail = GetTrackBits(n);
 

	
 
					if (!IsTileType(n, MP_RAILWAY) ||
 
@@ -1860,114 +1860,114 @@ static void TileLoop_Track(TileIndex til
 
							nrail == TRACK_BIT_LEFT) {
 
						new_ground = (new_ground == RAIL_GROUND_FENCE_NE) ?
 
							RAIL_GROUND_FENCE_NESW : RAIL_GROUND_FENCE_SW;
 
					}
 
				}
 
				break;
 
			}
 
		}
 
	}
 

	
 
	if (old_ground != new_ground) {
 
		SetRailGroundType(tile, new_ground);
 
		MarkTileDirtyByTile(tile);
 
	}
 
}
 

	
 

	
 
static uint32 GetTileTrackStatus_Track(TileIndex tile, TransportType mode)
 
{
 
	byte a;
 
	uint16 b;
 

	
 
	if (mode != TRANSPORT_RAIL) return 0;
 

	
 
	if (GetRailTileType(tile) != RAIL_TYPE_DEPOT_WAYPOINT) {
 
	if (GetRailTileType(tile) != RAIL_TILE_DEPOT_WAYPOINT) {
 
		TrackBits rails = GetTrackBits(tile);
 
		uint32 ret = rails * 0x101;
 

	
 
		if (GetRailTileType(tile) != RAIL_TYPE_SIGNALS) {
 
		if (GetRailTileType(tile) != RAIL_TILE_SIGNALS) {
 
			if (rails == TRACK_BIT_CROSS) ret |= 0x40;
 
		} else {
 
			/* has_signals */
 

	
 
			a = _m[tile].m3;
 
			b = _m[tile].m2;
 

	
 
			b &= a;
 

	
 
			/* When signals are not present (in neither
 
			 * direction), we pretend them to be green. (So if
 
			 * signals are only one way, the other way will
 
			 * implicitely become `red' */
 
			if ((a & 0xC0) == 0) b |= 0xC0;
 
			if ((a & 0x30) == 0) b |= 0x30;
 

	
 
			if ((b & 0x80) == 0) ret |= 0x10070000;
 
			if ((b & 0x40) == 0) ret |= 0x07100000;
 
			if ((b & 0x20) == 0) ret |= 0x20080000;
 
			if ((b & 0x10) == 0) ret |= 0x08200000;
 
		}
 
		return ret;
 
	} else {
 
		if (GetRailTileSubtype(tile) == RAIL_SUBTYPE_DEPOT) {
 
			return (DiagDirToAxis(GetRailDepotDirection(tile)) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y) * 0x101;
 
		} else {
 
			return GetRailWaypointBits(tile) * 0x101;
 
		}
 
	}
 
}
 

	
 
static void ClickTile_Track(TileIndex tile)
 
{
 
	if (IsTileDepotType(tile, TRANSPORT_RAIL)) {
 
		ShowTrainDepotWindow(tile);
 
	} else if (IsRailWaypoint(tile)) {
 
		ShowRenameWaypointWindow(GetWaypointByTile(tile));
 
	}
 
}
 

	
 
static void GetTileDesc_Track(TileIndex tile, TileDesc *td)
 
{
 
	td->owner = GetTileOwner(tile);
 
	switch (GetRailTileType(tile)) {
 
		case RAIL_TYPE_NORMAL:
 
		case RAIL_TILE_NORMAL:
 
			td->str = STR_1021_RAILROAD_TRACK;
 
			break;
 

	
 
		case RAIL_TYPE_SIGNALS: {
 
		case RAIL_TILE_SIGNALS: {
 
			const StringID signal_type[] = {
 
				STR_RAILROAD_TRACK_WITH_NORMAL_SIGNALS,
 
				STR_RAILROAD_TRACK_WITH_PRESIGNALS,
 
				STR_RAILROAD_TRACK_WITH_EXITSIGNALS,
 
				STR_RAILROAD_TRACK_WITH_COMBOSIGNALS
 
			};
 

	
 
			td->str = signal_type[GetSignalType(tile)];
 
			break;
 
		}
 

	
 
		case RAIL_TYPE_DEPOT_WAYPOINT:
 
		case RAIL_TILE_DEPOT_WAYPOINT:
 
		default:
 
			td->str = (GetRailTileSubtype(tile) == RAIL_SUBTYPE_DEPOT) ?
 
				STR_1023_RAILROAD_TRAIN_DEPOT : STR_LANDINFO_WAYPOINT;
 
			break;
 
	}
 
}
 

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

	
 
	if (new_player != OWNER_SPECTATOR) {
 
		SetTileOwner(tile, new_player);
 
	}	else {
 
		DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR);
 
	}
 
}
 

	
 
static const byte _fractcoords_behind[4] = { 0x8F, 0x8, 0x80, 0xF8 };
 
static const byte _fractcoords_enter[4] = { 0x8A, 0x48, 0x84, 0xA8 };
 
static const byte _deltacoord_leaveoffset[8] = {
 
	-1,  0,  1,  0, /* x */
 
	 0,  1,  0, -1  /* y */
 
};
rail_gui.c
Show inline comments
 
@@ -69,49 +69,49 @@ static void PlaceRail_N(TileIndex tile)
 

	
 
static void PlaceRail_NE(TileIndex tile)
 
{
 
	VpStartPlaceSizing(tile, VPM_FIX_Y);
 
}
 

	
 
static void PlaceRail_E(TileIndex tile)
 
{
 
	int cmd = _tile_fract_coords.x + _tile_fract_coords.y <= 15 ? 2 : 3;
 
	GenericPlaceRail(tile, cmd);
 
}
 

	
 
static void PlaceRail_NW(TileIndex tile)
 
{
 
	VpStartPlaceSizing(tile, VPM_FIX_X);
 
}
 

	
 
static void PlaceRail_AutoRail(TileIndex tile)
 
{
 
	VpStartPlaceSizing(tile, VPM_RAILDIRS);
 
}
 

	
 
static void PlaceExtraDepotRail(TileIndex tile, uint16 extra)
 
{
 
	if (GetRailTileType(tile) != RAIL_TYPE_NORMAL) return;
 
	if (GetRailTileType(tile) != RAIL_TILE_NORMAL) return;
 
	if ((GetTrackBits(tile) & GB(extra, 8, 8)) == 0) return;
 

	
 
	DoCommandP(tile, _cur_railtype, extra & 0xFF, NULL, CMD_BUILD_SINGLE_RAIL | CMD_AUTO | CMD_NO_WATER);
 
}
 

	
 
static const uint16 _place_depot_extra[12] = {
 
	0x604,		0x2102,		0x1202,		0x505,
 
	0x2400,		0x2801,		0x1800,		0x1401,
 
	0x2203,		0x904,		0x0A05,		0x1103,
 
};
 

	
 

	
 
void CcRailDepot(bool success, TileIndex tile, uint32 p1, uint32 p2)
 
{
 
	if (success) {
 
		DiagDirection dir = p2;
 

	
 
		SndPlayTileFx(SND_20_SPLAT_2, tile);
 
		ResetObjectToPlace();
 

	
 
		tile += TileOffsByDir(dir);
 

	
 
		if (IsTileType(tile, MP_RAILWAY)) {
 
			PlaceExtraDepotRail(tile, _place_depot_extra[dir]);
rail_map.h
Show inline comments
 
/* $Id$ */
 

	
 
#ifndef RAIL_MAP_H
 
#define RAIL_MAP_H
 

	
 
#include "direction.h"
 
#include "tile.h"
 

	
 

	
 
typedef enum RailTileType {
 
	RAIL_TYPE_NORMAL         = 0x0,
 
	RAIL_TYPE_SIGNALS        = 0x40,
 
	RAIL_TYPE_UNUSED         = 0x80, /* XXX: Maybe this could become waypoints? */
 
	RAIL_TYPE_DEPOT_WAYPOINT = 0xC0, /* Is really depots and waypoints... */
 
	RAIL_TILE_NORMAL         = 0x0,
 
	RAIL_TILE_SIGNALS        = 0x40,
 
	RAIL_TILE_UNUSED         = 0x80, /* XXX: Maybe this could become waypoints? */
 
	RAIL_TILE_DEPOT_WAYPOINT = 0xC0, /* Is really depots and waypoints... */
 
	RAIL_TILE_TYPE_MASK      = 0xC0
 
} RailTileType;
 

	
 
static inline RailTileType GetRailTileType(TileIndex t)
 
{
 
	assert(IsTileType(t, MP_RAILWAY));
 
	return _m[t].m5 & RAIL_TILE_TYPE_MASK;
 
}
 

	
 
/**
 
 * Returns whether this is plain rails, with or without signals. Iow, if this
 
 * tiles RailTileType is RAIL_TYPE_NORMAL or RAIL_TYPE_SIGNALS.
 
 * tiles RailTileType is RAIL_TILE_NORMAL or RAIL_TILE_SIGNALS.
 
 */
 
static inline bool IsPlainRailTile(TileIndex tile)
 
{
 
	RailTileType rtt = GetRailTileType(tile);
 
	return rtt == RAIL_TYPE_NORMAL || rtt == RAIL_TYPE_SIGNALS;
 
	return rtt == RAIL_TILE_NORMAL || rtt == RAIL_TILE_SIGNALS;
 
}
 

	
 
/**
 
 * Checks if a rail tile has signals.
 
 */
 
static inline bool HasSignals(TileIndex tile)
 
{
 
	return GetRailTileType(tile) == RAIL_TYPE_SIGNALS;
 
	return GetRailTileType(tile) == RAIL_TILE_SIGNALS;
 
}
 

	
 

	
 
/** These specify the subtype when the main rail type is
 
 * RAIL_TYPE_DEPOT_WAYPOINT */
 
 * RAIL_TILE_DEPOT_WAYPOINT */
 
typedef enum RailTileSubtypes {
 
	RAIL_SUBTYPE_DEPOT    = 0x00,
 
	RAIL_SUBTYPE_WAYPOINT = 0x04,
 
	RAIL_SUBTYPE_MASK     = 0x3C
 
} RailTileSubtype;
 

	
 
/**
 
 * Returns the RailTileSubtype of a given rail tile with type
 
 * RAIL_TYPE_DEPOT_WAYPOINT
 
 * RAIL_TILE_DEPOT_WAYPOINT
 
 */
 
static inline RailTileSubtype GetRailTileSubtype(TileIndex tile)
 
{
 
	assert(GetRailTileType(tile) == RAIL_TYPE_DEPOT_WAYPOINT);
 
	assert(GetRailTileType(tile) == RAIL_TILE_DEPOT_WAYPOINT);
 
	return (RailTileSubtype)(_m[tile].m5 & RAIL_SUBTYPE_MASK);
 
}
 

	
 

	
 
typedef enum RailTypes {
 
	RAILTYPE_RAIL     = 0,
 
	RAILTYPE_ELECTRIC = 1,
 
	RAILTYPE_MONO     = 2,
 
	RAILTYPE_MAGLEV   = 3,
 
	RAILTYPE_END,
 
	INVALID_RAILTYPE = 0xFF
 
} RailType;
 

	
 
typedef byte RailTypeMask;
 

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

	
 
// TODO remove this by moving to the same bits as GetRailType()
 
static inline RailType GetRailTypeCrossing(TileIndex t)
 
{
 
	return (RailType)GB(_m[t].m4, 0, 4);
 
@@ -180,55 +180,55 @@ static inline void ClearCustomWaypointSp
 
{
 
	CLRBIT(_m[t].m3, 4);
 
}
 

	
 
static inline bool IsCustomWaypoint(TileIndex t)
 
{
 
	return HASBIT(_m[t].m3, 4);
 
}
 

	
 
static inline Axis GetWaypointAxis(TileIndex t)
 
{
 
	return HASBIT(_m[t].m5, 0) ? AXIS_Y : AXIS_X;
 
}
 

	
 

	
 
typedef enum SignalType {
 
	SIGTYPE_NORMAL  = 0, // normal signal
 
	SIGTYPE_ENTRY   = 1, // presignal block entry
 
	SIGTYPE_EXIT    = 2, // presignal block exit
 
	SIGTYPE_COMBO   = 3  // presignal inter-block
 
} SignalType;
 

	
 
static inline SignalType GetSignalType(TileIndex t)
 
{
 
	assert(GetRailTileType(t) == RAIL_TYPE_SIGNALS);
 
	assert(GetRailTileType(t) == RAIL_TILE_SIGNALS);
 
	return (SignalType)GB(_m[t].m4, 0, 2);
 
}
 

	
 
static inline void SetSignalType(TileIndex t, SignalType s)
 
{
 
	assert(GetRailTileType(t) == RAIL_TYPE_SIGNALS);
 
	assert(GetRailTileType(t) == RAIL_TILE_SIGNALS);
 
	SB(_m[t].m4, 0, 2, s);
 
}
 

	
 
static inline bool IsPresignalEntry(TileIndex t)
 
{
 
	return GetSignalType(t) == SIGTYPE_ENTRY || GetSignalType(t) == SIGTYPE_COMBO;
 
}
 

	
 
static inline bool IsPresignalExit(TileIndex t)
 
{
 
	return GetSignalType(t) == SIGTYPE_EXIT || GetSignalType(t) == SIGTYPE_COMBO;
 
}
 

	
 
static inline void CycleSignalSide(TileIndex t, Track track)
 
{
 
	byte sig;
 
	byte pos = 6;
 
	if (track == TRACK_LOWER || track == TRACK_RIGHT) pos = 4;
 

	
 
	sig = GB(_m[t].m3, pos, 2);
 
	if (--sig == 0) sig = 3;
 
	SB(_m[t].m3, pos, 2, sig);
 
}
 

	
 
@@ -266,82 +266,82 @@ static inline SignalState GetSingleSigna
 
{
 
	return HASBIT(_m[t].m2, signalbit + 4);
 
}
 

	
 

	
 
typedef enum RailGroundType {
 
	RAIL_MAP2LO_GROUND_MASK = 0xF,
 
	RAIL_GROUND_BARREN = 0,
 
	RAIL_GROUND_GRASS = 1,
 
	RAIL_GROUND_FENCE_NW = 2,
 
	RAIL_GROUND_FENCE_SE = 3,
 
	RAIL_GROUND_FENCE_SENW = 4,
 
	RAIL_GROUND_FENCE_NE = 5,
 
	RAIL_GROUND_FENCE_SW = 6,
 
	RAIL_GROUND_FENCE_NESW = 7,
 
	RAIL_GROUND_FENCE_VERT1 = 8,
 
	RAIL_GROUND_FENCE_VERT2 = 9,
 
	RAIL_GROUND_FENCE_HORIZ1 = 10,
 
	RAIL_GROUND_FENCE_HORIZ2 = 11,
 
	RAIL_GROUND_ICE_DESERT = 12,
 
} RailGroundType;
 

	
 
static inline void SetRailGroundType(TileIndex t, RailGroundType rgt)
 
{
 
	if (GetRailTileType(t) == RAIL_TYPE_DEPOT_WAYPOINT) {
 
	if (GetRailTileType(t) == RAIL_TILE_DEPOT_WAYPOINT) {
 
		SB(_m[t].m4, 0, 4, rgt);
 
		return;
 
	}
 
	SB(_m[t].m2, 0, 4, rgt);
 
}
 

	
 
static inline RailGroundType GetRailGroundType(TileIndex t)
 
{
 
	/* TODO Unify this */
 
	if (GetRailTileType(t) == RAIL_TYPE_DEPOT_WAYPOINT) return GB(_m[t].m4, 0, 4);
 
	if (GetRailTileType(t) == RAIL_TILE_DEPOT_WAYPOINT) return GB(_m[t].m4, 0, 4);
 
	return GB(_m[t].m2, 0, 4);
 
}
 

	
 
static inline bool IsBarrenRailGround(TileIndex t)
 
{
 
	return GetRailGroundType(t) == RAIL_GROUND_BARREN;
 
}
 

	
 
static inline bool IsSnowRailGround(TileIndex t)
 
{
 
	return GetRailGroundType(t) == RAIL_GROUND_ICE_DESERT;
 
}
 

	
 

	
 
static inline void MakeRailNormal(TileIndex t, Owner o, TrackBits b, RailType r)
 
{
 
	SetTileType(t, MP_RAILWAY);
 
	SetTileOwner(t, o);
 
	_m[t].m2 = 0;
 
	_m[t].m3 = r;
 
	_m[t].m4 = 0;
 
	_m[t].m5 = RAIL_TYPE_NORMAL | b;
 
	_m[t].m5 = RAIL_TILE_NORMAL | b;
 
}
 

	
 

	
 
static inline void MakeRailDepot(TileIndex t, Owner o, DiagDirection d, RailType r)
 
{
 
	SetTileType(t, MP_RAILWAY);
 
	SetTileOwner(t, o);
 
	_m[t].m2 = 0;
 
	_m[t].m3 = r;
 
	_m[t].m4 = 0;
 
	_m[t].m5 = RAIL_TYPE_DEPOT_WAYPOINT | RAIL_SUBTYPE_DEPOT | d;
 
	_m[t].m5 = RAIL_TILE_DEPOT_WAYPOINT | RAIL_SUBTYPE_DEPOT | d;
 
}
 

	
 

	
 
static inline void MakeRailWaypoint(TileIndex t, Owner o, Axis a, RailType r, uint index)
 
{
 
	SetTileType(t, MP_RAILWAY);
 
	SetTileOwner(t, o);
 
	_m[t].m2 = index;
 
	_m[t].m3 = r;
 
	_m[t].m4 = 0;
 
	_m[t].m5 = RAIL_TYPE_DEPOT_WAYPOINT | RAIL_SUBTYPE_WAYPOINT | a;
 
	_m[t].m5 = RAIL_TILE_DEPOT_WAYPOINT | RAIL_SUBTYPE_WAYPOINT | a;
 
}
 

	
 
#endif
road_cmd.c
Show inline comments
 
@@ -302,49 +302,49 @@ int32 CmdBuildRoad(TileIndex tile, uint3
 
						return_cmd_error(STR_1007_ALREADY_BUILT);
 
					}
 
					goto do_clear;
 

	
 
				default:
 
				case ROAD_DEPOT:
 
					goto do_clear;
 
			}
 
			break;
 

	
 
		case MP_RAILWAY: {
 
			Axis roaddir;
 

	
 
			if (IsSteepSlope(tileh)) {
 
				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 
			}
 

	
 
#define M(x) (1 << (x))
 
			/* Level crossings may only be built on these slopes */
 
			if (!HASBIT(M(SLOPE_SEN) | M(SLOPE_ENW) | M(SLOPE_NWS) | M(SLOPE_NS) | M(SLOPE_WSE) | M(SLOPE_EW) | M(SLOPE_FLAT), tileh)) {
 
				return_cmd_error(STR_1000_LAND_SLOPED_IN_WRONG_DIRECTION);
 
			}
 
#undef M
 

	
 
			if (GetRailTileType(tile) != RAIL_TYPE_NORMAL) goto do_clear;
 
			if (GetRailTileType(tile) != RAIL_TILE_NORMAL) goto do_clear;
 
			switch (GetTrackBits(tile)) {
 
				case TRACK_BIT_X:
 
					if (pieces & ROAD_X) goto do_clear;
 
					roaddir = AXIS_Y;
 
					break;
 

	
 
				case TRACK_BIT_Y:
 
					if (pieces & ROAD_Y) goto do_clear;
 
					roaddir = AXIS_X;
 
					break;
 

	
 
				default: goto do_clear;
 
			}
 

	
 
			if (!EnsureNoVehicle(tile)) return CMD_ERROR;
 

	
 
			if (flags & DC_EXEC) {
 
				MakeRoadCrossing(tile, _current_player, GetTileOwner(tile), roaddir, GetRailType(tile), p2);
 
				MarkTileDirtyByTile(tile);
 
			}
 
			return _price.build_road * 2;
 
		}
 

	
 
		case MP_TUNNELBRIDGE:
train_cmd.c
Show inline comments
 
@@ -1798,49 +1798,49 @@ int32 CmdRefitRailVehicle(TileIndex tile
 
			}
 
		}
 
	} while ((v = v->next) != NULL);
 

	
 
	_returned_refit_capacity = num;
 

	
 
	return cost;
 
}
 

	
 
typedef struct TrainFindDepotData {
 
	uint best_length;
 
	TileIndex tile;
 
	PlayerID owner;
 
	/**
 
	 * true if reversing is necessary for the train to get to this depot
 
	 * This value is unused when new depot finding and NPF are both disabled
 
	 */
 
	bool reverse;
 
} TrainFindDepotData;
 

	
 
static bool NtpCallbFindDepot(TileIndex tile, TrainFindDepotData *tfdd, int track, uint length)
 
{
 
	if (IsTileType(tile, MP_RAILWAY) &&
 
			IsTileOwner(tile, tfdd->owner) &&
 
			GetRailTileType(tile) == RAIL_TYPE_DEPOT_WAYPOINT &&
 
			GetRailTileType(tile) == RAIL_TILE_DEPOT_WAYPOINT &&
 
			GetRailTileSubtype(tile) == RAIL_SUBTYPE_DEPOT) {
 
		tfdd->best_length = length;
 
		tfdd->tile = tile;
 
		return true;
 
	}
 

	
 
	return false;
 
}
 

	
 
// returns the tile of a depot to goto to. The given vehicle must not be
 
// crashed!
 
static TrainFindDepotData FindClosestTrainDepot(Vehicle *v)
 
{
 
	TrainFindDepotData tfdd;
 
	TileIndex tile = v->tile;
 

	
 
	assert(!(v->vehstatus & VS_CRASHED));
 

	
 
	tfdd.owner = v->owner;
 
	tfdd.best_length = (uint)-1;
 
	tfdd.reverse = false;
 

	
 
	if (IsTileDepotType(tile, TRANSPORT_RAIL)){
 
		tfdd.tile = tile;
 
@@ -2679,49 +2679,49 @@ static void AffectSpeedByDirChange(Vehic
 
/* Modify the speed of the vehicle due to a change in altitude */
 
static void AffectSpeedByZChange(Vehicle *v, byte old_z)
 
{
 
	const RailtypeSlowdownParams *rsp;
 
	if (old_z == v->z_pos || _patches.realistic_acceleration) return;
 

	
 
	rsp = &_railtype_slowdown[v->u.rail.railtype];
 

	
 
	if (old_z < v->z_pos) {
 
		v->cur_speed -= (v->cur_speed * rsp->z_up >> 8);
 
	} else {
 
		uint16 spd = v->cur_speed + rsp->z_down;
 
		if (spd <= v->max_speed) v->cur_speed = spd;
 
	}
 
}
 

	
 
static const DiagDirection _otherside_signal_directions[] = {
 
	DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE, 0, 0,
 
	DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE
 
};
 

	
 
static void TrainMovedChangeSignals(TileIndex tile, DiagDirection dir)
 
{
 
	if (IsTileType(tile, MP_RAILWAY) &&
 
			GetRailTileType(tile) == RAIL_TYPE_SIGNALS) {
 
			GetRailTileType(tile) == RAIL_TILE_SIGNALS) {
 
		uint i = FindFirstBit2x64(GetTrackBits(tile) * 0x101 & _reachable_tracks[dir]);
 
		UpdateSignalsOnSegment(tile, _otherside_signal_directions[i]);
 
	}
 
}
 

	
 

	
 
typedef struct TrainCollideChecker {
 
	const Vehicle *v;
 
	const Vehicle *v_skip;
 
} TrainCollideChecker;
 

	
 
static void *FindTrainCollideEnum(Vehicle *v, void *data)
 
{
 
	const TrainCollideChecker* tcc = data;
 

	
 
	if (v != tcc->v &&
 
			v != tcc->v_skip &&
 
			v->type == VEH_Train &&
 
			v->u.rail.track != 0x80 &&
 
			myabs(v->z_pos - tcc->v->z_pos) <= 6 &&
 
			myabs(v->x_pos - tcc->v->x_pos) < 6 &&
 
			myabs(v->y_pos - tcc->v->y_pos) < 6) {
 
		return v;
 
	} else {
tunnelbridge_cmd.c
Show inline comments
 
@@ -313,49 +313,49 @@ int32 CmdBuildBridge(TileIndex end_tile,
 
	odd_middle_part = (bridge_len % 2) ? (bridge_len / 2) : bridge_len;
 

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

	
 
		tile += delta;
 

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

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

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

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

	
 
			default:
 
not_valid_below:;
 
				/* try and clear the middle landscape */
 
				ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 
				if (CmdFailed(ret)) return ret;
 
				cost += ret;
 
				transport_under = INVALID_TRANSPORT;
waypoint.c
Show inline comments
 
@@ -161,49 +161,49 @@ void UpdateAllWaypointCustomGraphics(voi
 
	}
 
}
 

	
 
/** Convert existing rail to waypoint. Eg build a waypoint station over
 
 * piece of rail
 
 * @param tile tile where waypoint will be built
 
 * @param p1 graphics for waypoint type, 0 indicates standard graphics
 
 * @param p2 unused
 
 *
 
 * @todo When checking for the tile slope,
 
 * distingush between "Flat land required" and "land sloped in wrong direction"
 
 */
 
int32 CmdBuildTrainWaypoint(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	Waypoint *wp;
 
	Slope tileh;
 
	Axis axis;
 

	
 
	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 

	
 
	/* if custom gfx are used, make sure it is within bounds */
 
	if (p1 >= GetNumCustomStations(STAT_CLASS_WAYP)) return CMD_ERROR;
 

	
 
	if (!IsTileType(tile, MP_RAILWAY) ||
 
			GetRailTileType(tile) != RAIL_TYPE_NORMAL || (
 
			GetRailTileType(tile) != RAIL_TILE_NORMAL || (
 
				(axis = AXIS_X, GetTrackBits(tile) != TRACK_BIT_X) &&
 
				(axis = AXIS_Y, GetTrackBits(tile) != TRACK_BIT_Y)
 
			)) {
 
		return_cmd_error(STR_1005_NO_SUITABLE_RAILROAD_TRACK);
 
	}
 

	
 
	if (!CheckTileOwnership(tile))
 
		return CMD_ERROR;
 

	
 
	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
 

	
 
	tileh = GetTileSlope(tile, NULL);
 
	if (tileh != SLOPE_FLAT) {
 
		if (!_patches.build_on_slopes || IsSteepSlope(tileh) || !(tileh & (0x3 << axis)) || !(tileh & ~(0x3 << axis)))
 
			return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 
	}
 

	
 
	/* Check if there is an already existing, deleted, waypoint close to us that we can reuse. */
 
	wp = FindDeletedWaypointCloseTo(tile);
 
	if (wp == NULL) {
 
		wp = AllocateWaypoint();
 
		if (wp == NULL) return CMD_ERROR;
 

	
 
		wp->town_index = 0;
waypoint.h
Show inline comments
 
@@ -4,49 +4,49 @@
 
#define WAYPOINT_H
 

	
 
#include "pool.h"
 
#include "rail_map.h"
 

	
 
struct Waypoint {
 
	TileIndex xy;      ///< Tile of waypoint
 
	StationID index;   ///< Index of waypoint
 

	
 
	TownID town_index; ///< Town associated with the waypoint
 
	byte town_cn;      ///< The Nth waypoint for this town (consecutive number)
 
	StringID string;   ///< If this is zero (i.e. no custom name), town + town_cn is used for naming
 

	
 
	ViewportSign sign; ///< Dimensions of sign (not saved)
 
	uint16 build_date; ///< Date of construction
 

	
 
	byte stat_id;      ///< ID of waypoint within the waypoint class (not saved)
 
	uint32 grfid;      ///< ID of GRF file
 
	byte localidx;     ///< Index of station within GRF file
 

	
 
	byte deleted;      ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is deleted.
 
};
 

	
 
enum {
 
	RAIL_TYPE_WAYPOINT = 0xC4,
 
	RAIL_TILE_WAYPOINT = 0xC4,
 
	RAIL_WAYPOINT_TRACK_MASK = 1,
 
};
 

	
 
extern MemoryPool _waypoint_pool;
 

	
 
/**
 
 * Get the pointer to the waypoint with index 'index'
 
 */
 
static inline Waypoint *GetWaypoint(uint index)
 
{
 
	return (Waypoint*)GetItemFromPool(&_waypoint_pool, index);
 
}
 

	
 
/**
 
 * Get the current size of the WaypointPool
 
 */
 
static inline uint16 GetWaypointPoolSize(void)
 
{
 
	return _waypoint_pool.total_items;
 
}
 

	
 
static inline bool IsWaypointIndex(uint index)
 
{
 
	return index < GetWaypointPoolSize();
0 comments (0 inline, 0 general)