(*i)->message(msg);
}
-void Train::place(const BlockIter &block)
+bool Train::place(const BlockIter &block)
{
if(!block)
throw invalid_argument("Train::place");
if(controller->get_speed())
throw logic_error("moving");
- allocator.start_from(block);
accurate_position = false;
last_entry_block = BlockIter();
- if(reverse)
- vehicles.front()->place(block.reverse().track_iter(), 0, Vehicle::FRONT_BUFFER);
+ if(allocator.start_from(block))
+ {
+ if(reverse)
+ vehicles.front()->place(block.reverse().track_iter(), VehiclePlacement::FRONT_BUFFER);
+ else
+ vehicles.back()->place(block.track_iter(), VehiclePlacement::BACK_BUFFER);
+ return true;
+ }
else
- vehicles.back()->place(block.track_iter(), 0, Vehicle::BACK_BUFFER);
+ {
+ unplace();
+ return false;
+ }
}
void Train::unplace()
bool Train::is_block_critical(const Block &block) const
{
- return get_reserved_distance_until(&block)<controller->get_braking_distance()*1.3;
+ return get_reserved_distance_until(&block)<=controller->get_braking_distance()*1.3;
}
BlockIter Train::get_first_noncritical_block() const
Vehicle &vehicle = *(reverse ? vehicles.back() : vehicles.front());
float d = speed*(dt/Time::sec);
- if(allocator.is_block_current(vehicle.get_track()->get_block()))
+ if(allocator.is_block_current(vehicle.get_placement().get_position(reverse ? VehiclePlacement::BACK_AXLE : VehiclePlacement::FRONT_AXLE)->get_block()))
{
SetFlag setf(advancing);
vehicle.advance(reverse ? -d : d);
accurate_position = true;
overshoot_dist = 0;
- if(!advancing && vehicles.front()->get_track())
+ if(!advancing && vehicles.front()->is_placed())
{
TrackIter track = last_entry_block.track_iter();
if(reverse)
{
track = track.flip();
- vehicles.back()->place(track, 0, Vehicle::BACK_AXLE);
+ vehicles.back()->place(track, VehiclePlacement::BACK_AXLE);
}
else
- vehicles.front()->place(track, 0, Vehicle::FRONT_AXLE);
+ vehicles.front()->place(track, VehiclePlacement::FRONT_AXLE);
}
}
else if(BeamGate *gate = dynamic_cast<BeamGate *>(&sensor))
{
- if(!advancing && vehicles.front()->get_track())
+ if(!advancing && vehicles.front()->is_placed())
{
TrackIter track = allocator.iter_for(*block).track_iter();
for(; (track && &track->get_block()==block); track=track.next())
track = track.reverse();
float offset = gate->get_offset_from_endpoint(track.entry());
if(reverse)
- vehicles.back()->place(track, offset, Vehicle::BACK_BUFFER);
+ vehicles.back()->place(TrackOffsetIter(track, offset), VehiclePlacement::BACK_BUFFER);
else
- vehicles.front()->place(track, offset, Vehicle::FRONT_BUFFER);
+ vehicles.front()->place(TrackOffsetIter(track, offset), VehiclePlacement::FRONT_BUFFER);
break;
}
}
Vehicle &veh = *(reverse ? vehicles.back() : vehicles.front());
- TrackIter track = veh.get_track_iter().track_iter();
+ TrackOffsetIter track = veh.get_placement().get_position(reverse ? VehiclePlacement::BACK_AXLE : VehiclePlacement::FRONT_AXLE);
if(!track) // XXX Probably unnecessary
return 0;
return 0;
// Account for the vehicle's offset on its current track
- float result = veh.get_offset();
+ float result = track.offset();
if(reverse)
track = track.reverse();
else
- result = track->get_type().get_path_length(track->get_active_path())-result;
+ result = track->get_path_length()-result;
result -= veh.get_type().get_length()/2;
BlockIter block = track.block_iter();
// Count remaining distance in the vehicle's current block
for(track=track.next(); &track->get_block()==&*block; track=track.next())
- result += track->get_type().get_path_length(track->get_active_path());
+ result += track->get_path_length();
const BlockIter &last = allocator.last();
if(&*block==&*last)
{
TrackIter track = obj.allocator.first().track_iter();
float offset = 2*obj.layout.get_catalogue().get_scale();
- obj.vehicles.back()->place(track, offset, Vehicle::BACK_BUFFER);
+ obj.vehicles.back()->place(TrackOffsetIter(track, offset), VehiclePlacement::BACK_BUFFER);
}
}