ai_rail.cpp

Go to the documentation of this file.
00001 /* $Id: ai_rail.cpp 16481 2009-05-31 12:18:03Z rubidium $ */
00002 
00005 #include "ai_rail.hpp"
00006 #include "ai_map.hpp"
00007 #include "ai_station.hpp"
00008 #include "../../debug.h"
00009 #include "../../station_map.h"
00010 #include "../../company_func.h"
00011 #include "../../waypoint.h"
00012 #include "../../newgrf_generic.h"
00013 #include "../../newgrf_station.h"
00014 
00015 /* static */ bool AIRail::IsRailTile(TileIndex tile)
00016 {
00017   if (!::IsValidTile(tile)) return false;
00018 
00019   return (::IsTileType(tile, MP_RAILWAY) && !::IsRailDepot(tile)) ||
00020       (::IsRailwayStationTile(tile) && !::IsStationTileBlocked(tile)) || ::IsLevelCrossingTile(tile);
00021 }
00022 
00023 /* static */ bool AIRail::IsLevelCrossingTile(TileIndex tile)
00024 {
00025   if (!::IsValidTile(tile)) return false;
00026 
00027   return ::IsLevelCrossingTile(tile);
00028 }
00029 
00030 /* static */ bool AIRail::IsRailDepotTile(TileIndex tile)
00031 {
00032   if (!::IsValidTile(tile)) return false;
00033 
00034   return ::IsRailDepotTile(tile);
00035 }
00036 
00037 /* static */ bool AIRail::IsRailStationTile(TileIndex tile)
00038 {
00039   if (!::IsValidTile(tile)) return false;
00040 
00041   return ::IsRailwayStationTile(tile);
00042 }
00043 
00044 /* static */ bool AIRail::IsRailWaypointTile(TileIndex tile)
00045 {
00046   if (!::IsValidTile(tile)) return false;
00047 
00048   return ::IsTileType(tile, MP_RAILWAY) && ::IsRailWaypointTile(tile);
00049 }
00050 
00051 /* static */ bool AIRail::IsRailTypeAvailable(RailType rail_type)
00052 {
00053   if ((::RailType)rail_type < RAILTYPE_BEGIN || (::RailType)rail_type >= RAILTYPE_END) return false;
00054 
00055   return ::HasRailtypeAvail(_current_company, (::RailType)rail_type);
00056 }
00057 
00058 /* static */ AIRail::RailType AIRail::GetCurrentRailType()
00059 {
00060   return (RailType)AIObject::GetRailType();
00061 }
00062 
00063 /* static */ void AIRail::SetCurrentRailType(RailType rail_type)
00064 {
00065   if (!IsRailTypeAvailable(rail_type)) return;
00066 
00067   AIObject::SetRailType((::RailType)rail_type);
00068 }
00069 
00070 /* static */ bool AIRail::TrainCanRunOnRail(AIRail::RailType engine_rail_type, AIRail::RailType track_rail_type)
00071 {
00072   if (!AIRail::IsRailTypeAvailable(engine_rail_type)) return false;
00073   if (!AIRail::IsRailTypeAvailable(track_rail_type)) return false;
00074 
00075   return ::IsCompatibleRail((::RailType)engine_rail_type, (::RailType)track_rail_type);
00076 }
00077 
00078 /* static */ bool AIRail::TrainHasPowerOnRail(AIRail::RailType engine_rail_type, AIRail::RailType track_rail_type)
00079 {\
00080   if (!AIRail::IsRailTypeAvailable(engine_rail_type)) return false;
00081   if (!AIRail::IsRailTypeAvailable(track_rail_type)) return false;
00082 
00083   return ::HasPowerOnRail((::RailType)engine_rail_type, (::RailType)track_rail_type);
00084 }
00085 
00086 /* static */ AIRail::RailType AIRail::GetRailType(TileIndex tile)
00087 {
00088   if (!AITile::HasTransportType(tile, AITile::TRANSPORT_RAIL)) return RAILTYPE_INVALID;
00089 
00090   return (RailType)::GetRailType(tile);
00091 }
00092 
00093 /* static */ bool AIRail::ConvertRailType(TileIndex start_tile, TileIndex end_tile, AIRail::RailType convert_to)
00094 {
00095   EnforcePrecondition(false, ::IsValidTile(start_tile));
00096   EnforcePrecondition(false, ::IsValidTile(end_tile));
00097   EnforcePrecondition(false, IsRailTypeAvailable(convert_to));
00098 
00099   return AIObject::DoCommand(start_tile, end_tile, convert_to, CMD_CONVERT_RAIL);
00100 }
00101 
00102 /* static */ TileIndex AIRail::GetRailDepotFrontTile(TileIndex depot)
00103 {
00104   if (!IsRailDepotTile(depot)) return INVALID_TILE;
00105 
00106   return depot + ::TileOffsByDiagDir(::GetRailDepotDirection(depot));
00107 }
00108 
00109 /* static */ AIRail::RailTrack AIRail::GetRailStationDirection(TileIndex tile)
00110 {
00111   if (!IsRailStationTile(tile)) return RAILTRACK_INVALID;
00112 
00113   return (RailTrack)::GetRailStationTrackBits(tile);
00114 }
00115 
00116 /* static */ bool AIRail::BuildRailDepot(TileIndex tile, TileIndex front)
00117 {
00118   EnforcePrecondition(false, tile != front);
00119   EnforcePrecondition(false, ::IsValidTile(tile));
00120   EnforcePrecondition(false, ::IsValidTile(front));
00121   EnforcePrecondition(false, ::TileX(tile) == ::TileX(front) || ::TileY(tile) == ::TileY(front));
00122   EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType()));
00123 
00124   uint entrance_dir = (::TileX(tile) == ::TileX(front)) ? (::TileY(tile) < ::TileY(front) ? 1 : 3) : (::TileX(tile) < ::TileX(front) ? 2 : 0);
00125 
00126   return AIObject::DoCommand(tile, AIObject::GetRailType(), entrance_dir, CMD_BUILD_TRAIN_DEPOT);
00127 }
00128 
00129 /* static */ bool AIRail::BuildRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id)
00130 {
00131   EnforcePrecondition(false, ::IsValidTile(tile));
00132   EnforcePrecondition(false, direction == RAILTRACK_NW_SE || direction == RAILTRACK_NE_SW);
00133   EnforcePrecondition(false, num_platforms > 0 && num_platforms <= 0xFF);
00134   EnforcePrecondition(false, platform_length > 0 && platform_length <= 0xFF);
00135   EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType()));
00136   EnforcePrecondition(false, station_id == AIStation::STATION_NEW || station_id == AIStation::STATION_JOIN_ADJACENT || AIStation::IsValidStation(station_id));
00137 
00138   uint32 p1 = GetCurrentRailType() | (platform_length << 16) | (num_platforms << 8);
00139   if (direction == RAILTRACK_NW_SE) p1 |= (1 << 4);
00140   if (station_id != AIStation::STATION_JOIN_ADJACENT) p1 |= (1 << 24);
00141   return AIObject::DoCommand(tile, p1, (AIStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16, CMD_BUILD_RAILROAD_STATION);
00142 }
00143 
00144 /* static */ bool AIRail::BuildNewGRFRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id, CargoID cargo_id, IndustryType source_industry, IndustryType goal_industry, int distance, bool source_station)
00145 {
00146   EnforcePrecondition(false, ::IsValidTile(tile));
00147   EnforcePrecondition(false, direction == RAILTRACK_NW_SE || direction == RAILTRACK_NE_SW);
00148   EnforcePrecondition(false, num_platforms > 0 && num_platforms <= 0xFF);
00149   EnforcePrecondition(false, platform_length > 0 && platform_length <= 0xFF);
00150   EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType()));
00151   EnforcePrecondition(false, station_id == AIStation::STATION_NEW || station_id == AIStation::STATION_JOIN_ADJACENT || AIStation::IsValidStation(station_id));
00152 
00153   uint32 p1 = GetCurrentRailType() | (platform_length << 16) | (num_platforms << 8);
00154   if (direction == RAILTRACK_NW_SE) p1 |= 1 << 4;
00155   if (station_id != AIStation::STATION_JOIN_ADJACENT) p1 |= (1 << 24);
00156 
00157   const GRFFile *file;
00158   uint16 res = GetAiPurchaseCallbackResult(GSF_STATION, cargo_id, 0, source_industry, goal_industry, min(255, distance / 2), AICE_STATION_GET_STATION_ID, source_station ? 0 : 1, min(15, num_platforms) << 4 | min(15, platform_length), &file);
00159   uint32 p2 = (AIStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16;
00160   if (res != CALLBACK_FAILED) {
00161     int index = 0;
00162     const StationSpec *spec = GetCustomStationSpecByGrf(file->grfid, res, &index);
00163     if (spec == NULL) {
00164       DEBUG(grf, 1, "%s returned an invalid station ID for 'AI construction/purchase selection (18)' callback", file->filename);
00165     } else {
00166       p2 |= spec->sclass | index << 8;
00167     }
00168 
00169   }
00170   return AIObject::DoCommand(tile, p1, p2, CMD_BUILD_RAILROAD_STATION);
00171 }
00172 
00173 /* static */ bool AIRail::BuildRailWaypoint(TileIndex tile)
00174 {
00175   EnforcePrecondition(false, ::IsValidTile(tile));
00176   EnforcePrecondition(false, IsRailTile(tile));
00177   EnforcePrecondition(false, GetRailTracks(tile) == RAILTRACK_NE_SW || GetRailTracks(tile) == RAILTRACK_NW_SE);
00178   EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType()));
00179 
00180   return AIObject::DoCommand(tile, 0, 0, CMD_BUILD_TRAIN_WAYPOINT);
00181 }
00182 
00183 /* static */ bool AIRail::RemoveRailWaypoint(TileIndex tile)
00184 {
00185   EnforcePrecondition(false, ::IsValidTile(tile));
00186   EnforcePrecondition(false, IsRailWaypointTile(tile));
00187 
00188   return AIObject::DoCommand(tile, 0, 0, CMD_REMOVE_TRAIN_WAYPOINT);
00189 }
00190 
00191 /* static */ bool AIRail::RemoveRailStationTileRect(TileIndex tile, TileIndex tile2)
00192 {
00193   EnforcePrecondition(false, ::IsValidTile(tile));
00194   EnforcePrecondition(false, ::IsValidTile(tile2));
00195 
00196   return AIObject::DoCommand(tile, tile2, 0, CMD_REMOVE_FROM_RAILROAD_STATION);
00197 }
00198 
00199 /* static */ uint AIRail::GetRailTracks(TileIndex tile)
00200 {
00201   if (!IsRailTile(tile)) return RAILTRACK_INVALID;
00202 
00203   if (IsRailWaypointTile(tile)) return ::GetRailWaypointBits(tile);
00204   if (IsRailStationTile(tile)) return ::TrackToTrackBits(::GetRailStationTrack(tile));
00205   if (IsLevelCrossingTile(tile)) return ::GetCrossingRailBits(tile);
00206   if (IsRailDepotTile(tile)) return ::TRACK_BIT_NONE;
00207   return ::GetTrackBits(tile);
00208 }
00209 
00210 /* static */ bool AIRail::BuildRailTrack(TileIndex tile, RailTrack rail_track)
00211 {
00212   EnforcePrecondition(false, ::IsValidTile(tile));
00213   EnforcePrecondition(false, rail_track != 0);
00214   EnforcePrecondition(false, (rail_track & ~::TRACK_BIT_ALL) == 0);
00215   EnforcePrecondition(false, KillFirstBit((uint)rail_track) == 0);
00216   EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType()));
00217 
00218   return AIObject::DoCommand(tile, tile, GetCurrentRailType() | (FindFirstTrack((::TrackBits)rail_track) << 4), CMD_BUILD_RAILROAD_TRACK);
00219 }
00220 
00221 /* static */ bool AIRail::RemoveRailTrack(TileIndex tile, RailTrack rail_track)
00222 {
00223   EnforcePrecondition(false, ::IsValidTile(tile));
00224   EnforcePrecondition(false, ::IsTileType(tile, MP_RAILWAY) && ::IsPlainRailTile(tile));
00225   EnforcePrecondition(false, GetRailTracks(tile) & rail_track);
00226   EnforcePrecondition(false, KillFirstBit((uint)rail_track) == 0);
00227 
00228   return AIObject::DoCommand(tile, tile, GetCurrentRailType() | (FindFirstTrack((::TrackBits)rail_track) << 4), CMD_REMOVE_RAILROAD_TRACK);
00229 }
00230 
00231 /* static */ bool AIRail::AreTilesConnected(TileIndex from, TileIndex tile, TileIndex to)
00232 {
00233   if (!IsRailTile(tile)) return false;
00234   if (from == to || AIMap::DistanceManhattan(from, tile) != 1 || AIMap::DistanceManhattan(tile, to) != 1) return false;
00235 
00236   if (to < from) ::Swap(from, to);
00237 
00238   if (tile - from == 1) {
00239     if (to - tile == 1) return (GetRailTracks(tile) & RAILTRACK_NE_SW) != 0;
00240     if (to - tile == ::MapSizeX()) return (GetRailTracks(tile) & RAILTRACK_NE_SE) != 0;
00241   } else if (tile - from == ::MapSizeX()) {
00242     if (tile - to == 1) return (GetRailTracks(tile) & RAILTRACK_NW_NE) != 0;
00243     if (to - tile == 1) return (GetRailTracks(tile) & RAILTRACK_NW_SW) != 0;
00244     if (to - tile == ::MapSizeX()) return (GetRailTracks(tile) & RAILTRACK_NW_SE) != 0;
00245   } else {
00246     return (GetRailTracks(tile) & RAILTRACK_SW_SE) != 0;
00247   }
00248 
00249   NOT_REACHED();
00250 }
00251 
00256 static uint32 SimulateDrag(TileIndex from, TileIndex tile, TileIndex *to)
00257 {
00258   int diag_offset = abs(abs((int)::TileX(*to) - (int)::TileX(tile)) - abs((int)::TileY(*to) - (int)::TileY(tile)));
00259   uint32 p2 = AIRail::GetCurrentRailType();
00260   if (::TileY(from) == ::TileY(*to)) {
00261     p2 |= (TRACK_X << 4);
00262     *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1);
00263   } else if (::TileX(from) == ::TileX(*to)) {
00264     p2 |= (TRACK_Y << 4);
00265     *to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
00266   } else if (::TileY(from) < ::TileY(tile)) {
00267     if (::TileX(*to) < ::TileX(tile)) {
00268       p2 |= (TRACK_UPPER << 4);
00269     } else {
00270       p2 |= (TRACK_LEFT << 4);
00271     }
00272     if (diag_offset) {
00273       *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1);
00274     } else {
00275       *to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
00276     }
00277   } else if (::TileY(from) > ::TileY(tile)) {
00278     if (::TileX(*to) < ::TileX(tile)) {
00279       p2 |= (TRACK_RIGHT << 4);
00280     } else {
00281       p2 |= (TRACK_LOWER << 4);
00282     }
00283     if (diag_offset) {
00284       *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1);
00285     } else {
00286       *to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
00287     }
00288   } else if (::TileX(from) < ::TileX(tile)) {
00289     if (::TileY(*to) < ::TileY(tile)) {
00290       p2 |= (TRACK_UPPER << 4);
00291     } else {
00292       p2 |= (TRACK_RIGHT << 4);
00293     }
00294     if (!diag_offset) {
00295       *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1);
00296     } else {
00297       *to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
00298     }
00299   } else if (::TileX(from) > ::TileX(tile)) {
00300     if (::TileY(*to) < ::TileY(tile)) {
00301       p2 |= (TRACK_LEFT << 4);
00302     } else {
00303       p2 |= (TRACK_LOWER << 4);
00304     }
00305     if (!diag_offset) {
00306       *to -= Clamp((int)::TileX(*to) - (int)::TileX(tile), -1, 1);
00307     } else {
00308       *to -= ::MapSizeX() * Clamp((int)::TileY(*to) - (int)::TileY(tile), -1, 1);
00309     }
00310   }
00311   return p2;
00312 }
00313 
00314 /* static */ bool AIRail::BuildRail(TileIndex from, TileIndex tile, TileIndex to)
00315 {
00316   EnforcePrecondition(false, ::IsValidTile(from));
00317   EnforcePrecondition(false, ::IsValidTile(tile));
00318   EnforcePrecondition(false, ::IsValidTile(to));
00319   EnforcePrecondition(false, ::DistanceManhattan(from, tile) == 1);
00320   EnforcePrecondition(false, ::DistanceManhattan(tile, to) >= 1);
00321   EnforcePrecondition(false, IsRailTypeAvailable(GetCurrentRailType()));
00322   int diag_offset = abs(abs((int)::TileX(to) - (int)::TileX(tile)) - abs((int)::TileY(to) - (int)::TileY(tile)));
00323   EnforcePrecondition(false, diag_offset <= 1 ||
00324       (::TileX(from) == ::TileX(tile) && ::TileX(tile) == ::TileX(to)) ||
00325       (::TileY(from) == ::TileY(tile) && ::TileY(tile) == ::TileY(to)));
00326 
00327   uint32 p2 = SimulateDrag(from, tile, &to);
00328   return AIObject::DoCommand(tile, to, p2, CMD_BUILD_RAILROAD_TRACK);
00329 }
00330 
00331 /* static */ bool AIRail::RemoveRail(TileIndex from, TileIndex tile, TileIndex to)
00332 {
00333   EnforcePrecondition(false, ::IsValidTile(from));
00334   EnforcePrecondition(false, ::IsValidTile(tile));
00335   EnforcePrecondition(false, ::IsValidTile(to));
00336   EnforcePrecondition(false, ::DistanceManhattan(from, tile) == 1);
00337   EnforcePrecondition(false, ::DistanceManhattan(tile, to) >= 1);
00338   int diag_offset = abs(abs((int)::TileX(to) - (int)::TileX(tile)) - abs((int)::TileY(to) - (int)::TileY(tile)));
00339   EnforcePrecondition(false, diag_offset <= 1 ||
00340       (::TileX(from) == ::TileX(tile) && ::TileX(tile) == ::TileX(to)) ||
00341       (::TileY(from) == ::TileY(tile) && ::TileY(tile) == ::TileY(to)));
00342 
00343   if (!IsRailTypeAvailable(GetCurrentRailType())) SetCurrentRailType(GetRailType(tile));
00344   uint32 p2 = SimulateDrag(from, tile, &to);
00345   return AIObject::DoCommand(tile, to, p2, CMD_REMOVE_RAILROAD_TRACK);
00346 }
00347 
00352 struct AIRailSignalData {
00353   Track track;        
00354   Trackdir trackdir;  
00355   uint signal_cycles; 
00356 };
00357 
00358 static const int NUM_TRACK_DIRECTIONS = 3; 
00359 
00366 static const AIRailSignalData _possible_trackdirs[5][NUM_TRACK_DIRECTIONS] = {
00367   {{TRACK_UPPER,   TRACKDIR_UPPER_E, 0}, {TRACK_Y,       TRACKDIR_Y_SE,    0}, {TRACK_LEFT,    TRACKDIR_LEFT_S,  1}},
00368   {{TRACK_RIGHT,   TRACKDIR_RIGHT_S, 1}, {TRACK_X,       TRACKDIR_X_SW,    1}, {TRACK_UPPER,   TRACKDIR_UPPER_W, 1}},
00369   {{INVALID_TRACK, INVALID_TRACKDIR, 0}, {INVALID_TRACK, INVALID_TRACKDIR, 0}, {INVALID_TRACK, INVALID_TRACKDIR, 0}},
00370   {{TRACK_LOWER,   TRACKDIR_LOWER_E, 0}, {TRACK_X,       TRACKDIR_X_NE,    0}, {TRACK_LEFT,    TRACKDIR_LEFT_N,  0}},
00371   {{TRACK_RIGHT,   TRACKDIR_RIGHT_N, 0}, {TRACK_Y,       TRACKDIR_Y_NW,    1}, {TRACK_LOWER,   TRACKDIR_LOWER_W, 1}}
00372 };
00373 
00374 /* static */ AIRail::SignalType AIRail::GetSignalType(TileIndex tile, TileIndex front)
00375 {
00376   if (AIMap::DistanceManhattan(tile, front) != 1) return SIGNALTYPE_NONE;
00377   if (!::IsTileType(tile, MP_RAILWAY) || !::HasSignals(tile)) return SIGNALTYPE_NONE;
00378 
00379   int data_index = 2 + (::TileX(front) - ::TileX(tile)) + 2 * (::TileY(front) - ::TileY(tile));
00380 
00381   for (int i = 0; i < NUM_TRACK_DIRECTIONS; i++) {
00382     const Track &track = _possible_trackdirs[data_index][i].track;
00383     if (!(::TrackToTrackBits(track) & GetRailTracks(tile))) continue;
00384     if (!HasSignalOnTrack(tile, track)) continue;
00385     if (!HasSignalOnTrackdir(tile, _possible_trackdirs[data_index][i].trackdir)) continue;
00386     SignalType st = (SignalType)::GetSignalType(tile, track);
00387     if (HasSignalOnTrackdir(tile, ::ReverseTrackdir(_possible_trackdirs[data_index][i].trackdir))) st = (SignalType)(st | SIGNALTYPE_TWOWAY);
00388     return st;
00389   }
00390 
00391   return SIGNALTYPE_NONE;
00392 }
00393 
00397 static bool IsValidSignalType(int signal_type)
00398 {
00399   if (signal_type < AIRail::SIGNALTYPE_NORMAL || signal_type > AIRail::SIGNALTYPE_COMBO_TWOWAY) return false;
00400   if (signal_type > AIRail::SIGNALTYPE_PBS_ONEWAY && signal_type < AIRail::SIGNALTYPE_NORMAL_TWOWAY) return false;
00401   return true;
00402 }
00403 
00404 /* static */ bool AIRail::BuildSignal(TileIndex tile, TileIndex front, SignalType signal)
00405 {
00406   EnforcePrecondition(false, AIMap::DistanceManhattan(tile, front) == 1)
00407   EnforcePrecondition(false, ::IsTileType(tile, MP_RAILWAY) && ::IsPlainRailTile(tile));
00408   EnforcePrecondition(false, ::IsValidSignalType(signal));
00409 
00410   Track track = INVALID_TRACK;
00411   uint signal_cycles;
00412 
00413   int data_index = 2 + (::TileX(front) - ::TileX(tile)) + 2 * (::TileY(front) - ::TileY(tile));
00414   for (int i = 0; i < NUM_TRACK_DIRECTIONS; i++) {
00415     const Track &t = _possible_trackdirs[data_index][i].track;
00416     if (!(::TrackToTrackBits(t) & GetRailTracks(tile))) continue;
00417     track = t;
00418     signal_cycles = _possible_trackdirs[data_index][i].signal_cycles;
00419     break;
00420   }
00421   EnforcePrecondition(false, track != INVALID_TRACK);
00422 
00423   uint p1 = track;
00424   if (signal < SIGNALTYPE_TWOWAY) {
00425     if (signal != SIGNALTYPE_PBS && signal != SIGNALTYPE_PBS_ONEWAY) signal_cycles++;
00426     p1 |= (signal_cycles << 15);
00427   }
00428   p1 |= ((signal >= SIGNALTYPE_TWOWAY ? signal ^ SIGNALTYPE_TWOWAY : signal) << 5);
00429 
00430   return AIObject::DoCommand(tile, p1, 0, CMD_BUILD_SIGNALS);
00431 }
00432 
00433 /* static */ bool AIRail::RemoveSignal(TileIndex tile, TileIndex front)
00434 {
00435   EnforcePrecondition(false, AIMap::DistanceManhattan(tile, front) == 1)
00436   EnforcePrecondition(false, GetSignalType(tile, front) != SIGNALTYPE_NONE);
00437 
00438   Track track = INVALID_TRACK;
00439   int data_index = 2 + (::TileX(front) - ::TileX(tile)) + 2 * (::TileY(front) - ::TileY(tile));
00440   for (int i = 0; i < NUM_TRACK_DIRECTIONS; i++) {
00441     const Track &t = _possible_trackdirs[data_index][i].track;
00442     if (!(::TrackToTrackBits(t) & GetRailTracks(tile))) continue;
00443     track = t;
00444     break;
00445   }
00446   EnforcePrecondition(false, track != INVALID_TRACK);
00447 
00448   return AIObject::DoCommand(tile, track, 0, CMD_REMOVE_SIGNALS);
00449 }

Generated on Wed Jun 3 19:05:09 2009 for OpenTTD by  doxygen 1.5.6