(svn r25361) -Feature: distribute cargo according to plan given by linkgraph

This commit is contained in:
fonsinchen
2013-06-09 13:03:48 +00:00
parent 45d7df8fc2
commit f022550df9
16 changed files with 586 additions and 206 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}