Files
@ r11976:ae6aa97461b7
Branch filter:
Location: cpp/openttd-patchpack/source/src/yapf/follow_track.hpp - annotation
r11976:ae6aa97461b7
14.5 KiB
text/x-c++hdr
(svn r16387) -Codechange: use Aircraft instead of Vehicle where appropriate
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 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r6121:a8ff6abe7fb2 r6121:a8ff6abe7fb2 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r8962:cfbdc736c8db r8636:3549af41baf8 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r9802:ebfb6108a16c r9802:ebfb6108a16c r8636:3549af41baf8 r5475:3f5cd13d1b63 r8636:3549af41baf8 r8636:3549af41baf8 r8636:3549af41baf8 r8636:3549af41baf8 r8636:3549af41baf8 r8636:3549af41baf8 r9802:ebfb6108a16c r8636:3549af41baf8 r8636:3549af41baf8 r9439:245ff6cd82bd r9803:69a7dba82f1b r8636:3549af41baf8 r8636:3549af41baf8 r8636:3549af41baf8 r8636:3549af41baf8 r8636:3549af41baf8 r8636:3549af41baf8 r8636:3549af41baf8 r8636:3549af41baf8 r8636:3549af41baf8 r8636:3549af41baf8 r9439:245ff6cd82bd r9797:3ab84be9ba40 r5475:3f5cd13d1b63 r9797:3ab84be9ba40 r5475:3f5cd13d1b63 r9797:3ab84be9ba40 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r9803:69a7dba82f1b r9803:69a7dba82f1b r9803:69a7dba82f1b r9803:69a7dba82f1b r9803:69a7dba82f1b r9803:69a7dba82f1b r9797:3ab84be9ba40 r5475:3f5cd13d1b63 r6259:e2dba394134b r5475:3f5cd13d1b63 r9803:69a7dba82f1b r9803:69a7dba82f1b r9803:69a7dba82f1b r9803:69a7dba82f1b r9803:69a7dba82f1b r9803:69a7dba82f1b r9803:69a7dba82f1b r5475:3f5cd13d1b63 r11363:6906c490a00e r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r7211:2f67593ebe3e r9803:69a7dba82f1b r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r8465:864f39d86a27 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r9899:957eb89d266f r5475:3f5cd13d1b63 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r10160:39dc30004db2 r10160:39dc30004db2 r10160:39dc30004db2 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r9797:3ab84be9ba40 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r7211:2f67593ebe3e r9803:69a7dba82f1b r10160:39dc30004db2 r5475:3f5cd13d1b63 r8465:864f39d86a27 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r7211:2f67593ebe3e r7211:2f67593ebe3e r7211:2f67593ebe3e r7211:2f67593ebe3e r7211:2f67593ebe3e r5475:3f5cd13d1b63 r7211:2f67593ebe3e r7211:2f67593ebe3e r7211:2f67593ebe3e r7211:2f67593ebe3e r7211:2f67593ebe3e r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9873:dcdd95fcea9f r9873:dcdd95fcea9f r9899:957eb89d266f r9873:dcdd95fcea9f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9899:957eb89d266f r9802:ebfb6108a16c r7211:2f67593ebe3e r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r11363:6906c490a00e r8398:cf5cc32ab397 r8398:cf5cc32ab397 r8398:cf5cc32ab397 r11363:6906c490a00e r8398:cf5cc32ab397 r8398:cf5cc32ab397 r8398:cf5cc32ab397 r8398:cf5cc32ab397 r8398:cf5cc32ab397 r8398:cf5cc32ab397 r8398:cf5cc32ab397 r8398:cf5cc32ab397 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r8398:cf5cc32ab397 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r11363:6906c490a00e r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r11363:6906c490a00e r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r11941:8901ca1bc641 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r9803:69a7dba82f1b r8465:864f39d86a27 r10160:39dc30004db2 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r11363:6906c490a00e r6012:6160fb57dc8a r5475:3f5cd13d1b63 r7211:2f67593ebe3e r7211:2f67593ebe3e r5475:3f5cd13d1b63 r7211:2f67593ebe3e r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r8465:864f39d86a27 r10160:39dc30004db2 r10160:39dc30004db2 r10160:39dc30004db2 r10160:39dc30004db2 r10160:39dc30004db2 r10160:39dc30004db2 r8465:864f39d86a27 r8465:864f39d86a27 r11363:6906c490a00e r8954:770c53d1c4f5 r5475:3f5cd13d1b63 r7211:2f67593ebe3e r7211:2f67593ebe3e r5475:3f5cd13d1b63 r7211:2f67593ebe3e r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r6012:6160fb57dc8a r11363:6906c490a00e r5475:3f5cd13d1b63 r7211:2f67593ebe3e r7211:2f67593ebe3e r5475:3f5cd13d1b63 r7211:2f67593ebe3e r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r8465:864f39d86a27 r10160:39dc30004db2 r10160:39dc30004db2 r10160:39dc30004db2 r10160:39dc30004db2 r10160:39dc30004db2 r10160:39dc30004db2 r8465:864f39d86a27 r8465:864f39d86a27 r11363:6906c490a00e r8954:770c53d1c4f5 r5475:3f5cd13d1b63 r7211:2f67593ebe3e r7211:2f67593ebe3e r5475:3f5cd13d1b63 r7211:2f67593ebe3e r11363:6906c490a00e r9803:69a7dba82f1b r7211:2f67593ebe3e r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r8954:770c53d1c4f5 r5475:3f5cd13d1b63 r7211:2f67593ebe3e r7211:2f67593ebe3e r5475:3f5cd13d1b63 r7211:2f67593ebe3e r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r11363:6906c490a00e r9803:69a7dba82f1b r11363:6906c490a00e r7211:2f67593ebe3e r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r11363:6906c490a00e r5475:3f5cd13d1b63 r6154:ac5bfaeff771 r9797:3ab84be9ba40 r11363:6906c490a00e r7211:2f67593ebe3e r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r11363:6906c490a00e r9490:5cf190d39c21 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r8083:8cd2123a0c7c r7211:2f67593ebe3e r7214:b82aad925d0b r7211:2f67593ebe3e r7211:2f67593ebe3e r5475:3f5cd13d1b63 r8390:ef5ec525d36d r5475:3f5cd13d1b63 r8083:8cd2123a0c7c r7211:2f67593ebe3e r7214:b82aad925d0b r7211:2f67593ebe3e r7211:2f67593ebe3e r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r11363:6906c490a00e r5475:3f5cd13d1b63 r11363:6906c490a00e r11363:6906c490a00e r5998:69c1cce26321 r11363:6906c490a00e r5475:3f5cd13d1b63 r11363:6906c490a00e r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r8465:864f39d86a27 r8465:864f39d86a27 r5475:3f5cd13d1b63 r11363:6906c490a00e r8954:770c53d1c4f5 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r11363:6906c490a00e r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r8465:864f39d86a27 r11363:6906c490a00e r10160:39dc30004db2 r11363:6906c490a00e r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r8465:864f39d86a27 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r8465:864f39d86a27 r11363:6906c490a00e r5475:3f5cd13d1b63 r11363:6906c490a00e r5475:3f5cd13d1b63 r11363:6906c490a00e r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r11363:6906c490a00e r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r7211:2f67593ebe3e r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r7037:90a889f00874 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r11363:6906c490a00e r5475:3f5cd13d1b63 r8491:493075733a1d r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r11363:6906c490a00e r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r5475:3f5cd13d1b63 r9802:ebfb6108a16c r9802:ebfb6108a16c r9802:ebfb6108a16c r5475:3f5cd13d1b63 | /* $Id$ */
/** @file follow_track.hpp Template function for track followers */
#ifndef FOLLOW_TRACK_HPP
#define FOLLOW_TRACK_HPP
#include "yapf.hpp"
#include "../depot_map.h"
/** Track follower helper template class (can serve pathfinders and vehicle
* controllers). See 6 different typedefs below for 3 different transport
* types w/ or w/o 90-deg turns allowed */
template <TransportType Ttr_type_, bool T90deg_turns_allowed_ = true, bool Tmask_reserved_tracks = false>
struct CFollowTrackT
{
enum ErrorCode {
EC_NONE,
EC_OWNER,
EC_RAIL_TYPE,
EC_90DEG,
EC_NO_WAY,
EC_RESERVED,
};
const Vehicle *m_veh; ///< moving vehicle
Owner m_veh_owner; ///< owner of the vehicle
TileIndex m_old_tile; ///< the origin (vehicle moved from) before move
Trackdir m_old_td; ///< the trackdir (the vehicle was on) before move
TileIndex m_new_tile; ///< the new tile (the vehicle has entered)
TrackdirBits m_new_td_bits; ///< the new set of available trackdirs
DiagDirection m_exitdir; ///< exit direction (leaving the old tile)
bool m_is_tunnel; ///< last turn passed tunnel
bool m_is_bridge; ///< last turn passed bridge ramp
bool m_is_station; ///< last turn passed station
int m_tiles_skipped; ///< number of skipped tunnel or station tiles
ErrorCode m_err;
CPerformanceTimer *m_pPerf;
RailTypes m_railtypes;
FORCEINLINE CFollowTrackT(const Vehicle *v = NULL, RailTypes railtype_override = INVALID_RAILTYPES, CPerformanceTimer *pPerf = NULL)
{
Init(v, railtype_override, pPerf);
}
FORCEINLINE CFollowTrackT(Owner o, RailTypes railtype_override = INVALID_RAILTYPES, CPerformanceTimer *pPerf = NULL)
{
m_veh = NULL;
Init(o, railtype_override, pPerf);
}
FORCEINLINE void Init(const Vehicle *v, RailTypes railtype_override, CPerformanceTimer *pPerf)
{
assert(!IsRailTT() || (v != NULL && v->type == VEH_TRAIN));
m_veh = v;
Init(v != NULL ? v->owner : INVALID_OWNER, railtype_override == INVALID_RAILTYPES ? v->u.rail.compatible_railtypes : railtype_override, pPerf);
}
FORCEINLINE void Init(Owner o, RailTypes railtype_override, CPerformanceTimer *pPerf)
{
assert((!IsRoadTT() || m_veh != NULL) && (!IsRailTT() || railtype_override != INVALID_RAILTYPES));
m_veh_owner = o;
m_pPerf = pPerf;
/* don't worry, all is inlined so compiler should remove unnecessary initializations */
m_new_tile = INVALID_TILE;
m_new_td_bits = TRACKDIR_BIT_NONE;
m_exitdir = INVALID_DIAGDIR;
m_is_station = m_is_bridge = m_is_tunnel = false;
m_tiles_skipped = 0;
m_err = EC_NONE;
m_railtypes = railtype_override;
}
FORCEINLINE static TransportType TT() {return Ttr_type_;}
FORCEINLINE static bool IsWaterTT() {return TT() == TRANSPORT_WATER;}
FORCEINLINE static bool IsRailTT() {return TT() == TRANSPORT_RAIL;}
FORCEINLINE bool IsTram() {return IsRoadTT() && HasBit(m_veh->u.road.compatible_roadtypes, ROADTYPE_TRAM);}
FORCEINLINE static bool IsRoadTT() {return TT() == TRANSPORT_ROAD;}
FORCEINLINE static bool Allow90degTurns() {return T90deg_turns_allowed_;}
FORCEINLINE static bool DoTrackMasking() {return IsRailTT() && Tmask_reserved_tracks;}
/** Tests if a tile is a road tile with a single tramtrack (tram can reverse) */
FORCEINLINE DiagDirection GetSingleTramBit(TileIndex tile)
{
assert(IsTram()); // this function shouldn't be called in other cases
if (IsNormalRoadTile(tile)) {
RoadBits rb = GetRoadBits(tile, ROADTYPE_TRAM);
switch (rb) {
case ROAD_NW: return DIAGDIR_NW;
case ROAD_SW: return DIAGDIR_SW;
case ROAD_SE: return DIAGDIR_SE;
case ROAD_NE: return DIAGDIR_NE;
default: break;
}
}
return INVALID_DIAGDIR;
}
/** main follower routine. Fills all members and return true on success.
* Otherwise returns false if track can't be followed. */
inline bool Follow(TileIndex old_tile, Trackdir old_td)
{
m_old_tile = old_tile;
m_old_td = old_td;
m_err = EC_NONE;
assert(((TrackStatusToTrackdirBits(GetTileTrackStatus(m_old_tile, TT(), m_veh ? m_veh->u.road.compatible_roadtypes : 0)) & TrackdirToTrackdirBits(m_old_td)) != 0) ||
(IsTram() && GetSingleTramBit(m_old_tile) != INVALID_DIAGDIR)); // Disable the assertion for single tram bits
m_exitdir = TrackdirToExitdir(m_old_td);
if (ForcedReverse()) return true;
if (!CanExitOldTile()) return false;
FollowTileExit();
if (!QueryNewTileTrackStatus()) return TryReverse();
if (!CanEnterNewTile()) return false;
m_new_td_bits &= DiagdirReachesTrackdirs(m_exitdir);
if (m_new_td_bits == TRACKDIR_BIT_NONE) {
m_err = EC_NO_WAY;
return false;
}
if (!Allow90degTurns()) {
m_new_td_bits &= (TrackdirBits)~(int)TrackdirCrossesTrackdirs(m_old_td);
if (m_new_td_bits == TRACKDIR_BIT_NONE) {
m_err = EC_90DEG;
return false;
}
}
return true;
}
inline bool MaskReservedTracks()
{
if (!DoTrackMasking()) return true;
if (m_is_station) {
/* Check skipped station tiles as well. */
TileIndexDiff diff = TileOffsByDiagDir(m_exitdir);
for (TileIndex tile = m_new_tile - diff * m_tiles_skipped; tile != m_new_tile; tile += diff) {
if (GetRailwayStationReservation(tile)) {
m_new_td_bits = TRACKDIR_BIT_NONE;
m_err = EC_RESERVED;
return false;
}
}
}
TrackBits reserved = GetReservedTrackbits(m_new_tile);
/* Mask already reserved trackdirs. */
m_new_td_bits &= ~TrackBitsToTrackdirBits(reserved);
/* Mask out all trackdirs that conflict with the reservation. */
uint bits = (uint)TrackdirBitsToTrackBits(m_new_td_bits);
int i;
FOR_EACH_SET_BIT(i, bits) {
if (TracksOverlap(reserved | TrackToTrackBits((Track)i))) m_new_td_bits &= ~TrackToTrackdirBits((Track)i);
}
if (m_new_td_bits == TRACKDIR_BIT_NONE) {
m_err = EC_RESERVED;
return false;
}
return true;
}
protected:
/** Follow the m_exitdir from m_old_tile and fill m_new_tile and m_tiles_skipped */
FORCEINLINE void FollowTileExit()
{
m_is_station = m_is_bridge = m_is_tunnel = false;
m_tiles_skipped = 0;
/* extra handling for tunnels and bridges in our direction */
if (IsTileType(m_old_tile, MP_TUNNELBRIDGE)) {
DiagDirection enterdir = GetTunnelBridgeDirection(m_old_tile);
if (enterdir == m_exitdir) {
/* we are entering the tunnel / bridge */
if (IsTunnel(m_old_tile)) {
m_is_tunnel = true;
m_new_tile = GetOtherTunnelEnd(m_old_tile);
} else { // IsBridge(m_old_tile)
m_is_bridge = true;
m_new_tile = GetOtherBridgeEnd(m_old_tile);
}
m_tiles_skipped = GetTunnelBridgeLength(m_new_tile, m_old_tile);
return;
}
assert(ReverseDiagDir(enterdir) == m_exitdir);
}
/* normal or station tile, do one step */
TileIndexDiff diff = TileOffsByDiagDir(m_exitdir);
m_new_tile = TILE_ADD(m_old_tile, diff);
/* special handling for stations */
if (IsRailTT() && IsRailwayStationTile(m_new_tile)) {
m_is_station = true;
} else if (IsRoadTT() && IsRoadStopTile(m_new_tile)) {
m_is_station = true;
} else {
m_is_station = false;
}
}
/** stores track status (available trackdirs) for the new tile into m_new_td_bits */
FORCEINLINE bool QueryNewTileTrackStatus()
{
CPerfStart perf(*m_pPerf);
if (IsRailTT() && IsPlainRailTile(m_new_tile)) {
m_new_td_bits = (TrackdirBits)(GetTrackBits(m_new_tile) * 0x101);
} else {
m_new_td_bits = TrackStatusToTrackdirBits(GetTileTrackStatus(m_new_tile, TT(), m_veh != NULL ? m_veh->u.road.compatible_roadtypes : 0));
if (IsTram() && m_new_td_bits == 0) {
/* GetTileTrackStatus() returns 0 for single tram bits.
* As we cannot change it there (easily) without breaking something, change it here */
switch (GetSingleTramBit(m_new_tile)) {
case DIAGDIR_NE:
case DIAGDIR_SW:
m_new_td_bits = TRACKDIR_BIT_X_NE | TRACKDIR_BIT_X_SW;
break;
case DIAGDIR_NW:
case DIAGDIR_SE:
m_new_td_bits = TRACKDIR_BIT_Y_NW | TRACKDIR_BIT_Y_SE;
break;
default: break;
}
}
}
return (m_new_td_bits != TRACKDIR_BIT_NONE);
}
/** return true if we can leave m_old_tile in m_exitdir */
FORCEINLINE bool CanExitOldTile()
{
/* road stop can be left at one direction only unless it's a drive-through stop */
if (IsRoadTT() && IsStandardRoadStopTile(m_old_tile)) {
DiagDirection exitdir = GetRoadStopDir(m_old_tile);
if (exitdir != m_exitdir) {
m_err = EC_NO_WAY;
return false;
}
}
/* single tram bits can only be left in one direction */
if (IsTram()) {
DiagDirection single_tram = GetSingleTramBit(m_old_tile);
if (single_tram != INVALID_DIAGDIR && single_tram != m_exitdir) {
m_err = EC_NO_WAY;
return false;
}
}
/* road depots can be also left in one direction only */
if (IsRoadTT() && IsDepotTypeTile(m_old_tile, TT())) {
DiagDirection exitdir = GetRoadDepotDirection(m_old_tile);
if (exitdir != m_exitdir) {
m_err = EC_NO_WAY;
return false;
}
}
return true;
}
/** return true if we can enter m_new_tile from m_exitdir */
FORCEINLINE bool CanEnterNewTile()
{
if (IsRoadTT() && IsStandardRoadStopTile(m_new_tile)) {
/* road stop can be entered from one direction only unless it's a drive-through stop */
DiagDirection exitdir = GetRoadStopDir(m_new_tile);
if (ReverseDiagDir(exitdir) != m_exitdir) {
m_err = EC_NO_WAY;
return false;
}
}
/* single tram bits can only be entered from one direction */
if (IsTram()) {
DiagDirection single_tram = GetSingleTramBit(m_new_tile);
if (single_tram != INVALID_DIAGDIR && single_tram != ReverseDiagDir(m_exitdir)) {
m_err = EC_NO_WAY;
return false;
}
}
/* road and rail depots can also be entered from one direction only */
if (IsRoadTT() && IsDepotTypeTile(m_new_tile, TT())) {
DiagDirection exitdir = GetRoadDepotDirection(m_new_tile);
if (ReverseDiagDir(exitdir) != m_exitdir) {
m_err = EC_NO_WAY;
return false;
}
/* don't try to enter other company's depots */
if (GetTileOwner(m_new_tile) != m_veh_owner) {
m_err = EC_OWNER;
return false;
}
}
if (IsRailTT() && IsDepotTypeTile(m_new_tile, TT())) {
DiagDirection exitdir = GetRailDepotDirection(m_new_tile);
if (ReverseDiagDir(exitdir) != m_exitdir) {
m_err = EC_NO_WAY;
return false;
}
}
/* rail transport is possible only on tiles with the same owner as vehicle */
if (IsRailTT() && GetTileOwner(m_new_tile) != m_veh_owner) {
/* different owner */
m_err = EC_NO_WAY;
return false;
}
/* rail transport is possible only on compatible rail types */
if (IsRailTT()) {
RailType rail_type = GetTileRailType(m_new_tile);
if (!HasBit(m_railtypes, rail_type)) {
/* incompatible rail type */
m_err = EC_RAIL_TYPE;
return false;
}
}
/* tunnel holes and bridge ramps can be entered only from proper direction */
if (IsTileType(m_new_tile, MP_TUNNELBRIDGE)) {
if (IsTunnel(m_new_tile)) {
if (!m_is_tunnel) {
DiagDirection tunnel_enterdir = GetTunnelBridgeDirection(m_new_tile);
if (tunnel_enterdir != m_exitdir) {
m_err = EC_NO_WAY;
return false;
}
}
} else { // IsBridge(m_new_tile)
if (!m_is_bridge) {
DiagDirection ramp_enderdir = GetTunnelBridgeDirection(m_new_tile);
if (ramp_enderdir != m_exitdir) {
m_err = EC_NO_WAY;
return false;
}
}
}
}
/* special handling for rail stations - get to the end of platform */
if (IsRailTT() && m_is_station) {
/* entered railway station
* get platform length */
uint length = GetStationByTile(m_new_tile)->GetPlatformLength(m_new_tile, TrackdirToExitdir(m_old_td));
/* how big step we must do to get to the last platform tile; */
m_tiles_skipped = length - 1;
/* move to the platform end */
TileIndexDiff diff = TileOffsByDiagDir(m_exitdir);
diff *= m_tiles_skipped;
m_new_tile = TILE_ADD(m_new_tile, diff);
return true;
}
return true;
}
/** return true if we must reverse (in depots and single tram bits) */
FORCEINLINE bool ForcedReverse()
{
/* rail and road depots cause reversing */
if (!IsWaterTT() && IsDepotTypeTile(m_old_tile, TT())) {
DiagDirection exitdir = IsRailTT() ? GetRailDepotDirection(m_old_tile) : GetRoadDepotDirection(m_old_tile);
if (exitdir != m_exitdir) {
/* reverse */
m_new_tile = m_old_tile;
m_new_td_bits = TrackdirToTrackdirBits(ReverseTrackdir(m_old_td));
m_exitdir = exitdir;
m_tiles_skipped = 0;
m_is_tunnel = m_is_bridge = m_is_station = false;
return true;
}
}
/* single tram bits cause reversing */
if (IsTram() && GetSingleTramBit(m_old_tile) == ReverseDiagDir(m_exitdir)) {
/* reverse */
m_new_tile = m_old_tile;
m_new_td_bits = TrackdirToTrackdirBits(ReverseTrackdir(m_old_td));
m_exitdir = ReverseDiagDir(m_exitdir);
m_tiles_skipped = 0;
m_is_tunnel = m_is_bridge = m_is_station = false;
return true;
}
return false;
}
/** return true if we successfully reversed at end of road/track */
FORCEINLINE bool TryReverse()
{
if (IsRoadTT() && !IsTram()) {
/* if we reached the end of road, we can reverse the RV and continue moving */
m_exitdir = ReverseDiagDir(m_exitdir);
/* new tile will be the same as old one */
m_new_tile = m_old_tile;
/* set new trackdir bits to all reachable trackdirs */
QueryNewTileTrackStatus();
m_new_td_bits &= DiagdirReachesTrackdirs(m_exitdir);
if (m_new_td_bits != TRACKDIR_BIT_NONE) {
/* we have some trackdirs reachable after reversal */
return true;
}
}
m_err = EC_NO_WAY;
return false;
}
public:
/** Helper for pathfinders - get min/max speed on the m_old_tile/m_old_td */
int GetSpeedLimit(int *pmin_speed = NULL) const
{
int min_speed = 0;
int max_speed = INT_MAX; // no limit
/* for now we handle only on-bridge speed limit */
if (!IsWaterTT() && IsBridgeTile(m_old_tile)) {
int spd = GetBridgeSpec(GetBridgeType(m_old_tile))->speed;
if (IsRoadTT()) spd *= 2;
if (max_speed > spd) max_speed = spd;
}
/* if min speed was requested, return it */
if (pmin_speed) *pmin_speed = min_speed;
return max_speed;
}
};
typedef CFollowTrackT<TRANSPORT_WATER, true > CFollowTrackWater;
typedef CFollowTrackT<TRANSPORT_ROAD , true > CFollowTrackRoad;
typedef CFollowTrackT<TRANSPORT_RAIL , true > CFollowTrackRail;
typedef CFollowTrackT<TRANSPORT_WATER, false> CFollowTrackWaterNo90;
typedef CFollowTrackT<TRANSPORT_ROAD , false> CFollowTrackRoadNo90;
typedef CFollowTrackT<TRANSPORT_RAIL , false> CFollowTrackRailNo90;
typedef CFollowTrackT<TRANSPORT_RAIL , true , true> CFollowTrackFreeRail;
typedef CFollowTrackT<TRANSPORT_RAIL , false, true> CFollowTrackFreeRailNo90;
#endif /* FOLLOW_TRACK_HPP */
|