rubidium@9453: /* $Id$ */ rubidium@9453: rubidium@9513: /** @file ai_road.cpp handles the functions of the AIRoad class */ rubidium@9453: rubidium@9453: #include "ai_road.hpp" rubidium@9453: #include "../../command.h" rubidium@9453: #include "../../road_map.h" rubidium@9453: #include "../../station_map.h" rubidium@9453: rubidium@9453: bool AIRoad::IsRoadTile(TileIndex tile) rubidium@9453: { rubidium@9453: /* Outside of the map */ rubidium@9620: if (tile >= ::MapSize()) return false; rubidium@9453: rubidium@9694: return (::IsTileType(tile, MP_ROAD) && ::GetRoadTileType(tile) != ROAD_TILE_DEPOT) || rubidium@9556: this->IsDriveThroughRoadStationTile(tile); rubidium@9551: } rubidium@9551: rubidium@9551: bool AIRoad::IsRoadDepotTile(TileIndex tile) rubidium@9551: { rubidium@9551: /* Outside of the map */ rubidium@9620: if (tile >= ::MapSize()) return false; rubidium@9551: rubidium@9694: return ::IsTileType(tile, MP_ROAD) && ::GetRoadTileType(tile) == ROAD_TILE_DEPOT; rubidium@9551: } rubidium@9551: rubidium@9551: bool AIRoad::IsRoadStationTile(TileIndex tile) rubidium@9551: { rubidium@9551: /* Outside of the map */ rubidium@9620: if (tile >= ::MapSize()) return false; rubidium@9551: rubidium@9551: return ::IsRoadStopTile(tile); rubidium@9551: } rubidium@9551: rubidium@9551: bool AIRoad::IsDriveThroughRoadStationTile(TileIndex tile) rubidium@9551: { rubidium@9551: /* Outside of the map */ rubidium@9620: if (tile >= ::MapSize()) return false; rubidium@9551: rubidium@9551: return ::IsDriveThroughStopTile(tile); rubidium@9551: } rubidium@9551: rubidium@9551: bool AIRoad::AreRoadTilesConnected(TileIndex t1, TileIndex t2) rubidium@9551: { rubidium@9551: /* Outside of the map */ rubidium@9620: if (t1 >= ::MapSize() || t2 >= ::MapSize()) return false; rubidium@9551: rubidium@9551: /* Tiles not neighbouring */ rubidium@9551: if ((abs((int)::TileX(t1) - (int)::TileX(t2)) + abs((int)::TileY(t1) - (int)::TileY(t2))) != 1) return false; rubidium@9551: glx@9624: RoadBits r1 = ::GetAnyRoadBits(t1, ROADTYPE_ROAD); glx@9624: RoadBits r2 = ::GetAnyRoadBits(t2, ROADTYPE_ROAD); rubidium@9551: rubidium@9551: DiagDirection dir_1 = (DiagDirection)((::TileX(t1) == ::TileX(t2)) ? (::TileY(t1) < ::TileY(t2) ? 2 : 0) : (::TileX(t1) < ::TileX(t2) ? 1 : 3)); rubidium@9551: DiagDirection dir_2 = ::ReverseDiagDir(dir_1); rubidium@9551: rubidium@9551: return HASBIT(r1, dir_1) && HASBIT(r2, dir_2); rubidium@9551: } rubidium@9551: truelight@9617: int32 AIRoad::GetNeighbourRoadCount(TileIndex tile) truelight@9617: { truelight@9617: /* Outside of the map */ rubidium@9620: if (tile >= ::MapSize()) return false; truelight@9617: truelight@9617: int32 neighbour = 0; truelight@9617: rubidium@9694: if (::IsTileType(tile + ::TileDiffXY(-1, 0), MP_ROAD) && ::GetRoadTileType(tile + ::TileDiffXY(-1, 0)) != ROAD_TILE_DEPOT) neighbour++; rubidium@9694: if (::IsTileType(tile + ::TileDiffXY( 1, 0), MP_ROAD) && ::GetRoadTileType(tile + ::TileDiffXY( 1, 0)) != ROAD_TILE_DEPOT) neighbour++; rubidium@9694: if (::IsTileType(tile + ::TileDiffXY( 0,-1), MP_ROAD) && ::GetRoadTileType(tile + ::TileDiffXY( 0,-1)) != ROAD_TILE_DEPOT) neighbour++; rubidium@9694: if (::IsTileType(tile + ::TileDiffXY( 0, 1), MP_ROAD) && ::GetRoadTileType(tile + ::TileDiffXY( 0, 1)) != ROAD_TILE_DEPOT) neighbour++; truelight@9617: truelight@9617: return neighbour; truelight@9617: } truelight@9617: rubidium@9551: TileIndex AIRoad::GetRoadDepotFrontTile(TileIndex depot) rubidium@9551: { rubidium@9551: if (!this->IsRoadDepotTile(depot)) return INVALID_TILE; rubidium@9551: rubidium@9551: return depot + ::TileOffsByDiagDir(::GetRoadDepotDirection(depot)); rubidium@9551: } rubidium@9551: rubidium@9551: TileIndex AIRoad::GetRoadStationFrontTile(TileIndex station) rubidium@9551: { rubidium@9551: if (!this->IsRoadStationTile(station)) return INVALID_TILE; rubidium@9551: rubidium@9551: return station + ::TileOffsByDiagDir(::GetRoadStopDir(station)); rubidium@9551: } rubidium@9551: rubidium@9551: TileIndex AIRoad::GetDriveThroughBackTile(TileIndex station) rubidium@9551: { rubidium@9551: if (!this->IsDriveThroughRoadStationTile(station)) return INVALID_TILE; rubidium@9551: rubidium@9551: return station + ::TileOffsByDiagDir(::ReverseDiagDir(::GetRoadStopDir(station))); rubidium@9453: } rubidium@9453: rubidium@9453: bool AIRoad::BuildRoad(TileIndex start, TileIndex end) rubidium@9453: { rubidium@9453: /* Outside of the map */ rubidium@9620: if (start >= ::MapSize() || end >= ::MapSize() || start == end) return false; rubidium@9453: /* Not on one line */ rubidium@9453: if (TileX(start) != TileX(end) && rubidium@9453: TileY(start) != TileY(end)) return false; rubidium@9453: glx@9624: return this->DoCommand(end, start, (TileY(start) != TileY(end) ? 4 : 0) | (start < end ? 1 : 2) | (ROADTYPE_ROAD << 3), CMD_BUILD_LONG_ROAD); rubidium@9453: } rubidium@9453: glx@9659: bool AIRoad::BuildRoadFull(TileIndex start, TileIndex end) glx@9659: { glx@9659: /* Outside of the map */ glx@9659: if (start >= ::MapSize() || end >= ::MapSize() || start == end) return false; glx@9659: /* Not on one line */ glx@9659: if (TileX(start) != TileX(end) && glx@9659: TileY(start) != TileY(end)) return false; glx@9659: glx@9659: return this->DoCommand(end, start, (TileY(start) != TileY(end) ? 4 : 0) | (start < end ? 2 : 1), CMD_BUILD_LONG_ROAD); glx@9659: } glx@9659: rubidium@9453: bool AIRoad::BuildRoadDepot(TileIndex tile, TileIndex front) rubidium@9453: { rubidium@9453: /* Outside of the map */ rubidium@9620: if (tile >= ::MapSize() || tile == front) return false; rubidium@9453: glx@9504: uint entrance_dir = (TileX(tile) == TileX(front)) ? (TileY(tile) < TileY(front) ? 1 : 3) : (TileX(tile) < TileX(front) ? 2 : 0); rubidium@9453: glx@9624: return this->DoCommand(tile, entrance_dir, ROADTYPE_ROAD << 2, CMD_BUILD_ROAD_DEPOT); rubidium@9453: } rubidium@9453: rubidium@9503: bool AIRoad::BuildRoadStation(TileIndex tile, TileIndex front, bool truck, bool drive_through) rubidium@9453: { rubidium@9453: /* Outside of the map */ rubidium@9620: if (tile >= ::MapSize() || tile == front) return false; rubidium@9453: rubidium@9453: uint entrance_dir; rubidium@9453: if (drive_through) { truelight@9482: entrance_dir = TileY(tile) != TileY(front); rubidium@9453: } else { glx@9504: entrance_dir = (TileX(tile) == TileX(front)) ? (TileY(tile) < TileY(front) ? 1 : 3) : (TileX(tile) < TileX(front) ? 2 : 0); rubidium@9453: } rubidium@9453: glx@9624: return this->DoCommand(tile, entrance_dir, (drive_through ? 2 : 0) | (truck ? 1 : 0) | (ROADTYPES_ROAD << 2), CMD_BUILD_ROAD_STOP); rubidium@9453: } rubidium@9453: rubidium@9453: bool AIRoad::RemoveRoad(TileIndex start, TileIndex end) rubidium@9453: { rubidium@9453: /* Outside of the map */ rubidium@9620: if (start >= ::MapSize() || end >= ::MapSize()) return false; rubidium@9453: /* Not on one line */ rubidium@9453: if (TileX(start) != TileX(end) && rubidium@9453: TileY(start) != TileY(end)) return false; rubidium@9453: glx@9624: return this->DoCommand(end, start, (TileY(start) != TileY(end) ? 4 : 0) | (start < end ? 1 : 2) | (ROADTYPE_ROAD << 3), CMD_REMOVE_LONG_ROAD); rubidium@9453: } rubidium@9453: glx@9659: bool AIRoad::RemoveRoadFull(TileIndex start, TileIndex end) glx@9659: { glx@9659: /* Outside of the map */ glx@9659: if (start >= ::MapSize() || end >= ::MapSize()) return false; glx@9659: /* Not on one line */ glx@9659: if (TileX(start) != TileX(end) && glx@9659: TileY(start) != TileY(end)) return false; glx@9659: glx@9659: return this->DoCommand(end, start, (TileY(start) != TileY(end) ? 4 : 0) | (start < end ? 2 : 1), CMD_REMOVE_LONG_ROAD); glx@9659: } glx@9659: rubidium@9453: bool AIRoad::RemoveRoadDepot(TileIndex tile) rubidium@9453: { rubidium@9453: /* Outside of the map */ rubidium@9620: if (tile >= ::MapSize()) return false; rubidium@9453: rubidium@9453: /* Not a road depot tile */ rubidium@9694: if (!IsTileType(tile, MP_ROAD) || GetRoadTileType(tile) != ROAD_TILE_DEPOT) return false; rubidium@9453: truelight@9486: return this->DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR); rubidium@9453: } rubidium@9453: rubidium@9453: bool AIRoad::RemoveRoadStation(TileIndex tile) rubidium@9453: { rubidium@9453: /* Outside of the map */ rubidium@9620: if (tile >= ::MapSize()) return false; rubidium@9453: rubidium@9453: /* Not a road station tile */ rubidium@9453: if (!IsTileType(tile, MP_STATION) || !IsRoadStop(tile)) return false; rubidium@9453: truelight@9486: return this->DoCommand(tile, 0, GetRoadStopType(tile), CMD_REMOVE_ROAD_STOP); rubidium@9453: }