|
|
/* $Id$ */
|
|
|
|
|
|
/** @file elrail.cpp
|
|
|
* This file deals with displaying wires and pylons for electric railways.
|
|
|
* <h2>Basics</h2>
|
|
|
*
|
|
|
* <h3>Tile Types</h3>
|
|
|
*
|
|
|
* We have two different types of tiles in the drawing code:
|
|
|
* Normal Railway Tiles (NRTs) which can have more than one track on it, and
|
|
|
* Special Railways tiles (SRTs) which have only one track (like crossings, depots
|
|
|
* stations, etc).
|
|
|
*
|
|
|
* <h3>Location Categories</h3>
|
|
|
*
|
|
|
* All tiles are categorized into three location groups (TLG):
|
|
|
* Group 0: Tiles with both an even X coordinate and an even Y coordinate
|
|
|
* Group 1: Tiles with an even X and an odd Y coordinate
|
|
|
* Group 2: Tiles with an odd X and an even Y coordinate
|
|
|
* Group 3: Tiles with both an odd X and Y coordnate.
|
|
|
*
|
|
|
* <h3>Pylon Points</h3>
|
|
|
* <h4>Control Points</h4>
|
|
|
* A Pylon Control Point (PCP) is a position where a wire (or rather two)
|
|
|
* is mounted onto a pylon.
|
|
|
* Each NRT does contain 4 PCPs which are bitmapped to a byte
|
|
|
* variable and are represented by the DiagDirection enum
|
|
|
*
|
|
|
* Each track ends on two PCPs and thus requires one pylon on each end. However,
|
|
|
* there is one exception: Straight-and-level tracks only have one pylon every
|
|
|
* other tile.
|
|
|
*
|
|
|
* Now on each edge there are two PCPs: One from each adjacent tile. Both PCPs
|
|
|
* are merged using an OR operation (i. e. if one tile needs a PCP at the postion
|
|
|
* in question, both tiles get it).
|
|
|
*
|
|
|
* <h4>Position Points</h4>
|
|
|
* A Pylon Position Point (PPP) is a position where a pylon is located on the
|
|
|
* ground. Each PCP owns 8 in (45 degree steps) PPPs that are located around
|
|
|
* it. PPPs are represented using the Direction enum. Each track bit has PPPs
|
|
|
* that are impossible (because the pylon would be situated on the track) and
|
|
|
* some that are preferred (because the pylon would be rectangular to the track).
|
|
|
*
|
|
|
* <img src="../../elrail_tile.png">
|
|
|
* <img src="../../elrail_track.png">
|
|
|
*
|
|
|
*/
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
#include "openttd.h"
|
|
|
#include "station_map.h"
|
|
|
#include "viewport_func.h"
|
|
|
#include "settings_type.h"
|
|
|
#include "landscape.h"
|
|
|
#include "rail_type.h"
|
|
|
#include "debug.h"
|
|
|
#include "tunnel_map.h"
|
|
|
#include "road_map.h"
|
|
|
#include "bridge_map.h"
|
|
|
#include "bridge.h"
|
|
|
#include "rail_map.h"
|
|
|
#include "train.h"
|
|
|
#include "rail_gui.h"
|
|
|
#include "transparency.h"
|
|
|
#include "tunnelbridge_map.h"
|
|
|
#include "vehicle_func.h"
|
|
|
#include "company_base.h"
|
|
|
#include "tunnelbridge.h"
|
|
|
#include "engine_func.h"
|
|
|
#include "elrail_func.h"
|
|
|
#include "engine_base.h"
|
|
|
|
|
|
#include "table/sprites.h"
|
|
|
#include "table/elrail_data.h"
|
|
|
|
|
|
static inline TLG GetTLG(TileIndex t)
|
|
|
{
|
|
|
return (TLG)((HasBit(TileX(t), 0) << 1) + HasBit(TileY(t), 0));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Finds which Electrified Rail Bits are present on a given tile.
|
|
|
* @param t tile to check
|
|
|
* @param override pointer to PCP override, can be NULL
|
|
|
* @return trackbits of tile if it is electrified
|
|
|
*/
|
|
|
static TrackBits GetRailTrackBitsUniversal(TileIndex t, byte *override)
|
|
|
{
|
|
|
switch (GetTileType(t)) {
|
|
|
case MP_RAILWAY:
|
|
|
if (!HasCatenary(GetRailType(t))) return TRACK_BIT_NONE;
|
|
|
switch (GetRailTileType(t)) {
|
|
|
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 (!HasCatenary(GetRailType(t))) return TRACK_BIT_NONE;
|
|
|
if (override != NULL && (IsTunnel(t) || GetTunnelBridgeLength(t, GetOtherBridgeEnd(t)) > 0)) {
|
|
|
*override = 1 << GetTunnelBridgeDirection(t);
|
|
|
}
|
|
|
return DiagDirToDiagTrackBits(GetTunnelBridgeDirection(t));
|
|
|
|
|
|
case MP_ROAD:
|
|
|
if (!IsLevelCrossing(t)) return TRACK_BIT_NONE;
|
|
|
if (!HasCatenary(GetRailType(t))) return TRACK_BIT_NONE;
|
|
|
return GetCrossingRailBits(t);
|
|
|
|
|
|
case MP_STATION:
|
|
|
if (!IsRailwayStation(t)) return TRACK_BIT_NONE;
|
|
|
if (!HasCatenary(GetRailType(t))) return TRACK_BIT_NONE;
|
|
|
if (!IsStationTileElectrifiable(t)) return TRACK_BIT_NONE;
|
|
|
return TrackToTrackBits(GetRailStationTrack(t));
|
|
|
|
|
|
default:
|
|
|
return TRACK_BIT_NONE;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Get the base wire sprite to use.
|
|
|
*/
|
|
|
static inline SpriteID GetWireBase(TileIndex tile)
|
|
|
{
|
|
|
return SPR_WIRE_BASE;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Get the base pylon sprite to use.
|
|
|
*/
|
|
|
static inline SpriteID GetPylonBase(TileIndex tile)
|
|
|
{
|
|
|
return SPR_PYLON_BASE;
|
|
|
}
|
|
|
|
|
|
/** 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 {
|
|
|
*tileh = InclinedSlope(GetTunnelBridgeDirection(tile));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* Returns the Z position of a Pylon Control Point.
|
|
|
*
|
|
|
* @param tile The tile the pylon should stand on.
|
|
|
* @param PCPpos The PCP of the tile.
|
|
|
* @return The Z position of the PCP.
|
|
|
*/
|
|
|
static byte GetPCPElevation(TileIndex tile, DiagDirection PCPpos)
|