-bool Train::advance_route(list<RouteRef>::iterator &iter, Track &track)
-{
- 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=blocks.begin(); i!=blocks.end(); ++i)
- {
- 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);
- }
-
- lead->add_tracks(tracks);
-
- return lead;
-}
-
-bool Train::is_valid_diversion(const Route &diversion, const TrackIter &from)
-{
- float diversion_len = 0;
- TrackLoopIter track1 = from;
- while(diversion.has_track(*track1))
- {
- unsigned path = diversion.get_path(*track1);
- diversion_len += track1->get_type().get_path_length(path);
-
- track1 = track1.next(path);
-
- if(track1.looped())
- return false;
- }
-
- list<RouteRef>::iterator route = routes.begin();
- if(!advance_route(route, *from))
- return false;
-
- float route_len = 0;
- TrackLoopIter track2 = from;
- while(1)
- {
- unsigned path = route->route->get_path(*track2);
- route_len += track2->get_type().get_path_length(path);
-
- bool ok = (track2!=from && diversion.has_track(*track2));
-
- track2 = track2.next(path);
-
- if(ok)
- break;
-
- if(track2.looped())
- return false;
-
- if(!advance_route(route, *track2))
- return false;
- }
-
- // Must end up at the same place through both routes
- if(track2!=track1)
- 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);
-}
-