use of jmri.jmrit.operations.routes.RouteLocation in project JMRI by JMRI.
the class TrainCommon method blockCarsByTrackNameTwoColumn.
/**
* Produces a two column format for car pick ups and set outs. Sorted by
* track and then by destination. Track name in header format, track name
* removed from format. This routine is used to generate the
* "Two Column by Track" format.
*
* @param file Manifest or switch list File
* @param train The train being printed.
* @param carList List of cars for this train
* @param routeList The train's list of RouteLocations
* @param rl The RouteLocation being printed
* @param printHeader True if new location.
* @param isManifest True if manifest, false if switch list.
*/
protected void blockCarsByTrackNameTwoColumn(PrintWriter file, Train train, List<Car> carList, List<RouteLocation> routeList, RouteLocation rl, boolean printHeader, boolean isManifest) {
index = 0;
int lineLength = getLineLength(isManifest);
List<Track> tracks = rl.getLocation().getTrackByNameList(null);
List<String> trackNames = new ArrayList<String>();
doneCars.clear();
// list utility cars by quantity
clearUtilityCarTypes();
if (printHeader) {
printCarHeader(file, isManifest, IS_TWO_COLUMN_TRACK);
}
for (Track track : tracks) {
String trackName = splitString(track.getName());
if (trackNames.contains(trackName)) {
continue;
}
// block car pick ups by destination
// begin blocking at rl
boolean found = false;
for (RouteLocation rld : routeList) {
if (rld != rl && !found) {
continue;
}
found = true;
for (Car car : carList) {
if (car.getTrack() != null && car.getRouteLocation() == rl && trackName.equals(splitString(car.getTrackName())) && ((car.getRouteDestination() == rld && !car.isCaboose() && !car.hasFred()) || (rld == routeList.get(routeList.size() - 1) && (car.isCaboose() || car.hasFred())))) {
if (!trackNames.contains(trackName)) {
printTrackNameHeader(file, trackName, isManifest);
}
// use a track name once
trackNames.add(trackName);
pickupCars = true;
cars++;
if (car.getLoadType().equals(CarLoad.LOAD_TYPE_EMPTY)) {
emptyCars++;
}
String s;
if (car.isUtility()) {
s = pickupUtilityCars(carList, car, isManifest, IS_TWO_COLUMN_TRACK);
if (s == null) {
continue;
}
s = s.trim();
} else {
s = pickupCar(car, isManifest, IS_TWO_COLUMN_TRACK).trim();
}
s = padAndTruncateString(s, lineLength / 2, true);
s = appendSetoutString(s, trackName, carList, rl, isManifest, IS_TWO_COLUMN_TRACK);
addLine(file, s);
}
}
}
for (Car car : carList) {
if (!doneCars.contains(car) && car.getRouteDestination() == rl && trackName.equals(splitString(car.getDestinationTrackName()))) {
if (!trackNames.contains(trackName)) {
printTrackNameHeader(file, trackName, isManifest);
}
// use a track name once
trackNames.add(trackName);
String s = padString("", lineLength / 2);
String so = appendSetoutString(s, carList, rl, car, isManifest, IS_TWO_COLUMN_TRACK);
// check for utility car
if (so.equals(s)) {
continue;
}
String test = so.trim();
if (// null line contains |
test.length() > 1) {
addLine(file, so);
}
}
}
}
}
use of jmri.jmrit.operations.routes.RouteLocation in project JMRI by JMRI.
the class TrainCommon method blockCarsByTrackTwoColumn.
/**
* Produces a two column format for car pick ups and set outs. Sorted by
* track and then by destination. This routine is used for the "Two Column"
* format.
*
* @param file Manifest or switch list File
* @param train The train being printed.
* @param carList List of cars for this train
* @param routeList The train's list of RouteLocations
* @param rl The RouteLocation being printed
* @param printHeader True if new location.
* @param isManifest True if manifest, false if switch list.
*/
protected void blockCarsByTrackTwoColumn(PrintWriter file, Train train, List<Car> carList, List<RouteLocation> routeList, RouteLocation rl, boolean printHeader, boolean isManifest) {
index = 0;
int lineLength = getLineLength(isManifest);
List<Track> tracks = rl.getLocation().getTrackByNameList(null);
List<String> trackNames = new ArrayList<String>();
// list utility cars by quantity
clearUtilityCarTypes();
if (printHeader) {
printCarHeader(file, isManifest, !IS_TWO_COLUMN_TRACK);
}
for (Track track : tracks) {
if (trackNames.contains(splitString(track.getName()))) {
continue;
}
// use a track name once
trackNames.add(splitString(track.getName()));
// block car pick ups by destination
// begin blocking at rl
boolean found = false;
for (RouteLocation rld : routeList) {
if (rld != rl && !found) {
continue;
}
found = true;
for (int k = 0; k < carList.size(); k++) {
Car car = carList.get(k);
if (car.getTrack() != null && car.getRouteLocation() == rl && ((car.getRouteDestination() == rld && !car.isCaboose() && !car.hasFred()) || (rld == routeList.get(routeList.size() - 1) && (car.isCaboose() || car.hasFred())))) {
if (Setup.isSortByTrackNameEnabled() && !splitString(track.getName()).equals(splitString(car.getTrackName()))) {
continue;
}
pickupCars = true;
cars++;
if (car.getLoadType().equals(CarLoad.LOAD_TYPE_EMPTY)) {
emptyCars++;
}
String s;
if (car.isUtility()) {
s = pickupUtilityCars(carList, car, isManifest, !IS_TWO_COLUMN_TRACK);
if (s == null) {
continue;
}
s = s.trim();
} else {
s = pickupCar(car, isManifest, !IS_TWO_COLUMN_TRACK).trim();
}
s = padAndTruncateString(s, lineLength / 2, true);
if (isLocalMove(car)) {
String sl = appendSetoutString(s, carList, car.getRouteDestination(), car, isManifest, !IS_TWO_COLUMN_TRACK);
// check for utility car, and local route with two or more locations
if (!sl.equals(s)) {
s = sl;
// done with this car, remove from list
carList.remove(car);
k--;
} else {
s = padAndTruncateString(s + VERTICAL_LINE_CHAR, getLineLength(isManifest), true);
}
} else {
s = appendSetoutString(s, carList, rl, true, isManifest, !IS_TWO_COLUMN_TRACK);
}
addLine(file, s);
}
}
}
if (!Setup.isSortByTrackNameEnabled()) {
// done
break;
}
}
while (index < carList.size()) {
String s = padString("", lineLength / 2);
s = appendSetoutString(s, carList, rl, false, isManifest, !IS_TWO_COLUMN_TRACK);
String test = s.trim();
if (// null line contains |
test.length() > 1) {
addLine(file, s);
}
}
}
use of jmri.jmrit.operations.routes.RouteLocation in project JMRI by JMRI.
the class TrainCsvCommon method printTrackComments.
protected void printTrackComments(PrintWriter fileOut, RouteLocation rl, List<Car> carList) {
Location location = rl.getLocation();
if (location != null) {
List<Track> tracks = location.getTrackByNameList(null);
for (Track track : tracks) {
// any pick ups or set outs to this track?
boolean pickup = false;
boolean setout = false;
for (Car car : carList) {
if (car.getRouteLocation() == rl && car.getTrack() != null && car.getTrack() == track) {
pickup = true;
}
if (car.getRouteDestination() == rl && car.getDestinationTrack() != null && car.getDestinationTrack() == track) {
setout = true;
}
}
// each comment can have multiple lines
if (pickup && setout && !track.getCommentBoth().equals(Track.NONE)) {
String[] comments = track.getCommentBoth().split(NEW_LINE);
for (String comment : comments) {
addLine(fileOut, TKCB + comment);
}
} else if (pickup && !setout && !track.getCommentPickup().equals(Track.NONE)) {
String[] comments = track.getCommentPickup().split(NEW_LINE);
for (String comment : comments) {
addLine(fileOut, TKCP + comment);
}
} else if (!pickup && setout && !track.getCommentSetout().equals(Track.NONE)) {
String[] comments = track.getCommentSetout().split(NEW_LINE);
for (String comment : comments) {
addLine(fileOut, TKCS + comment);
}
}
}
}
}
use of jmri.jmrit.operations.routes.RouteLocation in project JMRI by JMRI.
the class TrainBuilder method checkCarForDestinationAndTrack.
/**
* Checks to see if car has a destination and tries to add car to train
*
* @param rl the car's route location
* @param routeIndex where in the route the car pick up is
* @return true if car has a destination.
* @throws BuildFailedException if destination was staging and can't place
* car there
*/
private boolean checkCarForDestinationAndTrack(Car car, RouteLocation rl, int routeIndex) throws BuildFailedException {
if (car.getDestination() == null) {
return false;
}
addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCarHasAssignedDest"), new Object[] { car.toString(), (car.getDestinationName() + ", " + car.getDestinationTrackName()) }));
RouteLocation rld = _train.getRoute().getLastLocationByName(car.getDestinationName());
if (rld == null) {
// car has a destination that isn't serviced by this train (destination loaded by router)
addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildExcludeCarDestNotPartRoute"), new Object[] { car.toString(), car.getDestinationName(), _train.getRoute().getName() }));
// done
return true;
}
if (car.getRouteLocation() != null) {
// The following code should never execute if train was reset before a build!
addLine(_buildReport, THREE, MessageFormat.format(Bundle.getMessage("buildCarAlreadyAssigned"), new Object[] { car.toString() }));
}
// now go through the route and try and find a location with
// the correct destination name
int locCount = 0;
for (int k = routeIndex; k < _routeList.size(); k++) {
rld = _routeList.get(k);
// if car can be picked up later at same location, skip
if (checkForLaterPickUp(rl, rld, car)) {
break;
}
if (!rld.getName().equals(car.getDestinationName())) {
continue;
}
// is the car's destination the terminal and is that allowed?
if (!_train.isAllowThroughCarsEnabled() && !_train.isLocalSwitcher() && !car.isCaboose() && !car.hasFred() && !car.isPassenger() && splitString(car.getLocationName()).equals(splitString(_departLocation.getName())) && splitString(car.getDestinationName()).equals(splitString(_terminateLocation.getName())) && !splitString(_departLocation.getName()).equals(splitString(_terminateLocation.getName()))) {
addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildCarHasDestination"), new Object[] { car.toString(), _departLocation.getName(), _terminateLocation.getName() }));
addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildThroughTrafficNotAllow"), new Object[] { _departLocation.getName(), _terminateLocation.getName() }));
// add line when in detailed report mode
addLine(_buildReport, FIVE, BLANK_LINE);
// done
return true;
}
// show when this car would be dropped at location
locCount++;
log.debug("Car ({}) found a destination in train's route", car.toString());
// are drops allows at this location?
if (!rld.isDropAllowed()) {
addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildRouteNoDropsStop"), new Object[] { _train.getRoute().getName(), rld.getName(), rld.getId(), locCount }));
continue;
}
if (rld.getCarMoves() >= rld.getMaxCarMoves()) {
addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildNoAvailableMovesStop"), new Object[] { _train.getRoute().getName(), rld.getId(), rld.getName(), locCount }));
continue;
}
// is the train length okay?
if (!checkTrainLength(car, rl, rld)) {
continue;
}
// check for valid destination track
if (car.getDestinationTrack() == null) {
addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildCarDoesNotHaveDest"), new Object[] { car.toString() }));
// is there a destination track assigned for staging cars?
if (rld == _train.getTrainTerminatesRouteLocation() && _terminateStageTrack != null) {
String status = car.testDestination(car.getDestination(), _terminateStageTrack);
if (status.equals(Track.OKAY)) {
addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildCarAssignedToStaging"), new Object[] { car.toString(), _terminateStageTrack.getName() }));
addCarToTrain(car, rl, rld, _terminateStageTrack);
return true;
} else {
addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCanNotDropCarBecause"), new Object[] { car.toString(), _terminateStageTrack.getName(), status, _terminateStageTrack.getTrackTypeName() }));
continue;
}
// no staging at this location, now find a destination track this this car
} else {
List<Track> tracks = car.getDestination().getTrackByMovesList(null);
addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildSearchForTrack"), new Object[] { tracks.size(), car.getDestinationName(), car.toString(), car.getLoadName() }));
for (Track testTrack : tracks) {
// dropping to the same track isn't allowed
if (testTrack == car.getTrack()) {
addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCanNotDropCarSameTrack"), new Object[] { car.toString(), testTrack.getName() }));
continue;
}
// is train direction correct?
if (!checkDropTrainDirection(car, rld, testTrack)) {
continue;
}
// drop to interchange or spur?
if (!checkTrainCanDrop(car, testTrack)) {
continue;
}
String status = car.testDestination(car.getDestination(), testTrack);
// is the testTrack a spur with a schedule and alternate track?
if (!status.equals(Track.OKAY) && status.startsWith(Track.LENGTH) && testTrack.checkSchedule(car).equals(Track.OKAY) && testTrack.getTrackType().equals(Track.SPUR) && testTrack.getAlternateTrack() != null) {
addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildTrackFullHasAlternate"), new Object[] { testTrack.getLocation().getName(), testTrack.getName(), testTrack.getAlternateTrack().getName() }));
String altStatus = car.testDestination(car.getDestination(), testTrack.getAlternateTrack());
// TODO most of the other code only allows a yard or interchange track to be the alternate.
if (altStatus.equals(Track.OKAY) || (altStatus.contains(Track.CUSTOM) && altStatus.contains(Track.LOAD))) {
addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildUseAlternateTrack"), new Object[] { car.toString(), testTrack.getAlternateTrack().getName() }));
// forward the car to the original destination
car.setFinalDestination(car.getDestination());
car.setFinalDestinationTrack(testTrack);
car.setNextLoadName(car.getLoadName());
addCarToTrain(car, rl, rld, testTrack.getAlternateTrack());
// bump the number of moves
testTrack.setMoves(testTrack.getMoves() + 1);
return true;
} else {
addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCanNotDropCarBecause"), new Object[] { car.toString(), testTrack.getAlternateTrack().getName(), altStatus, testTrack.getTrackTypeName() }));
}
}
if (!status.equals(Track.OKAY)) {
addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCanNotDropCarBecause"), new Object[] { car.toString(), testTrack.getName(), status, testTrack.getTrackTypeName() }));
continue;
}
addCarToTrain(car, rl, rld, testTrack);
return true;
}
}
// car has a destination track
} else {
log.debug("Car ({}) has a destination track ({})", car.toString(), car.getDestinationTrack().getName());
// going into the correct staging track?
if (rld.equals(_train.getTrainTerminatesRouteLocation()) && _terminateStageTrack != null && _terminateStageTrack != car.getDestinationTrack()) {
// car going to wrong track in staging, change track
addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCarDestinationStaging"), new Object[] { car.toString(), car.getDestinationName(), car.getDestinationTrackName() }));
car.setDestination(_terminateStageTrack.getLocation(), _terminateStageTrack);
}
if (!rld.equals(_train.getTrainTerminatesRouteLocation()) || _terminateStageTrack == null || _terminateStageTrack == car.getDestinationTrack()) {
// is train direction correct?
if (checkDropTrainDirection(car, rld, car.getDestinationTrack())) {
// drop to interchange or spur?
if (checkTrainCanDrop(car, car.getDestinationTrack())) {
String status = car.testDestination(car.getDestination(), car.getDestinationTrack());
if (status.equals(Track.OKAY) && checkDropTrainDirection(car, rld, car.getDestinationTrack())) {
addCarToTrain(car, rl, rld, car.getDestinationTrack());
return true;
} else {
addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildCanNotDropCarBecause"), new Object[] { car.toString(), car.getDestinationTrackName(), status, car.getDestinationTrack().getTrackTypeName() }));
}
}
}
} else {
throw new BuildFailedException(MessageFormat.format(Bundle.getMessage("buildCarDestinationStaging"), new Object[] { car.toString(), car.getDestinationName(), car.getDestinationTrackName() }));
}
}
addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildCanNotDropCar"), new Object[] { car.toString(), car.getDestinationName(), rld.getId(), locCount }));
if (car.getDestinationTrack() == null) {
log.debug("Could not find a destination track for location ({})", car.getDestinationName());
}
}
log.debug("car ({}) not added to train", car.toString());
addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildDestinationNotReachable"), new Object[] { car.getDestinationName(), rl.getName(), rl.getId() }));
// remove destination and revert to final destination
if (car.getDestinationTrack() != null) {
Track destTrack = car.getDestinationTrack();
// TODO should we leave the car's destination? The spur expects this car!
if (destTrack.getSchedule() != null && destTrack.getScheduleMode() == Track.SEQUENTIAL) {
// log.debug("Scheduled delivery to ("+destTrack.getName()+") cancelled");
addLine(_buildReport, SEVEN, MessageFormat.format(Bundle.getMessage("buildPickupCancelled"), new Object[] { destTrack.getLocation().getName(), destTrack.getName() }));
}
}
car.setFinalDestination(car.getPreviousFinalDestination());
car.setFinalDestinationTrack(car.getPreviousFinalDestinationTrack());
car.setDestination(null, null);
car.updateKernel();
checkCarOrder(car);
// car no longer has a destination, but it had one.
return true;
}
use of jmri.jmrit.operations.routes.RouteLocation in project JMRI by JMRI.
the class TrainBuilder method placeCars.
/**
* Main routine to place cars into the train. Can be called multiple times,
* percent controls how many cars are placed in any given pass. When
* departing staging, ignore those cars on the first pass unless the option
* to build normal was selected by user.
*
* @param percent How much of the available moves should be used in this
* pass.
* @param firstPass True if first pass, ignore cars in staging.
*/
private void placeCars(int percent, boolean firstPass) throws BuildFailedException {
// add line when in normal report mode
addLine(_buildReport, THREE, BLANK_LINE);
if (percent < 100) {
addLine(_buildReport, THREE, MessageFormat.format(Bundle.getMessage("buildMultiplePass"), new Object[] { percent }));
multipass = true;
}
if (percent == 100 && multipass) {
addLine(_buildReport, THREE, Bundle.getMessage("buildFinalPass"));
}
// now go through each location starting at departure and place cars as requested
for (int routeIndex = 0; routeIndex < _routeList.size(); routeIndex++) {
RouteLocation rl = _routeList.get(routeIndex);
if (_train.skipsLocation(rl.getId())) {
addLine(_buildReport, ONE, MessageFormat.format(Bundle.getMessage("buildLocSkipped"), new Object[] { rl.getName(), rl.getId(), _train.getName() }));
continue;
}
if (!rl.isPickUpAllowed()) {
addLine(_buildReport, ONE, MessageFormat.format(Bundle.getMessage("buildLocNoPickups"), new Object[] { _train.getRoute().getName(), rl.getId(), rl.getName() }));
continue;
}
// no pick ups from staging unless at the start of the train's route
if (routeIndex > 0 && rl.getLocation().isStaging()) {
addLine(_buildReport, ONE, MessageFormat.format(Bundle.getMessage("buildNoPickupsFromStaging"), new Object[] { rl.getName() }));
continue;
}
// the next check provides a build report message if there's an issue with the train direction
if (!checkPickUpTrainDirection(rl)) {
continue;
}
// the number of moves completed for this location
_completedMoves = 0;
// true when done with this location
_success = true;
// the number of moves requested
_reqNumOfMoves = (rl.getMaxCarMoves() - rl.getCarMoves()) * percent / 99;
// round up requested moves if less than half way through build. Improves pickups when the move count is small.
int remainder = (rl.getMaxCarMoves() - rl.getCarMoves()) % (100 / percent);
if (percent < 51 && remainder > 0) {
_reqNumOfMoves++;
}
// multiple pass build?
if (firstPass) {
// Departing staging?
if (routeIndex == 0 && _departStageTrack != null) {
// Move cars out of staging after working other locations
_reqNumOfMoves = 0;
// if leaving and returning to staging on the same track temporary pull cars off the track
if (_departStageTrack == _terminateStageTrack) {
if (!_train.isAllowReturnToStagingEnabled() && !Setup.isAllowReturnToStagingEnabled()) {
// takes care of cars in a kernel by getting all cars
for (RollingStock rs : carManager.getList()) {
// don't remove caboose or car with FRED already assigned to train
if (rs.getTrack() == _departStageTrack && rs.getRouteDestination() == null) {
rs.setLocation(rs.getLocation(), null);
}
}
} else {
// since all cars can return to staging, the track space is consumed for now
addLine(_buildReport, THREE, BLANK_LINE);
addLine(_buildReport, THREE, MessageFormat.format(Bundle.getMessage("buildWarnDepartStaging"), new Object[] { _departStageTrack.getLocation().getName(), _departStageTrack.getName() }));
addLine(_buildReport, THREE, BLANK_LINE);
}
}
addLine(_buildReport, THREE, MessageFormat.format(Bundle.getMessage("buildDepartStagingAggressive"), new Object[] { _departStageTrack.getLocation().getName() }));
}
} else if (routeIndex == 0 && _departStageTrack != null && _departStageTrack == _terminateStageTrack && !_train.isAllowReturnToStagingEnabled() && !Setup.isAllowReturnToStagingEnabled()) {
// restore departure track for cars departing staging
for (Car car : _carList) {
if (car.getLocation() == _departStageTrack.getLocation() && car.getTrack() == null) {
// force
car.setLocation(_departStageTrack.getLocation(), _departStageTrack, RollingStock.FORCE);
if (car.getKernel() != null) {
for (Car k : car.getKernel().getCars()) {
// force
k.setLocation(_departStageTrack.getLocation(), _departStageTrack, RollingStock.FORCE);
}
}
}
}
}
// save a copy for status message
int saveReqMoves = _reqNumOfMoves;
addLine(_buildReport, ONE, MessageFormat.format(Bundle.getMessage("buildLocReqMoves"), new Object[] { rl.getName(), rl.getId(), _reqNumOfMoves, rl.getMaxCarMoves() - rl.getCarMoves(), rl.getMaxCarMoves() }));
// add line when in detailed report mode
addLine(_buildReport, FIVE, BLANK_LINE);
// show the car load generation options for staging
if (routeIndex == 0 && _departStageTrack != null && _reqNumOfMoves > 0 && (_departStageTrack.isAddCustomLoadsEnabled() || _departStageTrack.isAddCustomLoadsAnySpurEnabled() || _departStageTrack.isAddCustomLoadsAnyStagingTrackEnabled())) {
addLine(_buildReport, FIVE, MessageFormat.format(Bundle.getMessage("buildCustomLoadOptions"), new Object[] { _departStageTrack.getName() }));
if (_departStageTrack.isAddCustomLoadsEnabled()) {
addLine(_buildReport, FIVE, Bundle.getMessage("buildLoadCarLoads"));
}
if (_departStageTrack.isAddCustomLoadsAnySpurEnabled()) {
addLine(_buildReport, FIVE, Bundle.getMessage("buildLoadAnyCarLoads"));
}
if (_departStageTrack.isAddCustomLoadsAnyStagingTrackEnabled()) {
addLine(_buildReport, FIVE, Bundle.getMessage("buildLoadsStaging"));
}
// add line when in detailed report mode
addLine(_buildReport, FIVE, BLANK_LINE);
}
// see reportCarsNotMoved(rl, percent) below
_carIndex = 0;
findDestinationsForCarsFromLocation(rl, routeIndex, false);
// only in aggressive mode, and at least one car has a new destination
if (Setup.isBuildAggressive() && saveReqMoves != _reqNumOfMoves) {
log.debug("Perform extra pass at location ({})", rl.getName());
// use up to half of the available moves left for this location
if (_reqNumOfMoves < (rl.getMaxCarMoves() - rl.getCarMoves()) * percent / 200) {
_reqNumOfMoves = (rl.getMaxCarMoves() - rl.getCarMoves()) * percent / 200;
}
findDestinationsForCarsFromLocation(rl, routeIndex, true);
}
// we might have freed up space at a spur that has an alternate track
if (redirectCarsFromAlternateTrack()) {
// add line when in very detailed report mode
addLine(_buildReport, SEVEN, BLANK_LINE);
}
if (routeIndex == 0) {
// report ASAP that the build has failed
checkDepartureForStaging(percent);
}
addLine(_buildReport, ONE, MessageFormat.format(Bundle.getMessage("buildStatusMsg"), new Object[] { (saveReqMoves <= _completedMoves ? Bundle.getMessage("Success") : Bundle.getMessage("Partial")), Integer.toString(_completedMoves), Integer.toString(saveReqMoves), rl.getName(), _train.getName() }));
reportCarsNotMoved(rl, percent);
}
// covers the cases: no pick ups, wrong train direction and train skips,
checkDepartureForStaging(percent);
}
Aggregations