(svn r13404) [NoAI] -Change [API CHANGE]: AITile::IsBuildable no longer returns 'true' on road, but only on a halve piece of road (as that is auto-removed). This should make this function return less 'true', and more sane results :)
/* $Id$ */
/** @file ai_tile.cpp Implementation of AITile. */
#include "ai_tile.hpp"
#include "ai_map.hpp"
#include "ai_town.hpp"
#include "../../openttd.h"
#include "../../tile_map.h"
#include "../../map_func.h"
#include "../../variables.h"
#include "../../station_func.h"
#include "../../command_type.h"
#include "../../settings_type.h"
#include "../../player_func.h"
#include "../../road_map.h"
/* static */ bool AITile::IsBuildable(TileIndex tile)
{
if (!::IsValidTile(tile)) return false;
switch (::GetTileType(tile)) {
default: return false;
case MP_CLEAR: return true;
case MP_ROAD:
/* Depots aren't considered buildable */
if (::GetRoadTileType(tile) == ROAD_TILE_DEPOT) return false;
if (CountBits(GetAllRoadBits(tile)) != 1) return false;
if (IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN)) return true;
if (IsRoadOwner(tile, ROADTYPE_ROAD, _current_player)) return true;
return false;
}
}
/* static */ bool AITile::IsBuildableRectangle(TileIndex tile, uint width, uint height)
{
uint tx, ty;
tx = AIMap::GetTileX(tile);
ty = AIMap::GetTileY(tile);
for (uint x = tx; x < width + tx; x++) {
for (uint y = ty; y < height + ty; y++) {
if (!IsBuildable(AIMap::GetTileIndex(x, y))) return false;
}
}
return true;
}
/* static */ bool AITile::IsWater(TileIndex tile)
{
if (!::IsValidTile(tile)) return false;
return ::GetTileType(tile) == MP_WATER;
}
/* static */ bool AITile::IsSteepSlope(Slope slope)
{
if (slope == SLOPE_INVALID) return false;
return ::IsSteepSlope((::Slope)slope);
}
/* static */ bool AITile::IsHalftileSlope(Slope slope)
{
if (slope == SLOPE_INVALID) return false;
return ::IsHalftileSlope((::Slope)slope);
}
/* static */ AITile::Slope AITile::GetSlope(TileIndex tile)
{
if (!::IsValidTile(tile)) return SLOPE_INVALID;
return (Slope)::GetTileSlope(tile, NULL);
}
/* static */ AITile::Slope AITile::GetComplementSlope(Slope slope)
{
if (slope == SLOPE_INVALID) return SLOPE_INVALID;
if (IsSteepSlope(slope)) return SLOPE_INVALID;
if (IsHalftileSlope(slope)) return SLOPE_INVALID;
return (Slope)::ComplementSlope((::Slope)slope);
}
/* static */ int32 AITile::GetHeight(TileIndex tile)
{
if (!::IsValidTile(tile)) return false;
return ::TileHeight(tile);
}
/* static */ AICompany::CompanyIndex AITile::GetOwner(TileIndex tile)
{
if (!::IsValidTile(tile)) return AICompany::INVALID_COMPANY;
if (::IsTileType(tile, MP_HOUSE)) return AICompany::INVALID_COMPANY;
if (::IsTileType(tile, MP_INDUSTRY)) return AICompany::INVALID_COMPANY;
return AICompany::ResolveCompanyIndex((AICompany::CompanyIndex)(byte)::GetTileOwner(tile));
}
/* static */ int32 AITile::GetCargoAcceptance(TileIndex tile, CargoID cargo_type, uint width, uint height, uint radius)
{
if (!::IsValidTile(tile)) return false;
AcceptedCargo accepts;
::GetAcceptanceAroundTiles(accepts, tile, width, height, _settings_game.station.modified_catchment ? radius : (uint)CA_UNMODIFIED);
return accepts[cargo_type];
}
/* static */ int32 AITile::GetCargoProduction(TileIndex tile, CargoID cargo_type, uint width, uint height, uint radius)
{
if (!::IsValidTile(tile)) return false;
AcceptedCargo produced;
::GetProductionAroundTiles(produced, tile, width, height, _settings_game.station.modified_catchment ? radius : (uint)CA_UNMODIFIED);
return produced[cargo_type];
}
/* static */ int32 AITile::GetDistanceManhattanToTile(TileIndex tile_from, TileIndex tile_to)
{
return AIMap::DistanceManhattan(tile_from, tile_to);
}
/* static */ int32 AITile::GetDistanceSquareToTile(TileIndex tile_from, TileIndex tile_to)
{
return AIMap::DistanceSquare(tile_from, tile_to);
}
/* static */ bool AITile::RaiseTile(TileIndex tile, int32 slope)
{
EnforcePrecondition(false, ::IsValidTile(tile));
return AIObject::DoCommand(tile, slope, 1, CMD_TERRAFORM_LAND, false);
}
/* static */ bool AITile::LowerTile(TileIndex tile, int32 slope)
{
EnforcePrecondition(false, ::IsValidTile(tile));
return AIObject::DoCommand(tile, slope, 0, CMD_TERRAFORM_LAND, false);
}
/* static */ bool AITile::DemolishTile(TileIndex tile)
{
EnforcePrecondition(false, ::IsValidTile(tile));
return AIObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR);
}
/* static */ bool AITile::IsWithinTownInfluence(TileIndex tile, TownID town_id)
{
return AITown::IsWithinTownInfluence(town_id, tile);
}