mirror of https://github.com/OpenTTD/OpenTTD.git
(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:
parent
3a787f5a0b
commit
b7713a7e85
|
@ -1404,8 +1404,10 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
/* If the destination vehicle had a OrderList, destroy it */
|
/* If the destination vehicle had a OrderList, destroy it.
|
||||||
DeleteVehicleOrders(dst);
|
* 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;
|
dst->orders.list = src->orders.list;
|
||||||
|
|
||||||
|
@ -1451,8 +1453,10 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
||||||
Order *first = NULL;
|
Order *first = NULL;
|
||||||
Order **order_dst;
|
Order **order_dst;
|
||||||
|
|
||||||
/* If the destination vehicle had an order list, destroy the chain but keep the OrderList */
|
/* If the destination vehicle had an order list, destroy the chain but keep the OrderList.
|
||||||
DeleteVehicleOrders(dst, true);
|
* 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;
|
order_dst = &first;
|
||||||
FOR_VEHICLE_ORDERS(src, order) {
|
FOR_VEHICLE_ORDERS(src, order) {
|
||||||
|
@ -1674,11 +1678,15 @@ bool Vehicle::HasDepotOrder() const
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* Delete all orders from a vehicle
|
* 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);
|
DeleteOrderWarnings(v);
|
||||||
|
|
||||||
|
@ -1691,6 +1699,13 @@ void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist)
|
||||||
v->orders.list->FreeChain(keep_orderlist);
|
v->orders.list->FreeChain(keep_orderlist);
|
||||||
if (!keep_orderlist) v->orders.list = NULL;
|
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 */
|
/* Get the current order */
|
||||||
|
assert(v->cur_auto_order_index == 0 || v->cur_auto_order_index < v->GetNumOrders());
|
||||||
v->UpdateRealOrderIndex();
|
v->UpdateRealOrderIndex();
|
||||||
|
|
||||||
const Order *order = v->GetOrder(v->cur_real_order_index);
|
const Order *order = v->GetOrder(v->cur_real_order_index);
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination);
|
void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination);
|
||||||
void InvalidateVehicleOrder(const Vehicle *v, int data);
|
void InvalidateVehicleOrder(const Vehicle *v, int data);
|
||||||
void CheckOrders(const Vehicle*);
|
void CheckOrders(const Vehicle*);
|
||||||
void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist = false);
|
void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist = false, bool reset_order_indices = true);
|
||||||
bool ProcessOrders(Vehicle *v);
|
bool ProcessOrders(Vehicle *v);
|
||||||
bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth = 0);
|
bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth = 0);
|
||||||
VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v);
|
VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v);
|
||||||
|
|
|
@ -2564,6 +2564,9 @@ bool AfterLoadGame()
|
||||||
FOR_ALL_VEHICLES(v) {
|
FOR_ALL_VEHICLES(v) {
|
||||||
if (!v->IsPrimaryVehicle()) continue;
|
if (!v->IsPrimaryVehicle()) continue;
|
||||||
|
|
||||||
|
/* Older versions are less strict with indices being in range and fix them on the fly */
|
||||||
|
if (v->cur_auto_order_index >= v->GetNumOrders()) v->cur_auto_order_index = 0;
|
||||||
|
|
||||||
v->cur_real_order_index = v->cur_auto_order_index;
|
v->cur_real_order_index = v->cur_auto_order_index;
|
||||||
v->UpdateRealOrderIndex();
|
v->UpdateRealOrderIndex();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue