Changeset - r13970:10f5b52589eb
[Not reviewed]
master
0 5 0
yexo - 14 years ago 2009-12-16 21:31:21
yexo@openttd.org
(svn r18518) -Add [NoAI]: AIOrder::AIOF_GOTO_NEAREST_DEPOT for goto nearest depot orders
5 files changed with 23 insertions and 10 deletions:
0 comments (0 inline, 0 general)
src/ai/api/ai_changelog.hpp
Show inline comments
 
@@ -14,24 +14,25 @@
 
 * functions may still be available if you return an older API version
 
 * in GetAPIVersion() in info.nut.
 
 *
 
 * \b 0.8.0
 
 *
 
 * 0.8.0 is not yet released. The following changes are not set in stone yet.
 
 *
 
 * API additions:
 
 * \li AIBaseStation
 
 * \li AIBuoyList
 
 * \li AIEventCompanyAskMerger
 
 * \li AIIndustry::GetLastMonthTransportedPercentage
 
 * \li AIOrder::AIOF_GOTO_NEAREST_DEPOT
 
 * \li AIRail::RemoveRailStationTileRectangle
 
 * \li AIRail::RemoveRailWaypointTileRectangle
 
 * \li AISubsidy::SubsidyParticipantType
 
 * \li AISubsidy::GetSourceType
 
 * \li AISubsidy::GetSourceIndex
 
 * \li AISubsidy::GetDestinationType
 
 * \li AISubsidy::GetDestinationIndex
 
 * \li AITown::GetLastMonthTransportedPercentage
 
 * \li AIVehicleList_Depot
 
 *
 
 * API removals:
 
 * \li AIOrder::ChangeOrder, use AIOrder::SetOrderFlags instead
src/ai/api/ai_order.cpp
Show inline comments
 
@@ -111,25 +111,26 @@ static const Order *ResolveOrder(Vehicle
 

	
 
/* static */ AIOrder::OrderPosition AIOrder::ResolveOrderPosition(VehicleID vehicle_id, OrderPosition order_position)
 
{
 
	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;
 
}
 

	
 

	
 
/* static */ bool AIOrder::AreOrderFlagsValid(TileIndex destination, AIOrderFlags order_flags)
 
{
 
	switch (::GetOrderTypeByTile(destination)) {
 
	OrderType ot = (order_flags & AIOF_GOTO_NEAREST_DEPOT) ? OT_GOTO_DEPOT : ::GetOrderTypeByTile(destination);
 
	switch (ot) {
 
		case OT_GOTO_STATION:
 
			return (order_flags & ~(AIOF_NON_STOP_FLAGS | AIOF_UNLOAD_FLAGS | AIOF_LOAD_FLAGS)) == 0 &&
 
					/* Test the different mutual exclusive flags. */
 
					((order_flags & AIOF_TRANSFER)      == 0 || (order_flags & AIOF_UNLOAD)    == 0) &&
 
					((order_flags & AIOF_TRANSFER)      == 0 || (order_flags & AIOF_NO_UNLOAD) == 0) &&
 
					((order_flags & AIOF_UNLOAD)        == 0 || (order_flags & AIOF_NO_UNLOAD) == 0) &&
 
					((order_flags & AIOF_UNLOAD)        == 0 || (order_flags & AIOF_NO_UNLOAD) == 0) &&
 
					((order_flags & AIOF_NO_UNLOAD)     == 0 || (order_flags & AIOF_NO_LOAD)   == 0) &&
 
					((order_flags & AIOF_FULL_LOAD_ANY) == 0 || (order_flags & AIOF_NO_LOAD)   == 0);
 

	
 
		case OT_GOTO_DEPOT:
 
			return (order_flags & ~(AIOF_NON_STOP_FLAGS | AIOF_DEPOT_FLAGS)) == 0 &&
 
@@ -212,24 +213,25 @@ static const Order *ResolveOrder(Vehicle
 
{
 
	if (!IsValidVehicleOrder(vehicle_id, order_position)) return AIOF_INVALID;
 

	
 
	const Order *order = ::ResolveOrder(vehicle_id, order_position);
 
	if (order == NULL || order->GetType() == OT_CONDITIONAL) return AIOF_INVALID;
 

	
 
	AIOrderFlags order_flags = AIOF_NONE;
 
	order_flags |= (AIOrderFlags)order->GetNonStopType();
 
	switch (order->GetType()) {
 
		case OT_GOTO_DEPOT:
 
			if (order->GetDepotOrderType() & ODTFB_SERVICE) order_flags |= AIOF_SERVICE_IF_NEEDED;
 
			if (order->GetDepotActionType() & ODATFB_HALT) order_flags |= AIOF_STOP_IN_DEPOT;
 
			if (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) order_flags |= AIOF_GOTO_NEAREST_DEPOT;
 
			break;
 

	
 
		case OT_GOTO_STATION:
 
			order_flags |= (AIOrderFlags)(order->GetLoadType()   << 5);
 
			order_flags |= (AIOrderFlags)(order->GetUnloadType() << 2);
 
			break;
 

	
 
		default: break;
 
	}
 

	
 
	return order_flags;
 
}
 
@@ -326,37 +328,43 @@ static const Order *ResolveOrder(Vehicle
 
}
 

	
 
/* 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. */
 
	if (order_position == ORDER_CURRENT) order_position = AIOrder::ResolveOrderPosition(vehicle_id, order_position);
 

	
 
	EnforcePrecondition(false, AIVehicle::IsValidVehicle(vehicle_id));
 
	EnforcePrecondition(false, order_position >= 0 && order_position <= ::Vehicle::Get(vehicle_id)->GetNumOrders());
 
	EnforcePrecondition(false, AreOrderFlagsValid(destination, order_flags));
 

	
 
	Order order;
 
	switch (::GetOrderTypeByTile(destination)) {
 
	OrderType ot = (order_flags & AIOF_GOTO_NEAREST_DEPOT) ? OT_GOTO_DEPOT : ::GetOrderTypeByTile(destination);
 
	switch (ot) {
 
		case OT_GOTO_DEPOT: {
 
			OrderDepotTypeFlags odtf = (OrderDepotTypeFlags)(ODTFB_PART_OF_ORDERS | ((order_flags & AIOF_SERVICE_IF_NEEDED) ? ODTFB_SERVICE : 0));
 
			OrderDepotActionFlags odaf = (OrderDepotActionFlags)(ODATF_SERVICE_ONLY | ((order_flags & AIOF_STOP_IN_DEPOT) ? ODATFB_HALT : 0));
 
			if (order_flags & AIOF_GOTO_NEAREST_DEPOT) odaf |= ODATFB_NEAREST_DEPOT;
 
			OrderNonStopFlags onsf = (OrderNonStopFlags)((order_flags & AIOF_NON_STOP_INTERMEDIATE) ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE);
 
			/* Check explicitly if the order is to a station (for aircraft) or
 
			 * to a depot (other vehicle types). */
 
			if (::Vehicle::Get(vehicle_id)->type == VEH_AIRCRAFT) {
 
				if (!::IsTileType(destination, MP_STATION)) return false;
 
				order.MakeGoToDepot(::GetStationIndex(destination), odtf, onsf, odaf);
 
			if (order_flags & AIOF_GOTO_NEAREST_DEPOT) {
 
				order.MakeGoToDepot(0, odtf, onsf, odaf);
 
			} else {
 
				if (::IsTileType(destination, MP_STATION)) return false;
 
				order.MakeGoToDepot(::GetDepotIndex(destination), odtf, onsf, odaf);
 
				/* Check explicitly if the order is to a station (for aircraft) or
 
				 * to a depot (other vehicle types). */
 
				if (::Vehicle::Get(vehicle_id)->type == VEH_AIRCRAFT) {
 
					if (!::IsTileType(destination, MP_STATION)) return false;
 
					order.MakeGoToDepot(::GetStationIndex(destination), odtf, onsf, odaf);
 
				} else {
 
					if (::IsTileType(destination, MP_STATION)) return false;
 
					order.MakeGoToDepot(::GetDepotIndex(destination), odtf, onsf, odaf);
 
				}
 
			}
 
			break;
 
		}
 

	
 
		case OT_GOTO_STATION:
 
			order.MakeGoToStation(::GetStationIndex(destination));
 
			order.SetLoadType((OrderLoadFlags)GB(order_flags, 5, 3));
 
			order.SetUnloadType((OrderUnloadFlags)GB(order_flags, 2, 3));
 
			order.SetStopLocation(OSL_PLATFORM_FAR_END);
 
			break;
 

	
 
		case OT_GOTO_WAYPOINT:
src/ai/api/ai_order.hpp
Show inline comments
 
@@ -57,33 +57,35 @@ public:
 

	
 
		/** Wait till the vehicle is fully loaded; only for stations. Cannot be set when AIOF_NO_LOAD is set. */
 
		AIOF_FULL_LOAD         = 2 << 5,
 
		/** Wait till at least one cargo of the vehicle is fully loaded; only for stations. Cannot be set when AIOF_NO_LOAD is set. */
 
		AIOF_FULL_LOAD_ANY     = 3 << 5,
 
		/** Do not load any cargo; only for stations. Cannot be set when AIOF_NO_UNLOAD, AIOF_FULL_LOAD or AIOF_FULL_LOAD_ANY is set. */
 
		AIOF_NO_LOAD           = 1 << 7,
 

	
 
		/** Service the vehicle when needed, otherwise skip this order; only for depots. */
 
		AIOF_SERVICE_IF_NEEDED = 1 << 2,
 
		/** Stop in the depot instead of only go there for servicing; only for depots. */
 
		AIOF_STOP_IN_DEPOT     = 1 << 3,
 
		/** Go to nearest depot. */
 
		AIOF_GOTO_NEAREST_DEPOT = 1 << 4,
 

	
 
		/** All flags related to non-stop settings. */
 
		AIOF_NON_STOP_FLAGS    = AIOF_NON_STOP_INTERMEDIATE | AIOF_NON_STOP_DESTINATION,
 
		/** All flags related to unloading. */
 
		AIOF_UNLOAD_FLAGS      = AIOF_TRANSFER | AIOF_UNLOAD | AIOF_NO_UNLOAD,
 
		/** All flags related to loading. */
 
		AIOF_LOAD_FLAGS        = AIOF_FULL_LOAD | AIOF_FULL_LOAD_ANY | AIOF_NO_LOAD,
 
		/** All flags related to depots. */
 
		AIOF_DEPOT_FLAGS       = AIOF_SERVICE_IF_NEEDED | AIOF_STOP_IN_DEPOT,
 
		AIOF_DEPOT_FLAGS       = AIOF_SERVICE_IF_NEEDED | AIOF_STOP_IN_DEPOT | AIOF_GOTO_NEAREST_DEPOT,
 

	
 
		/** For marking invalid order flags */
 
		AIOF_INVALID           = 0xFFFF,
 
	};
 

	
 
	/**
 
	 * All conditions a conditional order can depend on.
 
	 */
 
	enum OrderCondition {
 
		/* Order _is_ important, as it's based on OrderConditionVariable in order_type.h. */
 
		OC_LOAD_PERCENTAGE,  //!< Skip based on the amount of load, value is in tons.
 
		OC_RELIABILITY,      //!< Skip based on the reliability, value is percent (0..100).
src/ai/api/ai_order.hpp.sq
Show inline comments
 
@@ -43,24 +43,25 @@ void SQAIOrder_Register(Squirrel *engine
 
	SQAIOrder.DefSQConst(engine, AIOrder::ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION, "ERR_ORDER_TOO_FAR_AWAY_FROM_PREVIOUS_DESTINATION");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_NONE,                                        "AIOF_NONE");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_NON_STOP_INTERMEDIATE,                       "AIOF_NON_STOP_INTERMEDIATE");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_NON_STOP_DESTINATION,                        "AIOF_NON_STOP_DESTINATION");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_UNLOAD,                                      "AIOF_UNLOAD");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_TRANSFER,                                    "AIOF_TRANSFER");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_NO_UNLOAD,                                   "AIOF_NO_UNLOAD");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_FULL_LOAD,                                   "AIOF_FULL_LOAD");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_FULL_LOAD_ANY,                               "AIOF_FULL_LOAD_ANY");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_NO_LOAD,                                     "AIOF_NO_LOAD");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_SERVICE_IF_NEEDED,                           "AIOF_SERVICE_IF_NEEDED");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_STOP_IN_DEPOT,                               "AIOF_STOP_IN_DEPOT");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_GOTO_NEAREST_DEPOT,                          "AIOF_GOTO_NEAREST_DEPOT");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_NON_STOP_FLAGS,                              "AIOF_NON_STOP_FLAGS");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_UNLOAD_FLAGS,                                "AIOF_UNLOAD_FLAGS");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_LOAD_FLAGS,                                  "AIOF_LOAD_FLAGS");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_DEPOT_FLAGS,                                 "AIOF_DEPOT_FLAGS");
 
	SQAIOrder.DefSQConst(engine, AIOrder::AIOF_INVALID,                                     "AIOF_INVALID");
 
	SQAIOrder.DefSQConst(engine, AIOrder::OC_LOAD_PERCENTAGE,                               "OC_LOAD_PERCENTAGE");
 
	SQAIOrder.DefSQConst(engine, AIOrder::OC_RELIABILITY,                                   "OC_RELIABILITY");
 
	SQAIOrder.DefSQConst(engine, AIOrder::OC_MAX_SPEED,                                     "OC_MAX_SPEED");
 
	SQAIOrder.DefSQConst(engine, AIOrder::OC_AGE,                                           "OC_AGE");
 
	SQAIOrder.DefSQConst(engine, AIOrder::OC_REQUIRES_SERVICE,                              "OC_REQUIRES_SERVICE");
 
	SQAIOrder.DefSQConst(engine, AIOrder::OC_UNCONDITIONALLY,                               "OC_UNCONDITIONALLY");
 
	SQAIOrder.DefSQConst(engine, AIOrder::OC_INVALID,                                       "OC_INVALID");
src/order_type.h
Show inline comments
 
@@ -94,24 +94,25 @@ enum OrderDepotTypeFlags {
 
	ODTFB_SERVICE        = 1 << 0, ///< This depot order is because of the servicing limit.
 
	ODTFB_PART_OF_ORDERS = 1 << 1, ///< This depot order is because of a regular order.
 
};
 

	
 
/**
 
 * Actions that can be performed when the vehicle enters the depot.
 
 */
 
enum OrderDepotActionFlags {
 
	ODATF_SERVICE_ONLY   = 0,      ///< Only service the vehicle.
 
	ODATFB_HALT          = 1 << 0, ///< Service the vehicle and then halt it.
 
	ODATFB_NEAREST_DEPOT = 1 << 1, ///< Send the vehicle to the nearest depot.
 
};
 
DECLARE_ENUM_AS_BIT_SET(OrderDepotActionFlags);
 

	
 
/**
 
 * Variables (of a vehicle) to 'cause' skipping on.
 
 */
 
enum OrderConditionVariable {
 
	OCV_LOAD_PERCENTAGE,  ///< Skip based on the amount of load
 
	OCV_RELIABILITY,      ///< Skip based on the reliability
 
	OCV_MAX_SPEED,        ///< Skip based on the maximum speed
 
	OCV_AGE,              ///< Skip based on the age
 
	OCV_REQUIRES_SERVICE, ///< Skip when the vehicle requires service
 
	OCV_UNCONDITIONALLY,  ///< Always skip
 
	OCV_END
0 comments (0 inline, 0 general)