ai_road.cpp

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

Generated on Sun Jan 9 16:01:51 2011 for OpenTTD by  doxygen 1.6.1