diff --git a/src/order_backup.cpp b/src/order_backup.cpp index 3a462e3ce6..ccbe93abe9 100644 --- a/src/order_backup.cpp +++ b/src/order_backup.cpp @@ -37,15 +37,10 @@ OrderBackup::OrderBackup(const Vehicle *v) /* If we have shared orders, store the vehicle we share the order with. */ if (v->IsOrderListShared()) { - const Vehicle *u = (v->FirstShared() == v) ? v->NextShared() : v->FirstShared(); - - this->clone = u->index; + this->clone = (v->FirstShared() == v) ? v->NextShared() : v->FirstShared(); } else { /* Else copy the orders */ - /* We do not have shared orders */ - this->clone = INVALID_VEHICLE; - /* Count the number of orders */ uint cnt = 0; const Order *order; @@ -72,9 +67,9 @@ void OrderBackup::RestoreTo(const Vehicle *v) if (this->name != NULL) DoCommandP(0, v->index, 0, CMD_RENAME_VEHICLE, NULL, this->name); /* If we had shared orders, recover that */ - if (this->clone != INVALID_VEHICLE) { - DoCommandP(0, v->index | (this->clone << 16), CO_SHARE, CMD_CLONE_ORDER); - } else { + if (this->clone != NULL) { + DoCommandP(0, v->index | (this->clone->index << 16), CO_SHARE, CMD_CLONE_ORDER); + } else if (this->orders != NULL) { /* CMD_NO_TEST_IF_IN_NETWORK is used here, because CMD_INSERT_ORDER checks if the * order number is one more than the current amount of orders, and because @@ -140,6 +135,20 @@ void OrderBackup::RestoreTo(const Vehicle *v) } } +/* static */ void OrderBackup::ClearVehicle(const Vehicle *v) +{ + assert(v != NULL); + OrderBackup *ob; + FOR_ALL_ORDER_BACKUPS(ob) { + if (ob->clone == v) { + /* Get another item in the shared list. */ + ob->clone = (v->FirstShared() == v) ? v->NextShared() : v->FirstShared(); + /* But if that isn't there, remove it. */ + if (ob->clone == NULL) delete ob; + } + } +} + void InitializeOrderBackups() { _order_backup_pool.CleanPool(); diff --git a/src/order_backup.h b/src/order_backup.h index a64c9b4fb6..04913c2ac4 100644 --- a/src/order_backup.h +++ b/src/order_backup.h @@ -39,7 +39,7 @@ private: uint16 service_interval; ///< The service interval of the vehicle. char *name; ///< The custom name of the vehicle. - VehicleID clone; ///< VehicleID this vehicle was a clone of, or INVALID_VEHICLE. + const Vehicle *clone; ///< Vehicle this vehicle was a clone of. VehicleOrderID orderindex; ///< The order-index the vehicle had. Order *orders; ///< The actual orders if the vehicle was not a clone. @@ -74,9 +74,18 @@ public: /** * Clear the group of all backups having this group ID. - * @param group The group to clear + * @param group The group to clear. */ static void ClearGroup(GroupID group); + + /** + * Clear/update the (clone) vehicle from an order backup. + * @param v The vehicle to clear. + * @pre v != NULL + * @note If it is not possible to set another vehicle as clone + * "example", then this backed up order will be removed. + */ + static void ClearVehicle(const Vehicle *v); }; #define FOR_ALL_ORDER_BACKUPS_FROM(var, start) FOR_ALL_ITEMS_FROM(OrderBackup, order_backup_index, var, start) diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 0089514f84..c19d03abc8 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -51,6 +51,7 @@ #include "engine_base.h" #include "newgrf.h" #include "core/backup_type.hpp" +#include "order_backup.h" #include "table/sprites.h" #include "table/strings.h" @@ -674,6 +675,7 @@ void Vehicle::PreDestructor() DeleteWindowById(WC_VEHICLE_DETAILS, this->index); DeleteWindowById(WC_VEHICLE_TIMETABLE, this->index); SetWindowDirty(WC_COMPANY, this->owner); + OrderBackup::ClearVehicle(this); } InvalidateWindowClassesData(GetWindowClassForVehicleType(this->type), 0);