- unsigned low = 0;
- unsigned high = 0;
- unsigned last = 0;
- for(unsigned i=0; (!high && i<real_speed.size()); ++i)
- if(real_speed[i].weight)
- {
- last = i;
- if(real_speed[i].speed<real)
- low = i;
- else
- high = i;
- }
- if(!high)
- {
- unsigned limit = real_speed.size()/5;
- if(!low)
- {
- if(real)
- return limit;
- else
- return 0;
- }
- return min(min(static_cast<unsigned>(low*real/real_speed[low].speed), real_speed.size()-1), last+limit);
- }
-
- float f = (real-real_speed[low].speed)/(real_speed[high].speed-real_speed[low].speed);
- return static_cast<unsigned>(low*(1-f)+high*f+0.5);
-}
-
-float Train::get_travel_speed() const
-{
- float speed = get_real_speed(current_speed_step);
- float scale = layout.get_catalogue().get_scale();
- return static_cast<int>(round(speed/scale*3.6/5))*5;
-}
-
-void Train::set_status(const string &s)
-{
- status = s;
- signal_status_changed.emit(s);
-}
-
-void Train::release_blocks()
-{
- release_blocks(blocks.begin(), blocks.end());
-}
-
-void Train::release_blocks(BlockList::iterator begin, BlockList::iterator end)
-{
- while(begin!=end)
- {
- if(begin==cur_blocks_end)
- cur_blocks_end = end;
- if(begin==clear_blocks_end)
- clear_blocks_end = end;
-
- Block &block = **begin;
- blocks.erase(begin++);
- block.reserve(0);
-
- if(begin==blocks.end())
- end_of_route = false;
- }
-}
-
-void Train::reverse_blocks(BlockList &blks) const
-{
- blks.reverse();
- for(BlockList::iterator i=blks.begin(); i!=blks.end(); ++i)
- *i = i->reverse();
-}
-
-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)