130 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			130 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* $Id$ */
 | |
| 
 | |
| #ifndef  YAPF_DESTRAIL_HPP
 | |
| #define  YAPF_DESTRAIL_HPP
 | |
| 
 | |
| class CYapfDestinationRailBase
 | |
| {
 | |
| protected:
 | |
| 	RailTypeMask m_compatible_railtypes;
 | |
| 
 | |
| public:
 | |
| 	void SetDestination(Vehicle* v)
 | |
| 	{
 | |
| 		m_compatible_railtypes = v->u.rail.compatible_railtypes;
 | |
| 	}
 | |
| 
 | |
| 	bool IsCompatibleRailType(RailType rt)
 | |
| 	{
 | |
| 		return HASBIT(m_compatible_railtypes, rt);
 | |
| 	}
 | |
| };
 | |
| 
 | |
| template <class Types>
 | |
| class CYapfDestinationAnyDepotRailT
 | |
| 	: public CYapfDestinationRailBase
 | |
| {
 | |
| public:
 | |
| 	typedef typename Types::Tpf Tpf;
 | |
| 	typedef typename Types::NodeList::Titem Node; ///< this will be our node type
 | |
| 	typedef typename Node::Key Key;    ///< key to hash tables
 | |
| 
 | |
| 	Tpf& Yapf() {return *static_cast<Tpf*>(this);}
 | |
| 
 | |
| 	FORCEINLINE bool PfDetectDestination(Node& n)
 | |
| 	{
 | |
| 		bool bDest = IsTileDepotType(n.GetLastTile(), TRANSPORT_RAIL);
 | |
| 		return bDest;
 | |
| 	}
 | |
| 
 | |
| 	FORCEINLINE bool PfCalcEstimate(Node& n)
 | |
| 	{
 | |
| 		n.m_estimate = n.m_cost;
 | |
| 		return true;
 | |
| 	}
 | |
| };
 | |
| 
 | |
| template <class Types>
 | |
| class CYapfDestinationTileOrStationRailT
 | |
| 	: public CYapfDestinationRailBase
 | |
| {
 | |
| public:
 | |
| 	typedef typename Types::Tpf Tpf;
 | |
| 	typedef typename Types::NodeList::Titem Node; ///< this will be our node type
 | |
| 	typedef typename Node::Key Key;    ///< key to hash tables
 | |
| 
 | |
| protected:
 | |
| 	TileIndex    m_destTile;
 | |
| 	TrackdirBits m_destTrackdirs;
 | |
| 	StationID    m_dest_station_id;
 | |
| 
 | |
| 	Tpf& Yapf() {return *static_cast<Tpf*>(this);}
 | |
| 
 | |
| 	static TileIndex CalcStationCenterTile(StationID station)
 | |
| 	{
 | |
| 		const Station* st = GetStation(station);
 | |
| 
 | |
| 		uint x = TileX(st->train_tile) + st->trainst_w / 2;
 | |
| 		uint y = TileY(st->train_tile) + st->trainst_h / 2;
 | |
| 		// return the tile of our target coordinates
 | |
| 		return TileXY(x, y);
 | |
| 	}
 | |
| 
 | |
| public:
 | |
| 	void SetDestination(Vehicle* v)
 | |
| 	{
 | |
| 		if (v->current_order.type == OT_GOTO_STATION) {
 | |
| 			m_destTile = CalcStationCenterTile(v->current_order.station);
 | |
| 			m_dest_station_id = v->current_order.station;
 | |
| 			m_destTrackdirs = INVALID_TRACKDIR_BIT;
 | |
| 		} else {
 | |
| 			m_destTile = v->dest_tile;
 | |
| 			m_dest_station_id = INVALID_STATION;
 | |
| 			m_destTrackdirs = (TrackdirBits)(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL) & TRACKDIR_BIT_MASK);
 | |
| 		}
 | |
| 		CYapfDestinationRailBase::SetDestination(v);
 | |
| 	}
 | |
| 
 | |
| 	FORCEINLINE bool PfDetectDestination(Node& n)
 | |
| 	{
 | |
| 		bool bDest;
 | |
| 		if (m_dest_station_id != INVALID_STATION) {
 | |
| 			bDest = IsRailwayStationTile(n.GetLastTile())
 | |
| 				&& (GetStationIndex(n.GetLastTile()) == m_dest_station_id)
 | |
| 				&& (GetRailStationTrack(n.GetLastTile()) == TrackdirToTrack(n.GetLastTrackdir()));
 | |
| 		} else {
 | |
| 			bDest = (n.GetLastTile() == m_destTile)
 | |
| 				&& ((m_destTrackdirs & TrackdirToTrackdirBits(n.GetLastTrackdir())) != TRACKDIR_BIT_NONE);
 | |
| 		}
 | |
| 		return bDest;
 | |
| 	}
 | |
| 
 | |
| 	FORCEINLINE bool PfCalcEstimate(Node& n)
 | |
| 	{
 | |
| 		static int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
 | |
| 		static int dg_dir_to_y_offs[] = {0, 1, 0, -1};
 | |
| 		if (PfDetectDestination(n)) {
 | |
| 			n.m_estimate = n.m_cost;
 | |
| 			return true;
 | |
| 		}
 | |
| 
 | |
| 		TileIndex tile = n.GetLastTile();
 | |
| 		DiagDirection exitdir = TrackdirToExitdir(n.GetLastTrackdir());
 | |
| 		int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
 | |
| 		int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
 | |
| 		int x2 = 2 * TileX(m_destTile);
 | |
| 		int y2 = 2 * TileY(m_destTile);
 | |
| 		int dx = abs(x1 - x2);
 | |
| 		int dy = abs(y1 - y2);
 | |
| 		int dmin = min(dx, dy);
 | |
| 		int dxy = abs(dx - dy);
 | |
| 		int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
 | |
| 		n.m_estimate = n.m_cost + d;
 | |
| 		assert(n.m_estimate >= n.m_parent->m_estimate);
 | |
| 		return true;
 | |
| 	}
 | |
| };
 | |
| 
 | |
| 
 | |
| #endif /* YAPF_DESTRAIL_HPP */
 | 
