summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/saveload/afterload.cpp9
-rw-r--r--src/train_cmd.cpp35
-rw-r--r--src/vehicle_gui.cpp1
3 files changed, 43 insertions, 2 deletions
diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp
index beba40d2d..8116b6d17 100644
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -1967,6 +1967,15 @@ bool AfterLoadGame()
}
}
+ /* The behaviour of force_proceed has been changed. Now
+ * it counts signals instead of some random time out. */
+ if (CheckSavegameVersion(131)) {
+ Train *t;
+ FOR_ALL_TRAINS(t) {
+ t->force_proceed = min<byte>(t->force_proceed, 1);
+ }
+ }
+
/* Road stops is 'only' updating some caches */
AfterLoadRoadStops();
AfterLoadLabelMaps();
diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp
index 3cd80ed0a..34d767bec 100644
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -1990,6 +1990,9 @@ CommandCost CmdReverseTrainDirection(TileIndex tile, DoCommandFlag flags, uint32
ToggleBit(v->flags, VRF_REVERSE_DIRECTION);
SetWindowDirty(WC_VEHICLE_DEPOT, v->tile);
SetWindowDirty(WC_VEHICLE_DETAILS, v->index);
+ /* We cancel any 'skip signal at dangers' here */
+ v->force_proceed = 0;
+ SetWindowDirty(WC_VEHICLE_VIEW, v->index);
}
} else {
/* turn the whole train around */
@@ -2007,6 +2010,10 @@ CommandCost CmdReverseTrainDirection(TileIndex tile, DoCommandFlag flags, uint32
}
}
+ /* We cancel any 'skip signal at dangers' here */
+ v->force_proceed = 0;
+ SetWindowDirty(WC_VEHICLE_VIEW, v->index);
+
if (_settings_game.vehicle.train_acceleration_model != TAM_ORIGINAL && v->cur_speed != 0) {
ToggleBit(v->flags, VRF_REVERSING);
} else {
@@ -2033,7 +2040,15 @@ CommandCost CmdForceTrainProceed(TileIndex tile, DoCommandFlag flags, uint32 p1,
Train *t = Train::GetIfValid(p1);
if (t == NULL || !CheckOwnership(t->owner)) return CMD_ERROR;
- if (flags & DC_EXEC) t->force_proceed = 0x50;
+ if (flags & DC_EXEC) {
+ /* If we are forced to proceed, cancel that order.
+ * If we are marked stuck we would want to force the train
+ * to proceed to the next signal. In the other cases we
+ * would like to pass the signal at danger and run till the
+ * next signal we encounter. */
+ t->force_proceed = t->force_proceed == 2 ? 0 : HasBit(t->flags, VRF_TRAIN_STUCK) || t->IsInDepot() ? 1 : 2;
+ SetWindowDirty(WC_VEHICLE_VIEW, t->index);
+ }
return CommandCost();
}
@@ -3348,6 +3363,21 @@ static void TrainController(Train *v, Vehicle *nomove)
chosen_track = TrackToTrackBits(ChooseTrainTrack(v, gp.new_tile, enterdir, bits, false, NULL, true));
assert(chosen_track & (bits | GetReservedTrackbits(gp.new_tile)));
+ if (v->force_proceed != 0 && IsPlainRailTile(gp.new_tile) && HasSignals(gp.new_tile)) {
+ /* For each signal we find decrease the counter by one.
+ * We start at two, so the first signal we pass decreases
+ * this to one, then if we reach the next signal it is
+ * decreased to zero and we won't pass that new signal. */
+ Trackdir dir = FindFirstTrackdir(trackdirbits);
+ if (GetSignalType(gp.new_tile, TrackdirToTrack(dir)) != SIGTYPE_PBS ||
+ !HasSignalOnTrackdir(gp.new_tile, ReverseTrackdir(dir))) {
+ /* However, we do not want to be stopped by PBS signals
+ * entered via the back. */
+ v->force_proceed--;
+ SetWindowDirty(WC_VEHICLE_VIEW, v->index);
+ }
+ }
+
/* Check if it's a red signal and that force proceed is not clicked. */
if ((red_signals & chosen_track) && v->force_proceed == 0) {
/* In front of a red signal */
@@ -3921,7 +3951,6 @@ static bool TrainLocoHandler(Train *v, bool mode)
}
if (v->force_proceed != 0) {
- v->force_proceed--;
ClrBit(v->flags, VRF_TRAIN_STUCK);
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
}
@@ -4006,6 +4035,8 @@ static bool TrainLocoHandler(Train *v, bool mode)
/* we need to invalidate the widget if we are stopping from 'Stopping 0 km/h' to 'Stopped' */
if (v->cur_speed == 0 && v->tcache.last_speed == 0 && (v->vehstatus & VS_STOPPED)) {
+ /* If we manually stopped, we're not force-proceeding anymore. */
+ v->force_proceed = 0;
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
}
diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp
index a9401784f..d4cd7212e 100644
--- a/src/vehicle_gui.cpp
+++ b/src/vehicle_gui.cpp
@@ -1959,6 +1959,7 @@ public:
this->SetWidgetDisabledState(VVW_WIDGET_CLONE_VEH, !is_localcompany);
if (v->type == VEH_TRAIN) {
+ this->SetWidgetLoweredState(VVW_WIDGET_FORCE_PROCEED, Train::From(v)->force_proceed == 2);
this->SetWidgetDisabledState(VVW_WIDGET_FORCE_PROCEED, !is_localcompany);
this->SetWidgetDisabledState(VVW_WIDGET_TURN_AROUND, !is_localcompany);
}