summaryrefslogtreecommitdiff
path: root/src/ai/api/ai_order.cpp
diff options
context:
space:
mode:
authoryexo <yexo@openttd.org>2009-02-19 23:12:57 +0000
committeryexo <yexo@openttd.org>2009-02-19 23:12:57 +0000
commitb3fe664d9017d21fd7b4360589f590b8207e503e (patch)
tree62ff4dcbb5936051928b052986bfaf6dc344bc8f /src/ai/api/ai_order.cpp
parent2fdc395d45d65f2b9cf8a54a90af87f20f2de778 (diff)
downloadopenttd-b3fe664d9017d21fd7b4360589f590b8207e503e.tar.xz
(svn r15526) -Add [NoAI]: Support for conditional orders.
Diffstat (limited to 'src/ai/api/ai_order.cpp')
-rw-r--r--src/ai/api/ai_order.cpp138
1 files changed, 132 insertions, 6 deletions
diff --git a/src/ai/api/ai_order.cpp b/src/ai/api/ai_order.cpp
index 6e8b1163a..194addf20 100644
--- a/src/ai/api/ai_order.cpp
+++ b/src/ai/api/ai_order.cpp
@@ -42,6 +42,15 @@ static OrderType GetOrderTypeByTile(TileIndex t)
return AIVehicle::IsValidVehicle(vehicle_id) && order_position >= 0 && (order_position < ::GetVehicle(vehicle_id)->GetNumOrders() || order_position == ORDER_CURRENT);
}
+/* static */ bool AIOrder::IsConditionalOrder(VehicleID vehicle_id, OrderPosition order_position)
+{
+ if (order_position == ORDER_CURRENT) return false;
+ if (!IsValidVehicleOrder(vehicle_id, order_position)) return false;
+
+ const Order *order = ::GetVehicleOrder(GetVehicle(vehicle_id), order_position);
+ return order->GetType() == OT_CONDITIONAL;
+}
+
/* static */ AIOrder::OrderPosition AIOrder::ResolveOrderPosition(VehicleID vehicle_id, OrderPosition order_position)
{
if (!AIVehicle::IsValidVehicle(vehicle_id)) return ORDER_INVALID;
@@ -70,6 +79,25 @@ static OrderType GetOrderTypeByTile(TileIndex t)
}
}
+/* static */ bool AIOrder::IsValidConditionalOrder(OrderCondition condition, CompareFunction compare)
+{
+ switch (condition) {
+ case OC_LOAD_PERCENTAGE:
+ case OC_RELIABILITY:
+ case OC_MAX_SPEED:
+ case OC_AGE:
+ return compare >= CF_EQUALS && compare <= CF_MORE_EQUALS);
+
+ case OC_REQUIRES_SERVICE:
+ return compare == CF_IS_TRUE || compare == CF_IS_FALSE;
+
+ case OC_UNCONDITIONALLY:
+ return true;
+
+ default: return false;
+ }
+}
+
/* static */ int32 AIOrder::GetOrderCount(VehicleID vehicle_id)
{
return AIVehicle::IsValidVehicle(vehicle_id) ? ::GetVehicle(vehicle_id)->GetNumOrders() : -1;
@@ -84,8 +112,8 @@ static OrderType GetOrderTypeByTile(TileIndex t)
if (order_position == ORDER_CURRENT) {
order = &v->current_order;
} else {
- order = v->GetFirstOrder();
- for (int i = 0; i < order_position; i++) order = order->next;
+ order = ::GetVehicleOrder(GetVehicle(vehicle_id), order_position);
+ if (order->GetType() == OT_CONDITIONAL) return INVALID_TILE;
}
switch (order->GetType()) {
@@ -107,8 +135,8 @@ static OrderType GetOrderTypeByTile(TileIndex t)
if (order_position == ORDER_CURRENT) {
order = &::GetVehicle(vehicle_id)->current_order;
} else {
- order = ::GetVehicle(vehicle_id)->GetFirstOrder();
- for (int i = 0; i < order_position; i++) order = order->next;
+ order = ::GetVehicleOrder(GetVehicle(vehicle_id), order_position);
+ if (order->GetType() == OT_CONDITIONAL) return AIOF_INVALID;
}
AIOrderFlags order_flags = AIOF_NONE;
@@ -129,12 +157,97 @@ static OrderType GetOrderTypeByTile(TileIndex t)
return order_flags;
}
+/* static */ AIOrder::OrderPosition AIOrder::GetOrderJumpTo(VehicleID vehicle_id, OrderPosition order_position)
+{
+ 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 = ::GetVehicleOrder(GetVehicle(vehicle_id), order_position);
+ return (OrderPosition)order->GetConditionSkipToOrder();
+}
+
+/* static */ AIOrder::OrderCondition AIOrder::GetOrderCondition(VehicleID vehicle_id, OrderPosition order_position)
+{
+ 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 = ::GetVehicleOrder(GetVehicle(vehicle_id), order_position);
+ return (OrderCondition)order->GetConditionVariable();
+}
+
+/* static */ AIOrder::CompareFunction AIOrder::GetOrderCompareFunction(VehicleID vehicle_id, OrderPosition order_position)
+{
+ 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 = ::GetVehicleOrder(GetVehicle(vehicle_id), order_position);
+ return (CompareFunction)order->GetConditionComparator();
+}
+
+/* static */ int32 AIOrder::GetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position)
+{
+ if (!IsValidVehicleOrder(vehicle_id, order_position)) return -1;
+ if (order_position == ORDER_CURRENT || !IsConditionalOrder(vehicle_id, order_position)) return -1;
+
+ const Order *order = ::GetVehicleOrder(GetVehicle(vehicle_id), order_position);
+ int32 value = order->GetConditionValue();
+ if (order->GetConditionVariable() == OCV_MAX_SPEED) value = value * 16 / 10;
+ return value;
+}
+
+/* static */ bool AIOrder::SetOrderJumpTo(VehicleID vehicle_id, OrderPosition order_position, OrderPosition jump_to)
+{
+ EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
+ EnforcePrecondition(false, order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position));
+ EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, jump_to) && jump_to != ORDER_CURRENT);
+
+ return AIObject::DoCommand(0, vehicle_id | (order_position << 16), MOF_COND_DESTINATION | (jump_to << 4), CMD_MODIFY_ORDER);
+}
+
+/* static */ bool AIOrder::SetOrderCondition(VehicleID vehicle_id, OrderPosition order_position, OrderCondition condition)
+{
+ EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
+ EnforcePrecondition(false, order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position));
+ EnforcePrecondition(false, condition >= OC_LOAD_PERCENTAGE && condition <= OC_UNCONDITIONALLY);
+
+ return AIObject::DoCommand(0, vehicle_id | (order_position << 16), MOF_COND_VARIABLE | (condition << 4), CMD_MODIFY_ORDER);
+}
+
+/* static */ bool AIOrder::SetOrderCompareFunction(VehicleID vehicle_id, OrderPosition order_position, CompareFunction compare)
+{
+ EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
+ EnforcePrecondition(false, order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position));
+ EnforcePrecondition(false, compare >= CF_EQUALS && compare <= CF_IS_FALSE);
+
+ return AIObject::DoCommand(0, vehicle_id | (order_position << 16), MOF_COND_COMPARATOR | (compare << 4), CMD_MODIFY_ORDER);
+}
+
+/* static */ bool AIOrder::SetOrderCompareValue(VehicleID vehicle_id, OrderPosition order_position, int32 value)
+{
+ EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
+ EnforcePrecondition(false, order_position != ORDER_CURRENT && IsConditionalOrder(vehicle_id, order_position));
+ EnforcePrecondition(false, value >= 0 && value < 2048);
+ if (GetOrderCondition(vehicle_id, order_position) == OC_MAX_SPEED) value = value * 10 / 16;
+
+ return AIObject::DoCommand(0, vehicle_id | (order_position << 16), MOF_COND_VALUE | (value << 4), CMD_MODIFY_ORDER);
+}
+
/* static */ bool AIOrder::AppendOrder(VehicleID vehicle_id, TileIndex destination, AIOrderFlags order_flags)
{
EnforcePrecondition(false, AIVehicle::IsValidVehicle(vehicle_id));
+ EnforcePrecondition(false, AreOrderFlagsValid(destination, order_flags));
+
return InsertOrder(vehicle_id, (AIOrder::OrderPosition)::GetVehicle(vehicle_id)->GetNumOrders(), destination, order_flags);
}
+/* static */ bool AIOrder::AppendConditionalOrder(VehicleID vehicle_id, OrderPosition jump_to)
+{
+ EnforcePrecondition(false, AIVehicle::IsValidVehicle(vehicle_id));
+ EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, jump_to));
+
+ return InsertConditionalOrder(vehicle_id, (AIOrder::OrderPosition)::GetVehicle(vehicle_id)->GetNumOrders(), jump_to);
+}
+
/* static */ bool AIOrder::InsertOrder(VehicleID vehicle_id, OrderPosition order_position, TileIndex destination, AIOrder::AIOrderFlags order_flags)
{
/* IsValidVehicleOrder is not good enough because it does not allow appending. */
@@ -169,6 +282,20 @@ static OrderType GetOrderTypeByTile(TileIndex t)
return AIObject::DoCommand(0, vehicle_id | (order_position << 16), order.Pack(), CMD_INSERT_ORDER);
}
+/* static */ bool AIOrder::InsertConditionalOrder(VehicleID vehicle_id, OrderPosition order_position, OrderPosition jump_to)
+{
+ /* IsValidVehicleOrder is not good enough because it does not allow appending. */
+ if (order_position == ORDER_CURRENT) order_position = AIOrder::ResolveOrderPosition(vehicle_id, order_position);
+
+ EnforcePrecondition(false, AIVehicle::IsValidVehicle(vehicle_id));
+ EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, jump_to));
+
+ Order order;
+ order.MakeConditional(jump_to);
+
+ return AIObject::DoCommand(0, vehicle_id | (order_position << 16), order.Pack(), CMD_INSERT_ORDER);
+}
+
/* static */ bool AIOrder::RemoveOrder(VehicleID vehicle_id, OrderPosition order_position)
{
order_position = AIOrder::ResolveOrderPosition(vehicle_id, order_position);
@@ -211,8 +338,7 @@ static void _DoCommandReturnChangeOrder(class AIInstance *instance)
EnforcePrecondition(false, IsValidVehicleOrder(vehicle_id, order_position));
EnforcePrecondition(false, AreOrderFlagsValid(GetOrderDestination(vehicle_id, order_position), order_flags));
- Order *order = ::GetVehicle(vehicle_id)->GetFirstOrder();
- for (int i = 0; i < order_position; i++) order = order->next;
+ const Order *order = ::GetVehicleOrder(GetVehicle(vehicle_id), order_position);
AIOrderFlags current = GetOrderFlags(vehicle_id, order_position);