2005-07-24 14:12:37 +00:00
/* $Id$ */
2008-05-06 15:11:33 +00:00
/** @file npf.h New A* pathfinder. */
2007-03-21 03:06:21 +00:00
2005-01-31 11:23:10 +00:00
# ifndef NPF_H
# define NPF_H
# include "aystar.h"
2008-03-31 00:06:17 +00:00
# include "station_type.h"
# include "rail_type.h"
2008-09-30 20:51:04 +00:00
# include "company_type.h"
2007-12-26 11:45:43 +00:00
# include "vehicle_type.h"
2007-12-19 23:26:02 +00:00
# include "tile_type.h"
2007-12-26 11:45:43 +00:00
# include "track_type.h"
2008-01-09 21:05:03 +00:00
# include "core/bitmath_func.hpp"
2008-05-07 09:07:19 +00:00
# include "transport_type.h"
2005-01-31 11:23:10 +00:00
2007-03-21 03:06:21 +00:00
/* mowing grass */
2005-04-07 19:19:16 +00:00
enum {
2007-03-21 03:06:21 +00:00
NPF_HASH_BITS = 12 , ///< The size of the hash used in pathfinding. Just changing this value should be sufficient to change the hash size. Should be an even value.
2005-04-07 19:19:16 +00:00
/* Do no change below values */
NPF_HASH_SIZE = 1 < < NPF_HASH_BITS ,
NPF_HASH_HALFBITS = NPF_HASH_BITS / 2 ,
NPF_HASH_HALFMASK = ( 1 < < NPF_HASH_HALFBITS ) - 1
} ;
2005-01-31 11:23:10 +00:00
2006-03-29 19:00:56 +00:00
/* For new pathfinding. Define here so it is globally available without having
* to include npf . h */
enum {
NPF_TILE_LENGTH = 100
} ;
2005-05-07 22:00:36 +00:00
enum {
/** This penalty is the equivalent of "inifite", which means that paths that
* get this penalty will be chosen , but only if there is no other route
* without it . Be careful with not applying this penalty to often , or the
* total path cost might overflow . .
* For now , this is just a Very Big Penalty , we might actually implement
* this in a nicer way : - )
*/
NPF_INFINITE_PENALTY = 1000 * NPF_TILE_LENGTH
} ;
2007-03-21 03:06:21 +00:00
/* Meant to be stored in AyStar.targetdata */
struct NPFFindStationOrTileData {
TileIndex dest_coords ; ///< An indication of where the station is, for heuristic purposes, or the target tile
StationID station_index ; ///< station index we're heading for, or INVALID_STATION when we're heading for a tile
2008-08-02 22:52:22 +00:00
bool reserve_path ; ///< Indicates whether the found path should be reserved
const Vehicle * v ; ///< The vehicle we are pathfinding for
2007-03-07 12:11:48 +00:00
} ;
2005-01-31 11:23:10 +00:00
2007-03-21 03:06:21 +00:00
/* Indices into AyStar.userdata[] */
enum {
NPF_TYPE = 0 , ///< Contains a TransportTypes value
2007-05-24 22:41:50 +00:00
NPF_SUB_TYPE , ///< Contains the sub transport type
2007-03-21 03:06:21 +00:00
NPF_OWNER , ///< Contains an Owner value
NPF_RAILTYPES , ///< Contains a bitmask the compatible RailTypes of the engine when NPF_TYPE == TRANSPORT_RAIL. Unused otherwise.
2005-01-31 11:23:10 +00:00
} ;
2007-03-21 03:06:21 +00:00
/* Indices into AyStarNode.userdata[] */
enum {
NPF_TRACKDIR_CHOICE = 0 , ///< The trackdir chosen to get here
2005-01-31 11:23:10 +00:00
NPF_NODE_FLAGS ,
} ;
2005-07-04 14:58:55 +00:00
2007-03-21 03:06:21 +00:00
/* Flags for AyStarNode.userdata[NPF_NODE_FLAGS]. Use NPFGetBit() and NPFGetBit() to use them. */
enum NPFNodeFlag {
2008-02-08 16:25:55 +00:00
NPF_FLAG_SEEN_SIGNAL , ///< Used to mark that a signal was seen on the way, for rail only
2008-08-02 22:52:36 +00:00
NPF_FLAG_2ND_SIGNAL , ///< Used to mark that two signals were seen, rail only
NPF_FLAG_3RD_SIGNAL , ///< Used to mark that three signals were seen, rail only
2008-02-08 16:25:55 +00:00
NPF_FLAG_REVERSE , ///< Used to mark that this node was reached from the second start node, if applicable
NPF_FLAG_LAST_SIGNAL_RED , ///< Used to mark that the last signal on this path was red
NPF_FLAG_IGNORE_START_TILE , ///< Used to mark that the start tile is invalid, and searching should start from the second tile on
2008-08-02 22:52:22 +00:00
NPF_FLAG_TARGET_RESERVED , ///< Used to mark that the possible reservation target is already reserved
2008-08-02 22:52:50 +00:00
NPF_FLAG_IGNORE_RESERVED , ///< Used to mark that reserved tiles should be considered impassable
2007-03-07 12:11:48 +00:00
} ;
2005-01-31 11:23:10 +00:00
2007-03-21 03:06:21 +00:00
/* Meant to be stored in AyStar.userpath */
struct NPFFoundTargetData {
uint best_bird_dist ; ///< The best heuristic found. Is 0 if the target was found
2008-10-14 18:38:51 +00:00
uint best_path_dist ; ///< The shortest path. Is UINT_MAX if no path is found
2007-03-21 03:06:21 +00:00
Trackdir best_trackdir ; ///< The trackdir that leads to the shortest path/closest birds dist
AyStarNode node ; ///< The node within the target the search led us to
2008-08-02 22:52:22 +00:00
bool res_okay ; ///< True if a path reservation could be made
2007-03-07 12:11:48 +00:00
} ;
2005-01-31 11:23:10 +00:00
/* These functions below are _not_ re-entrant, in favor of speed! */
/* Will search from the given tile and direction, for a route to the given
* station for the given transport type . See the declaration of
* NPFFoundTargetData above for the meaning of the result . */
2008-02-08 16:25:55 +00:00
NPFFoundTargetData NPFRouteToStationOrTile ( TileIndex tile , Trackdir trackdir , bool ignore_start_tile , NPFFindStationOrTileData * target , TransportType type , uint sub_type , Owner owner , RailTypes railtypes ) ;
2006-02-01 06:32:03 +00:00
2005-01-31 11:23:10 +00:00
/* Will search as above, but with two start nodes, the second being the
2005-03-08 19:54:10 +00:00
* reverse . Look at the NPF_FLAG_REVERSE flag in the result node to see which
* direction was taken ( NPFGetBit ( result . node , NPF_FLAG_REVERSE ) ) */
2008-02-08 16:25:55 +00:00
NPFFoundTargetData NPFRouteToStationOrTileTwoWay ( TileIndex tile1 , Trackdir trackdir1 , bool ignore_start_tile1 , TileIndex tile2 , Trackdir trackdir2 , bool ignore_start_tile2 , NPFFindStationOrTileData * target , TransportType type , uint sub_type , Owner owner , RailTypes railtypes ) ;
2005-01-31 11:23:10 +00:00
/* Will search a route to the closest depot. */
/* Search using breadth first. Good for little track choice and inaccurate
2005-05-07 22:00:36 +00:00
* heuristic , such as railway / road . */
2008-02-08 16:25:55 +00:00
NPFFoundTargetData NPFRouteToDepotBreadthFirst ( TileIndex tile , Trackdir trackdir , bool ignore_start_tile , TransportType type , uint sub_type , Owner owner , RailTypes railtypes ) ;
2005-05-07 22:00:36 +00:00
/* Same as above but with two start nodes, the second being the reverse. Call
* NPFGetBit ( result . node , NPF_FLAG_REVERSE ) to see from which node the path
* orginated . All pathfs from the second node will have the given
* reverse_penalty applied ( NPF_TILE_LENGTH is the equivalent of one full
* tile ) .
*/
2008-02-08 16:25:55 +00:00
NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay ( TileIndex tile1 , Trackdir trackdir1 , bool ignore_start_tile1 , TileIndex tile2 , Trackdir trackdir2 , bool ignore_start_tile2 , TransportType type , uint sub_type , Owner owner , RailTypes railtypes , uint reverse_penalty ) ;
2005-01-31 11:23:10 +00:00
/* Search by trying each depot in order of Manhattan Distance. Good for lots
2005-02-06 22:36:08 +00:00
* of choices and accurate heuristics , such as water . */
2008-02-08 16:25:55 +00:00
NPFFoundTargetData NPFRouteToDepotTrialError ( TileIndex tile , Trackdir trackdir , bool ignore_start_tile , TransportType type , uint sub_type , Owner owner , RailTypes railtypes ) ;
2005-01-31 11:23:10 +00:00
2008-08-02 22:52:50 +00:00
/**
* Search for any safe tile using a breadth first search and try to reserve a path .
*/
NPFFoundTargetData NPFRouteToSafeTile ( const Vehicle * v , TileIndex tile , Trackdir trackdir , bool override_railtype ) ;
2008-08-02 22:52:22 +00:00
void NPFFillWithOrderData ( NPFFindStationOrTileData * fstd , Vehicle * v , bool reserve_path = false ) ;
2005-01-31 11:23:10 +00:00
2005-03-08 19:54:10 +00:00
/*
* Functions to manipulate the various NPF related flags on an AyStarNode .
*/
/**
* Returns the current value of the given flag on the given AyStarNode .
*/
static inline bool NPFGetFlag ( const AyStarNode * node , NPFNodeFlag flag )
{
2007-11-19 21:02:30 +00:00
return HasBit ( node - > user_data [ NPF_NODE_FLAGS ] , flag ) ;
2005-03-08 19:54:10 +00:00
}
/**
* Sets the given flag on the given AyStarNode to the given value .
*/
static inline void NPFSetFlag ( AyStarNode * node , NPFNodeFlag flag , bool value )
{
if ( value )
2007-11-20 13:35:54 +00:00
SetBit ( node - > user_data [ NPF_NODE_FLAGS ] , flag ) ;
2005-03-08 19:54:10 +00:00
else
2007-11-19 21:32:20 +00:00
ClrBit ( node - > user_data [ NPF_NODE_FLAGS ] , flag ) ;
2005-03-08 19:54:10 +00:00
}
2005-09-18 20:56:44 +00:00
# endif /* NPF_H */