(svn r22046) -Fix [FS#4487]: Make sure order indices stay in range when copying, sharing, unsharing or deleting all orders.

This commit is contained in:
frosch
2011-02-09 21:40:32 +00:00
parent 3a787f5a0b
commit b7713a7e85
3 changed files with 27 additions and 8 deletions

View File

@@ -1404,8 +1404,10 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
}
if (flags & DC_EXEC) {
/* If the destination vehicle had a OrderList, destroy it */
DeleteVehicleOrders(dst);
/* If the destination vehicle had a OrderList, destroy it.
* We only reset the order indices, if the new orders are obviously different.
* (We mainly do this to keep the order indices valid and in range.) */
DeleteVehicleOrders(dst, false, dst->GetNumOrders() != src->GetNumOrders());
dst->orders.list = src->orders.list;
@@ -1451,8 +1453,10 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
Order *first = NULL;
Order **order_dst;
/* If the destination vehicle had an order list, destroy the chain but keep the OrderList */
DeleteVehicleOrders(dst, true);
/* If the destination vehicle had an order list, destroy the chain but keep the OrderList.
* We only reset the order indices, if the new orders are obviously different.
* (We mainly do this to keep the order indices valid and in range.) */
DeleteVehicleOrders(dst, true, dst->GetNumOrders() != src->GetNumOrders());
order_dst = &first;
FOR_VEHICLE_ORDERS(src, order) {
@@ -1674,11 +1678,15 @@ bool Vehicle::HasDepotOrder() const
}
/**
*
* Delete all orders from a vehicle
*
* @param v Vehicle whose orders to reset
* @param keep_orderlist If true, do not free the order list, only empty it.
* @param reset_order_indices If true, reset cur_auto_order_index and cur_real_order_index
* and cancel the current full load order (if the vehicle is loading).
* If false, _you_ have to make sure the order indices are valid after
* your messing with them!
*/
void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist)
void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist, bool reset_order_indices)
{
DeleteOrderWarnings(v);
@@ -1691,6 +1699,13 @@ void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist)
v->orders.list->FreeChain(keep_orderlist);
if (!keep_orderlist) v->orders.list = NULL;
}
if (reset_order_indices) {
v->cur_auto_order_index = v->cur_real_order_index = 0;
if (v->current_order.IsType(OT_LOADING)) {
CancelLoadingDueToDeletedOrder(v);
}
}
}
/**
@@ -1927,6 +1942,7 @@ bool ProcessOrders(Vehicle *v)
}
/* Get the current order */
assert(v->cur_auto_order_index == 0 || v->cur_auto_order_index < v->GetNumOrders());
v->UpdateRealOrderIndex();
const Order *order = v->GetOrder(v->cur_real_order_index);