# 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 */