|
|
@ -1614,10 +1614,7 @@ static void MarkTrainAsStuck(Train *v)
|
|
|
|
/* It is the first time the problem occured, set the "train stuck" flag. */
|
|
|
|
/* It is the first time the problem occured, set the "train stuck" flag. */
|
|
|
|
SetBit(v->flags, VRF_TRAIN_STUCK);
|
|
|
|
SetBit(v->flags, VRF_TRAIN_STUCK);
|
|
|
|
|
|
|
|
|
|
|
|
/* When loading the vehicle is already stopped. No need to change that. */
|
|
|
|
v->wait_counter = 0;
|
|
|
|
if (v->current_order.IsType(OT_LOADING)) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
v->time_counter = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Stop train */
|
|
|
|
/* Stop train */
|
|
|
|
v->cur_speed = 0;
|
|
|
|
v->cur_speed = 0;
|
|
|
@ -1957,7 +1954,7 @@ static void ReverseTrainDirection(Train *v)
|
|
|
|
} else if (HasBit(v->flags, VRF_TRAIN_STUCK)) {
|
|
|
|
} else if (HasBit(v->flags, VRF_TRAIN_STUCK)) {
|
|
|
|
/* A train not inside a PBS block can't be stuck. */
|
|
|
|
/* A train not inside a PBS block can't be stuck. */
|
|
|
|
ClrBit(v->flags, VRF_TRAIN_STUCK);
|
|
|
|
ClrBit(v->flags, VRF_TRAIN_STUCK);
|
|
|
|
v->time_counter = 0;
|
|
|
|
v->wait_counter = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -2304,12 +2301,12 @@ static bool CheckTrainStayInDepot(Train *v)
|
|
|
|
|
|
|
|
|
|
|
|
if (v->force_proceed == 0) {
|
|
|
|
if (v->force_proceed == 0) {
|
|
|
|
/* force proceed was not pressed */
|
|
|
|
/* force proceed was not pressed */
|
|
|
|
if (++v->time_counter < 37) {
|
|
|
|
if (++v->wait_counter < 37) {
|
|
|
|
SetWindowClassesDirty(WC_TRAINS_LIST);
|
|
|
|
SetWindowClassesDirty(WC_TRAINS_LIST);
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
v->time_counter = 0;
|
|
|
|
v->wait_counter = 0;
|
|
|
|
|
|
|
|
|
|
|
|
seg_state = _settings_game.pf.reserve_paths ? SIGSEG_PBS : UpdateSignalsOnSegment(v->tile, INVALID_DIAGDIR, v->owner);
|
|
|
|
seg_state = _settings_game.pf.reserve_paths ? SIGSEG_PBS : UpdateSignalsOnSegment(v->tile, INVALID_DIAGDIR, v->owner);
|
|
|
|
if (seg_state == SIGSEG_FULL || HasDepotReservation(v->tile)) {
|
|
|
|
if (seg_state == SIGSEG_FULL || HasDepotReservation(v->tile)) {
|
|
|
@ -2914,12 +2911,7 @@ bool TryPathReserve(Train *v, bool mark_as_stuck, bool first_tile_okay)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (HasBit(v->flags, VRF_TRAIN_STUCK)) {
|
|
|
|
if (HasBit(v->flags, VRF_TRAIN_STUCK)) {
|
|
|
|
/* This might be called when a train is loading. At that time the counter
|
|
|
|
v->wait_counter = 0;
|
|
|
|
* is (mis)used (or rather PBS misuses it) for determining how long to wait
|
|
|
|
|
|
|
|
* till going to the next load cycle. If that number is set to 0 the wait
|
|
|
|
|
|
|
|
* for loading will be 65535 ticks, which is not what we want. Actually, We
|
|
|
|
|
|
|
|
* do not want to reset the waiting period during loading in any case. */
|
|
|
|
|
|
|
|
if (!v->current_order.IsType(OT_LOADING)) v->time_counter = 0;
|
|
|
|
|
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ClrBit(v->flags, VRF_TRAIN_STUCK);
|
|
|
|
ClrBit(v->flags, VRF_TRAIN_STUCK);
|
|
|
@ -3396,12 +3388,12 @@ static void TrainController(Train *v, Vehicle *nomove)
|
|
|
|
v->cur_speed = 0;
|
|
|
|
v->cur_speed = 0;
|
|
|
|
v->subspeed = 0;
|
|
|
|
v->subspeed = 0;
|
|
|
|
v->progress = 255 - 100;
|
|
|
|
v->progress = 255 - 100;
|
|
|
|
if (_settings_game.pf.wait_oneway_signal == 255 || ++v->time_counter < _settings_game.pf.wait_oneway_signal * 20) return;
|
|
|
|
if (_settings_game.pf.wait_oneway_signal == 255 || ++v->wait_counter < _settings_game.pf.wait_oneway_signal * 20) return;
|
|
|
|
} else if (HasSignalOnTrackdir(gp.new_tile, i)) {
|
|
|
|
} else if (HasSignalOnTrackdir(gp.new_tile, i)) {
|
|
|
|
v->cur_speed = 0;
|
|
|
|
v->cur_speed = 0;
|
|
|
|
v->subspeed = 0;
|
|
|
|
v->subspeed = 0;
|
|
|
|
v->progress = 255 - 10;
|
|
|
|
v->progress = 255 - 10;
|
|
|
|
if (_settings_game.pf.wait_twoway_signal == 255 || ++v->time_counter < _settings_game.pf.wait_twoway_signal * 73) {
|
|
|
|
if (_settings_game.pf.wait_twoway_signal == 255 || ++v->wait_counter < _settings_game.pf.wait_twoway_signal * 73) {
|
|
|
|
DiagDirection exitdir = TrackdirToExitdir(i);
|
|
|
|
DiagDirection exitdir = TrackdirToExitdir(i);
|
|
|
|
TileIndex o_tile = TileAddByDiagDir(gp.new_tile, exitdir);
|
|
|
|
TileIndex o_tile = TileAddByDiagDir(gp.new_tile, exitdir);
|
|
|
|
|
|
|
|
|
|
|
@ -3415,7 +3407,7 @@ static void TrainController(Train *v, Vehicle *nomove)
|
|
|
|
/* If we would reverse but are currently in a PBS block and
|
|
|
|
/* If we would reverse but are currently in a PBS block and
|
|
|
|
* reversing of stuck trains is disabled, don't reverse. */
|
|
|
|
* reversing of stuck trains is disabled, don't reverse. */
|
|
|
|
if (_settings_game.pf.wait_for_pbs_path == 255 && UpdateSignalsOnSegment(v->tile, enterdir, v->owner) == SIGSEG_PBS) {
|
|
|
|
if (_settings_game.pf.wait_for_pbs_path == 255 && UpdateSignalsOnSegment(v->tile, enterdir, v->owner) == SIGSEG_PBS) {
|
|
|
|
v->time_counter = 0;
|
|
|
|
v->wait_counter = 0;
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
goto reverse_train_direction;
|
|
|
|
goto reverse_train_direction;
|
|
|
@ -3509,7 +3501,7 @@ static void TrainController(Train *v, Vehicle *nomove)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (v->IsFrontEngine()) {
|
|
|
|
if (v->IsFrontEngine()) {
|
|
|
|
v->time_counter = 0;
|
|
|
|
v->wait_counter = 0;
|
|
|
|
|
|
|
|
|
|
|
|
/* If we are approching a crossing that is reserved, play the sound now. */
|
|
|
|
/* If we are approching a crossing that is reserved, play the sound now. */
|
|
|
|
TileIndex crossing = TrainApproachingCrossingTile(v);
|
|
|
|
TileIndex crossing = TrainApproachingCrossingTile(v);
|
|
|
@ -3601,7 +3593,7 @@ invalid_rail:
|
|
|
|
if (prev != NULL) error("Disconnecting train");
|
|
|
|
if (prev != NULL) error("Disconnecting train");
|
|
|
|
|
|
|
|
|
|
|
|
reverse_train_direction:
|
|
|
|
reverse_train_direction:
|
|
|
|
v->time_counter = 0;
|
|
|
|
v->wait_counter = 0;
|
|
|
|
v->cur_speed = 0;
|
|
|
|
v->cur_speed = 0;
|
|
|
|
v->subspeed = 0;
|
|
|
|
v->subspeed = 0;
|
|
|
|
ReverseTrainDirection(v);
|
|
|
|
ReverseTrainDirection(v);
|
|
|
@ -3979,7 +3971,7 @@ static bool TrainLocoHandler(Train *v, bool mode)
|
|
|
|
|
|
|
|
|
|
|
|
bool valid_order = !v->current_order.IsType(OT_NOTHING) && v->current_order.GetType() != OT_CONDITIONAL;
|
|
|
|
bool valid_order = !v->current_order.IsType(OT_NOTHING) && v->current_order.GetType() != OT_CONDITIONAL;
|
|
|
|
if (ProcessOrders(v) && CheckReverseTrain(v)) {
|
|
|
|
if (ProcessOrders(v) && CheckReverseTrain(v)) {
|
|
|
|
v->time_counter = 0;
|
|
|
|
v->wait_counter = 0;
|
|
|
|
v->cur_speed = 0;
|
|
|
|
v->cur_speed = 0;
|
|
|
|
v->subspeed = 0;
|
|
|
|
v->subspeed = 0;
|
|
|
|
ReverseTrainDirection(v);
|
|
|
|
ReverseTrainDirection(v);
|
|
|
@ -4001,17 +3993,17 @@ static bool TrainLocoHandler(Train *v, bool mode)
|
|
|
|
|
|
|
|
|
|
|
|
/* Handle stuck trains. */
|
|
|
|
/* Handle stuck trains. */
|
|
|
|
if (!mode && HasBit(v->flags, VRF_TRAIN_STUCK)) {
|
|
|
|
if (!mode && HasBit(v->flags, VRF_TRAIN_STUCK)) {
|
|
|
|
++v->time_counter;
|
|
|
|
++v->wait_counter;
|
|
|
|
|
|
|
|
|
|
|
|
/* Should we try reversing this tick if still stuck? */
|
|
|
|
/* Should we try reversing this tick if still stuck? */
|
|
|
|
bool turn_around = v->time_counter % (_settings_game.pf.wait_for_pbs_path * DAY_TICKS) == 0 && _settings_game.pf.wait_for_pbs_path < 255;
|
|
|
|
bool turn_around = v->wait_counter % (_settings_game.pf.wait_for_pbs_path * DAY_TICKS) == 0 && _settings_game.pf.wait_for_pbs_path < 255;
|
|
|
|
|
|
|
|
|
|
|
|
if (!turn_around && v->time_counter % _settings_game.pf.path_backoff_interval != 0 && v->force_proceed == 0) return true;
|
|
|
|
if (!turn_around && v->wait_counter % _settings_game.pf.path_backoff_interval != 0 && v->force_proceed == 0) return true;
|
|
|
|
if (!TryPathReserve(v)) {
|
|
|
|
if (!TryPathReserve(v)) {
|
|
|
|
/* Still stuck. */
|
|
|
|
/* Still stuck. */
|
|
|
|
if (turn_around) ReverseTrainDirection(v);
|
|
|
|
if (turn_around) ReverseTrainDirection(v);
|
|
|
|
|
|
|
|
|
|
|
|
if (HasBit(v->flags, VRF_TRAIN_STUCK) && v->time_counter > 2 * _settings_game.pf.wait_for_pbs_path * DAY_TICKS) {
|
|
|
|
if (HasBit(v->flags, VRF_TRAIN_STUCK) && v->wait_counter > 2 * _settings_game.pf.wait_for_pbs_path * DAY_TICKS) {
|
|
|
|
/* Show message to player. */
|
|
|
|
/* Show message to player. */
|
|
|
|
if (_settings_client.gui.lost_train_warn && v->owner == _local_company) {
|
|
|
|
if (_settings_client.gui.lost_train_warn && v->owner == _local_company) {
|
|
|
|
SetDParam(0, v->index);
|
|
|
|
SetDParam(0, v->index);
|
|
|
@ -4021,12 +4013,12 @@ static bool TrainLocoHandler(Train *v, bool mode)
|
|
|
|
v->index
|
|
|
|
v->index
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
v->time_counter = 0;
|
|
|
|
v->wait_counter = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Exit if force proceed not pressed, else reset stuck flag anyway. */
|
|
|
|
/* Exit if force proceed not pressed, else reset stuck flag anyway. */
|
|
|
|
if (v->force_proceed == 0) return true;
|
|
|
|
if (v->force_proceed == 0) return true;
|
|
|
|
ClrBit(v->flags, VRF_TRAIN_STUCK);
|
|
|
|
ClrBit(v->flags, VRF_TRAIN_STUCK);
|
|
|
|
v->time_counter = 0;
|
|
|
|
v->wait_counter = 0;
|
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
|
SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, VVW_WIDGET_START_STOP_VEH);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|