mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r17516) [0.7] -Backport from trunk:
- Fix: Road vehicles could get lost when the prelimiary destination (for the pathfinder heuristics) is unreachable [FS#3188] (r17491) - Fix: Silence compile warning that is only triggered when you are using a broken iconv (r17479) - Fix: In some cases compilation failed because the search path for ICU was not added to the ldflags (r17476, r17474) - Document: Compiler warning when compiled without asserts in GCC 4.4+ is not our fault but a GCC bug. Includes a reference to the appropriate GCC bug report (r17461)
This commit is contained in:
parent
58ebb4c65c
commit
6e14331cda
|
@ -1301,7 +1301,8 @@ make_cflags_and_ldflags() {
|
||||||
CFLAGS="$CFLAGS -DWITH_ICU"
|
CFLAGS="$CFLAGS -DWITH_ICU"
|
||||||
CFLAGS="$CFLAGS `$icu_config --cppflags | tr '\n\r' ' '`"
|
CFLAGS="$CFLAGS `$icu_config --cppflags | tr '\n\r' ' '`"
|
||||||
|
|
||||||
LIBS="$LIBS `$icu_config --ldflags-libsonly | tr '\n\r' ' '`"
|
# Some icu-configs have the 'feature' of not adding a space where others do add the space
|
||||||
|
LIBS="$LIBS `$icu_config --ldflags-searchpath` `$icu_config --ldflags-libsonly | tr '\n\r' ' '`"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
@ -2296,9 +2297,9 @@ detect_icu() {
|
||||||
log 2 " returned $version"
|
log 2 " returned $version"
|
||||||
log 2 " exit code $ret"
|
log 2 " exit code $ret"
|
||||||
|
|
||||||
if [ -z "$version" ] || [ "$ret" != "0" ] || [ "$shortversion" -lt "20" ]; then
|
if [ -z "$version" ] || [ "$ret" != "0" ] || [ "$shortversion" -lt "22" ]; then
|
||||||
if [ -n "$shortversion" ] && [ "$shortversion" -lt "20" ]; then
|
if [ -n "$shortversion" ] && [ "$shortversion" -lt "22" ]; then
|
||||||
log 1 "checking libicu... needs at least version 2.0.0, icu NOT enabled"
|
log 1 "checking libicu... needs at least version 2.2.0, icu NOT enabled"
|
||||||
else
|
else
|
||||||
log 1 "checking libicu... not found"
|
log 1 "checking libicu... not found"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -297,6 +297,7 @@ public:
|
||||||
/** all deallocations should happen here */
|
/** all deallocations should happen here */
|
||||||
static FORCEINLINE void RawFree(CHdr *p)
|
static FORCEINLINE void RawFree(CHdr *p)
|
||||||
{
|
{
|
||||||
|
/* In case GCC warns about the following, see GCC's PR38509 why it is bogus. */
|
||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
/** fixing the four bytes at the end of blob data - useful when blob is used to hold string */
|
/** fixing the four bytes at the end of blob data - useful when blob is used to hold string */
|
||||||
|
|
|
@ -675,22 +675,8 @@ TileIndex RoadVehicle::GetOrderStationLocation(StationID station)
|
||||||
{
|
{
|
||||||
if (station == this->last_station_visited) this->last_station_visited = INVALID_STATION;
|
if (station == this->last_station_visited) this->last_station_visited = INVALID_STATION;
|
||||||
|
|
||||||
TileIndex dest = INVALID_TILE;
|
TileIndex dest;
|
||||||
const RoadStop *rs = GetStation(station)->GetPrimaryRoadStop(this);
|
if (YapfFindNearestRoadVehicleCompatibleStop(this, station, &dest)) {
|
||||||
if (rs != NULL) {
|
|
||||||
uint mindist = UINT_MAX;
|
|
||||||
|
|
||||||
for (; rs != NULL; rs = rs->GetNextRoadStop(this)) {
|
|
||||||
uint dist = DistanceManhattan(this->tile, rs->xy);
|
|
||||||
|
|
||||||
if (dist < mindist) {
|
|
||||||
mindist = dist;
|
|
||||||
dest = rs->xy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dest != INVALID_TILE) {
|
|
||||||
return dest;
|
return dest;
|
||||||
} else {
|
} else {
|
||||||
/* There is no stop left at the station, so don't even TRY to go there */
|
/* There is no stop left at the station, so don't even TRY to go there */
|
||||||
|
|
11
src/unix.cpp
11
src/unix.cpp
|
@ -133,11 +133,10 @@ static const char *GetLocalCode()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** FYI: This is not thread-safe.
|
/**
|
||||||
* convert between locales, which from and which to is set in the calling
|
* Convert between locales, which from and which to is set in the calling
|
||||||
* functions OTTD2FS() and FS2OTTD(). You should NOT use this function directly
|
* functions OTTD2FS() and FS2OTTD().
|
||||||
* NOTE: iconv was added in OSX 10.3. 10.2.x will still have the invalid char
|
*/
|
||||||
* issues. There aren't any easy fix for this */
|
|
||||||
static const char *convert_tofrom_fs(iconv_t convd, const char *name)
|
static const char *convert_tofrom_fs(iconv_t convd, const char *name)
|
||||||
{
|
{
|
||||||
static char buf[1024];
|
static char buf[1024];
|
||||||
|
@ -145,7 +144,7 @@ static const char *convert_tofrom_fs(iconv_t convd, const char *name)
|
||||||
* non-const. Correct implementation is at
|
* non-const. Correct implementation is at
|
||||||
* http://www.opengroup.org/onlinepubs/007908799/xsh/iconv.html */
|
* http://www.opengroup.org/onlinepubs/007908799/xsh/iconv.html */
|
||||||
#ifdef HAVE_BROKEN_ICONV
|
#ifdef HAVE_BROKEN_ICONV
|
||||||
char *inbuf = (char*)name;
|
char *inbuf = const_cast<char*>(name);
|
||||||
#else
|
#else
|
||||||
const char *inbuf = name;
|
const char *inbuf = name;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "../debug.h"
|
#include "../debug.h"
|
||||||
#include "../depot_type.h"
|
#include "../depot_type.h"
|
||||||
#include "../direction_type.h"
|
#include "../direction_type.h"
|
||||||
|
#include "../station_type.h"
|
||||||
#include "../pbs.h"
|
#include "../pbs.h"
|
||||||
|
|
||||||
/** Finds the best path for given ship.
|
/** Finds the best path for given ship.
|
||||||
|
@ -46,6 +47,14 @@ Trackdir YapfChooseRailTrack(const Vehicle *v, TileIndex tile, DiagDirection ent
|
||||||
*/
|
*/
|
||||||
uint YapfRoadVehDistanceToTile(const Vehicle *v, TileIndex tile);
|
uint YapfRoadVehDistanceToTile(const Vehicle *v, TileIndex tile);
|
||||||
|
|
||||||
|
/** Used to determinine the closest reachable compatible road stop for a given vehicle.
|
||||||
|
* @param v vehicle that needs to go to the road stop
|
||||||
|
* @param station the station the road stop must belong to
|
||||||
|
* @param stop_tile receives the stop tile if a stop was found
|
||||||
|
* @return true if stop was found.
|
||||||
|
*/
|
||||||
|
bool YapfFindNearestRoadVehicleCompatibleStop(const Vehicle *v, StationID station, TileIndex *stop_tile);
|
||||||
|
|
||||||
/** Used when user sends RV to the nearest depot or if RV needs servicing.
|
/** Used when user sends RV to the nearest depot or if RV needs servicing.
|
||||||
* Returns the nearest depot (or NULL if depot was not found).
|
* Returns the nearest depot (or NULL if depot was not found).
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -4,6 +4,10 @@
|
||||||
|
|
||||||
#include "../stdafx.h"
|
#include "../stdafx.h"
|
||||||
#include "../depot_base.h"
|
#include "../depot_base.h"
|
||||||
|
#include "../station_base.h"
|
||||||
|
#include "../roadveh.h"
|
||||||
|
#include "../cargotype.h"
|
||||||
|
#include "../newgrf_cargo.h"
|
||||||
|
|
||||||
#include "yapf.hpp"
|
#include "yapf.hpp"
|
||||||
#include "yapf_node_road.hpp"
|
#include "yapf_node_road.hpp"
|
||||||
|
@ -177,6 +181,78 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <class Types>
|
||||||
|
class CYapfDestinationAnyRoadVehicleCompatibleStopOfGivenStationT
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class)
|
||||||
|
typedef typename Types::TrackFollower TrackFollower;
|
||||||
|
typedef typename Types::NodeList::Titem Node; ///< this will be our node type
|
||||||
|
typedef typename Node::Key Key; ///< key to hash tables
|
||||||
|
|
||||||
|
TileIndex m_destTile;
|
||||||
|
StationID m_dest_station;
|
||||||
|
bool m_bus;
|
||||||
|
bool m_non_artic;
|
||||||
|
|
||||||
|
/** to access inherited path finder */
|
||||||
|
Tpf& Yapf()
|
||||||
|
{
|
||||||
|
return *static_cast<Tpf*>(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetDestination(const Vehicle *v, StationID sid, TileIndex destTile)
|
||||||
|
{
|
||||||
|
m_dest_station = sid;
|
||||||
|
m_destTile = destTile;
|
||||||
|
m_bus = IsCargoInClass(v->cargo_type, CC_PASSENGERS);
|
||||||
|
m_non_artic = !RoadVehHasArticPart(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called by YAPF to detect if node ends in the desired destination */
|
||||||
|
FORCEINLINE bool PfDetectDestination(Node& n)
|
||||||
|
{
|
||||||
|
return PfDetectDestinationTile(n.m_segment_last_tile, INVALID_TRACKDIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
IsTileType(tile, MP_STATION) &&
|
||||||
|
GetStationIndex(tile) == m_dest_station &&
|
||||||
|
(m_bus ? IsBusStop(tile) : IsTruckStop(tile)) &&
|
||||||
|
(m_non_artic || IsDriveThroughStopTile(tile));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 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 const int dg_dir_to_x_offs[] = {-1, 0, 1, 0};
|
||||||
|
static const int dg_dir_to_y_offs[] = {0, 1, 0, -1};
|
||||||
|
if (PfDetectDestination(n)) {
|
||||||
|
n.m_estimate = n.m_cost;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TileIndex tile = n.m_segment_last_tile;
|
||||||
|
DiagDirection exitdir = TrackdirToExitdir(n.m_segment_last_td);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template <class Types>
|
template <class Types>
|
||||||
class CYapfDestinationTileRoadT
|
class CYapfDestinationTileRoadT
|
||||||
{
|
{
|
||||||
|
@ -405,6 +481,30 @@ public:
|
||||||
Depot *ret = GetDepotByTile(depot_tile);
|
Depot *ret = GetDepotByTile(depot_tile);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool stFindNearestRoadVehicleCompatibleStop(const Vehicle *v, TileIndex tile, TileIndex destTile, Trackdir td, StationID sid, TileIndex *stop_tile)
|
||||||
|
{
|
||||||
|
Tpf pf;
|
||||||
|
return pf.FindNearestRoadVehicleCompatibleStop(v, tile, destTile, td, sid, stop_tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE bool FindNearestRoadVehicleCompatibleStop(const Vehicle *v, TileIndex tile, TileIndex destTile, Trackdir td, StationID sid, TileIndex *stop_tile)
|
||||||
|
{
|
||||||
|
/* set origin and destination nodes */
|
||||||
|
Yapf().SetOrigin(tile, TrackdirToTrackdirBits(td));
|
||||||
|
Yapf().SetDestination(v, sid, destTile);
|
||||||
|
|
||||||
|
/* find the best path */
|
||||||
|
bool bFound = Yapf().FindPath(v);
|
||||||
|
if (!bFound) return false;
|
||||||
|
|
||||||
|
/* some path found
|
||||||
|
* get found depot tile */
|
||||||
|
const Node *n = Yapf().GetBestNode();
|
||||||
|
|
||||||
|
*stop_tile = n->m_segment_last_tile;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Tpf_, class Tnode_list, template <class Types> class Tdestination>
|
template <class Tpf_, class Tnode_list, template <class Types> class Tdestination>
|
||||||
|
@ -429,6 +529,9 @@ struct CYapfRoad2 : CYapfT<CYapfRoad_TypesT<CYapfRoad2 , CRoadNod
|
||||||
struct CYapfRoadAnyDepot1 : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyDepot1, CRoadNodeListTrackDir, CYapfDestinationAnyDepotRoadT> > {};
|
struct CYapfRoadAnyDepot1 : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyDepot1, CRoadNodeListTrackDir, CYapfDestinationAnyDepotRoadT> > {};
|
||||||
struct CYapfRoadAnyDepot2 : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyDepot2, CRoadNodeListExitDir , CYapfDestinationAnyDepotRoadT> > {};
|
struct CYapfRoadAnyDepot2 : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyDepot2, CRoadNodeListExitDir , CYapfDestinationAnyDepotRoadT> > {};
|
||||||
|
|
||||||
|
struct CYapfRoadAnyRoadVehicleCompatibleStopOfGivenStation1 : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyRoadVehicleCompatibleStopOfGivenStation1, CRoadNodeListTrackDir, CYapfDestinationAnyRoadVehicleCompatibleStopOfGivenStationT> > {};
|
||||||
|
struct CYapfRoadAnyRoadVehicleCompatibleStopOfGivenStation2 : CYapfT<CYapfRoad_TypesT<CYapfRoadAnyRoadVehicleCompatibleStopOfGivenStation2, CRoadNodeListExitDir , CYapfDestinationAnyRoadVehicleCompatibleStopOfGivenStationT> > {};
|
||||||
|
|
||||||
|
|
||||||
Trackdir YapfChooseRoadTrack(const Vehicle *v, TileIndex tile, DiagDirection enterdir)
|
Trackdir YapfChooseRoadTrack(const Vehicle *v, TileIndex tile, DiagDirection enterdir)
|
||||||
{
|
{
|
||||||
|
@ -492,3 +595,29 @@ Depot *YapfFindNearestRoadDepot(const Vehicle *v)
|
||||||
Depot *ret = pfnFindNearestDepot(v, tile, trackdir);
|
Depot *ret = pfnFindNearestDepot(v, tile, trackdir);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool YapfFindNearestRoadVehicleCompatibleStop(const Vehicle *v, StationID station, TileIndex *stop_tile)
|
||||||
|
{
|
||||||
|
*stop_tile = INVALID_TILE;
|
||||||
|
|
||||||
|
const RoadStop *rs = GetStation(station)->GetPrimaryRoadStop(v);
|
||||||
|
if (rs == NULL) return false;
|
||||||
|
|
||||||
|
TileIndex tile = v->tile;
|
||||||
|
Trackdir trackdir = GetVehicleTrackdir(v);
|
||||||
|
if ((TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, v->u.road.compatible_roadtypes)) & TrackdirToTrackdirBits(trackdir)) == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* default is YAPF type 2 */
|
||||||
|
typedef bool (*PfnFindNearestRoadVehicleCompatibleStop)(const Vehicle*, TileIndex, TileIndex, Trackdir, StationID, TileIndex*);
|
||||||
|
PfnFindNearestRoadVehicleCompatibleStop pfnFindNearestRoadVehicleCompatibleStop = &CYapfRoadAnyRoadVehicleCompatibleStopOfGivenStation2::stFindNearestRoadVehicleCompatibleStop;
|
||||||
|
|
||||||
|
/* check if non-default YAPF type should be used */
|
||||||
|
if (_settings_game.pf.yapf.disable_node_optimization) {
|
||||||
|
pfnFindNearestRoadVehicleCompatibleStop = &CYapfRoadAnyRoadVehicleCompatibleStopOfGivenStation1::stFindNearestRoadVehicleCompatibleStop; // Trackdir, allow 90-deg
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ret = pfnFindNearestRoadVehicleCompatibleStop(v, tile, rs->xy, trackdir, station, stop_tile);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue