summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatric Stout <truebrain@openttd.org>2021-02-25 22:46:46 +0100
committerGitHub <noreply@github.com>2021-02-25 22:46:46 +0100
commitd4583fa64c067c00d3a7592642b3c269d02a8bef (patch)
tree942865605eb6ae2385ce5e4b5d7a010064586dbb
parent9209807d662a619ee8c3edcae0d5b5fcf6db6d1d (diff)
downloadopenttd-d4583fa64c067c00d3a7592642b3c269d02a8bef.tar.xz
Fix #8123: trams on half-tiles couldn't find depots (#8738)
Basically, follow_track.hpp contains a fix for half-tiles, but this wasn't duplicated for when trying to find a depot and in a few other places. This makes sure all places act the same.
-rw-r--r--src/pathfinder/follow_track.hpp23
-rw-r--r--src/pathfinder/pathfinder_func.h37
-rw-r--r--src/pathfinder/yapf/yapf_road.cpp7
3 files changed, 45 insertions, 22 deletions
diff --git a/src/pathfinder/follow_track.hpp b/src/pathfinder/follow_track.hpp
index cac8ec5c5..9b95578fd 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 @@ protected:
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 03edf6995..f11b8088a 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,40 @@ static inline TileIndex CalcClosestStationTile(StationID station, TileIndex tile
return TileXY(x, y);
}
+/**
+ * Wrapper around GetTileTrackStatus() and TrackStatusToTrackdirBits(), as for
+ * single tram bits GetTileTrackStatus() returns 0. The reason for this is
+ * that there are no half-tile TrackBits in OpenTTD.
+ * This tile, however, is a valid tile for trams, one on which they can
+ * reverse safely. To "fix" this, pretend that if we are on a half-tile, we
+ * are in fact on a straight tram track tile. CFollowTrackT will make sure
+ * the pathfinders cannot exit on the wrong side and allows reversing on such
+ * tiles.
+ */
+static inline TrackdirBits GetTrackdirBitsForRoad(TileIndex tile, RoadTramType rtt)
+{
+ TrackdirBits bits = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, rtt));
+
+ 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 0122e1d88..6e4861c55 100644
--- a/src/pathfinder/yapf/yapf_road.cpp
+++ b/src/pathfinder/yapf/yapf_road.cpp
@@ -370,7 +370,7 @@ public:
/* 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 @@ public:
/* 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();
}