# rail.cpp

Go to the documentation of this file.

    00001 /* $Id: rail.cpp 12313 2008-02-28 17:34:34Z frosch $ */
    00002
    00005 #include "stdafx.h"
    00006 #include "openttd.h"
    00007 #include "bridge_map.h"
    00008 #include "rail.h"
    00009 #include "station_map.h"
    00010 #include "tunnel_map.h"
    00011 #include "tunnelbridge_map.h"
    00012 #include "settings_type.h"
    00013 #include "date_func.h"
    00014 #include "player_func.h"
    00015 #include "player_base.h"
    00016
    00017
    00018 /* XXX: Below 3 tables store duplicate data. Maybe remove some? */
    00019 /* Maps a trackdir to the bit that stores its status in the map arrays, in the
    00020  * direction along with the trackdir */
    00021 extern const byte _signal_along_trackdir[TRACKDIR_END] = {
    00022   0x8, 0x8, 0x8, 0x2, 0x4, 0x1, 0, 0,
    00023   0x4, 0x4, 0x4, 0x1, 0x8, 0x2
    00024 };
    00025
    00026 /* Maps a trackdir to the bit that stores its status in the map arrays, in the
    00027  * direction against the trackdir */
    00028 extern const byte _signal_against_trackdir[TRACKDIR_END] = {
    00029   0x4, 0x4, 0x4, 0x1, 0x8, 0x2, 0, 0,
    00030   0x8, 0x8, 0x8, 0x2, 0x4, 0x1
    00031 };
    00032
    00033 /* Maps a Track to the bits that store the status of the two signals that can
    00034  * be present on the given track */
    00035 extern const byte _signal_on_track[] = {
    00036   0xC, 0xC, 0xC, 0x3, 0xC, 0x3
    00037 };
    00038
    00039 /* Maps a diagonal direction to the all trackdirs that are connected to any
    00040  * track entering in this direction (including those making 90 degree turns)
    00041  */
    00042 extern const TrackdirBits _exitdir_reaches_trackdirs[] = {
    00043   TRACKDIR_BIT_X_NE | TRACKDIR_BIT_LOWER_E | TRACKDIR_BIT_LEFT_N,  /* DIAGDIR_NE */
    00044   TRACKDIR_BIT_Y_SE | TRACKDIR_BIT_LEFT_S  | TRACKDIR_BIT_UPPER_E, /* DIAGDIR_SE */
    00045   TRACKDIR_BIT_X_SW | TRACKDIR_BIT_UPPER_W | TRACKDIR_BIT_RIGHT_S, /* DIAGDIR_SW */
    00046   TRACKDIR_BIT_Y_NW | TRACKDIR_BIT_RIGHT_N | TRACKDIR_BIT_LOWER_W  /* DIAGDIR_NW */
    00047 };
    00048
    00049 extern const Trackdir _next_trackdir[TRACKDIR_END] = {
    00050   TRACKDIR_X_NE,  TRACKDIR_Y_SE,  TRACKDIR_LOWER_E, TRACKDIR_UPPER_E, TRACKDIR_RIGHT_S, TRACKDIR_LEFT_S, INVALID_TRACKDIR, INVALID_TRACKDIR,
    00051   TRACKDIR_X_SW,  TRACKDIR_Y_NW,  TRACKDIR_LOWER_W, TRACKDIR_UPPER_W, TRACKDIR_RIGHT_N, TRACKDIR_LEFT_N
    00052 };
    00053
    00054 /* Maps a trackdir to all trackdirs that make 90 deg turns with it. */
    00055 extern const TrackdirBits _track_crosses_trackdirs[TRACKDIR_END] = {
    00056   TRACKDIR_BIT_Y_SE     | TRACKDIR_BIT_Y_NW,                                                   /* TRACK_X     */
    00057   TRACKDIR_BIT_X_NE     | TRACKDIR_BIT_X_SW,                                                   /* TRACK_Y     */
    00058   TRACKDIR_BIT_RIGHT_N  | TRACKDIR_BIT_RIGHT_S  | TRACKDIR_BIT_LEFT_N  | TRACKDIR_BIT_LEFT_S,  /* TRACK_UPPER */
    00059   TRACKDIR_BIT_RIGHT_N  | TRACKDIR_BIT_RIGHT_S  | TRACKDIR_BIT_LEFT_N  | TRACKDIR_BIT_LEFT_S,  /* TRACK_LOWER */
    00060   TRACKDIR_BIT_UPPER_W  | TRACKDIR_BIT_UPPER_E  | TRACKDIR_BIT_LOWER_W | TRACKDIR_BIT_LOWER_E, /* TRACK_LEFT  */
    00061   TRACKDIR_BIT_UPPER_W  | TRACKDIR_BIT_UPPER_E  | TRACKDIR_BIT_LOWER_W | TRACKDIR_BIT_LOWER_E  /* TRACK_RIGHT */
    00062 };
    00063
    00064 /* Maps a track to all tracks that make 90 deg turns with it. */
    00065 extern const TrackBits _track_crosses_tracks[] = {
    00066   TRACK_BIT_Y,    /* TRACK_X     */
    00067   TRACK_BIT_X,    /* TRACK_Y     */
    00068   TRACK_BIT_VERT, /* TRACK_UPPER */
    00069   TRACK_BIT_VERT, /* TRACK_LOWER */
    00070   TRACK_BIT_HORZ, /* TRACK_LEFT  */
    00071   TRACK_BIT_HORZ  /* TRACK_RIGHT */
    00072 };
    00073
    00074 /* Maps a trackdir to the (4-way) direction the tile is exited when following
    00075  * that trackdir */
    00076 extern const DiagDirection _trackdir_to_exitdir[TRACKDIR_END] = {
    00077   DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_SE, DIAGDIR_SW, DIAGDIR_SE, DIAGDIR_NE, DIAGDIR_NE,
    00078   DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NW, DIAGDIR_SW, DIAGDIR_NW, DIAGDIR_NE,
    00079 };
    00080
    00081 extern const Trackdir _track_exitdir_to_trackdir[][DIAGDIR_END] = {
    00082   {TRACKDIR_X_NE,     INVALID_TRACKDIR,  TRACKDIR_X_SW,     INVALID_TRACKDIR},
    00083   {INVALID_TRACKDIR,  TRACKDIR_Y_SE,     INVALID_TRACKDIR,  TRACKDIR_Y_NW},
    00084   {TRACKDIR_UPPER_E,  INVALID_TRACKDIR,  INVALID_TRACKDIR,  TRACKDIR_UPPER_W},
    00085   {INVALID_TRACKDIR,  TRACKDIR_LOWER_E,  TRACKDIR_LOWER_W,  INVALID_TRACKDIR},
    00086   {INVALID_TRACKDIR,  INVALID_TRACKDIR,  TRACKDIR_LEFT_S,   TRACKDIR_LEFT_N},
    00087   {TRACKDIR_RIGHT_N,  TRACKDIR_RIGHT_S,  INVALID_TRACKDIR,  INVALID_TRACKDIR}
    00088 };
    00089
    00090 extern const Trackdir _track_enterdir_to_trackdir[][DIAGDIR_END] = {
    00091   {TRACKDIR_X_NE,     INVALID_TRACKDIR,  TRACKDIR_X_SW,     INVALID_TRACKDIR},
    00092   {INVALID_TRACKDIR,  TRACKDIR_Y_SE,     INVALID_TRACKDIR,  TRACKDIR_Y_NW},
    00093   {INVALID_TRACKDIR,  TRACKDIR_UPPER_E,  TRACKDIR_UPPER_W,  INVALID_TRACKDIR},
    00094   {TRACKDIR_LOWER_E,  INVALID_TRACKDIR,  INVALID_TRACKDIR,  TRACKDIR_LOWER_W},
    00095   {TRACKDIR_LEFT_N,   TRACKDIR_LEFT_S,   INVALID_TRACKDIR,  INVALID_TRACKDIR},
    00096   {INVALID_TRACKDIR,  INVALID_TRACKDIR,  TRACKDIR_RIGHT_S,  TRACKDIR_RIGHT_N}
    00097 };
    00098
    00099 extern const Trackdir _track_direction_to_trackdir[][DIR_END] = {
    00100   {INVALID_TRACKDIR, TRACKDIR_X_NE,     INVALID_TRACKDIR, INVALID_TRACKDIR,  INVALID_TRACKDIR, TRACKDIR_X_SW,     INVALID_TRACKDIR, INVALID_TRACKDIR},
    00101   {INVALID_TRACKDIR, INVALID_TRACKDIR,  INVALID_TRACKDIR, TRACKDIR_Y_SE,     INVALID_TRACKDIR, INVALID_TRACKDIR,  INVALID_TRACKDIR, TRACKDIR_Y_NW},
    00102   {INVALID_TRACKDIR, INVALID_TRACKDIR,  TRACKDIR_UPPER_E, INVALID_TRACKDIR,  INVALID_TRACKDIR, INVALID_TRACKDIR,  TRACKDIR_UPPER_W, INVALID_TRACKDIR},
    00103   {INVALID_TRACKDIR, INVALID_TRACKDIR,  TRACKDIR_LOWER_E, INVALID_TRACKDIR,  INVALID_TRACKDIR, INVALID_TRACKDIR,  TRACKDIR_LOWER_W, INVALID_TRACKDIR},
    00104   {TRACKDIR_LEFT_N,  INVALID_TRACKDIR,  INVALID_TRACKDIR, INVALID_TRACKDIR,  TRACKDIR_LEFT_S,  INVALID_TRACKDIR,  INVALID_TRACKDIR, INVALID_TRACKDIR},
    00105   {TRACKDIR_RIGHT_N, INVALID_TRACKDIR,  INVALID_TRACKDIR, INVALID_TRACKDIR,  TRACKDIR_RIGHT_S, INVALID_TRACKDIR,  INVALID_TRACKDIR, INVALID_TRACKDIR}
    00106 };
    00107
    00108 extern const Trackdir _dir_to_diag_trackdir[] = {
    00109   TRACKDIR_X_NE, TRACKDIR_Y_SE, TRACKDIR_X_SW, TRACKDIR_Y_NW,
    00110 };
    00111
    00112 extern const TrackBits _corner_to_trackbits[] = {
    00113   TRACK_BIT_LEFT, TRACK_BIT_LOWER, TRACK_BIT_RIGHT, TRACK_BIT_UPPER,
    00114 };
    00115
    00116 extern const TrackdirBits _uphill_trackdirs[] = {
    00117   TRACKDIR_BIT_NONE                    ,
    00118   TRACKDIR_BIT_X_SW | TRACKDIR_BIT_Y_NW,
    00119   TRACKDIR_BIT_X_SW | TRACKDIR_BIT_Y_SE,
    00120   TRACKDIR_BIT_X_SW                    ,
    00121   TRACKDIR_BIT_X_NE | TRACKDIR_BIT_Y_SE,
    00122   TRACKDIR_BIT_NONE                    ,
    00123   TRACKDIR_BIT_Y_SE                    ,
    00124   TRACKDIR_BIT_NONE                    ,
    00125   TRACKDIR_BIT_X_NE | TRACKDIR_BIT_Y_NW,
    00126   TRACKDIR_BIT_Y_NW                    ,
    00127   TRACKDIR_BIT_NONE                    ,
    00128   TRACKDIR_BIT_NONE                    ,
    00129   TRACKDIR_BIT_X_NE                    ,
    00130   TRACKDIR_BIT_NONE                    ,
    00131   TRACKDIR_BIT_NONE                    ,
    00132   TRACKDIR_BIT_NONE                    ,
    00133   TRACKDIR_BIT_NONE                    ,
    00134   TRACKDIR_BIT_NONE                    ,
    00135   TRACKDIR_BIT_NONE                    ,
    00136   TRACKDIR_BIT_NONE                    ,
    00137   TRACKDIR_BIT_NONE                    ,
    00138   TRACKDIR_BIT_NONE                    ,
    00139   TRACKDIR_BIT_NONE                    ,
    00140   TRACKDIR_BIT_X_SW | TRACKDIR_BIT_Y_SE,
    00141   TRACKDIR_BIT_NONE                    ,
    00142   TRACKDIR_BIT_NONE                    ,
    00143   TRACKDIR_BIT_NONE                    ,
    00144   TRACKDIR_BIT_X_SW | TRACKDIR_BIT_Y_NW,
    00145   TRACKDIR_BIT_NONE                    ,
    00146   TRACKDIR_BIT_X_NE | TRACKDIR_BIT_Y_NW,
    00147   TRACKDIR_BIT_X_NE | TRACKDIR_BIT_Y_SE,
    00148 };
    00149
    00150 /* The default multiplier for the cost of building different types of railway
    00151  * track, which will be divided by 8. Can be changed by newgrf files. */
    00152 const int _default_railtype_cost_multiplier[RAILTYPE_END] = {
    00153   8, 12, 16, 24,
    00154 };
    00155 int _railtype_cost_multiplier[RAILTYPE_END];
    00156
    00157 RailType GetTileRailType(TileIndex tile)
    00158 {
    00159   switch (GetTileType(tile)) {
    00160     case MP_RAILWAY:
    00161       return GetRailType(tile);
    00162
    00163     case MP_ROAD:
    00164       /* rail/road crossing */
    00165       if (IsLevelCrossing(tile)) return GetRailType(tile);
    00166       break;
    00167
    00168     case MP_STATION:
    00169       if (IsRailwayStationTile(tile)) return GetRailType(tile);
    00170       break;
    00171
    00172     case MP_TUNNELBRIDGE:
    00173       if (GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL) return GetRailType(tile);
    00174       break;
    00175
    00176     default:
    00177       break;
    00178   }
    00179   return INVALID_RAILTYPE;
    00180 }
    00181
    00182 bool HasRailtypeAvail(const PlayerID p, const RailType railtype)
    00183 {
    00184   return HasBit(GetPlayer(p)->avail_railtypes, railtype);
    00185 }
    00186
    00187 bool ValParamRailtype(const RailType rail)
    00188 {
    00189   return HasRailtypeAvail(_current_player, rail);
    00190 }
    00191
    00192 RailType GetBestRailtype(const PlayerID p)
    00193 {
    00194   if (HasRailtypeAvail(p, RAILTYPE_MAGLEV)) return RAILTYPE_MAGLEV;
    00195   if (HasRailtypeAvail(p, RAILTYPE_MONO)) return RAILTYPE_MONO;
    00196   if (HasRailtypeAvail(p, RAILTYPE_ELECTRIC)) return RAILTYPE_ELECTRIC;
    00197   return RAILTYPE_RAIL;
    00198 }
    00199
    00200 RailTypes GetPlayerRailtypes(PlayerID p)
    00201 {
    00202   RailTypes rt = RAILTYPES_NONE;
    00203
    00204   EngineID i;
    00205   FOR_ALL_ENGINEIDS_OF_TYPE(i, VEH_TRAIN) {
    00206     const Engine* e = GetEngine(i);
    00207     const EngineInfo *ei = EngInfo(i);
    00208
    00209     if (HasBit(ei->climates, _opt.landscape) &&
    00210         (HasBit(e->player_avail, p) || _date >= e->intro_date + 365)) {
    00211       const RailVehicleInfo *rvi = RailVehInfo(i);
    00212
    00213       if (rvi->railveh_type != RAILVEH_WAGON) {
    00214         assert(rvi->railtype < RAILTYPE_END);
    00215         SetBit(rt, rvi->railtype);
    00216       }
    00217     }
    00218   }
    00219
    00220   return rt;
    00221 }