From 967bb84af34c317b8170867eceae5ea05c60fd6e Mon Sep 17 00:00:00 2001 From: yexo Date: Sun, 23 Jan 2011 13:08:50 +0000 Subject: (svn r21900) -Fix: [NoAI] hide automatic orders from AIs as they have no way of dealing with them --- src/ai/api/ai_order.cpp | 37 +++++++++++++++++++++++++++---------- src/ai/api/ai_order.hpp | 8 +++++++- 2 files changed, 34 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/ai/api/ai_order.cpp b/src/ai/api/ai_order.cpp index a79a6e7dd..fbf284563 100644 --- a/src/ai/api/ai_order.cpp +++ b/src/ai/api/ai_order.cpp @@ -48,7 +48,7 @@ static OrderType GetOrderTypeByTile(TileIndex t) /* static */ bool AIOrder::IsValidVehicleOrder(VehicleID vehicle_id, OrderPosition order_position) { - return AIVehicle::IsValidVehicle(vehicle_id) && order_position >= 0 && (order_position < ::Vehicle::Get(vehicle_id)->GetNumOrders() || order_position == ORDER_CURRENT); + return AIVehicle::IsValidVehicle(vehicle_id) && order_position >= 0 && (order_position < ::Vehicle::Get(vehicle_id)->GetNumManualOrders() || order_position == ORDER_CURRENT); } /** @@ -65,7 +65,14 @@ static const Order *ResolveOrder(VehicleID vehicle_id, AIOrder::OrderPosition or order_position = AIOrder::ResolveOrderPosition(vehicle_id, order_position); if (order_position == AIOrder::ORDER_INVALID) return NULL; } - return v->GetOrder(order_position); + const Order *order = v->orders.list->GetFirstOrder(); + while (order->GetType() == OT_AUTOMATIC) order = order->next; + while (order_position > 0) { + order_position = (AIOrder::OrderPosition)(order_position - 1); + order = order->next; + while (order->GetType() == OT_AUTOMATIC) order = order->next; + } + return order; } /* static */ bool AIOrder::IsGotoStationOrder(VehicleID vehicle_id, OrderPosition order_position) @@ -124,8 +131,18 @@ static const Order *ResolveOrder(VehicleID vehicle_id, AIOrder::OrderPosition or { if (!AIVehicle::IsValidVehicle(vehicle_id)) return ORDER_INVALID; - if (order_position == ORDER_CURRENT) return (AIOrder::OrderPosition)::Vehicle::Get(vehicle_id)->cur_order_index; - return (order_position >= 0 && order_position < ::Vehicle::Get(vehicle_id)->GetNumOrders()) ? order_position : ORDER_INVALID; + if (order_position == ORDER_CURRENT) { + int cur_order_pos = ::Vehicle::Get(vehicle_id)->cur_order_index; + const Order *order = ::Vehicle::Get(vehicle_id)->GetOrder(0); + if (order == NULL) return ORDER_INVALID; + int num_automatic_orders = 0; + for (int i = 0; i < cur_order_pos; i++) { + if (order->GetType() == OT_AUTOMATIC) num_automatic_orders++; + order = order->next; + } + return (AIOrder::OrderPosition)(cur_order_pos - num_automatic_orders); + } + return (order_position >= 0 && order_position < ::Vehicle::Get(vehicle_id)->GetNumManualOrders()) ? order_position : ORDER_INVALID; } @@ -262,7 +279,7 @@ static const Order *ResolveOrder(VehicleID vehicle_id, AIOrder::OrderPosition or if (!IsValidVehicleOrder(vehicle_id, order_position)) return ORDER_INVALID; if (order_position == ORDER_CURRENT || !IsConditionalOrder(vehicle_id, order_position)) return ORDER_INVALID; - const Order *order = Vehicle::Get(vehicle_id)->GetOrder(order_position); + const Order *order = ::ResolveOrder(vehicle_id, order_position); return (OrderPosition)order->GetConditionSkipToOrder(); } @@ -271,7 +288,7 @@ static const Order *ResolveOrder(VehicleID vehicle_id, AIOrder::OrderPosition or if (!IsValidVehicleOrder(vehicle_id, order_position)) return OC_INVALID; if (order_position == ORDER_CURRENT || !IsConditionalOrder(vehicle_id, order_position)) return OC_INVALID; - const Order *order = Vehicle::Get(vehicle_id)->GetOrder(order_position); + const Order *order = ::ResolveOrder(vehicle_id, order_position); return (OrderCondition)order->GetConditionVariable(); } @@ -280,7 +297,7 @@ static const Order *ResolveOrder(VehicleID vehicle_id, AIOrder::OrderPosition or if (!IsValidVehicleOrder(vehicle_id, order_position)) return CF_INVALID; if (order_position == ORDER_CURRENT || !IsConditionalOrder(vehicle_id, order_position)) return CF_INVALID; - const Order *order = Vehicle::Get(vehicle_id)->GetOrder(order_position); + const Order *order = ::ResolveOrder(vehicle_id, order_position); return (CompareFunction)order->GetConditionComparator(); } @@ -289,7 +306,7 @@ static const Order *ResolveOrder(VehicleID vehicle_id, AIOrder::OrderPosition or if (!IsValidVehicleOrder(vehicle_id, order_position)) return -1; if (order_position == ORDER_CURRENT || !IsConditionalOrder(vehicle_id, order_position)) return -1; - const Order *order = Vehicle::Get(vehicle_id)->GetOrder(order_position); + const Order *order = ::ResolveOrder(vehicle_id, order_position); int32 value = order->GetConditionValue(); if (order->GetConditionVariable() == OCV_MAX_SPEED) value = value * 16 / 10; return value; @@ -301,7 +318,7 @@ static const Order *ResolveOrder(VehicleID vehicle_id, AIOrder::OrderPosition or if (AIVehicle::GetVehicleType(vehicle_id) != AIVehicle::VT_RAIL) return STOPLOCATION_INVALID; if (!IsGotoStationOrder(vehicle_id, order_position)) return STOPLOCATION_INVALID; - const Order *order = Vehicle::Get(vehicle_id)->GetOrder(order_position); + const Order *order = ::ResolveOrder(vehicle_id, order_position); return (AIOrder::StopLocation)order->GetStopLocation(); } @@ -488,7 +505,7 @@ static void _DoCommandReturnSetOrderFlags(class AIInstance *instance) EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position)); EnforcePrecondition(false, AreOrderFlagsValid(GetOrderDestination(vehicle_id, order_position), order_flags)); - const Order *order = Vehicle::Get(vehicle_id)->GetOrder(order_position); + const Order *order = ::ResolveOrder(vehicle_id, order_position); AIOrderFlags current = GetOrderFlags(vehicle_id, order_position); diff --git a/src/ai/api/ai_order.hpp b/src/ai/api/ai_order.hpp index fbf9fed76..bfd10a0a9 100644 --- a/src/ai/api/ai_order.hpp +++ b/src/ai/api/ai_order.hpp @@ -112,7 +112,13 @@ public: CF_INVALID = -1, ///< Invalid compare function, do not use. }; - /** Different constants related to the OrderPosition */ + /** + * Index in the list of orders for a vehicle. The first order has index 0, the second + * order index 1, etc. The current order can be queried by using ORDER_CURRENT. Do not + * use ORDER_INVALID yourself, it's used as return value by for example ResolveOrderPosition. + * @note Automatic orders are hidden from AIs, so OrderPosition 0 will always be the first + * manual order. + */ enum OrderPosition { ORDER_CURRENT = 0xFF, ///< Constant that gets resolved to the current order. ORDER_INVALID = -1, ///< An invalid order. -- cgit v1.2.3-70-g09d2