2005-07-24 14:12:37 +00:00
/* $Id$ */
2009-08-21 20:21:05 +00:00
/*
* This file is part of OpenTTD .
* OpenTTD is free software ; you can redistribute it and / or modify it under the terms of the GNU General Public License as published by the Free Software Foundation , version 2.
* OpenTTD is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
* See the GNU General Public License for more details . You should have received a copy of the GNU General Public License along with OpenTTD . If not , see < http : //www.gnu.org/licenses/>.
*/
2008-05-06 15:11:33 +00:00
/** @file rail.h Rail specific functions. */
2005-07-29 19:35:23 +00:00
(svn r2448) General cleanup of rail related code, more to follow.
* Add: rail.[ch] for rail-related enums and wrapper functions.
* Codechange: Removed dozens of magic numbers with below enums.
* Codechange: Rewrote CheckTrackCombination().
* Add: TILE_SIZE, TILE_PIXELS and TILE_HEIGHT constants.
* Add: enums RailTileType, RailTileSubtype, SignalType to mask against the map arrays.
* Add: enums Track, TrackBits, Trackdir, TrackdirBits for railway track data. (Note that the old RAIL_BIT constants are replaced by TRACK_BIT ones).
* Add: enums Direction and DiagDirection
* Codechange: Moved a bunch of track(dir) related lookup arrays from npf.[ch] to rail.[ch].
* Codechange: move RailType enum from tile.h to rail.h.
* Add: Wrapper functions for masking signal status in the map arrays: SignalAlongTrackdir, SignalAgainstTrackdir and SignalOnTrack.
* Add: Wrapper functions to access rail tiles, using above enums
* Add: Wrapper functions to modify tracks, trackdirs, directions, etc.
* Add: Wrapper functions for all lookup arrays in rail.[ch] (Arrays are still used in parts of the code)
* Codechange: Renamed some variables and arguments to better represent what they contain (railbit -> track, bits -> trackdirbits, etc.).
* Codechange: Don't use FindLandscapeHeight() in CmdRemoveSingleRail(), since it returns way too much info. Use GetTileSlope() instead.
* Codechange: [NPF] Removed some unused globals and code from npf.c.
2005-06-16 18:04:02 +00:00
# ifndef RAIL_H
# define RAIL_H
2007-12-18 20:10:21 +00:00
# include "rail_type.h"
# include "track_type.h"
2007-12-23 10:56:02 +00:00
# include "gfx_type.h"
2007-12-21 19:21:21 +00:00
# include "core/bitmath_func.hpp"
2007-12-21 21:50:46 +00:00
# include "economy_func.h"
2008-05-08 16:48:29 +00:00
# include "slope_type.h"
2009-06-24 17:39:54 +00:00
# include "strings_type.h"
2011-01-18 21:30:59 +00:00
# include "date_type.h"
(svn r2448) General cleanup of rail related code, more to follow.
* Add: rail.[ch] for rail-related enums and wrapper functions.
* Codechange: Removed dozens of magic numbers with below enums.
* Codechange: Rewrote CheckTrackCombination().
* Add: TILE_SIZE, TILE_PIXELS and TILE_HEIGHT constants.
* Add: enums RailTileType, RailTileSubtype, SignalType to mask against the map arrays.
* Add: enums Track, TrackBits, Trackdir, TrackdirBits for railway track data. (Note that the old RAIL_BIT constants are replaced by TRACK_BIT ones).
* Add: enums Direction and DiagDirection
* Codechange: Moved a bunch of track(dir) related lookup arrays from npf.[ch] to rail.[ch].
* Codechange: move RailType enum from tile.h to rail.h.
* Add: Wrapper functions for masking signal status in the map arrays: SignalAlongTrackdir, SignalAgainstTrackdir and SignalOnTrack.
* Add: Wrapper functions to access rail tiles, using above enums
* Add: Wrapper functions to modify tracks, trackdirs, directions, etc.
* Add: Wrapper functions for all lookup arrays in rail.[ch] (Arrays are still used in parts of the code)
* Codechange: Renamed some variables and arguments to better represent what they contain (railbit -> track, bits -> trackdirbits, etc.).
* Codechange: Don't use FindLandscapeHeight() in CmdRemoveSingleRail(), since it returns way too much info. Use GetTileSlope() instead.
* Codechange: [NPF] Removed some unused globals and code from npf.c.
2005-06-16 18:04:02 +00:00
2010-03-14 12:04:10 +00:00
/** Railtype flags. */
2008-04-08 07:19:29 +00:00
enum RailTypeFlags {
2010-07-02 16:34:11 +00:00
RTF_CATENARY = 0 , ///< Bit number for drawing a catenary.
RTF_NO_LEVEL_CROSSING = 1 , ///< Bit number for disallowing level crossings.
2010-03-14 12:04:10 +00:00
2010-07-02 16:34:11 +00:00
RTFB_NONE = 0 , ///< All flags cleared.
RTFB_CATENARY = 1 < < RTF_CATENARY , ///< Value for drawing a catenary.
RTFB_NO_LEVEL_CROSSING = 1 < < RTF_NO_LEVEL_CROSSING , ///< Value for disallowing level crossings.
2008-04-08 07:19:29 +00:00
} ;
2010-03-23 22:25:43 +00:00
DECLARE_ENUM_AS_BIT_SET ( RailTypeFlags )
2008-04-08 07:19:29 +00:00
2010-02-07 22:22:54 +00:00
struct SpriteGroup ;
2010-03-14 12:39:24 +00:00
/** Sprite groups for a railtype. */
2010-02-07 22:22:54 +00:00
enum RailTypeSpriteGroup {
RTSG_CURSORS , ///< Cursor and toolbar icon images
RTSG_OVERLAY , ///< Images for overlaying track
RTSG_GROUND , ///< Main group of ground images
RTSG_TUNNEL , ///< Main group of ground images for snow or desert
RTSG_WIRES , ///< Catenary wires
RTSG_PYLONS , ///< Catenary pylons
RTSG_BRIDGE , ///< Bridge surface images
RTSG_CROSSING , ///< Level crossing overlay images
RTSG_DEPOT , ///< Depot images
RTSG_FENCES , ///< Fence images
RTSG_END ,
} ;
/**
* Offsets for sprites within an overlay / underlay set .
* These are the same for overlay and underlay sprites .
*/
enum RailTrackOffset {
RTO_X , ///< Piece of rail in X direction
RTO_Y , ///< Piece of rail in Y direction
RTO_N , ///< Piece of rail in northern corner
RTO_S , ///< Piece of rail in southern corner
RTO_E , ///< Piece of rail in eastern corner
RTO_W , ///< Piece of rail in western corner
RTO_SLOPE_NE , ///< Piece of rail on slope with north-east raised
RTO_SLOPE_SE , ///< Piece of rail on slope with south-east raised
RTO_SLOPE_SW , ///< Piece of rail on slope with south-west raised
RTO_SLOPE_NW , ///< Piece of rail on slope with north-west raised
RTO_CROSSING_XY , ///< Crossing of X and Y rail, with ballast
RTO_JUNCTION_SW , ///< Ballast for junction 'pointing' SW
RTO_JUNCTION_NE , ///< Ballast for junction 'pointing' NE
RTO_JUNCTION_SE , ///< Ballast for junction 'pointing' SE
RTO_JUNCTION_NW , ///< Ballast for junction 'pointing' NW
RTO_JUNCTION_NSEW , ///< Ballast for full junction
} ;
/**
* Offsets for spries within a bridge surface overlay set .
*/
enum RailTrackBridgeOffset {
RTBO_X , ///< Piece of rail in X direction
RTBO_Y , ///< Piece of rail in Y direction
RTBO_SLOPE , ///< Sloped rail pieces, in order NE, SE, SW, NW
} ;
2010-08-01 19:22:34 +00:00
/**
* Offsets from base sprite for fence sprites . These are in the order of
2009-01-13 08:39:25 +00:00
* the sprites in the original data files .
*/
enum RailFenceOffset {
RFO_FLAT_X ,
RFO_FLAT_Y ,
RFO_FLAT_VERT ,
RFO_FLAT_HORZ ,
RFO_SLOPE_SW ,
RFO_SLOPE_SE ,
RFO_SLOPE_NE ,
RFO_SLOPE_NW ,
} ;
2012-01-05 19:40:34 +00:00
/** List of rail type labels. */
typedef SmallVector < RailTypeLabel , 4 > RailTypeLabelList ;
2010-08-01 19:22:34 +00:00
/**
* This struct contains all the info that is needed to draw and construct tracks .
2005-07-29 21:36:02 +00:00
*/
2007-03-07 12:11:48 +00:00
struct RailtypeInfo {
2010-08-01 19:22:34 +00:00
/**
* Struct containing the main sprites . @ note not all sprites are listed , but only
2010-08-01 19:44:49 +00:00
* the ones used directly in the code
*/
2005-07-29 21:36:02 +00:00
struct {
SpriteID track_y ; ///< single piece of rail in Y direction, with ground
SpriteID track_ns ; ///< two pieces of rail in North and South corner (East-West direction)
SpriteID ground ; ///< ground sprite for a 3-way switch
2009-12-15 13:59:20 +00:00
SpriteID single_x ; ///< single piece of rail in X direction, without ground
2005-07-29 21:36:02 +00:00
SpriteID single_y ; ///< single piece of rail in Y direction, without ground
SpriteID single_n ; ///< single piece of rail in the northern corner
SpriteID single_s ; ///< single piece of rail in the southern corner
SpriteID single_e ; ///< single piece of rail in the eastern corner
SpriteID single_w ; ///< single piece of rail in the western corner
2008-06-11 14:55:02 +00:00
SpriteID single_sloped ; ///< single piecs of rail for slopes
2005-10-13 16:00:14 +00:00
SpriteID crossing ; ///< level crossing, rail in X direction
SpriteID tunnel ; ///< tunnel sprites base
2005-07-29 21:36:02 +00:00
} base_sprites ;
2010-08-01 19:22:34 +00:00
/**
* struct containing the sprites for the rail GUI . @ note only sprites referred to
2010-08-01 19:44:49 +00:00
* directly in the code are listed
*/
2005-08-03 11:08:13 +00:00
struct {
SpriteID build_ns_rail ; ///< button for building single rail in N-S direction
SpriteID build_x_rail ; ///< button for building single rail in X direction
SpriteID build_ew_rail ; ///< button for building single rail in E-W direction
SpriteID build_y_rail ; ///< button for building single rail in Y direction
SpriteID auto_rail ; ///< button for the autorail construction
SpriteID build_depot ; ///< button for building depots
SpriteID build_tunnel ; ///< button for building a tunnel
SpriteID convert_rail ; ///< button for converting rail
} gui_sprites ;
2005-10-14 08:11:18 +00:00
struct {
2007-08-03 12:29:56 +00:00
CursorID rail_ns ; ///< Cursor for building rail in N-S direction
CursorID rail_swne ; ///< Cursor for building rail in X direction
CursorID rail_ew ; ///< Cursor for building rail in E-W direction
CursorID rail_nwse ; ///< Cursor for building rail in Y direction
CursorID autorail ; ///< Cursor for autorail tool
CursorID depot ; ///< Cursor for building a depot
CursorID tunnel ; ///< Cursor for building a tunnel
CursorID convert ; ///< Cursor for converting track
2005-10-14 08:11:18 +00:00
} cursor ;
2005-08-03 11:08:13 +00:00
struct {
2011-11-07 19:35:02 +00:00
StringID name ;
2005-08-03 11:08:13 +00:00
StringID toolbar_caption ;
2008-08-24 21:31:24 +00:00
StringID menu_text ;
StringID build_caption ;
StringID replace_text ;
StringID new_loco ;
2005-08-03 11:08:13 +00:00
} strings ;
2005-07-29 21:36:02 +00:00
/** sprite number difference between a piece of track on a snowy ground and the corresponding one on normal ground */
SpriteID snow_offset ;
2006-03-29 16:30:26 +00:00
/** bitmask to the OTHER railtypes on which an engine of THIS railtype generates power */
2008-01-09 21:05:03 +00:00
RailTypes powered_railtypes ;
2006-03-29 16:30:26 +00:00
/** bitmask to the OTHER railtypes on which an engine of THIS railtype can physically travel */
2008-01-09 21:05:03 +00:00
RailTypes compatible_railtypes ;
2005-07-31 22:53:57 +00:00
2005-10-19 08:34:37 +00:00
/**
2006-06-27 21:25:53 +00:00
* Bridge offset
*/
2005-10-19 08:34:37 +00:00
SpriteID bridge_offset ;
2006-04-11 10:45:06 +00:00
/**
2011-05-08 15:58:59 +00:00
* Original railtype number to use when drawing non - newgrf railtypes , or when drawing stations .
2006-04-11 10:45:06 +00:00
*/
2011-05-08 15:58:59 +00:00
byte fallback_railtype ;
2008-01-01 14:00:31 +00:00
/**
* Multiplier for curve maximum speed advantage
*/
byte curve_speed ;
2008-04-08 07:19:29 +00:00
/**
* Bit mask of rail type flags
*/
RailTypeFlags flags ;
2008-08-24 23:10:23 +00:00
/**
* Cost multiplier for building this rail type
*/
2010-03-03 18:58:32 +00:00
uint16 cost_multiplier ;
2009-02-08 18:11:06 +00:00
2011-12-03 23:40:46 +00:00
/**
* Cost multiplier for maintenance of this rail type
*/
uint16 maintenance_multiplier ;
2010-01-09 15:33:41 +00:00
/**
* Acceleration type of this rail type
*/
uint8 acceleration_type ;
2010-01-31 13:17:29 +00:00
/**
* Maximum speed for vehicles travelling on this rail type
*/
uint16 max_speed ;
2009-02-08 18:11:06 +00:00
/**
* Unique 32 bit rail type identifier
*/
RailTypeLabel label ;
2010-02-07 22:22:54 +00:00
2012-01-05 19:40:34 +00:00
/**
* Rail type labels this type provides in addition to the main label .
*/
RailTypeLabelList alternate_labels ;
2010-03-03 19:07:34 +00:00
/**
* Colour on mini - map
*/
byte map_colour ;
2011-01-18 21:30:59 +00:00
/**
* Introduction date .
* When # INVALID_DATE or a vehicle using this railtype gets introduced earlier ,
* the vehicle ' s introduction date will be used instead for this railtype .
* The introduction at this date is furthermore limited by the
* # introduction_required_types .
*/
Date introduction_date ;
/**
* Bitmask of railtypes that are required for this railtype to be introduced
* at a given # introduction_date .
*/
RailTypes introduction_required_railtypes ;
2011-01-18 21:28:07 +00:00
/**
* Bitmask of which other railtypes are introduced when this railtype is introduced .
*/
RailTypes introduces_railtypes ;
2011-01-20 12:22:38 +00:00
/**
* The sorting order of this railtype for the toolbar dropdown .
*/
byte sorting_order ;
2011-07-04 20:25:17 +00:00
/**
* NewGRF providing the Action3 for the railtype . NULL if not available .
*/
const GRFFile * grffile [ RTSG_END ] ;
2010-02-07 22:22:54 +00:00
/**
* Sprite groups for resolving sprites
*/
const SpriteGroup * group [ RTSG_END ] ;
inline bool UsesOverlay ( ) const
{
return this - > group [ RTSG_GROUND ] ! = NULL ;
}
2011-05-08 15:58:59 +00:00
/**
* Offset between the current railtype and normal rail . This means that : < p >
* 1 ) All the sprites in a railset MUST be in the same order . This order
* is determined by normal rail . Check sprites 1005 and following for this order < p >
* 2 ) The position where the railtype is loaded must always be the same , otherwise
* the offset will fail .
*/
inline uint GetRailtypeSpriteOffset ( ) const
{
return 82 * this - > fallback_railtype ;
}
2007-03-07 12:11:48 +00:00
} ;
2005-07-29 21:36:02 +00:00
/**
* Returns a pointer to the Railtype information for a given railtype
* @ param railtype the rail type which the information is requested for
* @ return The pointer to the RailtypeInfo
*/
2005-07-29 22:13:04 +00:00
static inline const RailtypeInfo * GetRailTypeInfo ( RailType railtype )
2005-07-29 21:36:02 +00:00
{
2007-02-26 22:32:21 +00:00
extern RailtypeInfo _railtypes [ RAILTYPE_END ] ;
2005-07-29 21:36:02 +00:00
assert ( railtype < RAILTYPE_END ) ;
2005-07-29 22:13:04 +00:00
return & _railtypes [ railtype ] ;
2005-07-29 21:36:02 +00:00
}
2005-07-03 13:02:54 +00:00
/**
* Checks if an engine of the given RailType can drive on a tile with a given
* RailType . This would normally just be an equality check , but for electric
* rails ( which also support non - electric engines ) .
* @ return Whether the engine can drive on this tile .
* @ param enginetype The RailType of the engine we are considering .
* @ param tiletype The RailType of the tile we are considering .
*/
static inline bool IsCompatibleRail ( RailType enginetype , RailType tiletype )
{
2007-11-19 21:02:30 +00:00
return HasBit ( GetRailTypeInfo ( enginetype ) - > compatible_railtypes , tiletype ) ;
2005-07-03 13:02:54 +00:00
}
2007-08-03 12:29:56 +00:00
/**
* Checks if an engine of the given RailType got power on a tile with a given
* RailType . This would normally just be an equality check , but for electric
* rails ( which also support non - electric engines ) .
* @ return Whether the engine got power on this tile .
* @ param enginetype The RailType of the engine we are considering .
* @ param tiletype The RailType of the tile we are considering .
*/
2006-03-29 16:30:26 +00:00
static inline bool HasPowerOnRail ( RailType enginetype , RailType tiletype )
{
2007-11-19 21:02:30 +00:00
return HasBit ( GetRailTypeInfo ( enginetype ) - > powered_railtypes , tiletype ) ;
2006-03-29 16:30:26 +00:00
}
2010-07-02 16:34:11 +00:00
/**
* Test if a RailType disallows build of level crossings .
* @ param rt The RailType to check .
* @ return Whether level crossings are not allowed .
*/
static inline bool RailNoLevelCrossings ( RailType rt )
{
return HasBit ( GetRailTypeInfo ( rt ) - > flags , RTF_NO_LEVEL_CROSSING ) ;
}
2007-10-14 21:20:12 +00:00
/**
* Returns the cost of building the specified railtype .
* @ param railtype The railtype being built .
* @ return The cost multiplier .
*/
static inline Money RailBuildCost ( RailType railtype )
{
assert ( railtype < RAILTYPE_END ) ;
2009-11-07 22:47:54 +00:00
return ( _price [ PR_BUILD_RAIL ] * GetRailTypeInfo ( railtype ) - > cost_multiplier ) > > 3 ;
2007-10-14 21:20:12 +00:00
}
2010-03-16 06:30:31 +00:00
/**
* Returns the ' cost ' of clearing the specified railtype .
* @ param railtype The railtype being removed .
* @ return The cost .
*/
static inline Money RailClearCost ( RailType railtype )
{
/* Clearing rail in fact earns money, but if the build cost is set
* very low then a loophole exists where money can be made .
* In this case we limit the removal earnings to 3 / 4 s of the build
* cost .
*/
assert ( railtype < RAILTYPE_END ) ;
return max ( _price [ PR_CLEAR_RAIL ] , - RailBuildCost ( railtype ) * 3 / 4 ) ;
}
2007-12-08 19:53:30 +00:00
/**
* Calculates the cost of rail conversion
* @ param from The railtype we are converting from
* @ param to The railtype we are converting to
* @ return Cost per TrackBit
*/
static inline Money RailConvertCost ( RailType from , RailType to )
{
2011-01-27 00:38:12 +00:00
/* Get the costs for removing and building anew
* A conversion can never be more costly */
Money rebuildcost = RailBuildCost ( to ) + RailClearCost ( from ) ;
/* Conversion between somewhat compatible railtypes:
* Pay 1 / 8 of the target rail cost ( labour costs ) and additionally any difference in the
* build costs , if the target type is more expensive ( material upgrade costs ) .
* Upgrade can never be more expensive than re - building . */
if ( HasPowerOnRail ( from , to ) | | HasPowerOnRail ( to , from ) ) {
Money upgradecost = RailBuildCost ( to ) / 8 + max ( ( Money ) 0 , RailBuildCost ( to ) - RailBuildCost ( from ) ) ;
return min ( upgradecost , rebuildcost ) ;
2007-12-08 19:53:30 +00:00
}
2011-01-27 00:38:12 +00:00
/* make the price the same as remove + build new type for rail types
* which are not compatible in any way */
return rebuildcost ;
2007-12-08 19:53:30 +00:00
}
2011-12-03 23:40:46 +00:00
/**
* Calculates the maintenance cost of a number of track bits .
* @ param railtype The railtype to get the cost of .
2012-02-11 22:43:39 +00:00
* @ param num Number of track bits of this railtype .
* @ param total_num Total number of track bits of all railtypes .
2011-12-03 23:40:46 +00:00
* @ return Total cost .
*/
2012-02-11 22:43:39 +00:00
static inline Money RailMaintenanceCost ( RailType railtype , uint32 num , uint32 total_num )
2011-12-03 23:40:46 +00:00
{
assert ( railtype < RAILTYPE_END ) ;
2012-02-11 22:43:39 +00:00
return ( _price [ PR_INFRASTRUCTURE_RAIL ] * GetRailTypeInfo ( railtype ) - > maintenance_multiplier * num * ( 1 + IntSqrt ( total_num ) ) ) > > 11 ; // 4 bits fraction for the multiplier and 7 bits scaling.
2011-12-03 23:40:46 +00:00
}
/**
* Calculates the maintenance cost of a number of signals .
* @ param num Number of signals .
* @ return Total cost .
*/
static inline Money SignalMaintenanceCost ( uint32 num )
{
return ( _price [ PR_INFRASTRUCTURE_RAIL ] * 15 * num * ( 1 + IntSqrt ( num ) ) ) > > 8 ; // 1 bit fraction for the multiplier and 7 bits scaling.
}
2005-10-16 09:13:04 +00:00
void DrawTrainDepotSprite ( int x , int y , int image , RailType railtype ) ;
2009-05-22 22:55:41 +00:00
int TicksToLeaveDepot ( const Train * v ) ;
2006-03-29 16:30:26 +00:00
2007-07-26 16:51:10 +00:00
Foundation GetRailFoundation ( Slope tileh , TrackBits bits ) ;
2006-11-17 19:31:44 +00:00
2008-09-30 20:39:50 +00:00
bool HasRailtypeAvail ( const CompanyID company , const RailType railtype ) ;
2008-01-09 21:05:03 +00:00
bool ValParamRailtype ( const RailType rail ) ;
2011-01-18 21:30:59 +00:00
RailTypes AddDateIntroducedRailTypes ( RailTypes current , Date date ) ;
2011-01-18 23:09:43 +00:00
RailType GetBestRailtype ( const CompanyID company ) ;
2008-10-07 20:57:41 +00:00
RailTypes GetCompanyRailtypes ( const CompanyID c ) ;
2008-01-09 21:05:03 +00:00
2012-01-05 19:40:34 +00:00
RailType GetRailTypeByLabel ( RailTypeLabel label , bool allow_alternate_labels = true ) ;
2009-02-08 18:11:06 +00:00
2008-08-24 23:00:11 +00:00
void ResetRailTypes ( ) ;
2010-02-07 22:22:54 +00:00
void InitRailTypes ( ) ;
2010-01-30 21:49:22 +00:00
RailType AllocateRailType ( RailTypeLabel label ) ;
2005-09-18 20:56:44 +00:00
# endif /* RAIL_H */