+ while(iter!=routes.end() && !iter->route->has_track(track))
+ ++iter;
+ if(iter==routes.end())
+ return false;
+
+ list<RouteRef>::iterator next = iter;
+ ++next;
+ if(next!=routes.end() && next->diversion && next->route->has_track(track))
+ iter = next;
+
+ return true;
+}
+
+Route *Train::create_lead_route(Route *lead, const Route *target)
+{
+ if(!lead)
+ {
+ lead = new Route(layout);
+ lead->set_name("Lead");
+ lead->set_temporary(true);
+ }
+
+ set<Track *> tracks;
+ for(BlockList::iterator i=cur_blocks.begin(); i!=rsv_blocks.end(); )
+ {
+ const set<Track *> &btracks = (*i)->get_tracks();
+ for(set<Track *>::const_iterator j=btracks.begin(); j!=btracks.end(); ++j)
+ if(!target || !target->has_track(**j))
+ tracks.insert(*j);
+
+ if(++i==cur_blocks.end())
+ i = rsv_blocks.begin();
+ }
+
+ lead->add_tracks(tracks);
+
+ return lead;
+}
+
+bool Train::is_valid_diversion(const Route &diversion, Track &from, unsigned from_ep)
+{
+ float diversion_len = 0;
+ TrackIter track(&from, from_ep);
+ while(diversion.has_track(*track))
+ {
+ unsigned tid = track->get_turnout_id();
+ unsigned path = (tid ? diversion.get_turnout(tid) : 0);
+ diversion_len += track->get_type().get_path_length(path);
+
+ track = track.next(path);
+
+ if(&*track==&from)
+ return false;
+ }
+
+ list<RouteRef>::iterator route = routes.begin();
+ if(!advance_route(route, from))
+ return false;
+
+ set<Track *> visited;
+ float route_len = 0;
+ track = TrackIter(&from, from_ep);
+ while(1)
+ {
+ unsigned tid = track->get_turnout_id();
+ unsigned path = (tid ? route->route->get_turnout(tid) : 0);
+ route_len += track->get_type().get_path_length(path);
+
+ if(&*track!=&from && diversion.has_track(*track))
+ break;
+
+ if(visited.count(&*track))
+ return false;
+ visited.insert(&*track);
+
+ track = track.next(path);
+
+ if(!advance_route(route, *track))
+ return false;
+ }
+
+ return diversion_len<route_len*1.2;
+}
+
+
+Train::RouteRef::RouteRef(const Route *r, unsigned d):
+ route(r),
+ diversion(d)
+{ }
+
+
+Train::RealSpeed::RealSpeed():
+ speed(0),
+ weight(0)
+{ }
+
+void Train::RealSpeed::add(float s, float w)
+{
+ speed = (speed*weight+s*w)/(weight+w);
+ weight = min(weight+w, 300.0f);