From 444a90dda83dca0bec5f861cb0de07102d977c45 Mon Sep 17 00:00:00 2001 From: SamuXarick <43006711+SamuXarick@users.noreply.github.com> Date: Sun, 31 Dec 2023 22:47:02 +0000 Subject: [PATCH] Codechange: Iterate group vehicle lists for RemoveOrderFromAllVehicles Additionally make the function receive one parameter more with the owner of the destination, to help it perform faster. --- src/aircraft_cmd.cpp | 2 +- src/depot.cpp | 2 +- src/order_cmd.cpp | 89 ++++++++++++++++++++++++-------------------- src/order_func.h | 2 +- src/station.cpp | 2 +- src/waypoint.cpp | 2 +- 6 files changed, 54 insertions(+), 45 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 45c7e47537..a57840a97a 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -2163,5 +2163,5 @@ void UpdateAirplanesOnNewStation(const Station *st) } /* Heliports don't have a hangar. Invalidate all go to hangar orders from all aircraft. */ - if (!st->airport.HasHangar()) RemoveOrderFromAllVehicles(OT_GOTO_DEPOT, st->index, true); + if (!st->airport.HasHangar()) RemoveOrderFromAllVehicles(OT_GOTO_DEPOT, st->index, st->owner, true); } diff --git a/src/depot.cpp b/src/depot.cpp index 13317e8a35..3976f8ffc1 100644 --- a/src/depot.cpp +++ b/src/depot.cpp @@ -38,7 +38,7 @@ Depot::~Depot() OrderBackup::Reset(this->xy, false); /* Clear the depot from all order-lists */ - RemoveOrderFromAllVehicles(OT_GOTO_DEPOT, this->index); + RemoveOrderFromAllVehicles(OT_GOTO_DEPOT, this->index, GetTileOwner(this->xy)); /* Delete the depot-window */ CloseWindowById(WC_VEHICLE_DEPOT, this->xy); diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 2650843c1f..482e910bd9 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -1735,62 +1735,71 @@ void CheckOrders(const Vehicle *v) * Removes an order from all vehicles. Triggers when, say, a station is removed. * @param type The type of the order (OT_GOTO_[STATION|DEPOT|WAYPOINT]). * @param destination The destination. Can be a StationID, DepotID or WaypointID. + * @param owner The owner of the destination object. * @param hangar Only used for airports in the destination. * When false, remove airport and hangar orders. * When true, remove either airport or hangar order. */ -void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, bool hangar) +void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, Owner owner, bool hangar) { /* Aircraft have StationIDs for depot orders and never use DepotIDs * This fact is handled specially below */ /* Go through all vehicles */ - for (Vehicle *v : Vehicle::Iterate()) { - if ((v->type == VEH_AIRCRAFT && v->current_order.IsType(OT_GOTO_DEPOT) && !hangar ? OT_GOTO_STATION : v->current_order.GetType()) == type && - (!hangar || v->type == VEH_AIRCRAFT) && v->current_order.GetDestination() == destination) { - v->current_order.MakeDummy(); - SetWindowDirty(WC_VEHICLE_VIEW, v->index); - } + for (const Company *c : Company::Iterate()) { + /* Only iterate over all companies in the case of neutral owners */ + if (owner != c->index && owner != OWNER_NONE) continue; + for (VehicleType vtype = VEH_BEGIN; vtype < VEH_COMPANY_END; vtype++) { + const VehicleList &vehicle_list = c->group_all[vtype].vehicle_list; + for (const Vehicle *u : vehicle_list) { + Vehicle *v = Vehicle::Get(u->index); + if ((v->type == VEH_AIRCRAFT && v->current_order.IsType(OT_GOTO_DEPOT) && !hangar ? OT_GOTO_STATION : v->current_order.GetType()) == type && + (!hangar || v->type == VEH_AIRCRAFT) && v->current_order.GetDestination() == destination) { + v->current_order.MakeDummy(); + SetWindowDirty(WC_VEHICLE_VIEW, v->index); + } - /* Clear the order from the order-list */ - int id = -1; - for (Order *order : v->Orders()) { - id++; + /* Clear the order from the order-list */ + int id = -1; + for (Order *order : v->Orders()) { + id++; restart: - OrderType ot = order->GetType(); - if (ot == OT_GOTO_DEPOT && (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) continue; - if (ot == OT_GOTO_DEPOT && hangar && v->type != VEH_AIRCRAFT) continue; // Not an aircraft? Can't have a hangar order. - if (ot == OT_IMPLICIT || (v->type == VEH_AIRCRAFT && ot == OT_GOTO_DEPOT && !hangar)) 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 != nullptr) goto restart; - break; - } + OrderType ot = order->GetType(); + if (ot == OT_GOTO_DEPOT && (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) continue; + if (ot == OT_GOTO_DEPOT && hangar && v->type != VEH_AIRCRAFT) continue; // Not an aircraft? Can't have a hangar order. + if (ot == OT_IMPLICIT || (v->type == VEH_AIRCRAFT && ot == OT_GOTO_DEPOT && !hangar)) 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 != nullptr) goto restart; + break; + } - /* Clear wait time */ - v->orders->UpdateTotalDuration(-order->GetWaitTime()); - if (order->IsWaitTimetabled()) { - v->orders->UpdateTimetableDuration(-order->GetTimetabledWait()); - order->SetWaitTimetabled(false); - } - order->SetWaitTime(0); + /* Clear wait time */ + v->orders->UpdateTotalDuration(-order->GetWaitTime()); + if (order->IsWaitTimetabled()) { + v->orders->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); + /* Clear order, preserving travel time */ + bool travel_timetabled = order->IsTravelTimetabled(); + order->MakeDummy(); + order->SetTravelTimetabled(travel_timetabled); - for (const Vehicle *w = v->FirstShared(); w != nullptr; 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); + for (const Vehicle *w = v->FirstShared(); w != nullptr; 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); + } + } } } } diff --git a/src/order_func.h b/src/order_func.h index c879a2a30d..0eebed03e5 100644 --- a/src/order_func.h +++ b/src/order_func.h @@ -15,7 +15,7 @@ #include "company_type.h" /* Functions */ -void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, bool hangar = false); +void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, Owner owner, bool hangar = false); void InvalidateVehicleOrder(const Vehicle *v, int data); void CheckOrders(const Vehicle*); void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist = false, bool reset_order_indices = true); diff --git a/src/station.cpp b/src/station.cpp index 1338077d57..42efef7591 100644 --- a/src/station.cpp +++ b/src/station.cpp @@ -143,7 +143,7 @@ Station::~Station() CloseWindowById(WC_STATION_VIEW, index); /* Now delete all orders that go to the station */ - RemoveOrderFromAllVehicles(OT_GOTO_STATION, this->index); + RemoveOrderFromAllVehicles(OT_GOTO_STATION, this->index, this->owner); /* Remove all news items */ DeleteStationNews(this->index); diff --git a/src/waypoint.cpp b/src/waypoint.cpp index db1b36b1ec..047b52cffa 100644 --- a/src/waypoint.cpp +++ b/src/waypoint.cpp @@ -52,6 +52,6 @@ Waypoint::~Waypoint() { if (CleaningPool()) return; CloseWindowById(WC_WAYPOINT_VIEW, this->index); - RemoveOrderFromAllVehicles(OT_GOTO_WAYPOINT, this->index); + RemoveOrderFromAllVehicles(OT_GOTO_WAYPOINT, this->index, this->owner); if (this->sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeWaypoint(this->index)); }