From d8365c63fd56352f07418bd079a971c043fa13b8 Mon Sep 17 00:00:00 2001 From: fonsinchen Date: Tue, 20 Aug 2013 20:05:31 +0000 Subject: [PATCH] (svn r25735) -Feature: allow implicit orders even if no explicit ones are given. --- src/order_type.h | 6 ++++++ src/vehicle.cpp | 32 ++++++++++++++++++++++---------- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/order_type.h b/src/order_type.h index 947f00da86..d3a771ce8b 100644 --- a/src/order_type.h +++ b/src/order_type.h @@ -27,6 +27,12 @@ static const VehicleOrderID MAX_VEH_ORDER_ID = INVALID_VEH_ORDER_ID - 1; /** Invalid order (sentinel) */ static const OrderID INVALID_ORDER = 0xFFFF; +/** + * Maximum number of orders in implicit-only lists before we start searching + * harder for duplicates. + */ +static const uint IMPLICIT_ORDER_ONLY_CAP = 32; + /** Order types */ enum OrderType { OT_BEGIN = 0, diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 7d9a67924a..8a21b7ce96 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1943,13 +1943,12 @@ void Vehicle::BeginLoading() } else { /* We weren't scheduled to stop here. Insert an implicit order - * to show that we are stopping here, but only do that if the order - * list isn't empty. + * to show that we are stopping here. * While only groundvehicles have implicit orders, e.g. aircraft might still enter * the 'wrong' terminal when skipping orders etc. */ Order *in_list = this->GetOrder(this->cur_implicit_order_index); - if (this->IsGroundVehicle() && in_list != NULL && - (!in_list->IsType(OT_IMPLICIT) || + if (this->IsGroundVehicle() && + (in_list == NULL || !in_list->IsType(OT_IMPLICIT) || in_list->GetDestination() != this->last_station_visited)) { bool suppress_implicit_orders = HasBit(this->GetGroundVehicleFlags(), GVF_SUPPRESS_IMPLICIT_ORDERS); /* Do not create consecutive duplicates of implicit orders */ @@ -1959,18 +1958,28 @@ void Vehicle::BeginLoading() prev_order->GetDestination() != this->last_station_visited) { /* Prefer deleting implicit orders instead of inserting new ones, - * so test whether the right order follows later */ + * so test whether the right order follows later. In case of only + * implicit orders treat the last order in the list like an + * explicit one, except if the overall number of orders surpasses + * IMPLICIT_ORDER_ONLY_CAP. */ int target_index = this->cur_implicit_order_index; bool found = false; - while (target_index != this->cur_real_order_index) { + while (target_index != this->cur_real_order_index || this->GetNumManualOrders() == 0) { const Order *order = this->GetOrder(target_index); + if (order == NULL) break; // No orders. if (order->IsType(OT_IMPLICIT) && order->GetDestination() == this->last_station_visited) { found = true; break; } target_index++; - if (target_index >= this->orders.list->GetNumOrders()) target_index = 0; - assert(target_index != this->cur_implicit_order_index); // infinite loop? + if (target_index >= this->orders.list->GetNumOrders()) { + if (this->GetNumManualOrders() == 0 && + this->GetNumOrders() < IMPLICIT_ORDER_ONLY_CAP) { + break; + } + target_index = 0; + } + if (target_index == this->cur_implicit_order_index) break; // Avoid infinite loop. } if (found) { @@ -2000,7 +2009,10 @@ void Vehicle::BeginLoading() assert(order != NULL); } } - } else if (!suppress_implicit_orders && this->orders.list->GetNumOrders() < MAX_VEH_ORDER_ID && Order::CanAllocateItem()) { + } else if (!suppress_implicit_orders && + ((this->orders.list == NULL && OrderList::CanAllocateItem()) || + this->orders.list->GetNumOrders() < MAX_VEH_ORDER_ID) && + Order::CanAllocateItem()) { /* Insert new implicit order */ Order *implicit_order = new Order(); implicit_order->MakeImplicit(this->last_station_visited); @@ -2381,7 +2393,7 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command) if (flags & DC_EXEC) { if (this->current_order.IsType(OT_LOADING)) this->LeaveStation(); - if (this->IsGroundVehicle()) { + if (this->IsGroundVehicle() && this->GetNumManualOrders() > 0) { uint16 &gv_flags = this->GetGroundVehicleFlags(); SetBit(gv_flags, GVF_SUPPRESS_IMPLICIT_ORDERS); }