summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2010-08-18 15:58:30 +0000
committerrubidium <rubidium@openttd.org>2010-08-18 15:58:30 +0000
commit287ee8c01d900ef15bd434e61607c0f341ec2d7e (patch)
treea42028ee5beaf4a395062e7e382d34a792a3e095
parentd28985fe8e701f061344f457d7c8704ad63d1ad8 (diff)
downloadopenttd-287ee8c01d900ef15bd434e61607c0f341ec2d7e.tar.xz
(svn r20541) -Fix: when removing a vehicle update the "clone orders of"-vehicle of a backed up order, or remove it if there is no vehicle sharing orders with that vehicle.
-rw-r--r--src/order_backup.cpp27
-rw-r--r--src/order_backup.h13
-rw-r--r--src/vehicle.cpp2
3 files changed, 31 insertions, 11 deletions
diff --git a/src/order_backup.cpp b/src/order_backup.cpp
index 3a462e3ce..ccbe93abe 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 a64c9b4fb..04913c2ac 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 0089514f8..c19d03abc 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);