- result = track->get_type().get_path_length(track->get_active_path())-result;
- result -= vtype.get_length()/2;
-
- while(1)
- {
- track = track.next();
- if(!track)
- break;
-
- if(!(*block)->has_track(*track))
- {
- if(back)
- {
- if(block==blocks.begin())
- break;
- --block;
- }
- else
- {
- ++block;
- if(block==clear_blocks_end)
- break;
- }
-
- if(&**block==until_block)
- break;
- }
-
- result += track->get_type().get_path_length(track->get_active_path());
- }
-
- return result;
-}
-
-float Train::get_real_speed(unsigned i) const
-{
- if(i==0)
- return 0;
- if(real_speed[i].weight)
- return real_speed[i].speed;
-
- unsigned low;
- unsigned high;
- for(low=i; low>0; --low)
- if(real_speed[low].weight)
- break;
- for(high=i; high+1<real_speed.size(); ++high)
- if(real_speed[high].weight)
- break;
-
- if(real_speed[high].weight)
- {
- if(real_speed[low].weight)
- {
- float f = float(i-low)/(high-low);
- return real_speed[low].speed*(1-f)+real_speed[high].speed*f;
- }
- else
- return real_speed[high].speed*float(i)/high;
- }
- else if(real_speed[low].weight)
- return real_speed[low].speed*float(i)/low;
- else
- return 0;
-}
-
-unsigned Train::find_speed_step(float real) const
-{
- if(real_speed.size()<=1)
- return 0;
- if(real<=real_speed[1].speed*0.5)
- return 0;
-
- 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;