Merge branch 'master' into jgrpp
Remove the viewport sign cache as this is now superseded by the kd tree implementation # Conflicts: # src/crashlog.cpp # src/lang/english.txt # src/misc.cpp # src/pathfinder/follow_track.hpp # src/pbs.cpp # src/rail_cmd.cpp # src/saveload/vehicle_sl.cpp # src/settings.cpp # src/settings_gui.cpp # src/ship_cmd.cpp # src/station.cpp # src/station_base.h # src/station_cmd.cpp # src/table/settings.ini # src/thread/thread_morphos.cpp # src/town_cmd.cpp # src/train_cmd.cpp # src/viewport.cpp # src/waypoint.cpp
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include "../../track_type.h"
|
||||
#include "../../vehicle_type.h"
|
||||
#include "../../ship.h"
|
||||
#include "../../roadveh.h"
|
||||
#include "../pathfinder_type.h"
|
||||
|
||||
/**
|
||||
@@ -45,7 +46,7 @@ bool YapfShipCheckReverse(const Ship *v);
|
||||
* @param path_found [out] Whether a path has been found (true) or has been guessed (false)
|
||||
* @return the best trackdir for next turn or INVALID_TRACKDIR if the path could not be found
|
||||
*/
|
||||
Trackdir YapfRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool &path_found);
|
||||
Trackdir YapfRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool &path_found, RoadVehPathCache &path_cache);
|
||||
|
||||
/**
|
||||
* Finds the best path for given train using YAPF.
|
||||
|
@@ -67,6 +67,7 @@ struct CYapfNodeT {
|
||||
Node *m_parent;
|
||||
int m_cost;
|
||||
int m_estimate;
|
||||
bool m_is_choice;
|
||||
|
||||
inline void Set(Node *parent, TileIndex tile, Trackdir td, bool is_choice)
|
||||
{
|
||||
@@ -75,6 +76,7 @@ struct CYapfNodeT {
|
||||
m_parent = parent;
|
||||
m_cost = 0;
|
||||
m_estimate = 0;
|
||||
m_is_choice = is_choice;
|
||||
}
|
||||
|
||||
inline Node *GetHashNext()
|
||||
@@ -112,6 +114,11 @@ struct CYapfNodeT {
|
||||
return m_estimate;
|
||||
}
|
||||
|
||||
inline bool GetIsChoice() const
|
||||
{
|
||||
return m_is_choice;
|
||||
}
|
||||
|
||||
inline bool operator<(const Node &other) const
|
||||
{
|
||||
return m_estimate < other.m_estimate;
|
||||
|
@@ -360,13 +360,13 @@ public:
|
||||
return 'r';
|
||||
}
|
||||
|
||||
static Trackdir stChooseRoadTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, bool &path_found)
|
||||
static Trackdir stChooseRoadTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, bool &path_found, RoadVehPathCache &path_cache)
|
||||
{
|
||||
Tpf pf;
|
||||
return pf.ChooseRoadTrack(v, tile, enterdir, path_found);
|
||||
return pf.ChooseRoadTrack(v, tile, enterdir, path_found, path_cache);
|
||||
}
|
||||
|
||||
inline Trackdir ChooseRoadTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, bool &path_found)
|
||||
inline Trackdir ChooseRoadTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, bool &path_found, RoadVehPathCache &path_cache)
|
||||
{
|
||||
/* Handle special case - when next tile is destination tile.
|
||||
* However, when going to a station the (initial) destination
|
||||
@@ -394,15 +394,30 @@ public:
|
||||
Trackdir next_trackdir = INVALID_TRACKDIR;
|
||||
Node *pNode = Yapf().GetBestNode();
|
||||
if (pNode != NULL) {
|
||||
uint steps = 0;
|
||||
for (Node *n = pNode; n->m_parent != NULL; n = n->m_parent) steps++;
|
||||
|
||||
/* path was found or at least suggested
|
||||
* walk through the path back to its origin */
|
||||
while (pNode->m_parent != NULL) {
|
||||
steps--;
|
||||
if (pNode->GetIsChoice() && steps < YAPF_ROADVEH_PATH_CACHE_SEGMENTS) {
|
||||
TrackdirByte td;
|
||||
td = pNode->GetTrackdir();
|
||||
path_cache.td.push_front(td);
|
||||
path_cache.tile.push_front(pNode->GetTile());
|
||||
}
|
||||
pNode = pNode->m_parent;
|
||||
}
|
||||
/* return trackdir from the best origin node (one of start nodes) */
|
||||
Node &best_next_node = *pNode;
|
||||
assert(best_next_node.GetTile() == tile);
|
||||
next_trackdir = best_next_node.GetTrackdir();
|
||||
/* remove last element for the special case when tile == dest_tile */
|
||||
if (path_found && !path_cache.empty() && tile == v->dest_tile) {
|
||||
path_cache.td.pop_back();
|
||||
path_cache.tile.pop_back();
|
||||
}
|
||||
}
|
||||
return next_trackdir;
|
||||
}
|
||||
@@ -509,18 +524,18 @@ struct CYapfRoadAnyDepot1 : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyDepot1, CRoadNod
|
||||
struct CYapfRoadAnyDepot2 : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyDepot2, CRoadNodeListExitDir , CYapfDestinationAnyDepotRoadT> > {};
|
||||
|
||||
|
||||
Trackdir YapfRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool &path_found)
|
||||
Trackdir YapfRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool &path_found, RoadVehPathCache &path_cache)
|
||||
{
|
||||
/* default is YAPF type 2 */
|
||||
typedef Trackdir (*PfnChooseRoadTrack)(const RoadVehicle*, TileIndex, DiagDirection, bool &path_found);
|
||||
PfnChooseRoadTrack pfnChooseRoadTrack = &CYapfRoad2::stChooseRoadTrack; // default: ExitDir
|
||||
typedef Trackdir (*PfnChooseRoadTrack)(const RoadVehicle*, TileIndex, DiagDirection, bool &path_found, RoadVehPathCache &path_cache);
|
||||
PfnChooseRoadTrack pfnChooseRoadTrack = &CYapfRoad2::stChooseRoadTrack; // default: ExitDir, allow 90-deg
|
||||
|
||||
/* check if non-default YAPF type should be used */
|
||||
if (_settings_game.pf.yapf.disable_node_optimization) {
|
||||
pfnChooseRoadTrack = &CYapfRoad1::stChooseRoadTrack; // Trackdir
|
||||
}
|
||||
|
||||
Trackdir td_ret = pfnChooseRoadTrack(v, tile, enterdir, path_found);
|
||||
Trackdir td_ret = pfnChooseRoadTrack(v, tile, enterdir, path_found, path_cache);
|
||||
return (td_ret != INVALID_TRACKDIR) ? td_ret : (Trackdir)FindFirstBit2x64(trackdirs);
|
||||
}
|
||||
|
||||
|
@@ -94,7 +94,8 @@ public:
|
||||
/* walk through the path back to the origin */
|
||||
Node *pPrevNode = NULL;
|
||||
while (pNode->m_parent != NULL) {
|
||||
if (steps > 1 && --steps < YAPF_SHIP_PATH_CACHE_LENGTH) {
|
||||
steps--;
|
||||
if (steps > 0 && steps < YAPF_SHIP_PATH_CACHE_LENGTH) {
|
||||
TrackdirByte td;
|
||||
td = pNode->GetTrackdir();
|
||||
path_cache.push_front(td);
|
||||
@@ -164,6 +165,21 @@ protected:
|
||||
}
|
||||
|
||||
public:
|
||||
inline int CurveCost(Trackdir td1, Trackdir td2)
|
||||
{
|
||||
assert(IsValidTrackdir(td1));
|
||||
assert(IsValidTrackdir(td2));
|
||||
|
||||
if (HasTrackdir(TrackdirCrossesTrackdirs(td1), td2)) {
|
||||
/* 90-deg curve penalty */
|
||||
return Yapf().PfGetSettings().ship_curve90_penalty;
|
||||
} else if (td2 != NextTrackdir(td1)) {
|
||||
/* 45-deg curve penalty */
|
||||
return Yapf().PfGetSettings().ship_curve45_penalty;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by YAPF to calculate the cost from the origin to the given node.
|
||||
* Calculates only the cost of given node, adds it to the parent node cost
|
||||
@@ -174,10 +190,7 @@ public:
|
||||
/* base tile cost depending on distance */
|
||||
int c = IsDiagonalTrackdir(n.GetTrackdir()) ? YAPF_TILE_LENGTH : YAPF_TILE_CORNER_LENGTH;
|
||||
/* additional penalty for curves */
|
||||
if (n.GetTrackdir() != NextTrackdir(n.m_parent->GetTrackdir())) {
|
||||
/* new trackdir does not match the next one when going straight */
|
||||
c += YAPF_TILE_LENGTH;
|
||||
}
|
||||
c += CurveCost(n.m_parent->GetTrackdir(), n.GetTrackdir());
|
||||
|
||||
/* Skipped tile cost for aqueducts. */
|
||||
c += YAPF_TILE_LENGTH * tf->m_tiles_skipped;
|
||||
@@ -298,6 +311,16 @@ struct CYapfShip1 : CYapfT<CYapfShip_TypesT<CYapfShip1, CFollowTrackWater , C
|
||||
/* YAPF type 2 - uses TileIndex/DiagDirection as Node key */
|
||||
struct CYapfShip2 : CYapfT<CYapfShip_TypesT<CYapfShip2, CFollowTrackWater , CShipNodeListExitDir > > {};
|
||||
|
||||
static inline bool RequireTrackdirKey()
|
||||
{
|
||||
/* If the two curve penalties are not equal, then it is not possible to use the
|
||||
* ExitDir keyed node list, as it there will be key overlap. Using Trackdir keyed
|
||||
* nodes means potentially more paths are tested, which would be wasteful if it's
|
||||
* not necessary.
|
||||
*/
|
||||
return _settings_game.pf.yapf.ship_curve45_penalty != _settings_game.pf.yapf.ship_curve90_penalty;
|
||||
}
|
||||
|
||||
/** Ship controller helper - path finder invoker */
|
||||
Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, ShipPathCache &path_cache)
|
||||
{
|
||||
@@ -306,7 +329,7 @@ Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir,
|
||||
PfnChooseShipTrack pfnChooseShipTrack = CYapfShip2::ChooseShipTrack; // default: ExitDir
|
||||
|
||||
/* check if non-default YAPF type needed */
|
||||
if (_settings_game.pf.yapf.disable_node_optimization) {
|
||||
if (_settings_game.pf.yapf.disable_node_optimization || RequireTrackdirKey()) {
|
||||
pfnChooseShipTrack = &CYapfShip1::ChooseShipTrack; // Trackdir
|
||||
}
|
||||
|
||||
@@ -324,7 +347,7 @@ bool YapfShipCheckReverse(const Ship *v)
|
||||
PfnCheckReverseShip pfnCheckReverseShip = CYapfShip2::CheckShipReverse; // default: ExitDir
|
||||
|
||||
/* check if non-default YAPF type needed */
|
||||
if (_settings_game.pf.yapf.disable_node_optimization) {
|
||||
if (_settings_game.pf.yapf.disable_node_optimization || RequireTrackdirKey()) {
|
||||
pfnCheckReverseShip = &CYapfShip1::CheckShipReverse; // Trackdir
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user