From 2db7e3a0a8a8db8ac3c27cbab70b36388f0c6397 Mon Sep 17 00:00:00 2001 From: rubidium Date: Wed, 6 May 2009 23:21:43 +0000 Subject: [PATCH] (svn r16248) [0.7] -Backport from trunk: - Fix: Improve corner case order handling: mark order as done only when actually done, obey non-stop orders, do only stop/refit at the depot in the order (r16240,r16228,r16199,r16198,r16187) - Fix: Use the stop/non-stop intermediate orderflags AIs can give for goto-depot orders (r16239) --- src/ai/api/ai_map.hpp | 2 +- src/ai/api/ai_order.cpp | 5 +++-- src/order_base.h | 13 +++++++------ src/order_cmd.cpp | 8 +++----- src/order_gui.cpp | 15 ++++++++------- src/vehicle.cpp | 21 ++++++++++++++------- 6 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/ai/api/ai_map.hpp b/src/ai/api/ai_map.hpp index 160da9849a..02514a2141 100644 --- a/src/ai/api/ai_map.hpp +++ b/src/ai/api/ai_map.hpp @@ -19,7 +19,7 @@ public: #endif /* DEFINE_SCRIPT_FILES */ #ifdef DOXYGEN_SKIP const static TileIndex TILE_INVALID; //!< Invalid TileIndex. -#endif +#endif /* DOXYGEN_SKIP */ static const char *GetClassName() { return "AIMap"; } diff --git a/src/ai/api/ai_order.cpp b/src/ai/api/ai_order.cpp index 576958ee76..1a21ab9e4e 100644 --- a/src/ai/api/ai_order.cpp +++ b/src/ai/api/ai_order.cpp @@ -336,14 +336,15 @@ static const Order *ResolveOrder(VehicleID vehicle_id, AIOrder::OrderPosition or 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)); + 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 (::GetVehicle(vehicle_id)->type == VEH_AIRCRAFT) { if (!::IsTileType(destination, MP_STATION)) return false; - order.MakeGoToDepot(::GetStationIndex(destination), odtf, odaf); + order.MakeGoToDepot(::GetStationIndex(destination), odtf, onsf, odaf); } else { if (::IsTileType(destination, MP_STATION)) return false; - order.MakeGoToDepot(::GetDepotByTile(destination)->index, odtf, odaf); + order.MakeGoToDepot(::GetDepotByTile(destination)->index, odtf, onsf, odaf); } break; } diff --git a/src/order_base.h b/src/order_base.h index 44e8d9c157..e7ae1ccee0 100644 --- a/src/order_base.h +++ b/src/order_base.h @@ -83,13 +83,14 @@ public: /** * Makes this order a Go To Depot order. - * @param destination the depot to go to. - * @param order is this order a 'default' order, or an overriden vehicle order? - * @param action what to do in the depot? - * @param cargo the cargo type to change to. - * @param subtype the subtype to change to. + * @param destination the depot to go to. + * @param order is this order a 'default' order, or an overriden vehicle order? + * @param non_stop_type how to get to the depot? + * @param action what to do in the depot? + * @param cargo the cargo type to change to. + * @param subtype the subtype to change to. */ - void MakeGoToDepot(DepotID destination, OrderDepotTypeFlags order, OrderDepotActionFlags action = ODATF_SERVICE_ONLY, CargoID cargo = CT_NO_REFIT, byte subtype = 0); + void MakeGoToDepot(DepotID destination, OrderDepotTypeFlags order, OrderNonStopFlags non_stop_type = ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS, OrderDepotActionFlags action = ODATF_SERVICE_ONLY, CargoID cargo = CT_NO_REFIT, byte subtype = 0); /** * Makes this order a Go To Waypoint order. diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index d54baab45d..0e80152034 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -51,14 +51,12 @@ void Order::MakeGoToStation(StationID destination) this->dest = destination; } -void Order::MakeGoToDepot(DepotID destination, OrderDepotTypeFlags order, OrderDepotActionFlags action, CargoID cargo, byte subtype) +void Order::MakeGoToDepot(DepotID destination, OrderDepotTypeFlags order, OrderNonStopFlags non_stop_type, OrderDepotActionFlags action, CargoID cargo, byte subtype) { this->type = OT_GOTO_DEPOT; this->SetDepotOrderType(order); this->SetDepotActionType(action); - if (!(order & ODTFB_PART_OF_ORDERS)) { - this->SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS); - } + this->SetNonStopType(non_stop_type); this->dest = destination; this->SetRefit(cargo, subtype); } @@ -1621,7 +1619,7 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth) if (v->FindClosestDepot(&location, &destination, &reverse)) { v->dest_tile = location; - v->current_order.MakeGoToDepot(destination, v->current_order.GetDepotOrderType(), (OrderDepotActionFlags)(v->current_order.GetDepotActionType() & ~ODATFB_NEAREST_DEPOT), v->current_order.GetRefitCargo(), v->current_order.GetRefitSubtype()); + v->current_order.MakeGoToDepot(destination, v->current_order.GetDepotOrderType(), v->current_order.GetNonStopType(), (OrderDepotActionFlags)(v->current_order.GetDepotActionType() & ~ODATFB_NEAREST_DEPOT), v->current_order.GetRefitCargo(), v->current_order.GetRefitSubtype()); /* If there is no depot in front, reverse automatically (trains only) */ if (v->type == VEH_TRAIN && reverse) DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_REVERSE_TRAIN_DIRECTION); diff --git a/src/order_gui.cpp b/src/order_gui.cpp index b4b9d5bb04..32a14cb0eb 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.cpp @@ -296,9 +296,9 @@ static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile) case MP_RAILWAY: if (v->type == VEH_TRAIN && IsTileOwner(tile, _local_company)) { if (IsRailDepot(tile)) { - order.MakeGoToDepot(GetDepotByTile(tile)->index, ODTFB_PART_OF_ORDERS); + order.MakeGoToDepot(GetDepotByTile(tile)->index, ODTFB_PART_OF_ORDERS, + _settings_client.gui.new_nonstop ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE); if (_ctrl_pressed) order.SetDepotOrderType((OrderDepotTypeFlags)(order.GetDepotOrderType() ^ ODTFB_SERVICE)); - if (_settings_client.gui.new_nonstop) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS); return order; } } @@ -306,9 +306,9 @@ static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile) case MP_ROAD: if (IsRoadDepot(tile) && v->type == VEH_ROAD && IsTileOwner(tile, _local_company)) { - order.MakeGoToDepot(GetDepotByTile(tile)->index, ODTFB_PART_OF_ORDERS); + order.MakeGoToDepot(GetDepotByTile(tile)->index, ODTFB_PART_OF_ORDERS, + _settings_client.gui.new_nonstop ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE); if (_ctrl_pressed) order.SetDepotOrderType((OrderDepotTypeFlags)(order.GetDepotOrderType() ^ ODTFB_SERVICE)); - if (_settings_client.gui.new_nonstop) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS); return order; } break; @@ -316,7 +316,7 @@ static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile) case MP_STATION: if (v->type != VEH_AIRCRAFT) break; if (IsHangar(tile) && IsTileOwner(tile, _local_company)) { - order.MakeGoToDepot(GetStationIndex(tile), ODTFB_PART_OF_ORDERS); + order.MakeGoToDepot(GetStationIndex(tile), ODTFB_PART_OF_ORDERS, ONSF_STOP_EVERYWHERE); if (_ctrl_pressed) order.SetDepotOrderType((OrderDepotTypeFlags)(order.GetDepotOrderType() ^ ODTFB_SERVICE)); return order; } @@ -327,7 +327,7 @@ static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile) if (IsShipDepot(tile) && IsTileOwner(tile, _local_company)) { TileIndex tile2 = GetOtherShipDepotTile(tile); - order.MakeGoToDepot(GetDepotByTile(tile < tile2 ? tile : tile2)->index, ODTFB_PART_OF_ORDERS); + order.MakeGoToDepot(GetDepotByTile(tile < tile2 ? tile : tile2)->index, ODTFB_PART_OF_ORDERS, ONSF_STOP_EVERYWHERE); if (_ctrl_pressed) order.SetDepotOrderType((OrderDepotTypeFlags)(order.GetDepotOrderType() ^ ODTFB_SERVICE)); return order; } @@ -506,7 +506,8 @@ private: Order order; order.next = NULL; order.index = 0; - order.MakeGoToDepot(0, ODTFB_PART_OF_ORDERS); + order.MakeGoToDepot(0, ODTFB_PART_OF_ORDERS, + _settings_client.gui.new_nonstop && (w->vehicle->type == VEH_TRAIN || w->vehicle->type == VEH_ROAD) ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE); order.SetDepotActionType(ODATFB_NEAREST_DEPOT); DoCommandP(w->vehicle->tile, w->vehicle->index + (w->OrderGetSel() << 16), order.Pack(), CMD_INSERT_ORDER | CMD_MSG(STR_8833_CAN_T_INSERT_NEW_ORDER)); diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 557048507f..00545ec751 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -600,11 +600,8 @@ Vehicle::~Vehicle() */ void VehicleEnteredDepotThisTick(Vehicle *v) { - /* Vehicle should stop in the depot if it was in 'stopping' state or - * when the vehicle is ordered to halt in the depot. */ - _vehicles_to_autoreplace[v] = !(v->vehstatus & VS_STOPPED) && - (!v->current_order.IsType(OT_GOTO_DEPOT) || - !(v->current_order.GetDepotActionType() & ODATFB_HALT)); + /* Vehicle should stop in the depot if it was in 'stopping' state */ + _vehicles_to_autoreplace[v] = !(v->vehstatus & VS_STOPPED); /* We ALWAYS set the stopped state. Even when the vehicle does not plan on * stopping in the depot, so we stop it to ensure that it will not reserve @@ -1038,9 +1035,19 @@ void VehicleEnterDepot(Vehicle *v) if (v->current_order.IsType(OT_GOTO_DEPOT)) { InvalidateWindow(WC_VEHICLE_VIEW, v->index); + const Order *real_order = GetVehicleOrder(v, v->cur_order_index); Order t = v->current_order; v->current_order.MakeDummy(); + /* Test whether we are heading for this depot. If not, do nothing. + * Note: The target depot for nearest-/manual-depot-orders is only updated on junctions, but we want to accept every depot. */ + if ((t.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) && + real_order != NULL && !(real_order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) && + (v->type == VEH_AIRCRAFT ? t.GetDestination() != GetStationIndex(v->tile) : v->dest_tile != v->tile)) { + /* We are heading for another depot, keep driving. */ + return; + } + if (t.IsRefit()) { _current_company = v->owner; CommandCost cost = DoCommand(v->tile, v->index, t.GetRefitCargo() | t.GetRefitSubtype() << 8, DC_EXEC, GetCmdRefitVeh(v)); @@ -1063,8 +1070,8 @@ void VehicleEnterDepot(Vehicle *v) v->cur_order_index++; } if (t.GetDepotActionType() & ODATFB_HALT) { - /* Force depot visit */ - v->vehstatus |= VS_STOPPED; + /* Vehicles are always stopped on entering depots. Do not restart this one. */ + _vehicles_to_autoreplace[v] = false; if (v->owner == _local_company) { StringID string;