464 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			464 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* $Id$ */
 | 
						|
 | 
						|
/*
 | 
						|
 * This file is part of OpenTTD.
 | 
						|
 * 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.
 | 
						|
 * 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.
 | 
						|
 * 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/>.
 | 
						|
 */
 | 
						|
 | 
						|
/** @file ai_rail.hpp Everything to query and build rails. */
 | 
						|
 | 
						|
#ifndef AI_RAIL_HPP
 | 
						|
#define AI_RAIL_HPP
 | 
						|
 | 
						|
#include "ai_object.hpp"
 | 
						|
#include "ai_error.hpp"
 | 
						|
#include "ai_tile.hpp"
 | 
						|
 | 
						|
/**
 | 
						|
 * Class that handles all rail related functions.
 | 
						|
 */
 | 
						|
class AIRail : public AIObject {
 | 
						|
public:
 | 
						|
	/** Get the name of this class to identify it towards squirrel. */
 | 
						|
	static const char *GetClassName() { return "AIRail"; }
 | 
						|
 | 
						|
	/**
 | 
						|
	 * All rail related error messages.
 | 
						|
	 */
 | 
						|
	enum ErrorMessages {
 | 
						|
		/** Base for rail building / maintaining errors */
 | 
						|
		ERR_RAIL_BASE = AIError::ERR_CAT_RAIL << AIError::ERR_CAT_BIT_SIZE,
 | 
						|
 | 
						|
		/** One-way roads cannot have crossings */
 | 
						|
		ERR_CROSSING_ON_ONEWAY_ROAD,       // [STR_ERROR_CROSSING_ON_ONEWAY_ROAD]
 | 
						|
 | 
						|
		/** Track not suitable for signals */
 | 
						|
		ERR_UNSUITABLE_TRACK,              // [STR_ERROR_NO_SUITABLE_RAILROAD_TRACK]
 | 
						|
 | 
						|
		/** Non-uniform stations is diabled */
 | 
						|
		ERR_NONUNIFORM_STATIONS_DISABLED,  // [STR_ERROR_NONUNIFORM_STATIONS_DISALLOWED]
 | 
						|
 | 
						|
		/** This railtype cannot have crossings */
 | 
						|
		ERR_RAILTYPE_DISALLOWS_CROSSING,   // [STR_ERROR_CROSSING_DISALLOWED]
 | 
						|
	};
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Types of rail known to the game.
 | 
						|
	 */
 | 
						|
	enum RailType {
 | 
						|
		/* Note: the values _are_ important as they represent an in-game value */
 | 
						|
		RAILTYPE_INVALID  = 0xFF, ///< Invalid RailType.
 | 
						|
	};
 | 
						|
 | 
						|
	/**
 | 
						|
	 * A bitmap with all possible rail tracks on a tile.
 | 
						|
	 */
 | 
						|
	enum RailTrack {
 | 
						|
		/* Note: the values _are_ important as they represent an in-game value */
 | 
						|
		RAILTRACK_NE_SW   = 1 << 0, ///< Track along the x-axis (north-east to south-west).
 | 
						|
		RAILTRACK_NW_SE   = 1 << 1, ///< Track along the y-axis (north-west to south-east).
 | 
						|
		RAILTRACK_NW_NE   = 1 << 2, ///< Track in the upper corner of the tile (north).
 | 
						|
		RAILTRACK_SW_SE   = 1 << 3, ///< Track in the lower corner of the tile (south).
 | 
						|
		RAILTRACK_NW_SW   = 1 << 4, ///< Track in the left corner of the tile (west).
 | 
						|
		RAILTRACK_NE_SE   = 1 << 5, ///< Track in the right corner of the tile (east).
 | 
						|
		RAILTRACK_INVALID = 0xFF,   ///< Flag for an invalid track.
 | 
						|
	};
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Types of signal known to the game.
 | 
						|
	 */
 | 
						|
	enum SignalType {
 | 
						|
		/* Note: the values _are_ important as they represent an in-game value */
 | 
						|
		SIGNALTYPE_NORMAL        = 0, ///< Normal signal.
 | 
						|
		SIGNALTYPE_ENTRY         = 1, ///< Entry presignal.
 | 
						|
		SIGNALTYPE_EXIT          = 2, ///< Exit signal.
 | 
						|
		SIGNALTYPE_COMBO         = 3, ///< Combo signal.
 | 
						|
		SIGNALTYPE_PBS           = 4, ///< Normal PBS signal.
 | 
						|
		SIGNALTYPE_PBS_ONEWAY    = 5, ///< No-entry PBS signal.
 | 
						|
		SIGNALTYPE_TWOWAY        = 8, ///< Bit mask for twoway signal.
 | 
						|
		SIGNALTYPE_NORMAL_TWOWAY = SIGNALTYPE_NORMAL | SIGNALTYPE_TWOWAY, ///< Normal twoway signal.
 | 
						|
		SIGNALTYPE_ENTRY_TWOWAY  = SIGNALTYPE_ENTRY | SIGNALTYPE_TWOWAY,  ///< Entry twoway signal.
 | 
						|
		SIGNALTYPE_EXIT_TWOWAY   = SIGNALTYPE_EXIT | SIGNALTYPE_TWOWAY,   ///< Exit twoway signal.
 | 
						|
		SIGNALTYPE_COMBO_TWOWAY  = SIGNALTYPE_COMBO | SIGNALTYPE_TWOWAY,  ///< Combo twoway signal.
 | 
						|
		SIGNALTYPE_NONE          = 0xFF, ///< No signal.
 | 
						|
	};
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Types of rail-related objects in the game.
 | 
						|
	 */
 | 
						|
	enum BuildType {
 | 
						|
		BT_TRACK,    ///< Build a track
 | 
						|
		BT_SIGNAL,   ///< Build a signal
 | 
						|
		BT_DEPOT,    ///< Build a depot
 | 
						|
		BT_STATION,  ///< Build a station
 | 
						|
		BT_WAYPOINT, ///< Build a rail waypoint
 | 
						|
	};
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Checks whether the given tile is actually a tile with rail that can be
 | 
						|
	 *  used to traverse a tile. This excludes rail depots but includes
 | 
						|
	 *  stations and waypoints.
 | 
						|
	 * @param tile The tile to check.
 | 
						|
	 * @pre AIMap::IsValidTile(tile).
 | 
						|
	 * @return True if and only if the tile has rail.
 | 
						|
	 */
 | 
						|
	static bool IsRailTile(TileIndex tile);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Checks whether there is a road / rail crossing on a tile.
 | 
						|
	 * @param tile The tile to check.
 | 
						|
	 * @return True if and only if there is a road / rail crossing.
 | 
						|
	 */
 | 
						|
	static bool IsLevelCrossingTile(TileIndex tile);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Checks whether the given tile is actually a tile with a rail depot.
 | 
						|
	 * @param tile The tile to check.
 | 
						|
	 * @pre AIMap::IsValidTile(tile).
 | 
						|
	 * @return True if and only if the tile has a rail depot.
 | 
						|
	 */
 | 
						|
	static bool IsRailDepotTile(TileIndex tile);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Checks whether the given tile is actually a tile with a rail station.
 | 
						|
	 * @param tile The tile to check.
 | 
						|
	 * @pre AIMap::IsValidTile(tile).
 | 
						|
	 * @return True if and only if the tile has a rail station.
 | 
						|
	 */
 | 
						|
	static bool IsRailStationTile(TileIndex tile);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Checks whether the given tile is actually a tile with a rail waypoint.
 | 
						|
	 * @param tile The tile to check.
 | 
						|
	 * @pre AIMap::IsValidTile(tile).
 | 
						|
	 * @return True if and only if the tile has a rail waypoint.
 | 
						|
	 */
 | 
						|
	static bool IsRailWaypointTile(TileIndex tile);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Check if a given RailType is available.
 | 
						|
	 * @param rail_type The RailType to check for.
 | 
						|
	 * @return True if this RailType can be used.
 | 
						|
	 */
 | 
						|
	static bool IsRailTypeAvailable(RailType rail_type);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get the current RailType set for all AIRail functions.
 | 
						|
	 * @return The RailType currently set.
 | 
						|
	 */
 | 
						|
	static RailType GetCurrentRailType();
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Set the RailType for all further AIRail functions.
 | 
						|
	 * @param rail_type The RailType to set.
 | 
						|
	 */
 | 
						|
	static void SetCurrentRailType(RailType rail_type);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Check if a train build for a rail type can run on another rail type.
 | 
						|
	 * @param engine_rail_type The rail type the train is build for.
 | 
						|
	 * @param track_rail_type The type you want to check.
 | 
						|
	 * @pre AIRail::IsRailTypeAvailable(engine_rail_type).
 | 
						|
	 * @pre AIRail::IsRailTypeAvailable(track_rail_type).
 | 
						|
	 * @return Whether a train build for 'engine_rail_type' can run on 'track_rail_type'.
 | 
						|
	 * @note Even if a train can run on a RailType that doesn't mean that it'll be
 | 
						|
	 *   able to power the train. Use TrainHasPowerOnRail for that.
 | 
						|
	 */
 | 
						|
	static bool TrainCanRunOnRail(AIRail::RailType engine_rail_type, AIRail::RailType track_rail_type);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Check if a train build for a rail type has power on another rail type.
 | 
						|
	 * @param engine_rail_type The rail type the train is build for.
 | 
						|
	 * @param track_rail_type The type you want to check.
 | 
						|
	 * @pre AIRail::IsRailTypeAvailable(engine_rail_type).
 | 
						|
	 * @pre AIRail::IsRailTypeAvailable(track_rail_type).
 | 
						|
	 * @return Whether a train build for 'engine_rail_type' has power on 'track_rail_type'.
 | 
						|
	 */
 | 
						|
	static bool TrainHasPowerOnRail(AIRail::RailType engine_rail_type, AIRail::RailType track_rail_type);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get the RailType that is used on a tile.
 | 
						|
	 * @param tile The tile to check.
 | 
						|
	 * @pre AITile::HasTransportType(tile, AITile.TRANSPORT_RAIL).
 | 
						|
	 * @return The RailType that is used on a tile.
 | 
						|
	 */
 | 
						|
	static RailType GetRailType(TileIndex tile);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Convert the tracks on all tiles within a rectangle to another RailType.
 | 
						|
	 * @param start_tile One corner of the rectangle.
 | 
						|
	 * @param end_tile The opposite corner of the rectangle.
 | 
						|
	 * @param convert_to The RailType you want to convert the rails to.
 | 
						|
	 * @pre AIMap::IsValidTile(start_tile).
 | 
						|
	 * @pre AIMap::IsValidTile(end_tile).
 | 
						|
	 * @pre IsRailTypeAvailable(convert_to).
 | 
						|
	 * @exception AIRail::ERR_UNSUITABLE_TRACK
 | 
						|
	 * @return Whether at least some rail has been converted successfully.
 | 
						|
	 */
 | 
						|
	static bool ConvertRailType(TileIndex start_tile, TileIndex end_tile, AIRail::RailType convert_to);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Gets the tile in front of a rail depot.
 | 
						|
	 * @param depot The rail depot tile.
 | 
						|
	 * @pre IsRailDepotTile(depot).
 | 
						|
	 * @return The tile in front of the depot.
 | 
						|
	 */
 | 
						|
	static TileIndex GetRailDepotFrontTile(TileIndex depot);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Gets the direction of a rail station tile.
 | 
						|
	 * @param tile The rail station tile.
 | 
						|
	 * @pre IsRailStationTile(tile).
 | 
						|
	 * @return The direction of the station (either RAILTRACK_NE_SW or RAILTRACK_NW_SE).
 | 
						|
	 */
 | 
						|
	static RailTrack GetRailStationDirection(TileIndex tile);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Builds a rail depot.
 | 
						|
	 * @param tile Place to build the depot.
 | 
						|
	 * @param front The tile exactly in front of the depot.
 | 
						|
	 * @pre AIMap::IsValidTile(tile).
 | 
						|
	 * @pre AIMap::IsValidTile(front).
 | 
						|
	 * @pre 'tile' is not equal to 'front', but in a straight line of it.
 | 
						|
	 * @pre IsRailTypeAvailable(GetCurrentRailType()).
 | 
						|
	 * @exception AIError::ERR_FLAT_LAND_REQUIRED
 | 
						|
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 | 
						|
	 * @return Whether the rail depot has been/can be build or not.
 | 
						|
	 */
 | 
						|
	static bool BuildRailDepot(TileIndex tile, TileIndex front);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Build a rail station.
 | 
						|
	 * @param tile Place to build the station.
 | 
						|
	 * @param direction The direction to build the station.
 | 
						|
	 * @param num_platforms The number of platforms to build.
 | 
						|
	 * @param platform_length The length of each platform.
 | 
						|
	 * @param station_id The station to join, AIStation::STATION_NEW or AIStation::STATION_JOIN_ADJACENT.
 | 
						|
	 * @pre IsRailTypeAvailable(GetCurrentRailType()).
 | 
						|
	 * @pre AIMap::IsValidTile(tile).
 | 
						|
	 * @pre direction == RAILTRACK_NW_SE || direction == RAILTRACK_NE_SW.
 | 
						|
	 * @pre num_platforms > 0 && num_platforms <= 255.
 | 
						|
	 * @pre platform_length > 0 && platform_length <= 255.
 | 
						|
	 * @pre station_id == AIStation::STATION_NEW || station_id == AIStation::STATION_JOIN_ADJACENT || AIStation::IsValidStation(station_id).
 | 
						|
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 | 
						|
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 | 
						|
	 * @exception AIError::ERR_FLAT_LAND_REQUIRED
 | 
						|
	 * @exception AIStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION
 | 
						|
	 * @exception AIStation::ERR_STATION_TOO_MANY_STATIONS
 | 
						|
	 * @exception AIStation::ERR_STATION_TOO_MANY_STATIONS_IN_TOWN
 | 
						|
	 * @return Whether the station has been/can be build or not.
 | 
						|
	 */
 | 
						|
	static bool BuildRailStation(TileIndex tile, RailTrack direction, uint num_platforms, uint platform_length, StationID station_id);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Build a NewGRF rail station. This calls callback 18 to let a NewGRF
 | 
						|
	 *  provide the station class / id to build, so we don't end up with
 | 
						|
	 *  only the default stations on the map.
 | 
						|
	 * @param tile Place to build the station.
 | 
						|
	 * @param direction The direction to build the station.
 | 
						|
	 * @param num_platforms The number of platforms to build.
 | 
						|
	 * @param platform_length The length of each platform.
 | 
						|
	 * @param station_id The station to join, AIStation::STATION_NEW or AIStation::STATION_JOIN_ADJACENT.
 | 
						|
	 * @param cargo_id The CargoID of the cargo that will be transported from / to this station.
 | 
						|
	 * @param source_industry The IndustryType of the industry you'll transport goods from, AIIndustryType::INDUSTRYTYPE_UNKNOWN or AIIndustryType::INDUSTRYTYPE_TOWN.
 | 
						|
	 * @param goal_industry The IndustryType of the industry you'll transport goods to, AIIndustryType::INDUSTRYTYPE_UNKNOWN or AIIndustryType::INDUSTRYTYPE_TOWN.
 | 
						|
	 * @param distance The manhattan distance you'll transport the cargo over.
 | 
						|
	 * @param source_station True if this is the source station, false otherwise.
 | 
						|
	 * @pre IsRailTypeAvailable(GetCurrentRailType()).
 | 
						|
	 * @pre AIMap::IsValidTile(tile).
 | 
						|
	 * @pre direction == RAILTRACK_NW_SE || direction == RAILTRACK_NE_SW.
 | 
						|
	 * @pre num_platforms > 0 && num_platforms <= 255.
 | 
						|
	 * @pre platform_length > 0 && platform_length <= 255.
 | 
						|
	 * @pre station_id == AIStation::STATION_NEW || station_id == AIStation::STATION_JOIN_ADJACENT || AIStation::IsValidStation(station_id).
 | 
						|
	 * @pre source_industry == AIIndustryType::INDUSTRYTYPE_UNKNOWN || source_industry == AIIndustryType::INDUSTRYTYPE_TOWN || AIIndustryType::IsValidIndustryType(source_industry).
 | 
						|
	 * @pre goal_industry == AIIndustryType::INDUSTRYTYPE_UNKNOWN || goal_industry == AIIndustryType::INDUSTRYTYPE_TOWN || AIIndustryType::IsValidIndustryType(goal_industry).
 | 
						|
	 * @exception AIError::ERR_OWNED_BY_ANOTHER_COMPANY
 | 
						|
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 | 
						|
	 * @exception AIError::ERR_FLAT_LAND_REQUIRED
 | 
						|
	 * @exception AIStation::ERR_STATION_TOO_CLOSE_TO_ANOTHER_STATION
 | 
						|
	 * @exception AIStation::ERR_STATION_TOO_MANY_STATIONS
 | 
						|
	 * @exception AIStation::ERR_STATION_TOO_MANY_STATIONS_IN_TOWN
 | 
						|
	 * @return Whether the station has been/can be build or not.
 | 
						|
	 */
 | 
						|
	static bool 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);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Build a rail waypoint.
 | 
						|
	 * @param tile Place to build the waypoint.
 | 
						|
	 * @pre AIMap::IsValidTile(tile).
 | 
						|
	 * @pre IsRailTile(tile).
 | 
						|
	 * @pre GetRailTracks(tile) == RAILTRACK_NE_SW || GetRailTracks(tile) == RAILTRACK_NW_SE.
 | 
						|
	 * @pre IsRailTypeAvailable(GetCurrentRailType()).
 | 
						|
	 * @exception AIError::ERR_FLAT_LAND_REQUIRED
 | 
						|
	 * @return Whether the rail waypoint has been/can be build or not.
 | 
						|
	 */
 | 
						|
	static bool BuildRailWaypoint(TileIndex tile);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Remove all rail waypoint pieces within a rectangle on the map.
 | 
						|
	 * @param tile One corner of the rectangle to clear.
 | 
						|
	 * @param tile2 The oppposite corner.
 | 
						|
	 * @param keep_rail Whether to keep the rail after removal.
 | 
						|
	 * @pre IsValidTile(tile).
 | 
						|
	 * @pre IsValidTile(tile2).
 | 
						|
	 * @return Whether at least one tile has been/can be cleared or not.
 | 
						|
	 */
 | 
						|
	static bool RemoveRailWaypointTileRectangle(TileIndex tile, TileIndex tile2, bool keep_rail);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Remove all rail station platform pieces within a rectangle on the map.
 | 
						|
	 * @param tile One corner of the rectangle to clear.
 | 
						|
	 * @param tile2 The oppposite corner.
 | 
						|
	 * @param keep_rail Whether to keep the rail after removal.
 | 
						|
	 * @pre IsValidTile(tile).
 | 
						|
	 * @pre IsValidTile(tile2).
 | 
						|
	 * @return Whether at least one tile has been/can be cleared or not.
 | 
						|
	 */
 | 
						|
	static bool RemoveRailStationTileRectangle(TileIndex tile, TileIndex tile2, bool keep_rail);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get all RailTracks on the given tile.
 | 
						|
	 * @note A depot has no railtracks.
 | 
						|
	 * @param tile The tile to check.
 | 
						|
	 * @pre IsRailTile(tile).
 | 
						|
	 * @return A bitmask of RailTrack with all RailTracks on the tile.
 | 
						|
	 */
 | 
						|
	static uint GetRailTracks(TileIndex tile);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Build rail on the given tile.
 | 
						|
	 * @param tile The tile to build on.
 | 
						|
	 * @param rail_track The RailTrack to build.
 | 
						|
	 * @pre AIMap::IsValidTile(tile).
 | 
						|
	 * @pre IsRailTypeAvailable(GetCurrentRailType()).
 | 
						|
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 | 
						|
	 * @exception AIError::ERR_LAND_SLOPED_WRONG
 | 
						|
	 * @exception AIRoad::ERR_ROAD_WORKS_IN_PROGRESS
 | 
						|
	 * @exception AIRail::ERR_CROSSING_ON_ONEWAY_ROAD
 | 
						|
	 * @exception AIError::ERR_ALREADY_BUILT
 | 
						|
	 * @return Whether the rail has been/can be build or not.
 | 
						|
	 * @note You can only build a single track with this function so do not
 | 
						|
	 *   use the values from RailTrack as bitmask.
 | 
						|
	 */
 | 
						|
	static bool BuildRailTrack(TileIndex tile, RailTrack rail_track);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Remove rail on the given tile.
 | 
						|
	 * @param tile The tile to remove rail from.
 | 
						|
	 * @param rail_track The RailTrack to remove.
 | 
						|
	 * @pre AIMap::IsValidTile(tile).
 | 
						|
	 * @pre (GetRailTracks(tile) & rail_track) != 0.
 | 
						|
	 * @return Whether the rail has been/can be removed or not.
 | 
						|
	 * @note You can only remove a single track with this function so do not
 | 
						|
	 *   use the values from RailTrack as bitmask.
 | 
						|
	 */
 | 
						|
	static bool RemoveRailTrack(TileIndex tile, RailTrack rail_track);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Check if a tile connects two adjacent tiles.
 | 
						|
	 * @param from The first tile to connect.
 | 
						|
	 * @param tile The tile that is checked.
 | 
						|
	 * @param to The second tile to connect.
 | 
						|
	 * @pre from != to.
 | 
						|
	 * @pre AIMap::DistanceManhattan(from, tile) == 1.
 | 
						|
	 * @pre AIMap::DistanceManhattan(to, tile) == 1.
 | 
						|
	 * @return True if 'tile' connects 'from' and 'to'.
 | 
						|
	 */
 | 
						|
	static bool AreTilesConnected(TileIndex from, TileIndex tile, TileIndex to);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Build a rail connection between two tiles.
 | 
						|
	 * @param from The tile just before the tile to build on.
 | 
						|
	 * @param tile The first tile to build on.
 | 
						|
	 * @param to The tile just after the last tile to build on.
 | 
						|
	 * @pre from != to.
 | 
						|
	 * @pre AIMap::DistanceManhattan(from, tile) == 1.
 | 
						|
	 * @pre AIMap::DistanceManhattan(to, tile) >= 1.
 | 
						|
	 * @pre (abs(abs(AIMap::GetTileX(to) - AIMap::GetTileX(tile)) -
 | 
						|
	 *          abs(AIMap::GetTileY(to) - AIMap::GetTileY(tile))) <= 1) ||
 | 
						|
	 *      (AIMap::GetTileX(from) == AIMap::GetTileX(tile) && AIMap::GetTileX(tile) == AIMap::GetTileX(to)) ||
 | 
						|
	 *      (AIMap::GetTileY(from) == AIMap::GetTileY(tile) && AIMap::GetTileY(tile) == AIMap::GetTileY(to)).
 | 
						|
	 * @pre IsRailTypeAvailable(GetCurrentRailType()).
 | 
						|
	 * @exception AIError::ERR_AREA_NOT_CLEAR
 | 
						|
	 * @exception AIError::ERR_LAND_SLOPED_WRONG
 | 
						|
	 * @exception AIRail::ERR_CROSSING_ON_ONEWAY_ROAD
 | 
						|
	 * @exception AIRoad::ERR_ROAD_WORKS_IN_PROGRESS
 | 
						|
	 * @exception AIError::ERR_ALREADY_BUILT
 | 
						|
	 * @note Construction will fail if an obstacle is found between the start and end tiles.
 | 
						|
	 * @return Whether the rail has been/can be build or not.
 | 
						|
	 */
 | 
						|
	static bool BuildRail(TileIndex from, TileIndex tile, TileIndex to);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Remove a rail connection between two tiles.
 | 
						|
	 * @param from The tile just before the tile to remove rail from.
 | 
						|
	 * @param tile The first tile to remove rail from.
 | 
						|
	 * @param to The tile just after the last tile to remove rail from.
 | 
						|
	 * @pre from != to.
 | 
						|
	 * @pre AIMap::DistanceManhattan(from, tile) == 1.
 | 
						|
	 * @pre AIMap::DistanceManhattan(to, tile) >= 1.
 | 
						|
	 * @pre (abs(abs(AIMap::GetTileX(to) - AIMap::GetTileX(tile)) -
 | 
						|
	 *          abs(AIMap::GetTileY(to) - AIMap::GetTileY(tile))) <= 1) ||
 | 
						|
	 *      (AIMap::GetTileX(from) == AIMap::GetTileX(tile) && AIMap::GetTileX(tile) == AIMap::GetTileX(to)) ||
 | 
						|
	 *      (AIMap::GetTileY(from) == AIMap::GetTileY(tile) && AIMap::GetTileY(tile) == AIMap::GetTileY(to)).
 | 
						|
	 * @return Whether the rail has been/can be removed or not.
 | 
						|
	 */
 | 
						|
	static bool RemoveRail(TileIndex from, TileIndex tile, TileIndex to);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get the SignalType of the signal on a tile or SIGNALTYPE_NONE if there is no signal.
 | 
						|
	 * @pre AIMap::DistanceManhattan(tile, front) == 1.
 | 
						|
	 * @param tile The tile that might have a signal.
 | 
						|
	 * @param front The tile in front of 'tile'.
 | 
						|
	 * @return The SignalType of the signal on 'tile' facing to 'front'.
 | 
						|
	 */
 | 
						|
	static SignalType GetSignalType(TileIndex tile, TileIndex front);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Build a signal on a tile.
 | 
						|
	 * @param tile The tile to build on.
 | 
						|
	 * @param front The tile in front of the signal.
 | 
						|
	 * @param signal The SignalType to build.
 | 
						|
	 * @pre AIMap::DistanceManhattan(tile, front) == 1.
 | 
						|
	 * @pre IsRailTile(tile) && !IsRailStationTile(tile) && !IsRailWaypointTile(tile).
 | 
						|
	 * @exception AIRail::ERR_UNSUITABLE_TRACK
 | 
						|
	 * @return Whether the signal has been/can be build or not.
 | 
						|
	 */
 | 
						|
	static bool BuildSignal(TileIndex tile, TileIndex front, SignalType signal);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Remove a signal.
 | 
						|
	 * @param tile The tile to remove the signal from.
 | 
						|
	 * @param front The tile in front of the signal.
 | 
						|
	 * @pre AIMap::DistanceManhattan(tile, front) == 1.
 | 
						|
	 * @pre GetSignalType(tile, front) != SIGNALTYPE_NONE.
 | 
						|
	 * @return Whether the signal has been/can be removed or not.
 | 
						|
	 */
 | 
						|
	static bool RemoveSignal(TileIndex tile, TileIndex front);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get the baseprice of building a rail-related object.
 | 
						|
	 * @param railtype the railtype that is build (on)
 | 
						|
	 * @param build_type the type of object to build
 | 
						|
	 * @pre IsRailTypeAvailable(railtype)
 | 
						|
	 * @return The baseprice of building the given object.
 | 
						|
	 */
 | 
						|
	static Money GetBuildCost(RailType railtype, BuildType build_type);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Get the maximum speed of trains running on this railtype.
 | 
						|
	 * @param railtype The railtype to get the maximum speed of.
 | 
						|
	 * @pre IsRailTypeAvailable(railtype)
 | 
						|
	 * @return The maximum speed trains can run on this railtype
 | 
						|
	 *   or 0 if there is no limit.
 | 
						|
	 * @note The speed is in OpenTTD's internal speed unit.
 | 
						|
	 *       This is mph / 1.6, which is roughly km/h.
 | 
						|
	 *       To get km/h multiply this number by 1.00584.
 | 
						|
	 */
 | 
						|
	static int32 GetMaxSpeed(RailType railtype);
 | 
						|
};
 | 
						|
 | 
						|
#endif /* AI_RAIL_HPP */
 |