diff --git a/projects/openttd_vs100.vcxproj b/projects/openttd_vs100.vcxproj index 4af9bff731..c7a4741483 100644 --- a/projects/openttd_vs100.vcxproj +++ b/projects/openttd_vs100.vcxproj @@ -572,6 +572,7 @@ + diff --git a/projects/openttd_vs100.vcxproj.filters b/projects/openttd_vs100.vcxproj.filters index 235415b148..f582429c11 100644 --- a/projects/openttd_vs100.vcxproj.filters +++ b/projects/openttd_vs100.vcxproj.filters @@ -948,6 +948,9 @@ Header Files + + Header Files + Header Files diff --git a/projects/openttd_vs140.vcxproj b/projects/openttd_vs140.vcxproj index ecce7b0882..bcf08d55a0 100644 --- a/projects/openttd_vs140.vcxproj +++ b/projects/openttd_vs140.vcxproj @@ -589,6 +589,7 @@ + diff --git a/projects/openttd_vs140.vcxproj.filters b/projects/openttd_vs140.vcxproj.filters index 235415b148..f582429c11 100644 --- a/projects/openttd_vs140.vcxproj.filters +++ b/projects/openttd_vs140.vcxproj.filters @@ -948,6 +948,9 @@ Header Files + + Header Files + Header Files diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj index 0fce10a864..313d1c20d0 100644 --- a/projects/openttd_vs80.vcproj +++ b/projects/openttd_vs80.vcproj @@ -1562,6 +1562,10 @@ RelativePath=".\..\src\order_base.h" > + + diff --git a/projects/openttd_vs90.vcproj b/projects/openttd_vs90.vcproj index 348dac176c..07330f36e5 100644 --- a/projects/openttd_vs90.vcproj +++ b/projects/openttd_vs90.vcproj @@ -1559,6 +1559,10 @@ RelativePath=".\..\src\order_base.h" > + + diff --git a/source.list b/source.list index 55507872b8..b63ccc58de 100644 --- a/source.list +++ b/source.list @@ -312,6 +312,7 @@ object_type.h openttd.h order_backup.h order_base.h +order_cmd.h order_func.h order_type.h pbs.h diff --git a/src/infrastructure.cpp b/src/infrastructure.cpp index 8c9921a1d2..cb8a4fdfb4 100644 --- a/src/infrastructure.cpp +++ b/src/infrastructure.cpp @@ -25,6 +25,7 @@ #include "company_base.h" #include "string_func.h" #include "scope_info.h" +#include "order_cmd.h" #include "table/strings.h" @@ -142,6 +143,7 @@ static bool OrderDestinationIsAllowed(const Order *order, const Vehicle *v, Owne { Owner dest_owner; switch (order->GetType()) { + case OT_IMPLICIT: case OT_GOTO_STATION: case OT_GOTO_WAYPOINT: dest_owner = BaseStation::Get(order->GetDestination())->owner; break; case OT_GOTO_DEPOT: dest_owner = (v->type == VEH_AIRCRAFT) ? Station::Get(order->GetDestination())->owner : GetTileOwner(Depot::Get(order->GetDestination())->xy); break; @@ -299,20 +301,10 @@ void HandleSharingCompanyDeletion(Owner owner) /* order list */ if (v->FirstShared() != v) continue; - Order *o = NULL; - int id = -1; - SCOPE_INFO_FMT([&], "HandleSharingCompanyDeletion: veh: %s, order: %d, %X", scope_dumper().VehicleInfo(v), id, o ? o->Pack() : 0); - FOR_VEHICLE_ORDERS(v, o) { - id++; - if (OrderDestinationIsAllowed(o, v, owner)) continue; - - o->MakeDummy(); - for (const Vehicle *w = v; w != NULL; w = w->NextShared()) { - /* In GUI, simulate by removing the order and adding it back */ - InvalidateVehicleOrder(w, id | (INVALID_VEH_ORDER_ID << 8)); - InvalidateVehicleOrder(w, (id << 8) | INVALID_VEH_ORDER_ID); - } - } + RemoveVehicleOrdersIf(v, [&](const Order *o) { + if (o->GetType() == OT_GOTO_DEPOT && (o->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) return false; + return !OrderDestinationIsAllowed(o, v, owner); + }); } } diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 3578ea50e9..72f1c66ffa 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -36,6 +36,7 @@ #include "order_backup.h" #include "cheat_type.h" #include "viewport_func.h" +#include "order_cmd.h" #include "table/strings.h" @@ -2065,55 +2066,22 @@ void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination) /* Go through all vehicles */ FOR_ALL_VEHICLES(v) { - Order *order; - - order = &v->current_order; + Order *order = &v->current_order; if ((v->type == VEH_AIRCRAFT && order->IsType(OT_GOTO_DEPOT) ? OT_GOTO_STATION : order->GetType()) == type && v->current_order.GetDestination() == destination) { order->MakeDummy(); SetWindowDirty(WC_VEHICLE_VIEW, v->index); } - /* Clear the order from the order-list */ - int id = -1; - FOR_VEHICLE_ORDERS(v, order) { - id++; -restart: + /* order list */ + if (v->FirstShared() != v) continue; - OrderType ot = order->GetType(); - if (ot == OT_GOTO_DEPOT && (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) continue; + RemoveVehicleOrdersIf(v, [&](const Order *o) { + OrderType ot = o->GetType(); + if (ot == OT_GOTO_DEPOT && (o->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) return false; if (ot == OT_IMPLICIT || (v->type == VEH_AIRCRAFT && ot == OT_GOTO_DEPOT)) ot = OT_GOTO_STATION; - if (ot == type && order->GetDestination() == destination) { - /* We want to clear implicit orders, but we don't want to make them - * dummy orders. They should just vanish. Also check the actual order - * type as ot is currently OT_GOTO_STATION. */ - if (order->IsType(OT_IMPLICIT)) { - order = order->next; // DeleteOrder() invalidates current order - DeleteOrder(v, id); - if (order != NULL) goto restart; - break; - } - - /* Clear wait time */ - v->orders.list->UpdateTotalDuration(-order->GetWaitTime()); - if (order->IsWaitTimetabled()) { - v->orders.list->UpdateTimetableDuration(-order->GetTimetabledWait()); - order->SetWaitTimetabled(false); - } - order->SetWaitTime(0); - - /* Clear order, preserving travel time */ - bool travel_timetabled = order->IsTravelTimetabled(); - order->MakeDummy(); - order->SetTravelTimetabled(travel_timetabled); - - for (const Vehicle *w = v->FirstShared(); w != NULL; w = w->NextShared()) { - /* In GUI, simulate by removing the order and adding it back */ - InvalidateVehicleOrder(w, id | (INVALID_VEH_ORDER_ID << 8)); - InvalidateVehicleOrder(w, (INVALID_VEH_ORDER_ID << 8) | id); - } - } - } + return (ot == type && o->GetDestination() == destination); + }); } OrderBackup::RemoveOrder(type, destination); diff --git a/src/order_cmd.h b/src/order_cmd.h new file mode 100644 index 0000000000..bbb6c1dc59 --- /dev/null +++ b/src/order_cmd.h @@ -0,0 +1,66 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file order_cmd.h Functions related to order commands. */ + +#ifndef ORDER_CMD_H +#define ORDER_CMD_H + +#include "order_base.h" +#include "order_func.h" +#include "vehicle_base.h" + +/** + * Removes all orders from a vehicle for which order_predicate returns true. + * Handles timetable updating, removing implicit orders correctly, etc. + * @param v The vehicle. + * @param order_predicate Functor with signature: bool (const Order *) + */ +template void RemoveVehicleOrdersIf(Vehicle * const v, F order_predicate) { + /* Clear the order from the order-list */ + Order *order; + int id = -1; + FOR_VEHICLE_ORDERS(v, order) { + id++; +restart: + + if (order_predicate(const_cast(order))) { + /* We want to clear implicit orders, but we don't want to make them + * dummy orders. They should just vanish. Also check the actual order + * type as ot is currently OT_GOTO_STATION. */ + if (order->IsType(OT_IMPLICIT)) { + order = order->next; // DeleteOrder() invalidates current order + DeleteOrder(v, id); + if (order != NULL) goto restart; + break; + } + + /* Clear wait time */ + v->orders.list->UpdateTotalDuration(-order->GetWaitTime()); + if (order->IsWaitTimetabled()) { + v->orders.list->UpdateTimetableDuration(-order->GetTimetabledWait()); + order->SetWaitTimetabled(false); + } + order->SetWaitTime(0); + + /* Clear order, preserving travel time */ + bool travel_timetabled = order->IsTravelTimetabled(); + order->MakeDummy(); + order->SetTravelTimetabled(travel_timetabled); + + for (const Vehicle *w = v->FirstShared(); w != NULL; w = w->NextShared()) { + /* In GUI, simulate by removing the order and adding it back */ + InvalidateVehicleOrder(w, id | (INVALID_VEH_ORDER_ID << 8)); + InvalidateVehicleOrder(w, (INVALID_VEH_ORDER_ID << 8) | id); + } + } + } +} + +#endif /* ORDER_CMD_H */