summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lang/english.txt1
-rw-r--r--src/train_cmd.cpp34
-rw-r--r--src/vehicle.cpp3
-rw-r--r--src/vehicle_base.h5
-rw-r--r--src/vehicle_gui.cpp2
5 files changed, 38 insertions, 7 deletions
diff --git a/src/lang/english.txt b/src/lang/english.txt
index fbdf4ae4e..915a99da0 100644
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -2905,6 +2905,7 @@ STR_TRAIN_STOPPING_VEL :{RED}Stopping,
STR_INCOMPATIBLE_RAIL_TYPES :Incompatible rail types
STR_TRAIN_NO_POWER :{RED}No power
STR_TRAIN_START_NO_CATENARY :This track lacks catenary, so the train can't start
+STR_TRAIN_STUCK :{ORANGE}Waiting for free path
STR_NEW_VEHICLE_NOW_AVAILABLE :{BLACK}{BIGFONT}New {STRING} now available!
STR_NEW_VEHICLE_TYPE :{BLACK}{BIGFONT}{ENGINE}
diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp
index 229f70d30..6b6f548ed 100644
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -1614,10 +1614,27 @@ static inline void SetLastSpeed(Vehicle *v, int spd)
}
}
-static void SwapTrainFlags(byte *swap_flag1, byte *swap_flag2)
+/** Mark a train as stuck and stop it if it isn't stopped right now. */
+static void MarkTrainAsStuck(Vehicle *v)
{
- byte flag1 = *swap_flag1;
- byte flag2 = *swap_flag2;
+ if (!HasBit(v->u.rail.flags, VRF_TRAIN_STUCK)) {
+ /* It is the first time the problem occured, set the "train stuck" flag. */
+ SetBit(v->u.rail.flags, VRF_TRAIN_STUCK);
+ v->load_unload_time_rem = 0;
+
+ /* Stop train */
+ v->cur_speed = 0;
+ v->subspeed = 0;
+ SetLastSpeed(v, 0);
+
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
+ }
+}
+
+static void SwapTrainFlags(uint16 *swap_flag1, uint16 *swap_flag2)
+{
+ uint16 flag1 = *swap_flag1;
+ uint16 flag2 = *swap_flag2;
/* Clear the flags */
ClrBit(*swap_flag1, VRF_GOINGUP);
@@ -2670,7 +2687,7 @@ static int UpdateTrainSpeed(Vehicle *v)
{
uint accel;
- if (v->vehstatus & VS_STOPPED || HasBit(v->u.rail.flags, VRF_REVERSING)) {
+ if (v->vehstatus & VS_STOPPED || HasBit(v->u.rail.flags, VRF_REVERSING) || HasBit(v->u.rail.flags, VRF_TRAIN_STUCK)) {
if (_settings_game.vehicle.realistic_acceleration) {
accel = GetTrainAcceleration(v, AM_BRAKE) * 2;
} else {
@@ -3059,6 +3076,9 @@ static void TrainController(Vehicle *v, Vehicle *nomove, bool update_image)
/* In front of a red signal */
Trackdir i = FindFirstTrackdir(trackdirbits);
+ /* Don't handle stuck trains here. */
+ if (HasBit(v->u.rail.flags, VRF_TRAIN_STUCK)) return;
+
if (!HasSignalOnTrackdir(gp.new_tile, ReverseTrackdir(i))) {
v->cur_speed = 0;
v->subspeed = 0;
@@ -3499,7 +3519,11 @@ static void TrainLocoHandler(Vehicle *v, bool mode)
return;
}
- if (v->u.rail.force_proceed != 0) v->u.rail.force_proceed--;
+ if (v->u.rail.force_proceed != 0) {
+ v->u.rail.force_proceed--;
+ ClrBit(v->u.rail.flags, VRF_TRAIN_STUCK);
+ InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
+ }
/* train is broken down? */
if (v->breakdown_ctr != 0) {
diff --git a/src/vehicle.cpp b/src/vehicle.cpp
index 18195eef2..555f1ddf0 100644
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -2072,7 +2072,8 @@ static const SaveLoad _train_desc[] = {
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, railtype), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, track), SLE_UINT8),
- SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags), SLE_UINT8, 2, SL_MAX_VERSION),
+ SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags), SLE_FILE_U8 | SLE_VAR_U16, 2, 99),
+ SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags), SLE_UINT16,100, SL_MAX_VERSION),
SLE_CONDNULL(2, 2, 59),
SLE_CONDNULL(2, 2, 19),
diff --git a/src/vehicle_base.h b/src/vehicle_base.h
index 0defc9566..440f30d1d 100644
--- a/src/vehicle_base.h
+++ b/src/vehicle_base.h
@@ -115,7 +115,7 @@ struct VehicleRail {
* 0xffff == not in train */
EngineID first_engine;
- byte flags;
+ uint16 flags;
TrackBitsByte track;
byte force_proceed;
RailTypeByte railtype;
@@ -143,6 +143,9 @@ enum VehicleRailFlags {
/* used for vehicle var 0xFE bit 8 (toggled each time the train is reversed, accurate for first vehicle only) */
VRF_TOGGLE_REVERSE = 7,
+
+ /* used to mark a train that can't get a path reservation */
+ VRF_TRAIN_STUCK = 8,
};
struct VehicleAir {
diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp
index faf044764..fda939d35 100644
--- a/src/vehicle_gui.cpp
+++ b/src/vehicle_gui.cpp
@@ -1895,6 +1895,8 @@ struct VehicleViewWindow : Window {
} else { // no train
str = STR_8861_STOPPED;
}
+ } else if (v->type == VEH_TRAIN && HasBit(v->u.rail.flags, VRF_TRAIN_STUCK)) {
+ str = STR_TRAIN_STUCK;
} else { // vehicle is in a "normal" state, show current order
switch (v->current_order.GetType()) {
case OT_GOTO_STATION: {