summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/pbs.cpp18
-rw-r--r--src/pbs.h2
-rw-r--r--src/train_cmd.cpp4
3 files changed, 19 insertions, 5 deletions
diff --git a/src/pbs.cpp b/src/pbs.cpp
index adae29e5b..9619b201b 100644
--- a/src/pbs.cpp
+++ b/src/pbs.cpp
@@ -262,7 +262,7 @@ static Vehicle *FindTrainOnTrackEnum(Vehicle *v, void *data)
* @param train_on_res Is set to a train we might encounter
* @returns The last tile of the reservation or the current train tile if no reservation present.
*/
-PBSTileInfo FollowTrainReservation(const Train *v, bool *train_on_res)
+PBSTileInfo FollowTrainReservation(const Train *v, Vehicle **train_on_res)
{
assert(v->type == VEH_TRAIN);
@@ -274,7 +274,21 @@ PBSTileInfo FollowTrainReservation(const Train *v, bool *train_on_res)
FindTrainOnTrackInfo ftoti;
ftoti.res = FollowReservation(v->owner, GetRailTypeInfo(v->railtype)->compatible_railtypes, tile, trackdir);
ftoti.res.okay = IsSafeWaitingPosition(v, ftoti.res.tile, ftoti.res.trackdir, true, _settings_game.pf.forbid_90_deg);
- if (train_on_res != NULL) *train_on_res = HasVehicleOnPos(ftoti.res.tile, &ftoti, FindTrainOnTrackEnum);
+ if (train_on_res != NULL) {
+ FindVehicleOnPos(ftoti.res.tile, &ftoti, FindTrainOnTrackEnum);
+ if (ftoti.best != NULL) *train_on_res = ftoti.best->First();
+ if (*train_on_res == NULL && IsRailStationTile(ftoti.res.tile)) {
+ /* The target tile is a rail station. The track follower
+ * has stopped on the last platform tile where we haven't
+ * found a train. Also check all previous platform tiles
+ * for a possible train. */
+ TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(ReverseTrackdir(ftoti.res.trackdir)));
+ for (TileIndex st_tile = ftoti.res.tile + diff; *train_on_res == NULL && IsCompatibleTrainStationTile(st_tile, ftoti.res.tile); st_tile += diff) {
+ FindVehicleOnPos(st_tile, &ftoti, FindTrainOnTrackEnum);
+ if (ftoti.best != NULL) *train_on_res = ftoti.best->First();
+ }
+ }
+ }
return ftoti.res;
}
diff --git a/src/pbs.h b/src/pbs.h
index f1248364a..ec24477af 100644
--- a/src/pbs.h
+++ b/src/pbs.h
@@ -34,7 +34,7 @@ struct PBSTileInfo {
PBSTileInfo(TileIndex _t, Trackdir _td, bool _okay) : tile(_t), trackdir(_td), okay(_okay) {}
};
-PBSTileInfo FollowTrainReservation(const Train *v, bool *train_on_res = NULL);
+PBSTileInfo FollowTrainReservation(const Train *v, Vehicle **train_on_res = NULL);
bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bool include_line_end, bool forbid_90deg = false);
bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bool forbid_90deg = false);
diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp
index 5fbd2278f..d2c64bc0a 100644
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -2872,14 +2872,14 @@ bool TryPathReserve(Train *v, bool mark_as_stuck, bool first_tile_okay)
}
}
- bool other_train = false;
+ Vehicle *other_train = NULL;
PBSTileInfo origin = FollowTrainReservation(v, &other_train);
/* The path we are driving on is alread blocked by some other train.
* This can only happen in certain situations when mixing path and
* block signals or when changing tracks and/or signals.
* Exit here as doing any further reservations will probably just
* make matters worse. */
- if (other_train && v->tile != origin.tile) {
+ if (other_train != NULL && other_train->index != v->index) {
if (mark_as_stuck) MarkTrainAsStuck(v);
return false;
}