payments.diff

Hirundo, 2010-02-01 23:35

Download (25.6 KB)

View differences:

src/cargopacket.cpp Mon Feb 01 23:26:10 2010 +0100
12 12
#include "stdafx.h"
13 13
#include "core/pool_func.hpp"
14 14
#include "economy_base.h"
15
#include "map_func.h"
15 16

  
16 17
/* Initialize the cargopacket-pool */
17 18
CargoPacketPool _cargopacket_pool("CargoPacket");
18 19
INSTANTIATE_POOL_METHODS(CargoPacket)
19 20

  
21
/* Initialize the cargohistory-pool */
22
CargoHistoryPool _cargohistory_pool("CargoHistory");
23
INSTANTIATE_POOL_METHODS(CargoHistory)
24

  
20 25
/**
21 26
 * Initialize, i.e. clean, the pool with cargo packets.
22 27
 */
23 28
void InitializeCargoPackets()
24 29
{
25 30
	_cargopacket_pool.CleanPool();
31
	_cargohistory_pool.CleanPool();
32
}
33

  
34

  
35
CargoHistory::CargoHistory(CompanyByte company, TileIndex dropped_at_xy, CargoHistory **first) :
36
	next(NULL),
37
	company(company),
38
	dropped_at_xy(dropped_at_xy)
39
{
40
	if (first != NULL) {
41
		/* insert at the _beginning_ of the list */
42
		this->next = *first;
43
		*first = this;
44
	}
45
}
46

  
47
CargoHistory::~CargoHistory()
48
{
49
	delete this->next;
50
}
51

  
52
CargoHistory *CargoHistory::Clone() const
53
{
54
	CargoHistory *ch = new CargoHistory(this->company, this->dropped_at_xy);
55
	if (this->next != NULL) ch->next = this->next->Clone();
56
	return ch;
57
}
58

  
59
uint CargoHistory::GetDistance(TileIndex source_xy) const
60
{
61
	return DistanceManhattan(this->dropped_at_xy, this->next != NULL ? this->next->dropped_at_xy : source_xy);
62
}
63

  
64
/* static */ bool CargoHistory::AreMergable(CargoHistory *ch1, CargoHistory *ch2)
65
{
66
	if (ch1 == NULL) return ch2 == NULL;
67
	return ch1->dropped_at_xy == ch2->dropped_at_xy &&
68
			ch2->company == ch2->company &&
69
			AreMergable(ch1->next, ch2->next);
70
}
71

  
72
/* static */ void CargoHistory::ChangeAllOwners(Owner old_owner, Owner new_owner)
73
{
74
	CargoHistory *ch;
75
	FOR_ALL_CARGOHISTORIES(ch) {
76
		if (ch->company == old_owner) ch->company = new_owner;
77
	}
26 78
}
27 79

  
28 80
CargoPacket::CargoPacket()
29 81
{
30
	this->source_type = ST_INDUSTRY;
31
	this->source_id   = INVALID_SOURCE;
82
	this->source_type  = ST_INDUSTRY;
83
	this->source_id    = INVALID_SOURCE;
84
	this->last_company = INVALID_COMPANY;
85
	this->history      = NULL;
32 86
}
33 87

  
34 88
/* NOTE: We have to zero memory ourselves here because we are using a 'new'
......
40 94
	source_id(source_id),
41 95
	source(source),
42 96
	source_xy(source_xy),
43
	loaded_at_xy(0)
97
	loaded_at_xy(0),
98
	history(NULL)
44 99
{
45 100
	assert(count != 0);
46 101
	this->source_type  = source_type;
102
	this->last_company = INVALID_COMPANY;
47 103
}
48 104

  
49
CargoPacket::CargoPacket(uint16 count, byte days_in_transit, StationID source, TileIndex source_xy, TileIndex loaded_at_xy, Money feeder_share, SourceType source_type, SourceID source_id) :
105
CargoPacket::CargoPacket(uint16 count, byte days_in_transit, StationID source, TileIndex source_xy, TileIndex loaded_at_xy, Money feeder_share, SourceType source_type, SourceID source_id, CompanyID last_company, CargoHistory *history) :
50 106
		feeder_share(feeder_share),
51 107
		count(count),
52 108
		days_in_transit(days_in_transit),
53 109
		source_id(source_id),
54 110
		source(source),
55 111
		source_xy(source_xy),
56
		loaded_at_xy(loaded_at_xy)
112
		loaded_at_xy(loaded_at_xy),
113
		history(NULL)
57 114
{
58 115
	assert(count != 0);
59 116
	this->source_type = source_type;
117
	this->last_company = last_company;
118
	if (history != NULL) this->history = history->Clone();
119
}
120

  
121
CargoPacket::~CargoPacket()
122
{
123
	delete this->history;
60 124
}
61 125

  
62 126
/**
......
84 148
	}
85 149
}
86 150

  
151
/**
152
 * Changes the last_company of all cargo packets that were last transported by a given owner.
153
 * @param old_owner Old owner that ceases to exist
154
 * @param new_owner New owner, or INVALID_COMPANY
155
 */
156
/* static */ void CargoPacket::ChangeAllOwners(Owner old_owner, Owner new_owner)
157
{
158
	CargoPacket *cp;
159
	FOR_ALL_CARGOPACKETS(cp) {
160
		if (cp->last_company == old_owner) cp->last_company = new_owner;
161
	}
162
}
163

  
87 164
/*
88 165
 *
89 166
 * Cargo list implementation
......
163 240

  
164 241
template <class Tinst>
165 242
template <class Tother_inst>
166
bool CargoList<Tinst>::MoveTo(Tother_inst *dest, uint max_move, MoveToAction mta, CargoPayment *payment, uint data)
243
bool CargoList<Tinst>::MoveTo(Tother_inst *dest, uint max_move, MoveToAction mta, CargoPayment *payment, uint data, Owner owner)
167 244
{
168 245
	assert(mta == MTA_FINAL_DELIVERY || dest != NULL);
169 246
	assert(mta == MTA_UNLOAD || mta == MTA_CARGO_LOAD || payment != NULL);
247
	assert(mta != MTA_CARGO_LOAD || owner != INVALID_OWNER);
170 248

  
171 249
	Iterator it(this->packets.begin());
172 250
	while (it != this->packets.end() && max_move > 0) {
......
190 268

  
191 269
				case MTA_CARGO_LOAD:
192 270
					cp->loaded_at_xy = data;
271
					if (owner != cp->last_company) {
272
						if (cp->last_company != INVALID_COMPANY) {
273
							/* item inserts itself in the list */
274
							new CargoHistory(cp->last_company, data, &cp->history);
275
						}
276
						cp->last_company = owner;
277
					}
193 278
					break;
194 279

  
195 280
				case MTA_TRANSFER:
......
223 308
			cp->feeder_share -= fs;
224 309
			cp->count -= max_move;
225 310

  
226
			CargoPacket *cp_new = new CargoPacket(max_move, cp->days_in_transit, cp->source, cp->source_xy, (mta == MTA_CARGO_LOAD) ? data : cp->loaded_at_xy, fs, cp->source_type, cp->source_id);
311
			CargoPacket *cp_new = new CargoPacket(max_move, cp->days_in_transit, cp->source, cp->source_xy, (mta == MTA_CARGO_LOAD) ? data : cp->loaded_at_xy, fs, cp->source_type, cp->source_id, cp->last_company, cp->history);
312
			if (mta == MTA_CARGO_LOAD && owner != cp_new->last_company) {
313
				if (cp_new->last_company != INVALID_COMPANY) {
314
					/* item inserts itself in the list */
315
					new CargoHistory(cp_new->last_company, data, &cp_new->history);
316
				}
317
				cp_new->last_company = owner;
318
			}
227 319
			static_cast<Tinst *>(this)->RemoveFromCache(cp_new); // this reflects the changes in cp.
228 320

  
229 321
			if (mta == MTA_TRANSFER) {
......
289 381
template class CargoList<StationCargoList>;
290 382

  
291 383
/** Autoreplace Vehicle -> Vehicle 'transfer' */
292
template bool CargoList<VehicleCargoList>::MoveTo(VehicleCargoList *, uint max_move, MoveToAction mta, CargoPayment *payment, uint data);
384
template bool CargoList<VehicleCargoList>::MoveTo(VehicleCargoList *, uint max_move, MoveToAction mta, CargoPayment *payment, uint data, Owner owner);
293 385
/** Cargo unloading at a station */
294
template bool CargoList<VehicleCargoList>::MoveTo(StationCargoList *, uint max_move, MoveToAction mta, CargoPayment *payment, uint data);
386
template bool CargoList<VehicleCargoList>::MoveTo(StationCargoList *, uint max_move, MoveToAction mta, CargoPayment *payment, uint data, Owner owner);
295 387
/** Cargo loading at a station */
296
template bool CargoList<StationCargoList>::MoveTo(VehicleCargoList *, uint max_move, MoveToAction mta, CargoPayment *payment, uint data);
388
template bool CargoList<StationCargoList>::MoveTo(VehicleCargoList *, uint max_move, MoveToAction mta, CargoPayment *payment, uint data, Owner owner);
src/cargopacket.h Mon Feb 01 23:26:10 2010 +0100
17 17
#include "station_type.h"
18 18
#include "cargo_type.h"
19 19
#include "vehicle_type.h"
20
#include "company_type.h"
20 21
#include <list>
21 22

  
22 23
/** Unique identifier for a single cargo packet. */
......
28 29
/** The actual pool with cargo packets */
29 30
extern CargoPacketPool _cargopacket_pool;
30 31

  
32
/** Unique identifier for a single item in a cargo packet's history. */
33
typedef uint32 CargoHistoryID;
34
struct CargoHistory;
35

  
36
/** Type of the pool for cargo packets. */
37
typedef Pool<CargoHistory, CargoHistoryID, 1024, 1048576, true, false> CargoHistoryPool;
38
/** The actual pool with cargo packets */
39
extern CargoHistoryPool _cargohistory_pool;
40

  
31 41
template <class Tinst> class CargoList;
32 42
extern const struct SaveLoad *GetCargoPacketDesc();
43
extern const struct SaveLoad *GetCargoHistoryDesc();
44

  
45
/**
46
 * Container to hold information about how far a company transported a cargo packet
47
 * @note The oldest history item is the last in the list. New items are prepended, not appended, for efficiency reasons.
48
 */
49
struct CargoHistory : CargoHistoryPool::PoolItem<&_cargohistory_pool> {
50
private:
51
	CargoHistory *next;          ///< Next history entry in the linked list
52
	TileIndex     dropped_at_xy; ///< Location where the company stopped transporting the cargo
53
	CompanyByte   company;       ///< Company that transported the cargo
54

  
55
	/* saveload code needs to know about us */
56
	friend const struct SaveLoad *GetCargoHistoryDesc();
57
public:
58
	/**
59
	 * Constructor used when loading savegames
60
	 */
61
	CargoHistory() {};
62

  
63
	/**
64
	 * Constructor to be used when adding a history item to the list
65
	 * @param company Company that transported the packet.
66
	 * @param dropped_at_xy The location where the company stopped transporting the packet.
67
	 * @param list The first item of the list to insert this item in
68
	 */
69
	CargoHistory(CompanyByte company, TileIndex dropped_at_xy, CargoHistory **first = NULL);
70

  
71
	/**
72
	 * Destructor
73
	 */
74
	~CargoHistory();
75

  
76
	/**
77
	 * Gets the next history item in the linked list
78
	 * @return The next CargoHistory
79
	 */
80
	CargoHistory *Next() const
81
	{
82
		return this->next;
83
	}
84

  
85
	/**
86
	 * Gets the location where the company stopped transporting the cargo
87
	 * @return The location where the company dropped the packet
88
	 */
89
	TileIndex DroppedAtXY() const
90
	{
91
		return this->dropped_at_xy;
92
	}
93

  
94
	/**
95
	 * Company that transported the packet in the past
96
	 * @return The company that transported the packet
97
	 */
98
	CompanyByte Company() const
99
	{
100
		return this->company;
101
	}
102

  
103
	/**
104
	 * Clone this CargoHistory item, to allow splitting packets.
105
	 * Do this recursively to clone the entire linked list.
106
	 * @return A pointer to the cloned history.
107
	 */
108
	CargoHistory *Clone() const;
109

  
110
	/**
111
	 * Get the distance this packet was transported by the company.
112
	 * @param source_xy The origin of the packet.
113
	 * @return The length of the 'leg' this history item specifies.
114
	 */
115
	uint GetDistance(TileIndex source_xy) const;
116

  
117
	/**
118
	 * Are two histories mergeable?
119
	 * This function recursively operates on the linked list,
120
	 * to check that all items are equal.
121
	  */
122
	static bool AreMergable(CargoHistory *ch1, CargoHistory *ch2);
123

  
124
	/**
125
	 * Change all cargo histories ('rewrite history') to replace all occurrences of old_owner with new_owner.
126
	 * @param old_owner Old owner that ceases to exist.
127
	 * @param new_owner New owner, or INVALID_COMPANY.
128
	 */
129
	static void ChangeAllOwners(Owner old_owner, Owner new_owner);
130
};
131

  
132
/**
133
 * Iterate over all _valid_ cargo history items from the given start
134
 * @param var   the variable used as "iterator"
135
 * @param start the cargo history ID of the first packet to iterate over
136
 */
137
#define FOR_ALL_CARGOHISTORIES_FROM(var, start) FOR_ALL_ITEMS_FROM(CargoHistory, cargohistory_index, var, start)
138

  
139
/**
140
 * Iterate over all _valid_ cargo history items from the begin of the pool
141
 * @param var   the variable used as "iterator"
142
 */
143
#define FOR_ALL_CARGOHISTORIES(var) FOR_ALL_CARGOHISTORIES_FROM(var, 0)
33 144

  
34 145
/**
35 146
 * Container for cargo from the same location and time
......
44 155
	StationID source;           ///< The station where the cargo came from first
45 156
	TileIndex source_xy;        ///< The origin of the cargo (first station in feeder chain)
46 157
	TileIndex loaded_at_xy;     ///< Location where this cargo has been loaded into the vehicle
158
	CompanyByte last_company;   ///< Company that has last transported this cargo
159
	CargoHistory *history;      ///< History of the companies that transported this packet
47 160

  
48 161
	/** The CargoList caches, thus needs to know about it. */
49 162
	template <class Tinst> friend class CargoList;
......
82 195
	 * @param feeder_share    feeder share the packet has already accumulated
83 196
	 * @param source_type     the 'type' of source the packet comes from (for subsidies)
84 197
	 * @param source_id       the actual source of the packet (for subsidies)
198
	 * @param last_company    the company that has last transported this cargo
199
	 * @param history         history of previous transfers of the cargo
85 200
	 */
86
	CargoPacket(uint16 count, byte days_in_transit, StationID source, TileIndex source_xy, TileIndex loaded_at_xy, Money feeder_share = 0, SourceType source_type = ST_INDUSTRY, SourceID source_id = INVALID_SOURCE);
201
	CargoPacket(uint16 count, byte days_in_transit, StationID source, TileIndex source_xy, TileIndex loaded_at_xy, Money feeder_share = 0, SourceType source_type = ST_INDUSTRY, SourceID source_id = INVALID_SOURCE, CompanyID last_company = INVALID_COMPANY, CargoHistory *history = NULL);
87 202

  
88 203
	/** Destroy the packet */
89
	~CargoPacket() { }
204
	~CargoPacket();
90 205

  
91 206

  
92 207
	/**
......
164 279
		return this->loaded_at_xy;
165 280
	}
166 281

  
282
	/**
283
	 * Gets the company that has last transported this cargo
284
	 * @return the company that has last transported this cargo
285
	 */
286
	FORCEINLINE CompanyByte LastCompany() const
287
	{
288
		return this->last_company;
289
	}
290

  
291
	/**
292
	 * Gets the location where LastCompany() loaded this cargo
293
	 * @return the last company's loading coordinates
294
	 */
295
	FORCEINLINE TileIndex CompanyLoadedAtXY() const
296
	{
297
		return this->history != NULL ? this->history->DroppedAtXY() : this->source_xy;
298
	}
299

  
300
	/**
301
	 * Gets a pointer to the history of the packet
302
	 * @return A linked list of the packet's history
303
	 */
304
	FORCEINLINE CargoHistory *History() const
305
	{
306
		return this->history;
307
	}
167 308

  
168 309
	static void InvalidateAllFrom(SourceType src_type, SourceID src);
169 310
	static void InvalidateAllFrom(StationID sid);
311
	static void ChangeAllOwners(Owner old_owner, Owner new_owner);
170 312
	static void AfterLoad();
171 313
};
172 314

  
......
309 451
	 *              - MTA_TRANSFER       - unused
310 452
	 *              - MTA_UNLOAD         - unused
311 453
	 * @param payment The payment helper
454
	 * @param owner   The vehicle owner. Only required when mta == MTA_CARGO_LOAD
312 455
	 *
313 456
	 * @pre mta == MTA_FINAL_DELIVERY || dest != NULL
314 457
	 * @pre mta == MTA_UNLOAD || mta == MTA_CARGO_LOAD || payment != NULL
458
	 * @pre mta != MTA_CARGO_LOAD || owner != INVALID_OWNER
315 459
	 * @return true if there are still packets that might be moved from this cargo list
316 460
	 */
317 461
	template <class Tother_inst>
318
	bool MoveTo(Tother_inst *dest, uint count, MoveToAction mta, CargoPayment *payment, uint data = 0);
462
	bool MoveTo(Tother_inst *dest, uint count, MoveToAction mta, CargoPayment *payment, uint data = 0, Owner owner = INVALID_OWNER);
319 463

  
320 464
	/** Invalidates the cached data and rebuild it */
321 465
	void InvalidateCache();
......
381 525
				cp1->days_in_transit == cp2->days_in_transit &&
382 526
				cp1->source_type     == cp2->source_type &&
383 527
				cp1->source_id       == cp2->source_id &&
528
				cp1->last_company    == cp2->last_company &&
529
				CargoHistory::AreMergable(cp1->history, cp2->history) &&
384 530
				cp1->loaded_at_xy    == cp2->loaded_at_xy;
385 531
	}
386 532
};
......
407 553
		return cp1->source_xy    == cp2->source_xy &&
408 554
				cp1->days_in_transit == cp2->days_in_transit &&
409 555
				cp1->source_type     == cp2->source_type &&
410
				cp1->source_id       == cp2->source_id;
556
				cp1->source_id       == cp2->source_id &&
557
				cp1->last_company    == cp2->last_company &&
558
				CargoHistory::AreMergable(cp1->history, cp2->history);
411 559
	}
412 560
};
413 561

  
src/economy.cpp Mon Feb 01 23:26:10 2010 +0100
463 463
		if (si->owner == old_owner) si->owner = new_owner == INVALID_OWNER ? OWNER_NONE : new_owner;
464 464
	}
465 465

  
466
	CargoPacket::ChangeAllOwners(old_owner, new_owner);
467
	CargoHistory::ChangeAllOwners(old_owner, new_owner);
468

  
469
	/* Fix cargo payments */
470
	CargoPayment *payment;
471
	FOR_ALL_CARGO_PAYMENTS(payment) {
472
		if (new_owner != INVALID_COMPANY) payment->route_profit[new_owner] += payment->route_profit[old_owner];
473
		payment->route_profit[old_owner] = 0;
474
	}
475

  
476

  
466 477
	/* Change colour of existing windows */
467 478
	if (new_owner != INVALID_OWNER) ChangeWindowOwner(old_owner, new_owner);
468 479

  
......
1025 1036
	if (this->visual_profit == 0) return;
1026 1037

  
1027 1038
	CompanyID old_company = _current_company;
1028
	_current_company = this->front->owner;
1039
	Money total_profit = 0;
1029 1040

  
1030
	SubtractMoneyFromCompany(CommandCost(this->front->GetExpenseType(true), -this->route_profit));
1041
	for (CompanyID cid = COMPANY_FIRST; cid < MAX_COMPANIES; cid++) {
1042
		Money company_profit;
1043
		if ((company_profit = this->route_profit[cid]) == 0) continue;
1044
		assert(Company::IsValidID(cid));
1045
		_current_company = cid;
1046
		SubtractMoneyFromCompany(CommandCost(this->front->GetExpenseType(true), -company_profit));
1047
		total_profit += company_profit;
1048
	}
1031 1049
	this->front->profit_this_year += this->visual_profit << 8;
1032 1050

  
1033
	if (this->route_profit != 0) {
1034
		if (IsLocalCompany() && !PlayVehicleSound(this->front, VSE_LOAD_UNLOAD)) {
1051
	if (total_profit != 0) {
1052
		if (IsInteractiveCompany(this->front->owner) && !PlayVehicleSound(this->front, VSE_LOAD_UNLOAD)) {
1035 1053
			SndPlayVehicleFx(SND_14_CASHTILL, this->front);
1036 1054
		}
1037 1055

  
......
1054 1072
		this->owner = Company::Get(this->front->owner);
1055 1073
	}
1056 1074

  
1057
	/* Handle end of route payment */
1075
	/* Deliver the goods and determine the total profit. */
1058 1076
	Money profit = DeliverGoods(count, this->ct, this->current_station, cp->SourceStationXY(), cp->DaysInTransit(), this->owner, cp->SourceSubsidyType(), cp->SourceSubsidyID());
1059
	this->route_profit += profit;
1077

  
1078
	/* Last leg should be transported by the owner of the vehicle */
1079
	assert(cp->LastCompany() == this->front->owner);
1080
	uint last_distance = DistanceManhattan(cp->CompanyLoadedAtXY(), Station::Get(this->current_station)->xy);
1081

  
1082
	/* Determine the total distance. */
1083
	uint total_distance = last_distance;
1084
	for (const CargoHistory *ch = cp->History(); ch != NULL; ch = ch->Next()) {
1085
		if (ch->Company() != INVALID_COMPANY) total_distance += ch->GetDistance(cp->SourceStationXY());
1086
	}
1087

  
1088
	if (total_distance != 0) {
1089
		/* Give each company that transported the packet a share of the profit, based on transported distance. */
1090
		this->route_profit[cp->LastCompany()] += profit * last_distance / total_distance;
1091
		for (const CargoHistory *ch = cp->History(); ch != NULL; ch = ch->Next()) {
1092
			if (ch->Company() != INVALID_COMPANY) this->route_profit[ch->Company()] += profit * ch->GetDistance(cp->SourceStationXY()) / total_distance;
1093
		}
1094
	} else {
1095
		/* In corner cases (source_xy == dest_xy, or company got deleted)
1096
		 * The combined distance of the legs may be zero.
1097
		 * Give any profit to the vehicle owner of the last leg. */
1098
		this->route_profit[cp->LastCompany()] += profit;
1099
	}
1060 1100

  
1061 1101
	/* The vehicle's profit is whatever route profit there is minus feeder shares. */
1062 1102
	this->visual_profit += profit - cp->FeederShare();
......
1282 1322
			completely_emptied = false;
1283 1323
			anything_loaded = true;
1284 1324

  
1285
			ge->cargo.MoveTo(&v->cargo, cap, StationCargoList::MTA_CARGO_LOAD, NULL, st->xy);
1325
			ge->cargo.MoveTo(&v->cargo, cap, StationCargoList::MTA_CARGO_LOAD, NULL, st->xy, v->owner);
1286 1326

  
1287 1327
			st->time_since_load = 0;
1288 1328
			st->last_vehicle_type = v->type;
src/economy_base.h Mon Feb 01 23:26:10 2010 +0100
24 24
 * Helper class to perform the cargo payment.
25 25
 */
26 26
struct CargoPayment : CargoPaymentPool::PoolItem<&_cargo_payment_pool> {
27
	Vehicle *front;      ///< The front vehicle to do the payment of
28
	Money route_profit;  ///< The amount of money to add/remove from the bank account
29
	Money visual_profit; ///< The visual profit to show
27
	Vehicle *front;                    ///< The front vehicle to do the payment of
28
	Money route_profit[MAX_COMPANIES]; ///< The amount of money to add/remove from the bank account of each company
29
	Money visual_profit;               ///< The total visual profit to show
30 30

  
31 31
	/* Unsaved variables */
32 32
	Company *owner;            ///< The owner of the vehicle
src/saveload/afterload.cpp Mon Feb 01 23:26:10 2010 +0100
2063 2063
		}
2064 2064
	}
2065 2065

  
2066
	/* Format of cargo payments is changed */
2067
	if (CheckSavegameVersion(139)) {
2068
		CargoPayment *cp;
2069
		FOR_ALL_CARGO_PAYMENTS(cp) {
2070
			Money route_profit = cp->route_profit[0];
2071
			cp->route_profit[0] = 0;
2072
			cp->route_profit[cp->front->owner] = route_profit;
2073
		}
2074
	}
2075

  
2066 2076
	/* Road stops is 'only' updating some caches */
2067 2077
	AfterLoadRoadStops();
2068 2078
	AfterLoadLabelMaps();
src/saveload/cargopacket_sl.cpp Mon Feb 01 23:26:10 2010 +0100
12 12
#include "../stdafx.h"
13 13
#include "../vehicle_base.h"
14 14
#include "../station_base.h"
15
#include "../company_base.h"
15 16

  
16 17
#include "saveload.h"
17 18

  
19

  
20
/**
21
 * Wrapper function to get the saveload description for CargoHistory objects
22
 * Used to allow accessing private variables
23
 * @return the SaveLoad description for CargoHistories.
24
 */
25
const SaveLoad *GetCargoHistoryDesc()
26
{
27
	static const SaveLoad _cargohistory_desc[] = {
28
		SLE_REF(CargoHistory, next,          REF_CARGO_HISTORY),
29
		SLE_VAR(CargoHistory, company,       SLE_UINT8),
30
		SLE_VAR(CargoHistory, dropped_at_xy, SLE_UINT32),
31
		SLE_END()
32
	};
33
	return _cargohistory_desc;
34
}
35

  
36
static void Save_CAHI()
37
{
38
	CargoHistory *ch;
39

  
40
	FOR_ALL_CARGOHISTORIES(ch) {
41
		SlSetArrayIndex(ch->index);
42
		SlObject(ch, GetCargoHistoryDesc());
43
	}
44
}
45

  
46
static void Load_CAHI()
47
{
48
	int index;
49

  
50
	while ((index = SlIterateArray()) != -1) {
51
		CargoHistory *ch = new (index) CargoHistory();
52
		SlObject(ch, GetCargoHistoryDesc());
53
	}
54
}
55

  
56
static void Ptrs_CAHI()
57
{
58
	CargoHistory *ch;
59

  
60
	FOR_ALL_CARGOHISTORIES(ch) {
61
		SlObject(ch, GetCargoHistoryDesc());
62
	}
63
}
64

  
18 65
/* static */ void CargoPacket::AfterLoad()
19 66
{
20 67
	if (CheckSavegameVersion(44)) {
......
74 121
			for (CargoID c = 0; c < NUM_CARGO; c++) st->goods[c].cargo.InvalidateCache();
75 122
		}
76 123
	}
124

  
125
	/* Set 'last_company' variable to be equal to the owner of the vehicle/station */
126
	if (CheckSavegameVersion(139)) {
127
		Vehicle *v;
128
		FOR_ALL_VEHICLES(v) {
129
			const VehicleCargoList::List *packets = v->cargo.Packets();
130
			for (VehicleCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) {
131
				(*it)->last_company = v->owner;
132
			}
133
		}
134

  
135
		Station *st;
136
		FOR_ALL_STATIONS(st) {
137
			for (CargoID c = 0; c < NUM_CARGO; c++) {
138
				const StationCargoList::List *packets = st->goods[c].cargo.Packets();
139
				for (StationCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) {
140
					/* in the case of stations without a valid owner (oil rigs) we set it to INVALID_COMPANY */
141
					(*it)->last_company = Company::IsValidID(st->owner) ? st->owner : INVALID_COMPANY;
142
				}
143
			}
144
		}
145
	}
77 146
}
78 147

  
79 148
/**
......
92 161
		     SLE_VAR(CargoPacket, feeder_share,    SLE_INT64),
93 162
		 SLE_CONDVAR(CargoPacket, source_type,     SLE_UINT8,  125, SL_MAX_VERSION),
94 163
		 SLE_CONDVAR(CargoPacket, source_id,       SLE_UINT16, 125, SL_MAX_VERSION),
164
		 SLE_CONDVAR(CargoPacket, last_company,    SLE_UINT8,  139, SL_MAX_VERSION),
165

  
166
		 SLE_CONDREF(CargoPacket, history,  REF_CARGO_HISTORY, 139, SL_MAX_VERSION),
95 167

  
96 168
		/* Used to be paid_for, but that got changed. */
97 169
		SLE_CONDNULL(1, 0, 120),
......
121 193
	}
122 194
}
123 195

  
196
static void Ptrs_CAPA()
197
{
198
	CargoPacket *cp;
199

  
200
	FOR_ALL_CARGOPACKETS(cp) {
201
		SlObject(cp, GetCargoPacketDesc());
202
	}
203
}
204

  
124 205
extern const ChunkHandler _cargopacket_chunk_handlers[] = {
125
	{ 'CAPA', Save_CAPA, Load_CAPA, NULL, CH_ARRAY | CH_LAST},
206
	{ 'CAHI', Save_CAHI, Load_CAHI, Ptrs_CAHI, CH_ARRAY},
207
	{ 'CAPA', Save_CAPA, Load_CAPA, Ptrs_CAPA, CH_ARRAY | CH_LAST},
126 208
};
src/saveload/economy_sl.cpp Mon Feb 01 23:26:10 2010 +0100
63 63
}
64 64

  
65 65
static const SaveLoad _cargopayment_desc[] = {
66
	SLE_REF(CargoPayment, front,         REF_VEHICLE),
67
	SLE_VAR(CargoPayment, route_profit,  SLE_INT64),
68
	SLE_VAR(CargoPayment, visual_profit, SLE_INT64),
69

  
70
	SLE_END()
66
	    SLE_REF(CargoPayment, front,           REF_VEHICLE),
67
	SLE_CONDVAR(CargoPayment, route_profit[0], SLE_INT64,                  0, 138),
68
	SLE_CONDARR(CargoPayment, route_profit,    SLE_INT64, MAX_COMPANIES, 139, SL_MAX_VERSION),
69
	    SLE_VAR(CargoPayment, visual_profit,   SLE_INT64),
70
	    SLE_END()
71 71
};
72 72

  
73 73
static void Save_CAPY()
src/saveload/saveload.cpp Mon Feb 01 23:26:10 2010 +0100
46 46

  
47 47
#include "saveload_internal.h"
48 48

  
49
extern const uint16 SAVEGAME_VERSION = 138;
49
extern const uint16 SAVEGAME_VERSION = 139;
50 50

  
51 51
SavegameType _savegame_type; ///< type of savegame we are loading
52 52

  
......
1525 1525
		case REF_TOWN:      return ((const     Town*)obj)->index + 1;
1526 1526
		case REF_ORDER:     return ((const    Order*)obj)->index + 1;
1527 1527
		case REF_ROADSTOPS: return ((const RoadStop*)obj)->index + 1;
1528
		case REF_ENGINE_RENEWS: return ((const EngineRenew*)obj)->index + 1;
1529
		case REF_CARGO_PACKET:  return ((const CargoPacket*)obj)->index + 1;
1530
		case REF_ORDERLIST:     return ((const   OrderList*)obj)->index + 1;
1528
		case REF_ENGINE_RENEWS: return ((const  EngineRenew*)obj)->index + 1;
1529
		case REF_CARGO_PACKET:  return ((const  CargoPacket*)obj)->index + 1;
1530
		case REF_ORDERLIST:     return ((const    OrderList*)obj)->index + 1;
1531
		case REF_CARGO_HISTORY: return ((const CargoHistory*)obj)->index + 1;
1531 1532
		default: NOT_REACHED();
1532 1533
	}
1533 1534
}
......
1597 1598
			if (CargoPacket::IsValidID(index)) return CargoPacket::Get(index);
1598 1599
			SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Referencing invalid CargoPacket");
1599 1600

  
1601
		case REF_CARGO_HISTORY:
1602
			if (CargoHistory::IsValidID(index)) return CargoHistory::Get(index);
1603
			SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Referencing invalid CargoHistory");
1604

  
1600 1605
		default: NOT_REACHED();
1601 1606
	}
1602 1607
}
src/saveload/saveload.h Mon Feb 01 23:26:10 2010 +0100
77 77
	REF_ENGINE_RENEWS = 6,
78 78
	REF_CARGO_PACKET  = 7,
79 79
	REF_ORDERLIST     = 8,
80
	REF_CARGO_HISTORY = 9,
80 81
};
81 82

  
82 83
#define SL_MAX_VERSION 255