diff options
-rw-r--r-- | src/lang/english.txt | 1 | ||||
-rw-r--r-- | src/train_cmd.cpp | 34 | ||||
-rw-r--r-- | src/vehicle.cpp | 3 | ||||
-rw-r--r-- | src/vehicle_base.h | 5 | ||||
-rw-r--r-- | src/vehicle_gui.cpp | 2 |
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: { |