(svn r21933) -Codechange: Split cur_order_index into cur_auto_order_index and cur_real_order_index to keep track of the current real order in an unambiguous way.

-Fix [FS#4440]: Automatic orders behave now stable wrt. service orders and are not added or removed depending on the need of servicing.
-Fix: Various other issues with automatic orders, e.g. vehicles getting stuck with "no orders" when there are automatic orders at the end of the order list.
This commit is contained in:
frosch
2011-01-31 20:44:15 +00:00
parent 67a5cd0b18
commit a97d52a29a
17 changed files with 242 additions and 97 deletions

View File

@@ -1266,7 +1266,7 @@ void VehicleEnterDepot(Vehicle *v)
if (v->current_order.IsType(OT_GOTO_DEPOT)) {
SetWindowDirty(WC_VEHICLE_VIEW, v->index);
const Order *real_order = v->GetNextManualOrder(v->cur_order_index);
const Order *real_order = v->GetOrder(v->cur_real_order_index);
Order t = v->current_order;
v->current_order.MakeDummy();
@@ -1303,7 +1303,7 @@ void VehicleEnterDepot(Vehicle *v)
/* Part of orders */
v->DeleteUnreachedAutoOrders();
UpdateVehicleTimetable(v, true);
v->IncrementOrderIndex();
v->IncrementAutoOrderIndex();
}
if (t.GetDepotActionType() & ODATFB_HALT) {
/* Vehicles are always stopped on entering depots. Do not restart this one. */
@@ -1797,11 +1797,25 @@ uint GetVehicleCapacity(const Vehicle *v, uint16 *mail_capacity)
*/
void Vehicle::DeleteUnreachedAutoOrders()
{
const Order *order = this->GetOrder(this->cur_order_index);
while (order != NULL && order->IsType(OT_AUTOMATIC)) {
/* Delete order effectively deletes order, so get the next before deleting it. */
order = order->next;
DeleteOrder(this, this->cur_order_index);
const Order *order = this->GetOrder(this->cur_auto_order_index);
while (order != NULL) {
if (this->cur_auto_order_index == this->cur_real_order_index) break;
if (order->IsType(OT_AUTOMATIC)) {
/* Delete order effectively deletes order, so get the next before deleting it. */
order = order->next;
DeleteOrder(this, this->cur_auto_order_index);
} else {
/* Skip non-automatic orders, e.g. service-orders */
order = order->next;
this->cur_auto_order_index++;
}
/* Wrap around */
if (order == NULL) {
order = this->GetOrder(0);
this->cur_auto_order_index = 0;
}
}
}
@@ -1817,7 +1831,7 @@ void Vehicle::BeginLoading()
this->current_order.GetDestination() == this->last_station_visited) {
this->DeleteUnreachedAutoOrders();
/* Now cur_order_index points to the destination station, and we can start loading */
/* Now both order indices point to the destination station, and we can start loading */
this->current_order.MakeLoading(true);
UpdateVehicleTimetable(this, true);
@@ -1832,14 +1846,14 @@ void Vehicle::BeginLoading()
/* We weren't scheduled to stop here. Insert an automatic order
* to show that we are stopping here, but only do that if the order
* list isn't empty. */
Order *in_list = this->GetOrder(this->cur_order_index);
Order *in_list = this->GetOrder(this->cur_auto_order_index);
if (in_list != NULL && this->orders.list->GetNumOrders() < MAX_VEH_ORDER_ID &&
(!in_list->IsType(OT_AUTOMATIC) ||
in_list->GetDestination() != this->last_station_visited)) {
Order *auto_order = new Order();
auto_order->MakeAutomatic(this->last_station_visited);
InsertOrder(this, auto_order, this->cur_order_index);
if (this->cur_order_index > 0) --this->cur_order_index;
InsertOrder(this, auto_order, this->cur_auto_order_index);
if (this->cur_auto_order_index > 0) --this->cur_auto_order_index;
}
this->current_order.MakeLoading(false);
}
@@ -1913,7 +1927,7 @@ void Vehicle::HandleLoading(bool mode)
default: return;
}
this->IncrementOrderIndex();
this->IncrementAutoOrderIndex();
}
/**
@@ -1948,7 +1962,7 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command)
if (flags & DC_EXEC) {
/* If the orders to 'goto depot' are in the orders list (forced servicing),
* then skip to the next order; effectively cancelling this forced service */
if (this->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) this->IncrementOrderIndex();
if (this->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) this->IncrementRealOrderIndex();
this->current_order.MakeDummy();
SetWindowWidgetDirty(WC_VEHICLE_VIEW, this->index, VVW_WIDGET_START_STOP_VEH);
@@ -2261,20 +2275,6 @@ void Vehicle::RemoveFromShared()
this->previous_shared = NULL;
}
/**
* Get the next manual (not OT_AUTOMATIC) order after the one at the given index.
* @param index The index to start searching at.
* @return The next manual order at or after index or NULL if there is none.
*/
Order *Vehicle::GetNextManualOrder(int index) const
{
Order *order = this->GetOrder(index);
while (order != NULL && order->IsType(OT_AUTOMATIC)) {
order = order->next;
}
return order;
}
void VehiclesYearlyLoop()
{
Vehicle *v;