Files
@ r6682:de95441ccf30
Branch filter:
Location: cpp/openttd-patchpack/source/src/yapf/yapf_destrail.hpp
r6682:de95441ccf30
5.1 KiB
text/x-c++hdr
(svn r9913) -Update: the landscape documentation to reflect the changes to the road bits.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | /* $Id$ */
/** @file yapf_destrail.hpp */
#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; ///< the pathfinder class (derived from THIS class)
typedef typename Types::NodeList::Titem Node; ///< this will be our node type
typedef typename Node::Key Key; ///< key to hash tables
/// to access inherited path finder
Tpf& Yapf() {return *static_cast<Tpf*>(this);}
/// Called by YAPF to detect if node ends in the desired destination
FORCEINLINE bool PfDetectDestination(Node& n)
{
return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
}
/// Called by YAPF to detect if node ends in the desired destination
FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
{
bool bDest = IsTileDepotType(tile, TRANSPORT_RAIL);
return bDest;
}
/** Called by YAPF to calculate cost estimate. Calculates distance to the destination
* adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
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; ///< the pathfinder class (derived from THIS class)
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;
/// to access inherited path finder
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)
{
switch (v->current_order.type) {
case OT_GOTO_STATION:
m_destTile = CalcStationCenterTile(v->current_order.dest);
m_dest_station_id = v->current_order.dest;
m_destTrackdirs = INVALID_TRACKDIR_BIT;
break;
case OT_GOTO_WAYPOINT: {
Waypoint *wp = GetWaypoint(v->current_order.dest);
if (wp == NULL) {
/* Invalid waypoint in orders! */
DEBUG(yapf, 0, "Invalid waypoint in orders == 0x%04X (train %d, player %d)", v->current_order.dest, v->unitnumber, (PlayerID)v->owner);
break;
}
m_destTile = wp->xy;
if (m_destTile != v->dest_tile) {
/* Something is wrong with orders! */
DEBUG(yapf, 0, "Invalid v->dest_tile == 0x%04X (train %d, player %d)", v->dest_tile, v->unitnumber, (PlayerID)v->owner);
}
m_dest_station_id = INVALID_STATION;
m_destTrackdirs = TrackToTrackdirBits(AxisToTrack(GetWaypointAxis(wp->xy)));
break;
}
default:
m_destTile = v->dest_tile;
m_dest_station_id = INVALID_STATION;
m_destTrackdirs = (TrackdirBits)(GetTileTrackStatus(v->dest_tile, TRANSPORT_RAIL) & TRACKDIR_BIT_MASK);
break;
}
CYapfDestinationRailBase::SetDestination(v);
}
/// Called by YAPF to detect if node ends in the desired destination
FORCEINLINE bool PfDetectDestination(Node& n)
{
return PfDetectDestination(n.GetLastTile(), n.GetLastTrackdir());
}
/// Called by YAPF to detect if node ends in the desired destination
FORCEINLINE bool PfDetectDestination(TileIndex tile, Trackdir td)
{
bool bDest;
if (m_dest_station_id != INVALID_STATION) {
bDest = IsRailwayStationTile(tile)
&& (GetStationIndex(tile) == m_dest_station_id)
&& (GetRailStationTrack(tile) == TrackdirToTrack(td));
} else {
bDest = (tile == m_destTile)
&& ((m_destTrackdirs & TrackdirToTrackdirBits(td)) != TRACKDIR_BIT_NONE);
}
return bDest;
}
/** Called by YAPF to calculate cost estimate. Calculates distance to the destination
* adds it to the actual cost from origin and stores the sum to the Node::m_estimate */
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 */
|