yapf/yapf_destrail.hpp
changeset 3900 4984308f9125
child 3914 f5118020cd84
equal deleted inserted replaced
3899:4c5b1de6cb17 3900:4984308f9125
       
     1 /* $Id$ */
       
     2 
       
     3 #ifndef  YAPF_DESTRAIL_HPP
       
     4 #define  YAPF_DESTRAIL_HPP
       
     5 
       
     6 class CYapfDestinationRailBase
       
     7 {
       
     8 protected:
       
     9 	RailTypeMask m_compatible_railtypes;
       
    10 
       
    11 public:
       
    12 	void SetDestination(Vehicle* v)
       
    13 	{
       
    14 		m_compatible_railtypes = v->u.rail.compatible_railtypes;
       
    15 	}
       
    16 
       
    17 	bool IsCompatibleRailType(RailType rt)
       
    18 	{
       
    19 		return HASBIT(m_compatible_railtypes, rt);
       
    20 	}
       
    21 };
       
    22 
       
    23 template <class Types>
       
    24 class CYapfDestinationAnyDepotRailT
       
    25 	: public CYapfDestinationRailBase
       
    26 {
       
    27 public:
       
    28 	typedef typename Types::Tpf Tpf;
       
    29 	typedef typename Types::NodeList::Titem Node; ///< this will be our node type
       
    30 	typedef typename Node::Key Key;    ///< key to hash tables
       
    31 
       
    32 	Tpf& Yapf() {return *static_cast<Tpf*>(this);}
       
    33 
       
    34 	FORCEINLINE bool PfDetectDestination(Node& n)
       
    35 	{
       
    36 		bool bDest = IsTileDepotType(n.GetLastTile(), TRANSPORT_RAIL);
       
    37 		return bDest;
       
    38 	}
       
    39 
       
    40 	FORCEINLINE bool PfCalcEstimate(Node& n)
       
    41 	{
       
    42 		n.m_estimate = n.m_cost;
       
    43 		return true;
       
    44 	}
       
    45 };
       
    46 
       
    47 template <class Types>
       
    48 class CYapfDestinationTileOrStationRailT
       
    49 	: public CYapfDestinationRailBase
       
    50 {
       
    51 public:
       
    52 	typedef typename Types::Tpf Tpf;
       
    53 	typedef typename Types::NodeList::Titem Node; ///< this will be our node type
       
    54 	typedef typename Node::Key Key;    ///< key to hash tables
       
    55 
       
    56 protected:
       
    57 	TileIndex    m_destTile;
       
    58 	TrackdirBits m_destTrackdirs;
       
    59 	StationID    m_dest_station_id;
       
    60 
       
    61 	Tpf& Yapf() {return *static_cast<Tpf*>(this);}
       
    62 
       
    63 	static TileIndex CalcStationCenterTile(StationID station)
       
    64 	{
       
    65 		const Station* st = GetStation(station);
       
    66 
       
    67 		uint x = TileX(st->train_tile) + st->trainst_w / 2;
       
    68 		uint y = TileY(st->train_tile) + st->trainst_h / 2;
       
    69 		// return the tile of our target coordinates
       
    70 		return TileXY(x, y);
       
    71 	}
       
    72 
       
    73 public:
       
    74 	void SetDestination(Vehicle* v)
       
    75 	{
       
    76 		if (v->current_order.type == OT_GOTO_STATION) {
       
    77 			m_destTile = CalcStationCenterTile(v->current_order.station);
       
    78 			m_dest_station_id = v->current_order.station;
       
    79 			m_destTrackdirs = INVALID_TRACKDIR_BIT;
       
    80 		} else {
       
    81 			m_destTile = v->dest_tile;
       
    82 			m_dest_station_id = INVALID_STATION;
       
    83 			m_destTrackdirs = (TrackdirBits)(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL) & TRACKDIR_BIT_MASK);
       
    84 		}
       
    85 		CYapfDestinationRailBase::SetDestination(v);
       
    86 	}
       
    87 
       
    88 	FORCEINLINE bool PfDetectDestination(Node& n)
       
    89 	{
       
    90 		bool bDest;
       
    91 		if (m_dest_station_id != INVALID_STATION) {
       
    92 			bDest = IsRailwayStationTile(n.GetLastTile())
       
    93 				&& (GetStationIndex(n.GetLastTile()) == m_dest_station_id)
       
    94 				&& (GetRailStationTrack(n.GetLastTile()) == TrackdirToTrack(n.GetLastTrackdir()));
       
    95 		} else {
       
    96 			bDest = (n.GetLastTile() == m_destTile)
       
    97 				&& ((m_destTrackdirs & TrackdirToTrackdirBits(n.GetLastTrackdir())) != TRACKDIR_BIT_NONE);
       
    98 		}
       
    99 		return bDest;
       
   100 	}
       
   101 
       
   102 	FORCEINLINE bool PfCalcEstimate(Node& n)
       
   103 	{
       
   104 		static int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
       
   105 		static int dg_dir_to_y_offs[] = {0, 1, 0, -1};
       
   106 		if (PfDetectDestination(n)) {
       
   107 			n.m_estimate = n.m_cost;
       
   108 			return true;
       
   109 		}
       
   110 
       
   111 		TileIndex tile = n.GetLastTile();
       
   112 		DiagDirection exitdir = TrackdirToExitdir(n.GetLastTrackdir());
       
   113 		int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
       
   114 		int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
       
   115 		int x2 = 2 * TileX(m_destTile);
       
   116 		int y2 = 2 * TileY(m_destTile);
       
   117 		int dx = abs(x1 - x2);
       
   118 		int dy = abs(y1 - y2);
       
   119 		int dmin = min(dx, dy);
       
   120 		int dxy = abs(dx - dy);
       
   121 		int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
       
   122 		n.m_estimate = n.m_cost + d;
       
   123 		assert(n.m_estimate >= n.m_parent->m_estimate);
       
   124 		return true;
       
   125 	}
       
   126 };
       
   127 
       
   128 
       
   129 #endif /* YAPF_DESTRAIL_HPP */