yapf_destrail.hpp

Go to the documentation of this file.
00001 /* $Id: yapf_destrail.hpp 12199 2008-02-20 17:49:50Z frosch $ */
00002 
00005 #ifndef  YAPF_DESTRAIL_HPP
00006 #define  YAPF_DESTRAIL_HPP
00007 
00008 class CYapfDestinationRailBase
00009 {
00010 protected:
00011   RailTypes m_compatible_railtypes;
00012 
00013 public:
00014   void SetDestination(Vehicle* v)
00015   {
00016     m_compatible_railtypes = v->u.rail.compatible_railtypes;
00017   }
00018 
00019   bool IsCompatibleRailType(RailType rt)
00020   {
00021     return HasBit(m_compatible_railtypes, rt);
00022   }
00023 };
00024 
00025 template <class Types>
00026 class CYapfDestinationAnyDepotRailT
00027   : public CYapfDestinationRailBase
00028 {
00029 public:
00030   typedef typename Types::Tpf Tpf;              
00031   typedef typename Types::NodeList::Titem Node; 
00032   typedef typename Node::Key Key;               
00033 
00035   Tpf& Yapf() {return *static_cast<Tpf*>(this);}
00036 
00038   FORCEINLINE bool PfDetectDestination(Node& n)
00039   {
00040     return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
00041   }
00042 
00044   FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
00045   {
00046     bool bDest = IsTileDepotType(tile, TRANSPORT_RAIL);
00047     return bDest;
00048   }
00049 
00052   FORCEINLINE bool PfCalcEstimate(Node& n)
00053   {
00054     n.m_estimate = n.m_cost;
00055     return true;
00056   }
00057 };
00058 
00059 template <class Types>
00060 class CYapfDestinationTileOrStationRailT
00061   : public CYapfDestinationRailBase
00062 {
00063 public:
00064   typedef typename Types::Tpf Tpf;              
00065   typedef typename Types::NodeList::Titem Node; 
00066   typedef typename Node::Key Key;               
00067 
00068 protected:
00069   TileIndex    m_destTile;
00070   TrackdirBits m_destTrackdirs;
00071   StationID    m_dest_station_id;
00072 
00074   Tpf& Yapf() {return *static_cast<Tpf*>(this);}
00075 
00076   static TileIndex CalcStationCenterTile(StationID station)
00077   {
00078     const Station* st = GetStation(station);
00079 
00080     uint x = TileX(st->train_tile) + st->trainst_w / 2;
00081     uint y = TileY(st->train_tile) + st->trainst_h / 2;
00082     // return the tile of our target coordinates
00083     return TileXY(x, y);
00084   }
00085 
00086 public:
00087   void SetDestination(Vehicle* v)
00088   {
00089     switch (v->current_order.type) {
00090       case OT_GOTO_STATION:
00091         m_destTile = CalcStationCenterTile(v->current_order.dest);
00092         m_dest_station_id = v->current_order.dest;
00093         m_destTrackdirs = INVALID_TRACKDIR_BIT;
00094         break;
00095 
00096       case OT_GOTO_WAYPOINT: {
00097         Waypoint *wp = GetWaypoint(v->current_order.dest);
00098         if (wp == NULL) {
00099           /* Invalid waypoint in orders! */
00100           DEBUG(yapf, 0, "Invalid waypoint in orders == 0x%04X (train %d, player %d)", v->current_order.dest, v->unitnumber, (PlayerID)v->owner);
00101           break;
00102         }
00103         m_destTile = wp->xy;
00104         if (m_destTile != v->dest_tile) {
00105           /* Something is wrong with orders! */
00106           DEBUG(yapf, 0, "Invalid v->dest_tile == 0x%04X (train %d, player %d)", v->dest_tile, v->unitnumber, (PlayerID)v->owner);
00107         }
00108         m_dest_station_id = INVALID_STATION;
00109         m_destTrackdirs = TrackToTrackdirBits(AxisToTrack(GetWaypointAxis(wp->xy)));
00110         break;
00111       }
00112 
00113       default:
00114         m_destTile = v->dest_tile;
00115         m_dest_station_id = INVALID_STATION;
00116         m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL, 0));
00117         break;
00118     }
00119     CYapfDestinationRailBase::SetDestination(v);
00120   }
00121 
00123   FORCEINLINE bool PfDetectDestination(Node& n)
00124   {
00125     return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
00126   }
00127 
00129   FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
00130   {
00131     bool bDest;
00132     if (m_dest_station_id != INVALID_STATION) {
00133       bDest = IsRailwayStationTile(tile)
00134         && (GetStationIndex(tile) == m_dest_station_id)
00135         && (GetRailStationTrack(tile) == TrackdirToTrack(td));
00136     } else {
00137       bDest = (tile == m_destTile)
00138         && ((m_destTrackdirs & TrackdirToTrackdirBits(td)) != TRACKDIR_BIT_NONE);
00139     }
00140     return bDest;
00141   }
00142 
00145   FORCEINLINE bool PfCalcEstimate(Node& n)
00146   {
00147     static int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
00148     static int dg_dir_to_y_offs[] = {0, 1, 0, -1};
00149     if (PfDetectDestination(n)) {
00150       n.m_estimate = n.m_cost;
00151       return true;
00152     }
00153 
00154     TileIndex tile = n.GetLastTile();
00155     DiagDirection exitdir = TrackdirToExitdir(n.GetLastTrackdir());
00156     int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir];
00157     int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir];
00158     int x2 = 2 * TileX(m_destTile);
00159     int y2 = 2 * TileY(m_destTile);
00160     int dx = abs(x1 - x2);
00161     int dy = abs(y1 - y2);
00162     int dmin = min(dx, dy);
00163     int dxy = abs(dx - dy);
00164     int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2);
00165     n.m_estimate = n.m_cost + d;
00166     assert(n.m_estimate >= n.m_parent->m_estimate);
00167     return true;
00168   }
00169 };
00170 
00171 
00172 #endif /* YAPF_DESTRAIL_HPP */

Generated on Wed Oct 1 17:03:26 2008 for openttd by  doxygen 1.5.6