diff --git a/src/pathfinder/follow_track.hpp b/src/pathfinder/follow_track.hpp index cac8ec5c5a1e..9b95578fd557 100644 --- a/src/pathfinder/follow_track.hpp +++ b/src/pathfinder/follow_track.hpp @@ -17,6 +17,7 @@ #include "../tunnelbridge.h" #include "../tunnelbridge_map.h" #include "../depot_map.h" +#include "pathfinder_func.h" #include "pf_performance_timer.hpp" /** @@ -239,26 +240,10 @@ struct CFollowTrackT CPerfStart perf(*m_pPerf); if (IsRailTT() && IsPlainRailTile(m_new_tile)) { m_new_td_bits = (TrackdirBits)(GetTrackBits(m_new_tile) * 0x101); + } else if (IsRoadTT()) { + m_new_td_bits = GetTrackdirBitsForRoad(m_new_tile, this->IsTram() ? RTT_TRAM : RTT_ROAD); } else { - m_new_td_bits = TrackStatusToTrackdirBits(GetTileTrackStatus(m_new_tile, TT(), IsRoadTT() ? (this->IsTram() ? RTT_TRAM : RTT_ROAD) : 0)); - - if (IsTram() && m_new_td_bits == TRACKDIR_BIT_NONE) { - /* 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; - } - } + m_new_td_bits = TrackStatusToTrackdirBits(GetTileTrackStatus(m_new_tile, TT(), 0)); } return (m_new_td_bits != TRACKDIR_BIT_NONE); } diff --git a/src/pathfinder/pathfinder_func.h b/src/pathfinder/pathfinder_func.h index 03edf6995b6a..9490305a02d3 100644 --- a/src/pathfinder/pathfinder_func.h +++ b/src/pathfinder/pathfinder_func.h @@ -10,6 +10,7 @@ #ifndef PATHFINDER_FUNC_H #define PATHFINDER_FUNC_H +#include "../tile_cmd.h" #include "../waypoint_base.h" /** @@ -46,4 +47,34 @@ static inline TileIndex CalcClosestStationTile(StationID station, TileIndex tile return TileXY(x, y); } +static inline TrackdirBits GetTrackdirBitsForRoad(TileIndex tile, RoadTramType rtt) +{ + TrackdirBits bits = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, rtt)); + + /* GetTileTrackStatus() returns 0 for single tram bits. But this is a valid + * tile to be on. So pretend that the tile is a straight tile, and + * CFollowTrackT will make sure it cannot be exited on the wrong side, and + * allow reversing on it. */ + if (rtt == RTT_TRAM && bits == TRACKDIR_BIT_NONE) { + if (IsNormalRoadTile(tile)) { + RoadBits rb = GetRoadBits(tile, RTT_TRAM); + switch (rb) { + case ROAD_NE: + case ROAD_SW: + bits = TRACKDIR_BIT_X_NE | TRACKDIR_BIT_X_SW; + break; + + case ROAD_NW: + case ROAD_SE: + bits = TRACKDIR_BIT_Y_NW | TRACKDIR_BIT_Y_SE; + break; + + default: break; + } + } + } + + return bits; +} + #endif /* PATHFINDER_FUNC_H */ diff --git a/src/pathfinder/yapf/yapf_road.cpp b/src/pathfinder/yapf/yapf_road.cpp index 0122e1d88b5b..6e4861c55f5d 100644 --- a/src/pathfinder/yapf/yapf_road.cpp +++ b/src/pathfinder/yapf/yapf_road.cpp @@ -370,7 +370,7 @@ class CYapfFollowRoadT /* our source tile will be the next vehicle tile (should be the given one) */ TileIndex src_tile = tile; /* get available trackdirs on the start tile */ - TrackdirBits src_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, GetRoadTramType(v->roadtype))); + TrackdirBits src_trackdirs = GetTrackdirBitsForRoad(tile, GetRoadTramType(v->roadtype)); /* select reachable trackdirs only */ src_trackdirs &= DiagdirReachesTrackdirs(enterdir); @@ -468,7 +468,7 @@ class CYapfFollowRoadT /* set origin (tile, trackdir) */ TileIndex src_tile = v->tile; Trackdir src_td = v->GetVehicleTrackdir(); - if (!HasTrackdir(TrackStatusToTrackdirBits(GetTileTrackStatus(src_tile, TRANSPORT_ROAD, this->IsTram() ? RTT_TRAM : RTT_ROAD)), src_td)) { + if (!HasTrackdir(GetTrackdirBitsForRoad(src_tile, this->IsTram() ? RTT_TRAM : RTT_ROAD), src_td)) { /* sometimes the roadveh is not on the road (it resides on non-existing track) * how should we handle that situation? */ return false; @@ -548,7 +548,8 @@ FindDepotData YapfRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_dist { TileIndex tile = v->tile; Trackdir trackdir = v->GetVehicleTrackdir(); - if (!HasTrackdir(TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, GetRoadTramType(v->roadtype))), trackdir)) { + + if (!HasTrackdir(GetTrackdirBitsForRoad(tile, GetRoadTramType(v->roadtype)), trackdir)) { return FindDepotData(); }