summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeterN <peter@fuzzle.org>2018-06-14 09:25:39 +0100
committerGitHub <noreply@github.com>2018-06-14 09:25:39 +0100
commitc2a77280842b5d752ef6c744adab20d9d1b67857 (patch)
tree1598d70926196cdaf99b64396a8624c1774411dc
parent7ae1e3e1e2a23b5cbd09bc88f9abd7ccdde23201 (diff)
downloadopenttd-c2a77280842b5d752ef6c744adab20d9d1b67857.tar.xz
Fix: Prevent ships moving into docks after finishing (un)loading. (#6791)
-rw-r--r--src/ship_cmd.cpp4
-rw-r--r--src/track_func.h21
-rw-r--r--src/train_cmd.cpp33
3 files changed, 31 insertions, 27 deletions
diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp
index 967cd4e1d..0bdcf7041 100644
--- a/src/ship_cmd.cpp
+++ b/src/ship_cmd.cpp
@@ -537,6 +537,10 @@ static void ShipController(Ship *v)
if (v->current_order.IsType(OT_LEAVESTATION)) {
v->current_order.Free();
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP);
+ /* Test if continuing forward would lead to a dead-end, moving into the dock. */
+ DiagDirection exitdir = VehicleExitDir(v->direction, v->state);
+ TileIndex tile = TileAddByDiagDir(v->tile, exitdir);
+ if (TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0, exitdir)) == TRACK_BIT_NONE) goto reverse_direction;
} else if (v->dest_tile != 0) {
/* We have a target, let's see if we reached it... */
if (v->current_order.IsType(OT_GOTO_WAYPOINT) &&
diff --git a/src/track_func.h b/src/track_func.h
index 68de827ef..5e1585c08 100644
--- a/src/track_func.h
+++ b/src/track_func.h
@@ -692,4 +692,25 @@ static inline bool IsUphillTrackdir(Slope slope, Trackdir dir)
return HasBit(_uphill_trackdirs[RemoveHalftileSlope(slope)], dir);
}
+/**
+ * Determine the side in which the vehicle will leave the tile
+ *
+ * @param direction vehicle direction
+ * @param track vehicle track bits
+ * @return side of tile the vehicle will leave
+ */
+static inline DiagDirection VehicleExitDir(Direction direction, TrackBits track)
+{
+ static const TrackBits state_dir_table[DIAGDIR_END] = { TRACK_BIT_RIGHT, TRACK_BIT_LOWER, TRACK_BIT_LEFT, TRACK_BIT_UPPER };
+
+ DiagDirection diagdir = DirToDiagDir(direction);
+
+ /* Determine the diagonal direction in which we will exit this tile */
+ if (!HasBit(direction, 0) && track != state_dir_table[diagdir]) {
+ diagdir = ChangeDiagDir(diagdir, DIAGDIRDIFF_90LEFT);
+ }
+
+ return diagdir;
+}
+
#endif /* TRACK_FUNC_H */
diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp
index 9f4ecbea6..daebb9789 100644
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -57,27 +57,6 @@ bool IsValidImageIndex<VEH_TRAIN>(uint8 image_index)
return image_index < lengthof(_engine_sprite_base);
}
-/**
- * Determine the side in which the train will leave the tile
- *
- * @param direction vehicle direction
- * @param track vehicle track bits
- * @return side of tile the train will leave
- */
-static inline DiagDirection TrainExitDir(Direction direction, TrackBits track)
-{
- static const TrackBits state_dir_table[DIAGDIR_END] = { TRACK_BIT_RIGHT, TRACK_BIT_LOWER, TRACK_BIT_LEFT, TRACK_BIT_UPPER };
-
- DiagDirection diagdir = DirToDiagDir(direction);
-
- /* Determine the diagonal direction in which we will exit this tile */
- if (!HasBit(direction, 0) && track != state_dir_table[diagdir]) {
- diagdir = ChangeDiagDir(diagdir, DIAGDIRDIFF_90LEFT);
- }
-
- return diagdir;
-}
-
/**
* Return the cargo weight multiplier to use for a rail vehicle
@@ -1872,9 +1851,9 @@ void ReverseTrainDirection(Train *v)
return;
}
- /* TrainExitDir does not always produce the desired dir for depots and
+ /* VehicleExitDir does not always produce the desired dir for depots and
* tunnels/bridges that is needed for UpdateSignalsOnSegment. */
- DiagDirection dir = TrainExitDir(v->direction, v->track);
+ DiagDirection dir = VehicleExitDir(v->direction, v->track);
if (IsRailDepotTile(v->tile) || IsTileType(v->tile, MP_TUNNELBRIDGE)) dir = INVALID_DIAGDIR;
if (UpdateSignalsOnSegment(v->tile, dir, v->owner) == SIGSEG_PBS || _settings_game.pf.reserve_paths) {
@@ -3098,7 +3077,7 @@ static Vehicle *CheckTrainAtSignal(Vehicle *v, void *data)
/* not front engine of a train, inside wormhole or depot, crashed */
if (!t->IsFrontEngine() || !(t->track & TRACK_BIT_MASK)) return NULL;
- if (t->cur_speed > 5 || TrainExitDir(t->direction, t->track) != exitdir) return NULL;
+ if (t->cur_speed > 5 || VehicleExitDir(t->direction, t->track) != exitdir) return NULL;
return t;
}
@@ -3681,7 +3660,7 @@ static TileIndex TrainApproachingCrossingTile(const Train *v)
if (!TrainCanLeaveTile(v)) return INVALID_TILE;
- DiagDirection dir = TrainExitDir(v->direction, v->track);
+ DiagDirection dir = VehicleExitDir(v->direction, v->track);
TileIndex tile = v->tile + TileOffsByDiagDir(dir);
/* not a crossing || wrong axis || unusable rail (wrong type or owner) */
@@ -3718,7 +3697,7 @@ static bool TrainCheckIfLineEnds(Train *v, bool reverse)
if (!TrainCanLeaveTile(v)) return true;
/* Determine the non-diagonal direction in which we will exit this tile */
- DiagDirection dir = TrainExitDir(v->direction, v->track);
+ DiagDirection dir = VehicleExitDir(v->direction, v->track);
/* Calculate next tile */
TileIndex tile = v->tile + TileOffsByDiagDir(dir);
@@ -3786,7 +3765,7 @@ static bool TrainLocoHandler(Train *v, bool mode)
/* Try to reserve a path when leaving the station as we
* might not be marked as wanting a reservation, e.g.
* when an overlength train gets turned around in a station. */
- DiagDirection dir = TrainExitDir(v->direction, v->track);
+ DiagDirection dir = VehicleExitDir(v->direction, v->track);
if (IsRailDepotTile(v->tile) || IsTileType(v->tile, MP_TUNNELBRIDGE)) dir = INVALID_DIAGDIR;
if (UpdateSignalsOnSegment(v->tile, dir, v->owner) == SIGSEG_PBS || _settings_game.pf.reserve_paths) {