summaryrefslogtreecommitdiff
path: root/src/vehicle.cpp
diff options
context:
space:
mode:
authorbjarni <bjarni@openttd.org>2008-04-27 20:09:29 +0000
committerbjarni <bjarni@openttd.org>2008-04-27 20:09:29 +0000
commit783e20a263a5e72bfed81ef7a9535a2caefebf79 (patch)
treeefbff2346a07d27ade486566153b76347444eb3f /src/vehicle.cpp
parentd6c971fd9b3777bcd0fa41ecaefb52ab2567bc89 (diff)
downloadopenttd-783e20a263a5e72bfed81ef7a9535a2caefebf79.tar.xz
(svn r12913) -Add: ability to backup and restore a player's economic data and data for a vehicle (or chain of vehicles)
Autoreplace uses this with the following benefits: -Mass autoreplace (the button in the depot window) will now estimate costs correctly -Autoreplace now either replaces correctly or manages to keep the original vehicle (no more broken trains) Thanks to Ammler for testing this
Diffstat (limited to 'src/vehicle.cpp')
-rw-r--r--src/vehicle.cpp88
1 files changed, 82 insertions, 6 deletions
diff --git a/src/vehicle.cpp b/src/vehicle.cpp
index ec4908669..03351b149 100644
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -712,12 +712,7 @@ void CallVehicleTicks()
v->leave_depot_instantly = false;
v->vehstatus &= ~VS_STOPPED;
}
-
- CommandCost cost = MaybeReplaceVehicle(v, 0, true);
- if (CmdSucceeded(cost) && cost.GetCost() != 0) {
- /* Looks like we can replace this vehicle so we go ahead and do so */
- MaybeReplaceVehicle(v, DC_EXEC, true);
- }
+ MaybeReplaceVehicle(v, DC_EXEC, true);
v = w;
}
_current_player = OWNER_NONE;
@@ -2689,6 +2684,87 @@ void Vehicle::SetNext(Vehicle *next)
}
}
+/** Backs up a chain of vehicles
+ * @return a pointer to the chain
+ */
+Vehicle* Vehicle::BackupVehicle() const
+{
+ int length = CountVehiclesInChain(this);
+
+ Vehicle *list = MallocT<Vehicle>(length);
+ Vehicle *copy = list; // store the pointer so we have something to return later
+
+ const Vehicle *original = this;
+
+ for (; 0 < length; original = original->next, copy++, length--) {
+ memcpy(copy, original, sizeof(Vehicle));
+ }
+ return list;
+}
+
+/** Restore a backed up row of vehicles
+ * @return a pointer to the first vehicle in chain
+ */
+Vehicle* Vehicle::RestoreBackupVehicle()
+{
+ Vehicle *backup = this;
+
+ Player *p = GetPlayer(backup->owner);
+
+ while (true) {
+ Vehicle *dest = GetVehicle(backup->index);
+ /* The vehicle should be free since we are restoring something we just sold. */
+ assert(!dest->IsValid());
+ memcpy(dest, backup, sizeof(Vehicle));
+
+ /* We decreased the engine count when we sold the engines so we will increase it again. */
+ if (IsEngineCountable(backup)) p->num_engines[backup->engine_type]++;
+
+ Vehicle *dummy = dest;
+ dest->old_new_hash = &dummy;
+ dest->left_coord = INVALID_COORD;
+ UpdateVehiclePosHash(dest, INVALID_COORD, 0);
+
+ if (backup->next == NULL) break;
+ backup++;
+ }
+ return GetVehicle(this->index);
+}
+
+/** Restores a backed up vehicle
+ * @param *v A vehicle we should sell and take the windows from (NULL for not using this)
+ * @return The vehicle we restored (front for trains) or v if we didn't have anything to restore
+ */
+Vehicle *BackuppedVehicle::Restore(Vehicle *v)
+{
+ if (!ContainsBackup()) return v;
+ if (v != NULL) {
+ ChangeVehicleViewWindow(v, INVALID_VEHICLE);
+ DoCommand(0, v->index, 1, DC_EXEC, GetCmdSellVeh(v));
+ }
+ v = this->vehicles->RestoreBackupVehicle();
+ ChangeVehicleViewWindow(INVALID_VEHICLE, v);
+ if (orders != NULL) RestoreVehicleOrdersBruteForce(v, orders);
+ if (economy != NULL) economy->Restore();
+ return v;
+}
+
+/** Backs up a vehicle
+ * This should never be called when the object already contains a backup
+ * @param v the vehicle to backup
+ * @param p If it's set to the vehicle's owner then economy is backed up. If NULL then economy backup will be skipped.
+ */
+void BackuppedVehicle::Backup(const Vehicle *v, Player *p)
+{
+ assert(!ContainsBackup());
+ if (p != NULL) {
+ assert(p->index == v->owner);
+ economy = new PlayerMoneyBackup(p);
+ }
+ vehicles = v->BackupVehicle();
+ if (orders != NULL) BackupVehicleOrders(v, orders);
+}
+
void StopAllVehicles()
{
Vehicle *v;