summaryrefslogtreecommitdiff
path: root/src/saveload
diff options
context:
space:
mode:
authorfonsinchen <fonsinchen@openttd.org>2013-06-09 13:03:48 +0000
committerfonsinchen <fonsinchen@openttd.org>2013-06-09 13:03:48 +0000
commit04e3eb6fabc0e4aff04c189368356b8af15e9655 (patch)
treeaa9d6a025fb3e343fc8cdc9358a913182445210b /src/saveload
parenta2ff96d6828bd32f7beb461bfb902880bf46ef75 (diff)
downloadopenttd-04e3eb6fabc0e4aff04c189368356b8af15e9655.tar.xz
(svn r25361) -Feature: distribute cargo according to plan given by linkgraph
Diffstat (limited to 'src/saveload')
-rw-r--r--src/saveload/cargopacket_sl.cpp4
-rw-r--r--src/saveload/oldloader_sl.cpp3
-rw-r--r--src/saveload/station_sl.cpp68
3 files changed, 69 insertions, 6 deletions
diff --git a/src/saveload/cargopacket_sl.cpp b/src/saveload/cargopacket_sl.cpp
index f9ebd3408..fbc38cc85 100644
--- a/src/saveload/cargopacket_sl.cpp
+++ b/src/saveload/cargopacket_sl.cpp
@@ -29,7 +29,7 @@
* to the current tile of the vehicle to prevent excessive profits
*/
FOR_ALL_VEHICLES(v) {
- const VehicleCargoList::List *packets = v->cargo.Packets();
+ const CargoPacketList *packets = v->cargo.Packets();
for (VehicleCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) {
CargoPacket *cp = *it;
cp->source_xy = Station::IsValidID(cp->source) ? Station::Get(cp->source)->xy : v->tile;
@@ -47,7 +47,7 @@
for (CargoID c = 0; c < NUM_CARGO; c++) {
GoodsEntry *ge = &st->goods[c];
- const StationCargoList::List *packets = ge->cargo.Packets();
+ const StationCargoPacketMap *packets = ge->cargo.Packets();
for (StationCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) {
CargoPacket *cp = *it;
cp->source_xy = Station::IsValidID(cp->source) ? Station::Get(cp->source)->xy : st->xy;
diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp
index 987af757a..791e63db5 100644
--- a/src/saveload/oldloader_sl.cpp
+++ b/src/saveload/oldloader_sl.cpp
@@ -711,7 +711,8 @@ static bool LoadOldGood(LoadgameState *ls, int num)
SB(ge->acceptance_pickup, GoodsEntry::GES_ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
SB(ge->acceptance_pickup, GoodsEntry::GES_PICKUP, 1, _cargo_source != 0xFF);
if (GB(_waiting_acceptance, 0, 12) != 0 && CargoPacket::CanAllocateItem()) {
- ge->cargo.Append(new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_days, (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, 0, 0));
+ ge->cargo.Append(new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_days, (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, 0, 0),
+ INVALID_STATION);
}
return true;
diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp
index 6f1a864a2..7c43cc7a8 100644
--- a/src/saveload/station_sl.cpp
+++ b/src/saveload/station_sl.cpp
@@ -237,6 +237,9 @@ static const SaveLoad _station_speclist_desc[] = {
SLE_END()
};
+std::list<CargoPacket *> _packets;
+uint32 _num_dests;
+
struct FlowSaveLoad {
FlowSaveLoad() : via(0), share(0) {}
StationID source;
@@ -273,7 +276,8 @@ const SaveLoad *GetGoodsDesc()
SLEG_CONDVAR( _cargo_feeder_share, SLE_FILE_U32 | SLE_VAR_I64, 14, 64),
SLEG_CONDVAR( _cargo_feeder_share, SLE_INT64, 65, 67),
SLE_CONDVAR(GoodsEntry, amount_fract, SLE_UINT8, 150, SL_MAX_VERSION),
- SLE_CONDLST(GoodsEntry, cargo.packets, REF_CARGO_PACKET, 68, SL_MAX_VERSION),
+ SLEG_CONDLST( _packets, REF_CARGO_PACKET, 68, 182),
+ SLEG_CONDVAR( _num_dests, SLE_UINT32, 183, SL_MAX_VERSION),
SLE_CONDVAR(GoodsEntry, cargo.reserved_count, SLE_UINT, 181, SL_MAX_VERSION),
SLE_CONDVAR(GoodsEntry, link_graph, SLE_UINT16, 183, SL_MAX_VERSION),
SLE_CONDVAR(GoodsEntry, node, SLE_UINT16, 183, SL_MAX_VERSION),
@@ -284,6 +288,35 @@ const SaveLoad *GetGoodsDesc()
return goods_desc;
}
+typedef std::pair<const StationID, std::list<CargoPacket *> > StationCargoPair;
+
+static const SaveLoad _cargo_list_desc[] = {
+ SLE_VAR(StationCargoPair, first, SLE_UINT16),
+ SLE_LST(StationCargoPair, second, REF_CARGO_PACKET),
+ SLE_END()
+};
+
+/**
+ * Swap the temporary packets with the packets without specific destination in
+ * the given goods entry. Assert that at least one of those is empty.
+ * @param ge Goods entry to swap with.
+ */
+static void SwapPackets(GoodsEntry *ge)
+{
+ StationCargoPacketMap &ge_packets = const_cast<StationCargoPacketMap &>(*ge->cargo.Packets());
+
+ if (_packets.empty()) {
+ std::map<StationID, std::list<CargoPacket *> >::iterator it(ge_packets.find(INVALID_STATION));
+ if (it == ge_packets.end()) {
+ return;
+ } else {
+ it->second.swap(_packets);
+ }
+ } else {
+ assert(ge_packets[INVALID_STATION].empty());
+ ge_packets[INVALID_STATION].swap(_packets);
+ }
+}
static void Load_STNS()
{
@@ -299,6 +332,7 @@ static void Load_STNS()
for (CargoID i = 0; i < num_cargo; i++) {
GoodsEntry *ge = &st->goods[i];
SlObject(ge, GetGoodsDesc());
+ SwapPackets(ge);
if (IsSavegameVersionBefore(68)) {
SB(ge->acceptance_pickup, GoodsEntry::GES_ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
if (GB(_waiting_acceptance, 0, 12) != 0) {
@@ -310,7 +344,10 @@ static void Load_STNS()
* savegame versions. As the CargoPacketPool has more than
* 16 million entries; it fits by an order of magnitude. */
assert(CargoPacket::CanAllocateItem());
- ge->cargo.Append(new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_days, source, _cargo_source_xy, _cargo_source_xy, _cargo_feeder_share));
+
+ /* Don't construct the packet with station here, because that'll fail with old savegames */
+ CargoPacket *cp = new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_days, source, _cargo_source_xy, _cargo_source_xy, _cargo_feeder_share);
+ ge->cargo.Append(cp, INVALID_STATION);
SB(ge->acceptance_pickup, GoodsEntry::GES_PICKUP, 1, 1);
}
}
@@ -336,7 +373,9 @@ static void Ptrs_STNS()
if (!IsSavegameVersionBefore(68)) {
for (CargoID i = 0; i < NUM_CARGO; i++) {
GoodsEntry *ge = &st->goods[i];
+ SwapPackets(ge);
SlObject(ge, GetGoodsDesc());
+ SwapPackets(ge);
}
}
SlObject(st, _old_station_desc);
@@ -427,6 +466,7 @@ static void RealSave_STNN(BaseStation *bst)
if (!waypoint) {
Station *st = Station::From(bst);
for (CargoID i = 0; i < NUM_CARGO; i++) {
+ _num_dests = (uint32)st->goods[i].cargo.Packets()->MapSize();
_num_flows = 0;
for (FlowStatMap::const_iterator it(st->goods[i].flows.begin()); it != st->goods[i].flows.end(); ++it) {
_num_flows += (uint32)it->second.GetShares()->size();
@@ -445,6 +485,9 @@ static void RealSave_STNN(BaseStation *bst)
SlObject(&flow, _flow_desc);
}
}
+ for (StationCargoPacketMap::ConstMapIterator it(st->goods[i].cargo.Packets()->begin()); it != st->goods[i].cargo.Packets()->end(); ++it) {
+ SlObject(const_cast<StationCargoPacketMap::value_type *>(&(*it)), _cargo_list_desc);
+ }
}
}
@@ -498,6 +541,16 @@ static void Load_STNN()
}
prev_source = flow.source;
}
+ if (IsSavegameVersionBefore(183)) {
+ SwapPackets(&st->goods[i]);
+ } else {
+ StationCargoPair pair;
+ for (uint j = 0; j < _num_dests; ++j) {
+ SlObject(&pair, _cargo_list_desc);
+ const_cast<StationCargoPacketMap &>(*(st->goods[i].cargo.Packets()))[pair.first].swap(pair.second);
+ assert(pair.second.empty());
+ }
+ }
}
}
@@ -520,7 +573,16 @@ static void Ptrs_STNN()
FOR_ALL_STATIONS(st) {
for (CargoID i = 0; i < NUM_CARGO; i++) {
GoodsEntry *ge = &st->goods[i];
- SlObject(ge, GetGoodsDesc());
+ if (IsSavegameVersionBefore(183)) {
+ SwapPackets(ge);
+ SlObject(ge, GetGoodsDesc());
+ SwapPackets(ge);
+ } else {
+ SlObject(ge, GetGoodsDesc());
+ for (StationCargoPacketMap::ConstMapIterator it = ge->cargo.Packets()->begin(); it != ge->cargo.Packets()->end(); ++it) {
+ SlObject(const_cast<StationCargoPair *>(&(*it)), _cargo_list_desc);
+ }
+ }
}
SlObject(st, _station_desc);
}