delay(info->router->get_departure_delay()),
duration(info->router->get_trip_duration()),
waypoint(0),
+ distance_traveled(0),
blocked_by(-1)
{
const Vehicle *veh = &info->train->get_vehicle(0);
}
float secs = dt/Time::sec;
- // There may be negative delay remaining after previous step.
+ // There may be some delay remaining.
if(delay)
{
secs -= delay/Time::sec;
if(state==MOVING)
advance(info->speed*secs);
else if(state!=ARRIVED)
- wait_time += secs*Time::sec;
+ {
+ float remaining_distance = occupied_tracks->path_length-offset;
+ if(remaining_distance>0)
+ {
+ advance(remaining_distance);
+ wait_time += (secs-remaining_distance/info->speed)*Time::sec;
+ }
+ else
+ wait_time += secs*Time::sec;
+ }
}
void TrainRoutePlanner::TrainRoutingState::advance_track(unsigned next_path)
if(next.update_states() && next.check_deadlocks())
return;
- int train_index = find_next_train();
+ int train_index = next.find_next_train();
if(train_index<0)
return;
return;
}
- train.advance_track(0);
+ if(train.state==MOVING)
+ train.advance_track(0);
+ else
+ {
+ new_steps.push_back(next);
+ return;
+ }
const TrackType::Endpoint &entry_ep = train.track.endpoint();
if(train.critical)
int TrainRoutePlanner::RoutingStep::find_next_train() const
{
+ /* Pick a moving train with the lowest time to next track. A train that
+ just became blocked can still travel until the end of its current track,
+ so consider those too. */
Time::TimeDelta min_dt;
int next_train = -1;
for(unsigned i=0; i<trains.size(); ++i)
- if(trains[i].state==MOVING)
+ if(trains[i].state==MOVING || (trains[i].state==BLOCKED && prev && prev->trains[i].state==MOVING))
{
Time::TimeDelta dt = trains[i].get_time_to_next_track();
if(dt<min_dt || next_train<0)