(svn r9374) [NoAI] -Add: functionality to modify orders.
--- a/projects/openttd.vcproj Tue Mar 20 13:55:04 2007 +0000
+++ b/projects/openttd.vcproj Tue Mar 20 14:27:54 2007 +0000
@@ -1048,6 +1048,9 @@
RelativePath=".\..\src\ai\api\ai_object.hpp">
</File>
<File
+ RelativePath=".\..\src\ai\api\ai_order.hpp">
+ </File>
+ <File
RelativePath=".\..\src\ai\api\ai_road.hpp">
</File>
<File
@@ -1097,6 +1100,9 @@
RelativePath=".\..\src\ai\api\ai_object.cpp">
</File>
<File
+ RelativePath=".\..\src\ai\api\ai_order.cpp">
+ </File>
+ <File
RelativePath=".\..\src\ai\api\ai_road.cpp">
</File>
<File
--- a/projects/openttd_vs80.vcproj Tue Mar 20 13:55:04 2007 +0000
+++ b/projects/openttd_vs80.vcproj Tue Mar 20 14:27:54 2007 +0000
@@ -1616,6 +1616,10 @@
>
</File>
<File
+ RelativePath=".\..\src\ai\api\ai_order.hpp"
+ >
+ </File>
+ <File
RelativePath=".\..\src\ai\api\ai_road.hpp"
>
</File>
@@ -1680,6 +1684,10 @@
>
</File>
<File
+ RelativePath=".\..\src\ai\api\ai_order.cpp"
+ >
+ </File>
+ <File
RelativePath=".\..\src\ai\api\ai_road.cpp"
>
</File>
--- a/source.list Tue Mar 20 13:55:04 2007 +0000
+++ b/source.list Tue Mar 20 14:27:54 2007 +0000
@@ -321,6 +321,7 @@
ai/api/ai_industry.hpp
ai/api/ai_map.hpp
ai/api/ai_object.hpp
+ai/api/ai_order.hpp
ai/api/ai_road.hpp
ai/api/ai_settings.hpp
ai/api/ai_town.hpp
@@ -338,6 +339,7 @@
ai/api/ai_industry.cpp
ai/api/ai_map.cpp
ai/api/ai_object.cpp
+ai/api/ai_order.cpp
ai/api/ai_road.cpp
ai/api/ai_settings.cpp
ai/api/ai_town.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/api/ai_order.cpp Tue Mar 20 14:27:54 2007 +0000
@@ -0,0 +1,147 @@
+/* $Id$ */
+
+/** @file ai_order.cpp handles the functions of the AIOrder class */
+
+#include "ai_order.hpp"
+#include "ai_map.hpp"
+#include "ai_vehicle.hpp"
+#include "../../command.h"
+#include "../../order.h"
+
+#include "../../depot.h"
+#include "../../rail_map.h"
+#include "../../road_map.h"
+#include "../../station_map.h"
+#include "../../water_map.h"
+#include "../../waypoint.h"
+
+/**
+ * Gets the order type given a tile
+ * @param t the tile to get the order from
+ * @return the order type, or OT_END when there is no order
+ */
+static OrderType GetOrderTypeByTile(TileIndex t)
+{
+ if (!::IsValidTile(t)) return OT_END;
+
+ switch (::GetTileType(t)) {
+ default: break;
+ case MP_STATION: return OT_GOTO_STATION; break;
+ case MP_WATER: if (::IsShipDepot(t)) return OT_GOTO_DEPOT; break;
+ case MP_STREET: if (::GetRoadTileType(t) == ROAD_TILE_DEPOT) return OT_GOTO_DEPOT; break;
+ case MP_RAILWAY:
+ switch (::GetRailTileType(t)) {
+ case RAIL_TILE_DEPOT: return OT_GOTO_DEPOT;
+ case RAIL_TILE_WAYPOINT: return OT_GOTO_WAYPOINT;
+ default: break;
+ }
+ break;
+ }
+
+ return OT_END;
+}
+
+/* static */ bool AIOrder::IsValidVehicleOrder(VehicleID vehicle_id, uint32 order_id)
+{
+ return AIVehicle::IsValidVehicle(vehicle_id) && order_id < ::GetVehicle(vehicle_id)->num_orders;
+}
+
+/* static */ bool AIOrder::AreOrderFlagsValid(TileIndex destination, AIOrderFlags order_flags)
+{
+ switch (::GetOrderTypeByTile(destination)) {
+ case OT_GOTO_DEPOT: return (order_flags & ~(AIOF_NON_STOP | AIOF_SERVICE_IF_NEEDED)) == 0;
+ case OT_GOTO_STATION: return (order_flags & ~(AIOF_NON_STOP | AIOF_TRANSFER | AIOF_UNLOAD | AIOF_FULL_LOAD)) == 0;
+ case OT_GOTO_WAYPOINT: return (order_flags & ~(AIOF_NON_STOP)) == 0;
+ default: return false;
+ }
+}
+
+int32 AIOrder::GetNumberOfOrders(VehicleID vehicle_id)
+{
+ return AIVehicle::IsValidVehicle(vehicle_id) ? ::GetVehicle(vehicle_id)->num_orders : -1;
+}
+
+TileIndex AIOrder::GetOrderDestination(VehicleID vehicle_id, uint32 order_id)
+{
+ if (!AIOrder::IsValidVehicleOrder(vehicle_id, order_id)) return INVALID_TILE;
+
+ Order *order = ::GetVehicle(vehicle_id)->orders;
+ for (uint i = 0; i < order_id; i++) order = order->next;
+
+ switch (order->type) {
+ case OT_GOTO_DEPOT: return ::GetDepot(order->dest)->xy;
+ case OT_GOTO_STATION: return ::GetStation(order->dest)->xy;
+ case OT_GOTO_WAYPOINT: return ::GetWaypoint(order->dest)->xy;
+ default: return INVALID_TILE;
+ }
+}
+
+AIOrder::AIOrderFlags AIOrder::GetOrderFlags(VehicleID vehicle_id, uint32 order_id)
+{
+ if (!AIOrder::IsValidVehicleOrder(vehicle_id, order_id)) return AIOF_INVALID;
+
+ Order *order = ::GetVehicle(vehicle_id)->orders;
+ for (uint i = 0; i < order_id; i++) order = order->next;
+
+ return (AIOrder::AIOrderFlags)order->flags;
+}
+
+bool AIOrder::AppendOrder(VehicleID vehicle_id, TileIndex destination, AIOrderFlags order_flags)
+{
+ if (!AIVehicle::IsValidVehicle(vehicle_id)) return false;
+ return this->InsertOrder(vehicle_id, GetVehicle(vehicle_id)->num_orders, destination, order_flags);
+}
+
+bool AIOrder::InsertOrder(VehicleID vehicle_id, uint32 order_id, TileIndex destination, AIOrder::AIOrderFlags order_flags)
+{
+ if (!IsValidVehicleOrder(vehicle_id, order_id) ||
+ !this->AreOrderFlagsValid(destination, order_flags)) return false;
+
+ Order order;
+ order.type = ::GetOrderTypeByTile(destination);
+ order.flags = order_flags;
+ switch (order.type) {
+ case OT_GOTO_DEPOT: order.dest = ::GetDepotByTile(destination)->index;
+ case OT_GOTO_STATION: order.dest = ::GetStationIndex(destination);
+ case OT_GOTO_WAYPOINT: order.dest = ::GetWaypointIndex(destination);
+ default: NOT_REACHED(); return false;
+ }
+
+ return this->DoCommand(0, vehicle_id | (order_id << 16), PackOrder(&order), CMD_INSERT_ORDER);
+}
+
+bool AIOrder::RemoveOrder(VehicleID vehicle_id, uint32 order_id)
+{
+ if (!IsValidVehicleOrder(vehicle_id, order_id)) return false;
+
+ return this->DoCommand(0, vehicle_id, order_id, CMD_DELETE_ORDER);
+}
+
+bool AIOrder::ChangeOrder(VehicleID vehicle_id, uint32 order_id, AIOrder::AIOrderFlags order_flags)
+{
+ if (!IsValidVehicleOrder(vehicle_id, order_id) ||
+ !this->AreOrderFlagsValid(GetOrderDestination(vehicle_id, order_id), order_flags)) return false;
+
+ return this->DoCommand(0, vehicle_id | (order_id << 16), order_flags, CMD_MODIFY_ORDER);
+}
+
+bool AIOrder::CopyOrders(VehicleID vehicle_id, VehicleID main_vehicle_id)
+{
+ if (!AIVehicle::IsValidVehicle(vehicle_id) || !AIVehicle::IsValidVehicle(main_vehicle_id)) return false;
+
+ return this->DoCommand(0, vehicle_id | (main_vehicle_id << 16), CO_COPY, CMD_CLONE_ORDER);
+}
+
+bool AIOrder::ShareOrders(VehicleID vehicle_id, VehicleID main_vehicle_id)
+{
+ if (!AIVehicle::IsValidVehicle(vehicle_id) || !AIVehicle::IsValidVehicle(main_vehicle_id)) return false;
+
+ return this->DoCommand(0, vehicle_id | (main_vehicle_id << 16), CO_SHARE, CMD_CLONE_ORDER);
+}
+
+bool AIOrder::UnshareOrders(VehicleID vehicle_id)
+{
+ if (!AIVehicle::IsValidVehicle(vehicle_id)) return false;
+
+ return this->DoCommand(0, vehicle_id, CO_UNSHARE, CMD_CLONE_ORDER);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/ai/api/ai_order.hpp Tue Mar 20 14:27:54 2007 +0000
@@ -0,0 +1,179 @@
+/* $Id$ */
+
+/** @file ai_order.hpp Everything to query and build Orders */
+
+#ifndef AI_ORDER_HPP
+#define AI_ORDER_HPP
+
+#include "ai_object.hpp"
+
+/**
+ * Class that handles all order related functions.
+ */
+class AIOrder : public AIObject {
+public:
+ /**
+ * Flags that can be used to modify the behaviour of orders.
+ */
+ enum AIOrderFlags {
+ /** Just go to the station/depot, stop unload if possible and load if needed. */
+ AIOF_NONE = 0,
+
+ /** Transfer instead of deliver the goods; only for stations. */
+ AIOF_TRANSFER = 1 << 0,
+ /** Always unload the vehicle; only for stations. */
+ AIOF_UNLOAD = 1 << 1,
+ /** Wait till the the vehicle is fully loaded; only for stations. */
+ AIOF_FULL_LOAD = 1 << 2,
+
+ /** Service the vehicle when needed, otherwise skip this order; only for depots. */
+ AIOF_SERVICE_IF_NEEDED = 1 << 2,
+
+ /** Do not stop at the stations that are passed when going to the destination. */
+ AIOF_NON_STOP = 1 << 3,
+
+ /** For marking invalid order flags */
+ AIOF_INVALID = 0xFFFF,
+ };
+
+ /**
+ * Checks whether the given order id is valid for the given vehicle.
+ * @param vehicle_id the vehicle to check the order index for.
+ * @param order_id the order index to check.
+ * @pre AIVehicle::IsValidVehicle(vehicle_id).
+ * @return true if and only if the order_id is valid for the given vehicle.
+ */
+ static bool IsValidVehicleOrder(VehicleID vehicle_id, uint32 order_id);
+
+ /**
+ * Checks whether the given order flags are valid for the given destination.
+ * @param destination the destination of the order.
+ * @param order_flags the flags given to the order.
+ * @return true if and only if the order_flags are valid for the given location.
+ */
+ static bool AreOrderFlagsValid(TileIndex destination, AIOrderFlags order_flags);
+
+ /**
+ * Returns the number of orders for the given vehicle.
+ * @param vehicle_id the vehicle to get the order count of.
+ * @pre AIVehicle::IsValidVehicle(vehicle_id).
+ * @return the number of orders for the given vehicle or a negative
+ * value when the vehicle does not exist.
+ */
+ int32 GetNumberOfOrders(VehicleID vehicle_id);
+
+ /**
+ * Gets the destination of the given order for the given vehicle.
+ * @param vehicle_id the vehicle to get the destination for.
+ * @param order_id the order to get the destination for.
+ * @pre IsValidVehicleOrder(vehicle_id, order_id).
+ * @return the destination tile of the order.
+ */
+ TileIndex GetOrderDestination(VehicleID vehicle_id, uint32 order_id);
+
+ /**
+ * Gets the AIOrderFlags of the given order for the given vehicle.
+ * @param vehicle_id the vehicle to get the destination for.
+ * @param order_id the order to get the destination for.
+ * @pre IsValidVehicleOrder(vehicle_id, order_id).
+ * @return the AIOrderFlags of the order.
+ */
+ AIOrderFlags GetOrderFlags(VehicleID vehicle_id, uint32 order_id);
+
+ /**
+ * Appends an order to the end of the vehicle's order list.
+ * @param vehicle_id the vehicle to append the order to.
+ * @param destination the destination of the order.
+ * @param order_flags the flags given to the order.
+ * @pre AIVehicle::IsValidVehicle(vehicle_id).
+ * @pre AreOrderFlagsValid(destination, order_flags).
+ * @return true if and only if the order was appended.
+ */
+ bool AppendOrder(VehicleID vehicle_id, TileIndex destination, AIOrderFlags order_flags);
+
+ /**
+ * Inserts an order before the given order_id into the vehicle's order list.
+ * @param vehicle_id the vehicle to add the order to.
+ * @param order_id the order to place the new order before.
+ * @param destination the destination of the order.
+ * @param order_flags the flags given to the order.
+ * @pre IsValidVehicleOrder(vehicle_id, order_id).
+ * @pre AreOrderFlagsValid(destination, order_flags).
+ * @return true if and only if the order was inserted.
+ */
+ bool InsertOrder(VehicleID vehicle_id, uint32 order_id, TileIndex destination, AIOrderFlags order_flags);
+
+ /**
+ * Removes an order from the vehicle's order list.
+ * @param vehicle_id the vehicle to remove the order from.
+ * @param order_id the order to remove from the order list.
+ * @pre AIVehicle::IsValidVehicleOrder(vehicle_id, order_id).
+ * @return true if and only if the order was removed.
+ */
+ bool RemoveOrder(VehicleID vehicle_id, uint32 order_id);
+
+ /**
+ * Changes the order flags of the given order.
+ * @param vehicle_id the vehicle to change the order of.
+ * @param order_id the order to change.
+ * @param order_flags the new flags given to the order.
+ * @pre IsValidVehicleOrder(vehicle_id, order_id).
+ * @pre AreOrderFlagsValid(GetOrderDestination(vehicle_id, order_id), order_flags).
+ * @return true if and only if the order was changed.
+ */
+ bool ChangeOrder(VehicleID vehicle_id, uint32 order_id, AIOrderFlags order_flags);
+
+ /**
+ * Copies the orders from another vehicle. The orders of the main
+ * vehicle are going to be the orders of the changed vehicle.
+ * @param vehicle_id the vehicle to copy the orders to.
+ * @param main_vehicle_id the vehicle to copy the orders from.
+ * @pre AIVehicle::IsValidVehicle(vehicle_id).
+ * @pre AIVehicle::IsValidVehicle(main_vehicle_id).
+ * @return true if and only if the copying succeeded.
+ */
+ bool CopyOrders(VehicleID vehicle_id, VehicleID main_vehicle_id);
+
+ /**
+ * Shares the orders between two vehicles. The orders of the main
+ * vehicle are going to be the orders of the changed vehicle.
+ * @param vehicle_id the vehicle to add to the shared order list.
+ * @param main_vehicle_id the vehicle to share the orders with.
+ * @pre AIVehicle::IsValidVehicle(vehicle_id).
+ * @pre AIVehicle::IsValidVehicle(main_vehicle_id).
+ * @return true if and only if the sharing succeeded.
+ */
+ bool ShareOrders(VehicleID vehicle_id, VehicleID main_vehicle_id);
+
+ /**
+ * Removes the given vehicle from a shared orders list.
+ * @param vehicle_id the vehicle to remove from the shared order list.
+ * @pre AIVehicle::IsValidVehicle(vehicle_id).
+ * @return true if and only if the unsharing succeeded.
+ */
+ bool UnshareOrders(VehicleID vehicle_id);
+};
+DECLARE_ENUM_AS_BIT_SET(AIOrder::AIOrderFlags);
+
+#ifdef DEFINE_SQUIRREL_CLASS
+void SQAIOrderRegister(Squirrel *engine) {
+ DefSQClass <AIOrder> SQAIOrder("AIOrder");
+ SQAIOrder.PreRegister(engine);
+ SQAIOrder.AddConstructor(engine);
+ SQAIOrder.DefSQFunction(engine, &AIOrder::IsValidVehicleOrder, "IsValidVehicleOrder");
+ SQAIOrder.DefSQFunction(engine, &AIOrder::ShareOrders, "ShareOrders");
+ SQAIOrder.DefSQFunction(engine, &AIOrder::UnshareOrders, "UnshareOrders");
+ SQAIOrder.DefSQFunction(engine, &AIOrder::AreOrderFlagsValid, "AreOrderFlagsValid");
+ SQAIOrder.DefSQFunction(engine, &AIOrder::GetNumberOfOrders, "GetNumberOfOrders");
+ SQAIOrder.DefSQFunction(engine, &AIOrder::GetOrderDestination, "GetOrderDestination");
+ SQAIOrder.DefSQFunction(engine, &AIOrder::GetOrderFlags, "GetOrderFlags");
+ SQAIOrder.DefSQFunction(engine, &AIOrder::AppendOrder, "AppendOrder");
+ SQAIOrder.DefSQFunction(engine, &AIOrder::InsertOrder, "InsertOrder");
+ SQAIOrder.DefSQFunction(engine, &AIOrder::RemoveOrder, "RemoveOrder");
+ SQAIOrder.DefSQFunction(engine, &AIOrder::ChangeOrder, "ChangeOrder");
+ SQAIOrder.DefSQFunction(engine, &AIOrder::CopyOrders, "CopyOrders");
+ SQAIOrder.PostRegister(engine);
+}
+#endif /* SQUIRREL_CLASS */
+
+#endif /* AI_ORDER_HPP */