ai_road.cpp

Go to the documentation of this file.
00001 /* $Id: ai_road.cpp 18557 2009-12-19 23:53:15Z smatz $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * 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.
00006  * 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.
00007  * 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/>.
00008  */
00009 
00012 #include "../../stdafx.h"
00013 #include "ai_map.hpp"
00014 #include "ai_station.hpp"
00015 #include "ai_cargo.hpp"
00016 #include "../../station_base.h"
00017 #include "../../command_type.h"
00018 #include "../../company_func.h"
00019 #include "../../script/squirrel_helper_type.hpp"
00020 
00021 /* static */ AIRoad::RoadVehicleType AIRoad::GetRoadVehicleTypeForCargo(CargoID cargo_type)
00022 {
00023   return AICargo::HasCargoClass(cargo_type, AICargo::CC_PASSENGERS) ? ROADVEHTYPE_BUS : ROADVEHTYPE_TRUCK;
00024 }
00025 
00026 /* static */ bool AIRoad::IsRoadTile(TileIndex tile)
00027 {
00028   if (!::IsValidTile(tile)) return false;
00029 
00030   return (::IsTileType(tile, MP_ROAD) && ::GetRoadTileType(tile) != ROAD_TILE_DEPOT) ||
00031       IsDriveThroughRoadStationTile(tile);
00032 }
00033 
00034 /* static */ bool AIRoad::IsRoadDepotTile(TileIndex tile)
00035 {
00036   if (!::IsValidTile(tile)) return false;
00037 
00038   return ::IsTileType(tile, MP_ROAD) && ::GetRoadTileType(tile) == ROAD_TILE_DEPOT &&
00039       (::RoadTypeToRoadTypes((::RoadType)GetCurrentRoadType()) & ::GetRoadTypes(tile)) != 0;
00040 }
00041 
00042 /* static */ bool AIRoad::IsRoadStationTile(TileIndex tile)
00043 {
00044   if (!::IsValidTile(tile)) return false;
00045 
00046   return ::IsRoadStopTile(tile) && (::RoadTypeToRoadTypes((::RoadType)GetCurrentRoadType()) & ::GetRoadTypes(tile)) != 0;
00047 }
00048 
00049 /* static */ bool AIRoad::IsDriveThroughRoadStationTile(TileIndex tile)
00050 {
00051   if (!::IsValidTile(tile)) return false;
00052 
00053   return ::IsDriveThroughStopTile(tile) && (::RoadTypeToRoadTypes((::RoadType)GetCurrentRoadType()) & ::GetRoadTypes(tile)) != 0;
00054 }
00055 
00056 /* static */ bool AIRoad::IsRoadTypeAvailable(RoadType road_type)
00057 {
00058   return ::HasRoadTypesAvail(_current_company, ::RoadTypeToRoadTypes((::RoadType)road_type));
00059 }
00060 
00061 /* static */ AIRoad::RoadType AIRoad::GetCurrentRoadType()
00062 {
00063   return (RoadType)AIObject::GetRoadType();
00064 }
00065 
00066 /* static */ void AIRoad::SetCurrentRoadType(RoadType road_type)
00067 {
00068   if (!IsRoadTypeAvailable(road_type)) return;
00069 
00070   AIObject::SetRoadType((::RoadType)road_type);
00071 }
00072 
00073 /* static */ bool AIRoad::HasRoadType(TileIndex tile, RoadType road_type)
00074 {
00075   if (!AIMap::IsValidTile(tile)) return false;
00076   if (!IsRoadTypeAvailable(road_type)) return false;
00077   return ::GetAnyRoadBits(tile, (::RoadType)road_type, false) != ROAD_NONE;
00078 }
00079 
00080 /* static */ bool AIRoad::AreRoadTilesConnected(TileIndex t1, TileIndex t2)
00081 {
00082   if (!::IsValidTile(t1)) return false;
00083   if (!::IsValidTile(t2)) return false;
00084   if (!IsRoadTypeAvailable(GetCurrentRoadType())) return false;
00085 
00086   /* Tiles not neighbouring */
00087   if ((abs((int)::TileX(t1) - (int)::TileX(t2)) + abs((int)::TileY(t1) - (int)::TileY(t2))) != 1) return false;
00088 
00089   RoadBits r1 = ::GetAnyRoadBits(t1, AIObject::GetRoadType());
00090   RoadBits r2 = ::GetAnyRoadBits(t2, AIObject::GetRoadType());
00091 
00092   uint dir_1 = (::TileX(t1) == ::TileX(t2)) ? (::TileY(t1) < ::TileY(t2) ? 2 : 0) : (::TileX(t1) < ::TileX(t2) ? 1 : 3);
00093   uint dir_2 = 2 ^ dir_1;
00094 
00095   DisallowedRoadDirections drd2 = IsNormalRoadTile(t2) ? GetDisallowedRoadDirections(t2) : DRD_NONE;
00096 
00097   return HasBit(r1, dir_1) && HasBit(r2, dir_2) && drd2 != DRD_BOTH && drd2 != (dir_1 > dir_2 ? DRD_SOUTHBOUND : DRD_NORTHBOUND);
00098 }
00099 
00100 /* Helper functions for AIRoad::CanBuildConnectedRoadParts(). */
00101 
00116 static bool CheckAutoExpandedRoadBits(const Array *existing, int32 start, int32 end)
00117 {
00118   return (start + end == 0) && (existing->size == 0 || existing->array[0] == start || existing->array[0] == end);
00119 }
00120 
00131 static int32 LookupWithoutBuildOnSlopes(::Slope slope, const Array *existing, int32 start, int32 end)
00132 {
00133   switch (slope) {
00134     /* Flat slopes can always be build. */
00135     case SLOPE_FLAT:
00136       return 1;
00137 
00138     /* Only 4 of the slopes can be build upon. Testing the existing bits is
00139      * necessary because these bits can be something else when the settings
00140      * in the game have been changed.
00141      */
00142     case SLOPE_NE: case SLOPE_SW:
00143       return (CheckAutoExpandedRoadBits(existing, start, end) && (start == 1 || end == 1)) ? (existing->size == 0 ? 2 : 1) : 0;
00144     case SLOPE_SE: case SLOPE_NW:
00145       return (CheckAutoExpandedRoadBits(existing, start, end) && (start != 1 && end != 1)) ? (existing->size == 0 ? 2 : 1) : 0;
00146 
00147     /* Any other tile cannot be built on. */
00148     default:
00149       return 0;
00150   }
00151 }
00152 
00158 static int32 RotateNeighbour(int32 neighbour)
00159 {
00160   switch (neighbour) {
00161     case -2: return -1;
00162     case -1: return  2;
00163     case  1: return -2;
00164     case  2: return  1;
00165     default: NOT_REACHED();
00166   }
00167 }
00168 
00174 static RoadBits NeighbourToRoadBits(int32 neighbour)
00175 {
00176   switch (neighbour) {
00177     case -2: return ROAD_NW;
00178     case -1: return ROAD_NE;
00179     case  2: return ROAD_SE;
00180     case  1: return ROAD_SW;
00181     default: NOT_REACHED();
00182   }
00183 }
00184 
00195 static int32 LookupWithBuildOnSlopes(::Slope slope, Array *existing, int32 start, int32 end)
00196 {
00197   if (::IsSteepSlope(slope)) {
00198     switch (slope) {
00199       /* On steep slopes one can only build straight roads that will be
00200        * automatically expanded to a straight road. Just check that the existing
00201        * road parts are in the same direction. */
00202       case SLOPE_STEEP_S:
00203       case SLOPE_STEEP_W:
00204       case SLOPE_STEEP_N:
00205       case SLOPE_STEEP_E:
00206         return CheckAutoExpandedRoadBits(existing, start, end) ? (existing->size == 0 ? 2 : 1) : 0;
00207 
00208       /* All other slopes are invalid slopes!. */
00209       default:
00210         return -1;
00211     }
00212   }
00213 
00214   /* The slope is not steep. Furthermore lots of slopes are generally the
00215    * same but are only rotated. So to reduce the amount of lookup work that
00216    * needs to be done the data is made uniform. This means rotating the
00217    * existing parts and updating the slope. */
00218   static const ::Slope base_slopes[] = {
00219     SLOPE_FLAT, SLOPE_W,   SLOPE_W,   SLOPE_SW,
00220     SLOPE_W,    SLOPE_EW,  SLOPE_SW,  SLOPE_WSE,
00221     SLOPE_W,    SLOPE_SW,  SLOPE_EW,  SLOPE_WSE,
00222     SLOPE_SW,   SLOPE_WSE, SLOPE_WSE};
00223   static const byte base_rotates[] = {0, 0, 1, 0, 2, 0, 1, 0, 3, 3, 2, 3, 2, 2, 1};
00224 
00225   if (slope >= (::Slope)lengthof(base_slopes)) {
00226     /* This slope is an invalid slope, so ignore it. */
00227     return -1;
00228   }
00229   byte base_rotate = base_rotates[slope];
00230   slope = base_slopes[slope];
00231 
00232   /* Some slopes don't need rotating, so return early when we know we do
00233    * not need to rotate. */
00234   switch (slope) {
00235     case SLOPE_FLAT:
00236       /* Flat slopes can always be build. */
00237       return 1;
00238 
00239     case SLOPE_EW:
00240     case SLOPE_WSE:
00241       /* A slope similar to a SLOPE_EW or SLOPE_WSE will always cause
00242        * foundations which makes them accessible from all sides. */
00243       return 1;
00244 
00245     case SLOPE_W:
00246     case SLOPE_SW:
00247       /* A slope for which we need perform some calculations. */
00248       break;
00249 
00250     default:
00251       /* An invalid slope. */
00252       return -1;
00253   }
00254 
00255   /* Now perform the actual rotation. */
00256   for (int j = 0; j < base_rotate; j++) {
00257     for (int i = 0; i < existing->size; i++) {
00258       existing->array[i] = RotateNeighbour(existing->array[i]);
00259     }
00260     start = RotateNeighbour(start);
00261     end   = RotateNeighbour(end);
00262   }
00263 
00264   /* Create roadbits out of the data for easier handling. */
00265   RoadBits start_roadbits    = NeighbourToRoadBits(start);
00266   RoadBits new_roadbits      = start_roadbits | NeighbourToRoadBits(end);
00267   RoadBits existing_roadbits = ROAD_NONE;
00268   for (int i = 0; i < existing->size; i++) {
00269     existing_roadbits |= NeighbourToRoadBits(existing->array[i]);
00270   }
00271 
00272   switch (slope) {
00273     case SLOPE_W:
00274       /* A slope similar to a SLOPE_W. */
00275       switch (new_roadbits) {
00276         case ROAD_N:
00277         case ROAD_E:
00278         case ROAD_S:
00279           /* Cannot build anything with a turn from the low side. */
00280           return 0;
00281 
00282         case ROAD_X:
00283         case ROAD_Y:
00284           /* A 'sloped' tile is going to be build. */
00285           if ((existing_roadbits | new_roadbits) != new_roadbits) {
00286             /* There is already a foundation on the tile, or at least
00287              * another slope that is not compatible with the new one. */
00288             return 0;
00289           }
00290           /* If the start is in the low part, it is automatically
00291            * building the second part too. */
00292           return ((start_roadbits & ROAD_E) && !(existing_roadbits & ROAD_W)) ? 2 : 1;
00293 
00294         default:
00295           /* Roadbits causing a foundation are going to be build.
00296            * When the existing roadbits are slopes (the lower bits
00297            * are used), this cannot be done. */
00298           if ((existing_roadbits | new_roadbits) == new_roadbits) return 1;
00299           return (existing_roadbits & ROAD_E) ? 0 : 1;
00300       }
00301 
00302     case SLOPE_SW:
00303       /* A slope similar to a SLOPE_SW. */
00304       switch (new_roadbits) {
00305         case ROAD_N:
00306         case ROAD_E:
00307           /* Cannot build anything with a turn from the low side. */
00308           return 0;
00309 
00310         case ROAD_X:
00311           /* A 'sloped' tile is going to be build. */
00312           if ((existing_roadbits | new_roadbits) != new_roadbits) {
00313             /* There is already a foundation on the tile, or at least
00314              * another slope that is not compatible with the new one. */
00315             return 0;
00316           }
00317           /* If the start is in the low part, it is automatically
00318            * building the second part too. */
00319           return ((start_roadbits & ROAD_NE) && !(existing_roadbits & ROAD_SW)) ? 2 : 1;
00320 
00321         default:
00322           /* Roadbits causing a foundation are going to be build.
00323            * When the existing roadbits are slopes (the lower bits
00324            * are used), this cannot be done. */
00325           return (existing_roadbits & ROAD_NE) ? 0 : 1;
00326       }
00327 
00328     default:
00329       NOT_REACHED();
00330   }
00331 }
00332 
00343 static bool NormaliseTileOffset(int32 *tile)
00344 {
00345     if (*tile == 1 || *tile == -1) return true;
00346     if (*tile == ::TileDiffXY(0, -1)) {
00347       *tile = -2;
00348       return true;
00349     }
00350     if (*tile == ::TileDiffXY(0, 1)) {
00351       *tile = 2;
00352       return true;
00353     }
00354     return false;
00355 }
00356 
00357 /* static */ int32 AIRoad::CanBuildConnectedRoadParts(AITile::Slope slope_, Array *existing, TileIndex start_, TileIndex end_)
00358 {
00359 	::Slope slope = (::Slope)slope_;
00360   int32 start = start_;
00361   int32 end = end_;
00362 
00363   /* The start tile and end tile cannot be the same tile either. */
00364   if (start == end) return -1;
00365 
00366   for (int i = 0; i < existing->size; i++) {
00367     if (!NormaliseTileOffset(&existing->array[i])) return -1;
00368   }
00369 
00370   if (!NormaliseTileOffset(&start)) return -1;
00371   if (!NormaliseTileOffset(&end)) return -1;
00372 
00373   /* Without build on slopes the characteristics are vastly different, so use
00374    * a different helper function (one that is much simpler). */
00375   return _settings_game.construction.build_on_slopes ? LookupWithBuildOnSlopes(slope, existing, start, end) : LookupWithoutBuildOnSlopes(slope, existing, start, end);
00376 }
00377 
00378 /* static */ int32 AIRoad::CanBuildConnectedRoadPartsHere(TileIndex tile, TileIndex start, TileIndex end)
00379 {
00380   if (!::IsValidTile(tile) || !::IsValidTile(start) || !::IsValidTile(end)) return -1;
00381   if (::DistanceManhattan(tile, start) != 1 || ::DistanceManhattan(tile, end) != 1) return -1;
00382 
00383   /*                                       ROAD_NW              ROAD_SW             ROAD_SE             ROAD_NE */
00384   static const TileIndex neighbours[] = {::TileDiffXY(0, -1), ::TileDiffXY(1, 0), ::TileDiffXY(0, 1), ::TileDiffXY(-1, 0)};
00385   Array *existing = (Array*)alloca(sizeof(Array) + lengthof(neighbours) * sizeof(int32));
00386   existing->size = 0;
00387 
00388 	::RoadBits rb = ::ROAD_NONE;
00389   if (::IsNormalRoadTile(tile)) {
00390     rb = ::GetAllRoadBits(tile);
00391   } else {
00392     for (::RoadType rt = ::ROADTYPE_BEGIN; rt < ::ROADTYPE_END; rt++) rb |= ::GetAnyRoadBits(tile, rt);
00393   }
00394   for (uint i = 0; i < lengthof(neighbours); i++) {
00395     if (HasBit(rb, i)) existing->array[existing->size++] = neighbours[i];
00396   }
00397 
00398   return AIRoad::CanBuildConnectedRoadParts(AITile::GetSlope(tile), existing, start - tile, end - tile);
00399 }
00400 
00409 static bool NeighbourHasReachableRoad(::RoadTypes rts, TileIndex start_tile, DiagDirection neighbour)
00410 {
00411   TileIndex neighbour_tile = ::TileAddByDiagDir(start_tile, neighbour);
00412   if ((rts & ::GetRoadTypes(neighbour_tile)) == 0) return false;
00413 
00414   switch (::GetTileType(neighbour_tile)) {
00415     case MP_ROAD:
00416       return (::GetRoadTileType(neighbour_tile) != ROAD_TILE_DEPOT);
00417 
00418     case MP_STATION:
00419       if (::IsDriveThroughStopTile(neighbour_tile)) {
00420         return (::DiagDirToAxis(neighbour) == ::DiagDirToAxis(::GetRoadStopDir(neighbour_tile)));
00421       }
00422       return false;
00423 
00424     default:
00425       return false;
00426   }
00427 }
00428 
00429 /* static */ int32 AIRoad::GetNeighbourRoadCount(TileIndex tile)
00430 {
00431   if (!::IsValidTile(tile)) return false;
00432   if (!IsRoadTypeAvailable(GetCurrentRoadType())) return false;
00433 
00434 	::RoadTypes rts = ::RoadTypeToRoadTypes((::RoadType)GetCurrentRoadType());
00435   int32 neighbour = 0;
00436 
00437   if (TileX(tile) > 0 && NeighbourHasReachableRoad(rts, tile, DIAGDIR_NE)) neighbour++;
00438   if (NeighbourHasReachableRoad(rts, tile, DIAGDIR_SE)) neighbour++;
00439   if (NeighbourHasReachableRoad(rts, tile, DIAGDIR_SW)) neighbour++;
00440   if (TileY(tile) > 0 && NeighbourHasReachableRoad(rts, tile, DIAGDIR_NW)) neighbour++;
00441 
00442   return neighbour;
00443 }
00444 
00445 /* static */ TileIndex AIRoad::GetRoadDepotFrontTile(TileIndex depot)
00446 {
00447   if (!IsRoadDepotTile(depot)) return INVALID_TILE;
00448 
00449   return depot + ::TileOffsByDiagDir(::GetRoadDepotDirection(depot));
00450 }
00451 
00452 /* static */ TileIndex AIRoad::GetRoadStationFrontTile(TileIndex station)
00453 {
00454   if (!IsRoadStationTile(station)) return INVALID_TILE;
00455 
00456   return station + ::TileOffsByDiagDir(::GetRoadStopDir(station));
00457 }
00458 
00459 /* static */ TileIndex AIRoad::GetDriveThroughBackTile(TileIndex station)
00460 {
00461   if (!IsDriveThroughRoadStationTile(station)) return INVALID_TILE;
00462 
00463   return station + ::TileOffsByDiagDir(::ReverseDiagDir(::GetRoadStopDir(station)));
00464 }
00465 
00466 /* static */ bool AIRoad::_BuildRoadInternal(TileIndex start, TileIndex end, bool one_way, bool full)
00467 {
00468   EnforcePrecondition(false, start != end);
00469   EnforcePrecondition(false, ::IsValidTile(start));
00470   EnforcePrecondition(false, ::IsValidTile(end));
00471   EnforcePrecondition(false, ::TileX(start) == ::TileX(end) || ::TileY(start) == ::TileY(end));
00472   EnforcePrecondition(false, !one_way || AIObject::GetRoadType() == ::ROADTYPE_ROAD);
00473   EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType()));
00474 
00475   return AIObject::DoCommand(end, start, (::TileY(start) != ::TileY(end) ? 4 : 0) | (((start < end) == !full) ? 1 : 2) | (AIObject::GetRoadType() << 3) | ((one_way ? 1 : 0) << 5), CMD_BUILD_LONG_ROAD);
00476 }
00477 
00478 /* static */ bool AIRoad::BuildRoad(TileIndex start, TileIndex end)
00479 {
00480   return _BuildRoadInternal(start, end, false, false);
00481 }
00482 
00483 /* static */ bool AIRoad::BuildOneWayRoad(TileIndex start, TileIndex end)
00484 {
00485   return _BuildRoadInternal(start, end, true, false);
00486 }
00487 
00488 /* static */ bool AIRoad::BuildRoadFull(TileIndex start, TileIndex end)
00489 {
00490   return _BuildRoadInternal(start, end, false, true);
00491 }
00492 
00493 /* static */ bool AIRoad::BuildOneWayRoadFull(TileIndex start, TileIndex end)
00494 {
00495   return _BuildRoadInternal(start, end, true, true);
00496 }
00497 
00498 /* static */ bool AIRoad::BuildRoadDepot(TileIndex tile, TileIndex front)
00499 {
00500   EnforcePrecondition(false, tile != front);
00501   EnforcePrecondition(false, ::IsValidTile(tile));
00502   EnforcePrecondition(false, ::IsValidTile(front));
00503   EnforcePrecondition(false, ::TileX(tile) == ::TileX(front) || ::TileY(tile) == ::TileY(front));
00504   EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType()));
00505 
00506   uint entrance_dir = (::TileX(tile) == ::TileX(front)) ? (::TileY(tile) < ::TileY(front) ? 1 : 3) : (::TileX(tile) < ::TileX(front) ? 2 : 0);
00507 
00508   return AIObject::DoCommand(tile, entrance_dir | (AIObject::GetRoadType() << 2), 0, CMD_BUILD_ROAD_DEPOT);
00509 }
00510 
00511 /* static */ bool AIRoad::_BuildRoadStationInternal(TileIndex tile, TileIndex front, RoadVehicleType road_veh_type, bool drive_through, StationID station_id)
00512 {
00513   EnforcePrecondition(false, tile != front);
00514   EnforcePrecondition(false, ::IsValidTile(tile));
00515   EnforcePrecondition(false, ::IsValidTile(front));
00516   EnforcePrecondition(false, ::TileX(tile) == ::TileX(front) || ::TileY(tile) == ::TileY(front));
00517   EnforcePrecondition(false, station_id == AIStation::STATION_NEW || station_id == AIStation::STATION_JOIN_ADJACENT || AIStation::IsValidStation(station_id));
00518   EnforcePrecondition(false, road_veh_type == ROADVEHTYPE_BUS || road_veh_type == ROADVEHTYPE_TRUCK);
00519   EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType()));
00520 
00521   uint entrance_dir;
00522   if (drive_through) {
00523     entrance_dir = ::TileY(tile) != ::TileY(front);
00524   } else {
00525     entrance_dir = (::TileX(tile) == ::TileX(front)) ? (::TileY(tile) < ::TileY(front) ? 1 : 3) : (::TileX(tile) < ::TileX(front) ? 2 : 0);
00526   }
00527 
00528   uint p2 = station_id == AIStation::STATION_JOIN_ADJACENT ? 0 : 32;
00529   p2 |= drive_through ? 2 : 0;
00530   p2 |= road_veh_type == ROADVEHTYPE_TRUCK ? 1 : 0;
00531   p2 |= ::RoadTypeToRoadTypes(AIObject::GetRoadType()) << 2;
00532   p2 |= (AIStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16;
00533   return AIObject::DoCommand(tile, entrance_dir, p2, CMD_BUILD_ROAD_STOP);
00534 }
00535 
00536 /* static */ bool AIRoad::BuildRoadStation(TileIndex tile, TileIndex front, RoadVehicleType road_veh_type, StationID station_id)
00537 {
00538   return _BuildRoadStationInternal(tile, front, road_veh_type, false, station_id);
00539 }
00540 
00541 /* static */ bool AIRoad::BuildDriveThroughRoadStation(TileIndex tile, TileIndex front, RoadVehicleType road_veh_type, StationID station_id)
00542 {
00543   return _BuildRoadStationInternal(tile, front, road_veh_type, true, station_id);
00544 }
00545 
00546 /* static */ bool AIRoad::RemoveRoad(TileIndex start, TileIndex end)
00547 {
00548   EnforcePrecondition(false, ::IsValidTile(start));
00549   EnforcePrecondition(false, ::IsValidTile(end));
00550   EnforcePrecondition(false, ::TileX(start) == ::TileX(end) || ::TileY(start) == ::TileY(end));
00551   EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType()));
00552 
00553   return AIObject::DoCommand(end, start, (::TileY(start) != ::TileY(end) ? 4 : 0) | (start < end ? 1 : 2) | (AIObject::GetRoadType() << 3), CMD_REMOVE_LONG_ROAD);
00554 }
00555 
00556 /* static */ bool AIRoad::RemoveRoadFull(TileIndex start, TileIndex end)
00557 {
00558   EnforcePrecondition(false, ::IsValidTile(start));
00559   EnforcePrecondition(false, ::IsValidTile(end));
00560   EnforcePrecondition(false, ::TileX(start) == ::TileX(end) || ::TileY(start) == ::TileY(end));
00561   EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType()));
00562 
00563   return AIObject::DoCommand(end, start, (::TileY(start) != ::TileY(end) ? 4 : 0) | (start < end ? 2 : 1) | (AIObject::GetRoadType() << 3), CMD_REMOVE_LONG_ROAD);
00564 }
00565 
00566 /* static */ bool AIRoad::RemoveRoadDepot(TileIndex tile)
00567 {
00568   EnforcePrecondition(false, ::IsValidTile(tile));
00569   EnforcePrecondition(false, IsTileType(tile, MP_ROAD))
00570   EnforcePrecondition(false, GetRoadTileType(tile) == ROAD_TILE_DEPOT);
00571 
00572   return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
00573 }
00574 
00575 /* static */ bool AIRoad::RemoveRoadStation(TileIndex tile)
00576 {
00577   EnforcePrecondition(false, ::IsValidTile(tile));
00578   EnforcePrecondition(false, IsTileType(tile, MP_STATION));
00579   EnforcePrecondition(false, IsRoadStop(tile));
00580 
00581   return AIObject::DoCommand(tile, 0, GetRoadStopType(tile), CMD_REMOVE_ROAD_STOP);
00582 }

Generated on Tue Jan 5 21:02:52 2010 for OpenTTD by  doxygen 1.5.6