rail.cpp

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

Generated on Mon Dec 14 21:00:01 2009 for OpenTTD by  doxygen 1.5.6