+ release_blocks(good_end, blocks.end());
+
+ if(blocks.back()!=start)
+ // We got some new blocks, so no longer need to yield
+ yielding_to = 0;
+
+ check_turnout_paths(true);
+
+ // Make any sensorless blocks at the beginning immediately current
+ while(cur_blocks_end!=clear_blocks_end && !(*cur_blocks_end)->get_sensor_id())
+ ++cur_blocks_end;
+
+ if(try_divert && divert(*divert_track))
+ reserve_more();
+}
+
+void Train::check_turnout_paths(bool set)
+{
+ if(clear_blocks_end==blocks.end())
+ return;
+
+ for(list<BlockIter>::iterator i=clear_blocks_end; i!=blocks.end(); ++i)
+ {
+ if((*i)->get_turnout_id())
+ {
+ TrackIter track = i->track_iter();
+ const TrackType::Endpoint &track_ep = track.endpoint();
+
+ unsigned path = 0;
+ list<BlockIter>::iterator j = i;
+ if(++j!=blocks.end())
+ {
+ TrackIter rev = j->track_iter().flip();
+ unsigned mask = rev.endpoint().paths&track_ep.paths;
+ for(path=0; mask>1; mask>>=1, ++path) ;
+ }
+ else
+ return;
+
+ if(path!=track->get_active_path())
+ {
+ if(set)
+ track->set_active_path(path);
+
+ /* Check again, in case the driver was able to service the request
+ instantly */
+ if(!set || path!=track->get_active_path())
+ continue;
+ }
+ }
+
+ if(i==clear_blocks_end)
+ ++clear_blocks_end;
+ }
+}
+
+float Train::get_reserved_distance_until(const Block *until_block, bool back) const
+{
+ if(blocks.empty())
+ return 0;
+
+ Vehicle &veh = *(reverse!=back ? vehicles.back() : vehicles.front());
+ const VehicleType &vtype = veh.get_type();
+
+ TrackIter track(veh.get_track(), veh.get_entry());
+ if(!track) // XXX Probably unnecessary
+ return 0;
+
+ BlockList::const_iterator block = blocks.begin();
+ while(block!=clear_blocks_end && !(*block)->has_track(*track))
+ ++block;
+ if(block==clear_blocks_end || &**block==until_block)
+ return 0;
+
+ float result = veh.get_offset();
+ if(reverse!=back)
+ track = track.reverse();
+ else
+ result = track->get_type().get_path_length(track->get_active_path())-result;
+ result -= vtype.get_length()/2;
+
+ while(1)