diff --git a/src/ai/api/ai_changelog.hpp b/src/ai/api/ai_changelog.hpp --- a/src/ai/api/ai_changelog.hpp +++ b/src/ai/api/ai_changelog.hpp @@ -23,6 +23,7 @@ * \li AIBuoyList * \li AIEventCompanyAskMerger * \li AIIndustry::GetLastMonthTransportedPercentage + * \li AIOrder::AIOF_GOTO_NEAREST_DEPOT * \li AIRail::RemoveRailStationTileRectangle * \li AIRail::RemoveRailWaypointTileRectangle * \li AISubsidy::SubsidyParticipantType diff --git a/src/ai/api/ai_order.cpp b/src/ai/api/ai_order.cpp --- a/src/ai/api/ai_order.cpp +++ b/src/ai/api/ai_order.cpp @@ -120,7 +120,8 @@ static const Order *ResolveOrder(Vehicle /* 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. */ @@ -221,6 +222,7 @@ static const Order *ResolveOrder(Vehicle 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: @@ -335,19 +337,25 @@ static const Order *ResolveOrder(Vehicle 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; } diff --git a/src/ai/api/ai_order.hpp b/src/ai/api/ai_order.hpp --- a/src/ai/api/ai_order.hpp +++ b/src/ai/api/ai_order.hpp @@ -66,6 +66,8 @@ public: 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, @@ -74,7 +76,7 @@ public: /** 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, diff --git a/src/ai/api/ai_order.hpp.sq b/src/ai/api/ai_order.hpp.sq --- a/src/ai/api/ai_order.hpp.sq +++ b/src/ai/api/ai_order.hpp.sq @@ -52,6 +52,7 @@ void SQAIOrder_Register(Squirrel *engine 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"); diff --git a/src/order_type.h b/src/order_type.h --- a/src/order_type.h +++ b/src/order_type.h @@ -103,6 +103,7 @@ enum OrderDepotActionFlags { 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.