changeset 17162:18e173373bb0 draft

(svn r21900) -Fix: [NoAI] hide automatic orders from AIs as they have no way of dealing with them
author yexo <yexo@openttd.org>
date Sun, 23 Jan 2011 13:08:50 +0000
parents 3ac03eb337d8
children 5cdb72b33b97
files src/ai/api/ai_order.cpp src/ai/api/ai_order.hpp
diffstat 2 files changed, 34 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/ai/api/ai_order.cpp
+++ b/src/ai/api/ai_order.cpp
@@ -48,7 +48,7 @@
 
 /* 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 @@
 		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 @@
 {
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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);
 
--- a/src/ai/api/ai_order.hpp
+++ b/src/ai/api/ai_order.hpp
@@ -112,7 +112,13 @@
 		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.