}
@Override
public MoveProgress moveTo(MovingRoadUser object,
RoadUser destinationRoadUser, TimeLapse time) {
final PDPModel pm = pdpModel.get();
DestinationObject newDestinationObject;
if (destinationRoadUser instanceof DefaultParcel) {
final DefaultParcel dp = (DefaultParcel) destinationRoadUser;
final DestType type = containsObject(dp) ? DestType.PICKUP
: DestType.DELIVERY;
final Point pos = getParcelPos(destinationRoadUser);
if (type == DestType.DELIVERY) {
checkArgument(
pm.containerContains((DefaultVehicle) object,
(DefaultParcel) destinationRoadUser),
"A vehicle can only move to the delivery location of a parcel if it is carrying it.");
}
newDestinationObject = new DestinationObject(type, pos, dp);
} else {
newDestinationObject = new DestinationObject(DestType.DEPOT,
getPosition(destinationRoadUser), destinationRoadUser);
}
boolean destChange = true;
if (destinations.containsKey(object) && !allowDiversion) {
final DestinationObject prev = destinations.get(object);
final boolean atDestination = getPosition(object).equals(prev.dest);
if (!atDestination && prev.type != DestType.DEPOT) {
// when we haven't reached our destination and the destination
// isn't the depot we are not allowed to change destination
checkArgument(
prev.roadUser == destinationRoadUser
|| isAlreadyServiced(prev.type, prev.roadUser),
"Diversion from the current destination is not allowed. Prev: %s, new: %s.",
prev, destinationRoadUser);
destChange = false;
} else
// change destination
if (prev.type == DestType.PICKUP) {
// when we are at the prev destination, and it was a pickup, we are
// allowed to move if it has been picked up
checkArgument(
pm.getParcelState((DefaultParcel) prev.roadUser) != ParcelState.AVAILABLE,
"Can not move away before the parcel has been picked up: %s.",
prev.roadUser);
} else if (prev.type == DestType.DELIVERY) {
// when we are at the prev destination and it was a delivery, we are
// allowed to move to other objects only, and only if the parcel is
// delivered
checkArgument(prev.roadUser != destinationRoadUser,
"Can not move to the same parcel since we are already there: %s.",
prev.roadUser);
checkArgument(
pm.getParcelState((DefaultParcel) prev.roadUser) == ParcelState.DELIVERED,
"The parcel needs to be delivered before moving away: %s.",
prev.roadUser);
} else {
// it is a depot
// the destination is only changed in case we are no longer going