Move StationCargoList and FlowStatMap out of GoodsEntry struct
Move them into a new GoodsEntryData struct referenced using a std::unique_ptr from GoodsEntry. The unique_ptr may be nullptr if the cargo list and flow stat map are both empty (this is the case for unused cargoes). This reduces GoodsEntry from 128 to 24 bytes, and Station from 8680 to 2024 bytes, (on Linux x86_64).
This commit is contained in:
@@ -1476,7 +1476,7 @@ static void MaybeCrashAirplane(Aircraft *v)
|
|||||||
/* Crash the airplane. Remove all goods stored at the station. */
|
/* Crash the airplane. Remove all goods stored at the station. */
|
||||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
||||||
st->goods[i].rating = 1;
|
st->goods[i].rating = 1;
|
||||||
st->goods[i].cargo.Truncate();
|
if (st->goods[i].data != nullptr) st->goods[i].data->cargo.Truncate();
|
||||||
}
|
}
|
||||||
|
|
||||||
CrashAirplane(v);
|
CrashAirplane(v);
|
||||||
|
@@ -638,6 +638,8 @@ bool VehicleCargoList::Stage(bool accepted, StationID current_station, StationID
|
|||||||
CargoPacketList transfer_deliver;
|
CargoPacketList transfer_deliver;
|
||||||
std::vector<CargoPacket *> keep;
|
std::vector<CargoPacket *> keep;
|
||||||
|
|
||||||
|
const FlowStatMap &flows = ge->CreateData().flows;
|
||||||
|
|
||||||
bool force_keep = (order_flags & OUFB_NO_UNLOAD) != 0;
|
bool force_keep = (order_flags & OUFB_NO_UNLOAD) != 0;
|
||||||
bool force_unload = (order_flags & OUFB_UNLOAD) != 0;
|
bool force_unload = (order_flags & OUFB_UNLOAD) != 0;
|
||||||
bool force_transfer = (order_flags & (OUFB_TRANSFER | OUFB_UNLOAD)) != 0;
|
bool force_transfer = (order_flags & (OUFB_TRANSFER | OUFB_UNLOAD)) != 0;
|
||||||
@@ -656,8 +658,8 @@ bool VehicleCargoList::Stage(bool accepted, StationID current_station, StationID
|
|||||||
action = MTA_TRANSFER;
|
action = MTA_TRANSFER;
|
||||||
/* We cannot send the cargo to any of the possible next hops and
|
/* We cannot send the cargo to any of the possible next hops and
|
||||||
* also not to the current station. */
|
* also not to the current station. */
|
||||||
FlowStatMap::const_iterator flow_it(ge->flows.find(cp->source));
|
FlowStatMap::const_iterator flow_it(flows.find(cp->source));
|
||||||
if (flow_it == ge->flows.end()) {
|
if (flow_it == flows.end()) {
|
||||||
cargo_next = INVALID_STATION;
|
cargo_next = INVALID_STATION;
|
||||||
} else {
|
} else {
|
||||||
FlowStat new_shares = *flow_it;
|
FlowStat new_shares = *flow_it;
|
||||||
@@ -675,12 +677,12 @@ bool VehicleCargoList::Stage(bool accepted, StationID current_station, StationID
|
|||||||
} else {
|
} else {
|
||||||
/* Rewrite an invalid source station to some random other one to
|
/* Rewrite an invalid source station to some random other one to
|
||||||
* avoid keeping the cargo in the vehicle forever. */
|
* avoid keeping the cargo in the vehicle forever. */
|
||||||
if (cp->source == INVALID_STATION && !ge->flows.empty()) {
|
if (cp->source == INVALID_STATION && !flows.empty()) {
|
||||||
cp->source = ge->flows.FirstStationID();
|
cp->source = flows.FirstStationID();
|
||||||
}
|
}
|
||||||
bool restricted = false;
|
bool restricted = false;
|
||||||
FlowStatMap::const_iterator flow_it(ge->flows.find(cp->source));
|
FlowStatMap::const_iterator flow_it(flows.find(cp->source));
|
||||||
if (flow_it == ge->flows.end()) {
|
if (flow_it == flows.end()) {
|
||||||
cargo_next = INVALID_STATION;
|
cargo_next = INVALID_STATION;
|
||||||
} else {
|
} else {
|
||||||
cargo_next = flow_it->GetViaWithRestricted(restricted);
|
cargo_next = flow_it->GetViaWithRestricted(restricted);
|
||||||
|
@@ -605,6 +605,11 @@ public:
|
|||||||
this->reserved_count += count;
|
this->reserved_count += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LoadSetReservedCount(uint count)
|
||||||
|
{
|
||||||
|
this->reserved_count = count;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Are the two CargoPackets mergeable in the context of
|
* Are the two CargoPackets mergeable in the context of
|
||||||
* a list of CargoPackets for a Station?
|
* a list of CargoPackets for a Station?
|
||||||
|
@@ -1668,7 +1668,7 @@ struct ReturnCargoAction
|
|||||||
*/
|
*/
|
||||||
bool operator()(Vehicle *v)
|
bool operator()(Vehicle *v)
|
||||||
{
|
{
|
||||||
v->cargo.Return(UINT_MAX, &this->st->goods[v->cargo_type].cargo, this->next_hop);
|
v->cargo.Return(UINT_MAX, &this->st->goods[v->cargo_type].CreateData().cargo, this->next_hop);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1704,7 +1704,7 @@ struct FinalizeRefitAction
|
|||||||
bool operator()(Vehicle *v)
|
bool operator()(Vehicle *v)
|
||||||
{
|
{
|
||||||
if (this->do_reserve || (cargo_type_loading == nullptr || (cargo_type_loading->current_order.GetCargoLoadTypeRaw(v->cargo_type) & OLFB_FULL_LOAD))) {
|
if (this->do_reserve || (cargo_type_loading == nullptr || (cargo_type_loading->current_order.GetCargoLoadTypeRaw(v->cargo_type) & OLFB_FULL_LOAD))) {
|
||||||
this->st->goods[v->cargo_type].cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(),
|
this->st->goods[v->cargo_type].CreateData().cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(),
|
||||||
&v->cargo, st->xy, this->next_station.Get(v->cargo_type));
|
&v->cargo, st->xy, this->next_station.Get(v->cargo_type));
|
||||||
}
|
}
|
||||||
this->consist_capleft[v->cargo_type] += v->cargo_cap - v->cargo.RemainingCount();
|
this->consist_capleft[v->cargo_type] += v->cargo_cap - v->cargo.RemainingCount();
|
||||||
@@ -1740,7 +1740,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station
|
|||||||
new_cid = v_start->cargo_type;
|
new_cid = v_start->cargo_type;
|
||||||
for (CargoID cid : SetCargoBitIterator(refit_mask)) {
|
for (CargoID cid : SetCargoBitIterator(refit_mask)) {
|
||||||
if (check_order && v->First()->current_order.GetCargoLoadType(cid) == OLFB_NO_LOAD) continue;
|
if (check_order && v->First()->current_order.GetCargoLoadType(cid) == OLFB_NO_LOAD) continue;
|
||||||
if (st->goods[cid].cargo.HasCargoFor(next_station.Get(cid))) {
|
if (st->goods[cid].data != nullptr && st->goods[cid].data->cargo.HasCargoFor(next_station.Get(cid))) {
|
||||||
/* Try to find out if auto-refitting would succeed. In case the refit is allowed,
|
/* Try to find out if auto-refitting would succeed. In case the refit is allowed,
|
||||||
* the returned refit capacity will be greater than zero. */
|
* the returned refit capacity will be greater than zero. */
|
||||||
DoCommand(v_start->tile, v_start->index, cid | 1U << 24 | 0xFF << 8 | 1U << 16, DC_QUERY_COST, GetCmdRefitVeh(v_start)); // Auto-refit and only this vehicle including artic parts.
|
DoCommand(v_start->tile, v_start->index, cid | 1U << 24 | 0xFF << 8 | 1U << 16, DC_QUERY_COST, GetCmdRefitVeh(v_start)); // Auto-refit and only this vehicle including artic parts.
|
||||||
@@ -1752,7 +1752,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station
|
|||||||
* of 0 for all cargoes. */
|
* of 0 for all cargoes. */
|
||||||
if (_returned_refit_capacity > 0 && (consist_capleft[cid] < consist_capleft[new_cid] ||
|
if (_returned_refit_capacity > 0 && (consist_capleft[cid] < consist_capleft[new_cid] ||
|
||||||
(consist_capleft[cid] == consist_capleft[new_cid] &&
|
(consist_capleft[cid] == consist_capleft[new_cid] &&
|
||||||
st->goods[cid].cargo.AvailableCount() > st->goods[new_cid].cargo.AvailableCount()))) {
|
st->goods[cid].data->cargo.AvailableCount() > st->goods[new_cid].CargoAvailableCount()))) {
|
||||||
new_cid = cid;
|
new_cid = cid;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1809,7 +1809,7 @@ struct ReserveCargoAction {
|
|||||||
if (!(flags & OLFB_FULL_LOAD) && !through_load) return true;
|
if (!(flags & OLFB_FULL_LOAD) && !through_load) return true;
|
||||||
}
|
}
|
||||||
if (v->cargo_cap > v->cargo.RemainingCount() && MayLoadUnderExclusiveRights(st, v)) {
|
if (v->cargo_cap > v->cargo.RemainingCount() && MayLoadUnderExclusiveRights(st, v)) {
|
||||||
st->goods[v->cargo_type].cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(),
|
st->goods[v->cargo_type].CreateData().cargo.Reserve(v->cargo_cap - v->cargo.RemainingCount(),
|
||||||
&v->cargo, st->xy, next_station.Get(v->cargo_type));
|
&v->cargo, st->xy, next_station.Get(v->cargo_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2022,6 +2022,7 @@ static void LoadUnloadVehicle(Vehicle *front)
|
|||||||
artic_part++;
|
artic_part++;
|
||||||
|
|
||||||
GoodsEntry *ge = &st->goods[v->cargo_type];
|
GoodsEntry *ge = &st->goods[v->cargo_type];
|
||||||
|
GoodsEntryData &ged = ge->CreateData();
|
||||||
|
|
||||||
if (HasBit(v->vehicle_flags, VF_CARGO_UNLOADING) && payment == nullptr) {
|
if (HasBit(v->vehicle_flags, VF_CARGO_UNLOADING) && payment == nullptr) {
|
||||||
/* Once the payment has been made, never attempt to unload again */
|
/* Once the payment has been made, never attempt to unload again */
|
||||||
@@ -2046,7 +2047,7 @@ static void LoadUnloadVehicle(Vehicle *front)
|
|||||||
uint new_remaining = v->cargo.RemainingCount() + v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER);
|
uint new_remaining = v->cargo.RemainingCount() + v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER);
|
||||||
if (v->cargo_cap < new_remaining) {
|
if (v->cargo_cap < new_remaining) {
|
||||||
/* Return some of the reserved cargo to not overload the vehicle. */
|
/* Return some of the reserved cargo to not overload the vehicle. */
|
||||||
v->cargo.Return(new_remaining - v->cargo_cap, &ge->cargo, INVALID_STATION);
|
v->cargo.Return(new_remaining - v->cargo_cap, &ged.cargo, INVALID_STATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Keep instead of delivering. This may lead to no cargo being unloaded, so ...*/
|
/* Keep instead of delivering. This may lead to no cargo being unloaded, so ...*/
|
||||||
@@ -2073,7 +2074,7 @@ static void LoadUnloadVehicle(Vehicle *front)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
amount_unloaded = v->cargo.Unload(amount_unloaded, &ge->cargo, payment);
|
amount_unloaded = v->cargo.Unload(amount_unloaded, &ged.cargo, payment);
|
||||||
remaining = v->cargo.UnloadCount() > 0;
|
remaining = v->cargo.UnloadCount() > 0;
|
||||||
if (amount_unloaded > 0) {
|
if (amount_unloaded > 0) {
|
||||||
dirty_vehicle = true;
|
dirty_vehicle = true;
|
||||||
@@ -2143,11 +2144,11 @@ static void LoadUnloadVehicle(Vehicle *front)
|
|||||||
|
|
||||||
/* If there's goods waiting at the station, and the vehicle
|
/* If there's goods waiting at the station, and the vehicle
|
||||||
* has capacity for it, load it on the vehicle. */
|
* has capacity for it, load it on the vehicle. */
|
||||||
if ((v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0 || ge->cargo.AvailableCount() > 0) && MayLoadUnderExclusiveRights(st, v)) {
|
if ((v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0 || ged.cargo.AvailableCount() > 0) && MayLoadUnderExclusiveRights(st, v)) {
|
||||||
if (v->cargo.StoredCount() == 0) TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO);
|
if (v->cargo.StoredCount() == 0) TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO);
|
||||||
if (_settings_game.order.gradual_loading) cap_left = std::min(cap_left, GetLoadAmount(v));
|
if (_settings_game.order.gradual_loading) cap_left = std::min(cap_left, GetLoadAmount(v));
|
||||||
|
|
||||||
uint loaded = ge->cargo.Load(cap_left, &v->cargo, st->xy, next_station.Get(v->cargo_type));
|
uint loaded = ged.cargo.Load(cap_left, &v->cargo, st->xy, next_station.Get(v->cargo_type));
|
||||||
if (v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) {
|
if (v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) {
|
||||||
/* Remember if there are reservations left so that we don't stop
|
/* Remember if there are reservations left so that we don't stop
|
||||||
* loading before they're loaded. */
|
* loading before they're loaded. */
|
||||||
@@ -2175,7 +2176,7 @@ static void LoadUnloadVehicle(Vehicle *front)
|
|||||||
st->time_since_load = 0;
|
st->time_since_load = 0;
|
||||||
ge->last_vehicle_type = v->type;
|
ge->last_vehicle_type = v->type;
|
||||||
|
|
||||||
if (ge->cargo.TotalCount() == 0) {
|
if (ged.cargo.TotalCount() == 0) {
|
||||||
TriggerStationRandomisation(st, st->xy, SRT_CARGO_TAKEN, v->cargo_type);
|
TriggerStationRandomisation(st, st->xy, SRT_CARGO_TAKEN, v->cargo_type);
|
||||||
TriggerStationAnimation(st, st->xy, SAT_CARGO_TAKEN, v->cargo_type);
|
TriggerStationAnimation(st, st->xy, SAT_CARGO_TAKEN, v->cargo_type);
|
||||||
AirportAnimationTrigger(st, AAT_STATION_CARGO_TAKEN, v->cargo_type);
|
AirportAnimationTrigger(st, AAT_STATION_CARGO_TAKEN, v->cargo_type);
|
||||||
|
@@ -172,7 +172,7 @@ void LinkGraphOverlay::RebuildCache(bool incremental)
|
|||||||
item->to_pt = to_pt;
|
item->to_pt = to_pt;
|
||||||
}
|
}
|
||||||
this->AddStats(c, lg.Monthly(edge.Capacity()), lg.Monthly(edge.Usage()),
|
this->AddStats(c, lg.Monthly(edge.Capacity()), lg.Monthly(edge.Usage()),
|
||||||
ge.flows.GetFlowVia(to->index),
|
ge.data != nullptr ? ge.data->flows.GetFlowVia(to->index) : 0,
|
||||||
edge.TravelTime(),
|
edge.TravelTime(),
|
||||||
from->owner == OWNER_NONE || to->owner == OWNER_NONE,
|
from->owner == OWNER_NONE || to->owner == OWNER_NONE,
|
||||||
item->prop);
|
item->prop);
|
||||||
|
@@ -121,6 +121,7 @@ void LinkGraphJob::FinaliseJob()
|
|||||||
|
|
||||||
LinkGraph *lg = LinkGraph::Get(ge.link_graph);
|
LinkGraph *lg = LinkGraph::Get(ge.link_graph);
|
||||||
FlowStatMap &flows = from.Flows();
|
FlowStatMap &flows = from.Flows();
|
||||||
|
FlowStatMap &geflows = ge.CreateData().flows;
|
||||||
|
|
||||||
for (Edge &edge : from.GetEdges()) {
|
for (Edge &edge : from.GetEdges()) {
|
||||||
if (edge.Flow() == 0) continue;
|
if (edge.Flow() == 0) continue;
|
||||||
@@ -135,7 +136,7 @@ void LinkGraphJob::FinaliseJob()
|
|||||||
/* Delete old flows for source stations which have been deleted
|
/* Delete old flows for source stations which have been deleted
|
||||||
* from the new flows. This avoids flow cycles between old and
|
* from the new flows. This avoids flow cycles between old and
|
||||||
* new flows. */
|
* new flows. */
|
||||||
while (!erased.IsEmpty()) ge.flows.erase(erased.Pop());
|
while (!erased.IsEmpty()) geflows.erase(erased.Pop());
|
||||||
} else if (lg_edge.LastUnrestrictedUpdate() == INVALID_DATE) {
|
} else if (lg_edge.LastUnrestrictedUpdate() == INVALID_DATE) {
|
||||||
/* Edge is fully restricted. */
|
/* Edge is fully restricted. */
|
||||||
flows.RestrictFlows(to);
|
flows.RestrictFlows(to);
|
||||||
@@ -146,7 +147,7 @@ void LinkGraphJob::FinaliseJob()
|
|||||||
* really delete them as we could then end up with unroutable cargo
|
* really delete them as we could then end up with unroutable cargo
|
||||||
* somewhere. Do delete them and also reroute relevant cargo if
|
* somewhere. Do delete them and also reroute relevant cargo if
|
||||||
* automatic distribution has been turned off for that cargo. */
|
* automatic distribution has been turned off for that cargo. */
|
||||||
for (FlowStatMap::iterator it(ge.flows.begin()); it != ge.flows.end();) {
|
for (FlowStatMap::iterator it(geflows.begin()); it != geflows.end();) {
|
||||||
FlowStatMap::iterator new_it = flows.find(it->GetOrigin());
|
FlowStatMap::iterator new_it = flows.find(it->GetOrigin());
|
||||||
if (new_it == flows.end()) {
|
if (new_it == flows.end()) {
|
||||||
if (_settings_game.linkgraph.GetDistributionType(this->Cargo()) != DT_MANUAL) {
|
if (_settings_game.linkgraph.GetDistributionType(this->Cargo()) != DT_MANUAL) {
|
||||||
@@ -154,7 +155,7 @@ void LinkGraphJob::FinaliseJob()
|
|||||||
NodeID origin = it->GetOrigin();
|
NodeID origin = it->GetOrigin();
|
||||||
FlowStat shares(INVALID_STATION, INVALID_STATION, 1);
|
FlowStat shares(INVALID_STATION, INVALID_STATION, 1);
|
||||||
it->SwapShares(shares);
|
it->SwapShares(shares);
|
||||||
it = ge.flows.erase(it);
|
it = geflows.erase(it);
|
||||||
for (FlowStat::const_iterator shares_it(shares.begin());
|
for (FlowStat::const_iterator shares_it(shares.begin());
|
||||||
shares_it != shares.end(); ++shares_it) {
|
shares_it != shares.end(); ++shares_it) {
|
||||||
RerouteCargoFromSource(st, this->Cargo(), origin, shares_it->second, st->index);
|
RerouteCargoFromSource(st, this->Cargo(), origin, shares_it->second, st->index);
|
||||||
@@ -165,7 +166,7 @@ void LinkGraphJob::FinaliseJob()
|
|||||||
} else {
|
} else {
|
||||||
FlowStat shares(INVALID_STATION, INVALID_STATION, 1);
|
FlowStat shares(INVALID_STATION, INVALID_STATION, 1);
|
||||||
it->SwapShares(shares);
|
it->SwapShares(shares);
|
||||||
it = ge.flows.erase(it);
|
it = geflows.erase(it);
|
||||||
for (FlowStat::const_iterator shares_it(shares.begin());
|
for (FlowStat::const_iterator shares_it(shares.begin());
|
||||||
shares_it != shares.end(); ++shares_it) {
|
shares_it != shares.end(); ++shares_it) {
|
||||||
RerouteCargo(st, this->Cargo(), shares_it->second, st->index);
|
RerouteCargo(st, this->Cargo(), shares_it->second, st->index);
|
||||||
@@ -178,9 +179,9 @@ void LinkGraphJob::FinaliseJob()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (FlowStatMap::iterator it(flows.begin()); it != flows.end(); ++it) {
|
for (FlowStatMap::iterator it(flows.begin()); it != flows.end(); ++it) {
|
||||||
ge.flows.insert(std::move(*it));
|
geflows.insert(std::move(*it));
|
||||||
}
|
}
|
||||||
ge.flows.SortStorage();
|
geflows.SortStorage();
|
||||||
InvalidateWindowData(WC_STATION_VIEW, st->index, this->Cargo());
|
InvalidateWindowData(WC_STATION_VIEW, st->index, this->Cargo());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -271,7 +271,7 @@ RoadStopResolverObject::RoadStopResolverObject(const RoadStopSpec *roadstopspec,
|
|||||||
/* Pick the first cargo that we have waiting */
|
/* Pick the first cargo that we have waiting */
|
||||||
for (const CargoSpec *cs : CargoSpec::Iterate()) {
|
for (const CargoSpec *cs : CargoSpec::Iterate()) {
|
||||||
if (roadstopspec->grf_prop.spritegroup[cs->Index()] != nullptr &&
|
if (roadstopspec->grf_prop.spritegroup[cs->Index()] != nullptr &&
|
||||||
station->goods[cs->Index()].cargo.TotalCount() > 0) {
|
station->goods[cs->Index()].CargoTotalCount() > 0) {
|
||||||
ctype = cs->Index();
|
ctype = cs->Index();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -474,7 +474,7 @@ void TriggerRoadStopRandomisation(Station *st, TileIndex tile, RoadStopRandomTri
|
|||||||
if (trigger == RSRT_CARGO_TAKEN) {
|
if (trigger == RSRT_CARGO_TAKEN) {
|
||||||
/* Create a bitmask of completely empty cargo types to be matched */
|
/* Create a bitmask of completely empty cargo types to be matched */
|
||||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
||||||
if (st->goods[i].cargo.TotalCount() == 0) {
|
if (st->goods[i].CargoTotalCount() == 0) {
|
||||||
SetBit(empty_mask, i);
|
SetBit(empty_mask, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -699,7 +699,7 @@ void DumpRoadStopSpriteGroup(const BaseStation *st, const RoadStopSpec *spec, Du
|
|||||||
/* Pick the first cargo that we have waiting */
|
/* Pick the first cargo that we have waiting */
|
||||||
for (const CargoSpec *cs : CargoSpec::Iterate()) {
|
for (const CargoSpec *cs : CargoSpec::Iterate()) {
|
||||||
if (spec->grf_prop.spritegroup[cs->Index()] != nullptr &&
|
if (spec->grf_prop.spritegroup[cs->Index()] != nullptr &&
|
||||||
station->goods[cs->Index()].cargo.TotalCount() > 0) {
|
station->goods[cs->Index()].CargoTotalCount() > 0) {
|
||||||
ctype = cs->Index();
|
ctype = cs->Index();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -447,10 +447,10 @@ uint32 Station::GetNewGRFVariable(const ResolverObject &object, uint16 variable,
|
|||||||
const GoodsEntry *ge = &this->goods[c];
|
const GoodsEntry *ge = &this->goods[c];
|
||||||
|
|
||||||
switch (variable) {
|
switch (variable) {
|
||||||
case 0x60: return std::min<uint32>(ge->cargo.TotalCount(), 4095);
|
case 0x60: return std::min<uint32>(ge->CargoTotalCount(), 4095);
|
||||||
case 0x61: return ge->HasVehicleEverTriedLoading() && ge->IsSupplyAllowed() ? ge->time_since_pickup : 0;
|
case 0x61: return ge->HasVehicleEverTriedLoading() && ge->IsSupplyAllowed() ? ge->time_since_pickup : 0;
|
||||||
case 0x62: return ge->HasRating() ? ge->rating : 0xFFFFFFFF;
|
case 0x62: return ge->HasRating() ? ge->rating : 0xFFFFFFFF;
|
||||||
case 0x63: return ge->cargo.DaysInTransit();
|
case 0x63: return ge->data != nullptr ? ge->data->cargo.DaysInTransit() : 0;
|
||||||
case 0x64: return ge->HasVehicleEverTriedLoading() && ge->IsSupplyAllowed() ? ge->last_speed | (ge->last_age << 8) : 0xFF00;
|
case 0x64: return ge->HasVehicleEverTriedLoading() && ge->IsSupplyAllowed() ? ge->last_speed | (ge->last_age << 8) : 0xFF00;
|
||||||
case 0x65: return GB(ge->status, GoodsEntry::GES_ACCEPTANCE, 1) << 3;
|
case 0x65: return GB(ge->status, GoodsEntry::GES_ACCEPTANCE, 1) << 3;
|
||||||
case 0x69: {
|
case 0x69: {
|
||||||
@@ -466,12 +466,12 @@ uint32 Station::GetNewGRFVariable(const ResolverObject &object, uint16 variable,
|
|||||||
if (variable >= 0x8C && variable <= 0xEC) {
|
if (variable >= 0x8C && variable <= 0xEC) {
|
||||||
const GoodsEntry *g = &this->goods[GB(variable - 0x8C, 3, 4)];
|
const GoodsEntry *g = &this->goods[GB(variable - 0x8C, 3, 4)];
|
||||||
switch (GB(variable - 0x8C, 0, 3)) {
|
switch (GB(variable - 0x8C, 0, 3)) {
|
||||||
case 0: return g->cargo.TotalCount();
|
case 0: return g->CargoTotalCount();
|
||||||
case 1: return GB(std::min(g->cargo.TotalCount(), 4095u), 0, 4) | (GB(g->status, GoodsEntry::GES_ACCEPTANCE, 1) << 7);
|
case 1: return GB(std::min(g->CargoTotalCount(), 4095u), 0, 4) | (GB(g->status, GoodsEntry::GES_ACCEPTANCE, 1) << 7);
|
||||||
case 2: return g->time_since_pickup;
|
case 2: return g->time_since_pickup;
|
||||||
case 3: return g->rating;
|
case 3: return g->rating;
|
||||||
case 4: return g->cargo.Source();
|
case 4: return g->data != nullptr ? g->data->cargo.Source() : INVALID_STATION;
|
||||||
case 5: return g->cargo.DaysInTransit();
|
case 5: return g->data != nullptr ? g->data->cargo.DaysInTransit() : 0;
|
||||||
case 6: return g->last_speed;
|
case 6: return g->last_speed;
|
||||||
case 7: return g->last_age;
|
case 7: return g->last_age;
|
||||||
}
|
}
|
||||||
@@ -533,12 +533,12 @@ uint32 Waypoint::GetNewGRFVariable(const ResolverObject &object, uint16 variable
|
|||||||
|
|
||||||
case CT_DEFAULT:
|
case CT_DEFAULT:
|
||||||
for (CargoID cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) {
|
for (CargoID cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) {
|
||||||
cargo += st->goods[cargo_type].cargo.TotalCount();
|
cargo += st->goods[cargo_type].CargoTotalCount();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
cargo = st->goods[this->station_scope.cargo_type].cargo.TotalCount();
|
cargo = st->goods[this->station_scope.cargo_type].CargoTotalCount();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -598,7 +598,7 @@ StationResolverObject::StationResolverObject(const StationSpec *statspec, BaseSt
|
|||||||
/* Pick the first cargo that we have waiting */
|
/* Pick the first cargo that we have waiting */
|
||||||
for (const CargoSpec *cs : CargoSpec::Iterate()) {
|
for (const CargoSpec *cs : CargoSpec::Iterate()) {
|
||||||
if (this->station_scope.statspec->grf_prop.spritegroup[cs->Index()] != nullptr &&
|
if (this->station_scope.statspec->grf_prop.spritegroup[cs->Index()] != nullptr &&
|
||||||
st->goods[cs->Index()].cargo.TotalCount() > 0) {
|
st->goods[cs->Index()].CargoTotalCount() > 0) {
|
||||||
ctype = cs->Index();
|
ctype = cs->Index();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1006,7 +1006,7 @@ void TriggerStationRandomisation(Station *st, TileIndex trigger_tile, StationRan
|
|||||||
if (trigger == SRT_CARGO_TAKEN) {
|
if (trigger == SRT_CARGO_TAKEN) {
|
||||||
/* Create a bitmask of completely empty cargo types to be matched */
|
/* Create a bitmask of completely empty cargo types to be matched */
|
||||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
||||||
if (st->goods[i].cargo.TotalCount() == 0) {
|
if (st->goods[i].CargoTotalCount() == 0) {
|
||||||
SetBit(empty_mask, i);
|
SetBit(empty_mask, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1916,14 +1916,16 @@ void CheckCaches(bool force_check, std::function<void(const char *)> log, CheckC
|
|||||||
|
|
||||||
for (Station *st : Station::Iterate()) {
|
for (Station *st : Station::Iterate()) {
|
||||||
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
||||||
uint old_count = st->goods[c].cargo.TotalCount();
|
if (st->goods[c].data == nullptr) continue;
|
||||||
uint64 old_cargo_days_in_transit = st->goods[c].cargo.CargoDaysInTransit();
|
|
||||||
|
|
||||||
st->goods[c].cargo.InvalidateCache();
|
uint old_count = st->goods[c].data->cargo.TotalCount();
|
||||||
|
uint64 old_cargo_days_in_transit = st->goods[c].data->cargo.CargoDaysInTransit();
|
||||||
|
|
||||||
|
st->goods[c].data->cargo.InvalidateCache();
|
||||||
|
|
||||||
uint changed = 0;
|
uint changed = 0;
|
||||||
if (st->goods[c].cargo.TotalCount() != old_count) SetBit(changed, 0);
|
if (st->goods[c].data->cargo.TotalCount() != old_count) SetBit(changed, 0);
|
||||||
if (st->goods[c].cargo.CargoDaysInTransit() != old_cargo_days_in_transit) SetBit(changed, 1);
|
if (st->goods[c].data->cargo.CargoDaysInTransit() != old_cargo_days_in_transit) SetBit(changed, 1);
|
||||||
if (changed != 0) {
|
if (changed != 0) {
|
||||||
CCLOG("station cargo cache mismatch: station %i, company %i, cargo %u: %c%c",
|
CCLOG("station cargo cache mismatch: station %i, company %i, cargo %u: %c%c",
|
||||||
st->index, (int)st->owner, c,
|
st->index, (int)st->owner, c,
|
||||||
|
@@ -3097,16 +3097,16 @@ VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v, Pro
|
|||||||
case OCV_UNCONDITIONALLY: skip_order = true; break;
|
case OCV_UNCONDITIONALLY: skip_order = true; break;
|
||||||
case OCV_CARGO_WAITING: {
|
case OCV_CARGO_WAITING: {
|
||||||
StationID next_station = GetNextRealStation(v, order);
|
StationID next_station = GetNextRealStation(v, order);
|
||||||
if (Station::IsValidID(next_station)) skip_order = OrderConditionCompare(occ, (Station::Get(next_station)->goods[value].cargo.AvailableCount() > 0), value);
|
if (Station::IsValidID(next_station)) skip_order = OrderConditionCompare(occ, (Station::Get(next_station)->goods[value].CargoAvailableCount() > 0), value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OCV_CARGO_WAITING_AMOUNT: {
|
case OCV_CARGO_WAITING_AMOUNT: {
|
||||||
StationID next_station = GetNextRealStation(v, order);
|
StationID next_station = GetNextRealStation(v, order);
|
||||||
if (Station::IsValidID(next_station)) {
|
if (Station::IsValidID(next_station)) {
|
||||||
if (GB(order->GetXData(), 16, 16) == 0) {
|
if (GB(order->GetXData(), 16, 16) == 0) {
|
||||||
skip_order = OrderConditionCompare(occ, Station::Get(next_station)->goods[value].cargo.AvailableCount(), GB(order->GetXData(), 0, 16));
|
skip_order = OrderConditionCompare(occ, Station::Get(next_station)->goods[value].CargoAvailableCount(), GB(order->GetXData(), 0, 16));
|
||||||
} else {
|
} else {
|
||||||
skip_order = OrderConditionCompare(occ, Station::Get(next_station)->goods[value].cargo.AvailableViaCount(GB(order->GetXData(), 16, 16) - 2), GB(order->GetXData(), 0, 16));
|
skip_order = OrderConditionCompare(occ, Station::Get(next_station)->goods[value].CargoAvailableViaCount(GB(order->GetXData(), 16, 16) - 2), GB(order->GetXData(), 0, 16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@@ -2051,7 +2051,7 @@ bool AfterLoadGame()
|
|||||||
for (Station *st : Station::Iterate()) {
|
for (Station *st : Station::Iterate()) {
|
||||||
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
||||||
st->goods[c].last_speed = 0;
|
st->goods[c].last_speed = 0;
|
||||||
if (st->goods[c].cargo.AvailableCount() != 0) SetBit(st->goods[c].status, GoodsEntry::GES_RATING);
|
if (st->goods[c].CargoAvailableCount() != 0) SetBit(st->goods[c].status, GoodsEntry::GES_RATING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -40,6 +40,7 @@ static Money _cargo_feeder_share;
|
|||||||
|
|
||||||
CargoPacketList _packets;
|
CargoPacketList _packets;
|
||||||
uint32 _old_num_dests;
|
uint32 _old_num_dests;
|
||||||
|
uint _cargo_reserved_count;
|
||||||
|
|
||||||
struct FlowSaveLoad {
|
struct FlowSaveLoad {
|
||||||
FlowSaveLoad() : source(0), via(0), share(0), restricted(false) {}
|
FlowSaveLoad() : source(0), via(0), share(0), restricted(false) {}
|
||||||
@@ -61,7 +62,7 @@ static byte _old_last_vehicle_type;
|
|||||||
*/
|
*/
|
||||||
static void SwapPackets(GoodsEntry *ge)
|
static void SwapPackets(GoodsEntry *ge)
|
||||||
{
|
{
|
||||||
StationCargoPacketMap &ge_packets = const_cast<StationCargoPacketMap &>(*ge->cargo.Packets());
|
StationCargoPacketMap &ge_packets = const_cast<StationCargoPacketMap &>(*ge->data->cargo.Packets());
|
||||||
|
|
||||||
if (_packets.empty()) {
|
if (_packets.empty()) {
|
||||||
std::map<StationID, CargoPacketList>::iterator it(ge_packets.find(INVALID_STATION));
|
std::map<StationID, CargoPacketList>::iterator it(ge_packets.find(INVALID_STATION));
|
||||||
@@ -153,14 +154,15 @@ public:
|
|||||||
StationCargoPair pair;
|
StationCargoPair pair;
|
||||||
for (uint j = 0; j < num_dests; ++j) {
|
for (uint j = 0; j < num_dests; ++j) {
|
||||||
SlObject(&pair, this->GetLoadDescription());
|
SlObject(&pair, this->GetLoadDescription());
|
||||||
const_cast<StationCargoPacketMap &>(*(ge->cargo.Packets()))[pair.first].swap(pair.second);
|
const_cast<StationCargoPacketMap &>(*(ge->data->cargo.Packets()))[pair.first].swap(pair.second);
|
||||||
assert(pair.second.empty());
|
assert(pair.second.empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FixPointers(GoodsEntry *ge) const override
|
void FixPointers(GoodsEntry *ge) const override
|
||||||
{
|
{
|
||||||
for (StationCargoPacketMap::ConstMapIterator it = ge->cargo.Packets()->begin(); it != ge->cargo.Packets()->end(); ++it) {
|
if (ge->data == nullptr) return;
|
||||||
|
for (StationCargoPacketMap::ConstMapIterator it = ge->data->cargo.Packets()->begin(); it != ge->data->cargo.Packets()->end(); ++it) {
|
||||||
SlObject(const_cast<StationCargoPair *>(&(*it)), this->GetDescription());
|
SlObject(const_cast<StationCargoPair *>(&(*it)), this->GetDescription());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,7 +194,7 @@ public:
|
|||||||
for (uint32 j = 0; j < num_flows; ++j) {
|
for (uint32 j = 0; j < num_flows; ++j) {
|
||||||
SlObject(&flow, this->GetLoadDescription());
|
SlObject(&flow, this->GetLoadDescription());
|
||||||
if (fs == nullptr || prev_source != flow.source) {
|
if (fs == nullptr || prev_source != flow.source) {
|
||||||
fs = &(*(ge->flows.insert(ge->flows.end(), FlowStat(flow.source, flow.via, flow.share, flow.restricted))));
|
fs = &(*(ge->data->flows.insert(ge->data->flows.end(), FlowStat(flow.source, flow.via, flow.share, flow.restricted))));
|
||||||
} else {
|
} else {
|
||||||
fs->AppendShare(flow.via, flow.share, flow.restricted);
|
fs->AppendShare(flow.via, flow.share, flow.restricted);
|
||||||
}
|
}
|
||||||
@@ -229,7 +231,7 @@ public:
|
|||||||
SLE_CONDVAR(GoodsEntry, amount_fract, SLE_UINT8, SLV_150, SL_MAX_VERSION),
|
SLE_CONDVAR(GoodsEntry, amount_fract, SLE_UINT8, SLV_150, SL_MAX_VERSION),
|
||||||
SLEG_CONDREFRING("packets", _packets, REF_CARGO_PACKET, SLV_68, SLV_183),
|
SLEG_CONDREFRING("packets", _packets, REF_CARGO_PACKET, SLV_68, SLV_183),
|
||||||
SLEG_CONDVAR("old_num_dests", _old_num_dests, SLE_UINT32, SLV_183, SLV_SAVELOAD_LIST_LENGTH),
|
SLEG_CONDVAR("old_num_dests", _old_num_dests, SLE_UINT32, SLV_183, SLV_SAVELOAD_LIST_LENGTH),
|
||||||
SLE_CONDVAR(GoodsEntry, cargo.reserved_count, SLE_UINT, SLV_181, SL_MAX_VERSION),
|
SLEG_CONDVAR("cargo.reserved_count", _cargo_reserved_count, SLE_UINT, SLV_181, SL_MAX_VERSION),
|
||||||
SLE_CONDVAR(GoodsEntry, link_graph, SLE_UINT16, SLV_183, SL_MAX_VERSION),
|
SLE_CONDVAR(GoodsEntry, link_graph, SLE_UINT16, SLV_183, SL_MAX_VERSION),
|
||||||
SLE_CONDVAR(GoodsEntry, node, SLE_UINT16, SLV_183, SL_MAX_VERSION),
|
SLE_CONDVAR(GoodsEntry, node, SLE_UINT16, SLV_183, SL_MAX_VERSION),
|
||||||
SLEG_CONDVAR("old_num_flows", _old_num_flows, SLE_UINT32, SLV_183, SLV_SAVELOAD_LIST_LENGTH),
|
SLEG_CONDVAR("old_num_flows", _old_num_flows, SLE_UINT32, SLV_183, SLV_SAVELOAD_LIST_LENGTH),
|
||||||
@@ -258,19 +260,15 @@ public:
|
|||||||
|
|
||||||
void Save(BaseStation *bst) const override
|
void Save(BaseStation *bst) const override
|
||||||
{
|
{
|
||||||
Station *st = Station::From(bst);
|
NOT_REACHED();
|
||||||
|
|
||||||
SlSetStructListLength(NUM_CARGO);
|
|
||||||
|
|
||||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
|
||||||
SlObject(&st->goods[i], this->GetDescription());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Load(BaseStation *bst) const override
|
void Load(BaseStation *bst) const override
|
||||||
{
|
{
|
||||||
Station *st = Station::From(bst);
|
Station *st = Station::From(bst);
|
||||||
|
|
||||||
|
std::unique_ptr<GoodsEntryData> spare_ged;
|
||||||
|
|
||||||
/* Before savegame version 161, persistent storages were not stored in a pool. */
|
/* Before savegame version 161, persistent storages were not stored in a pool. */
|
||||||
if (IsSavegameVersionBefore(SLV_161) && !IsSavegameVersionBefore(SLV_145) && st->facilities & FACIL_AIRPORT) {
|
if (IsSavegameVersionBefore(SLV_161) && !IsSavegameVersionBefore(SLV_145) && st->facilities & FACIL_AIRPORT) {
|
||||||
/* Store the old persistent storage. The GRFID will be added later. */
|
/* Store the old persistent storage. The GRFID will be added later. */
|
||||||
@@ -282,7 +280,15 @@ public:
|
|||||||
size_t num_cargo = this->GetNumCargo();
|
size_t num_cargo = this->GetNumCargo();
|
||||||
for (size_t i = 0; i < num_cargo; i++) {
|
for (size_t i = 0; i < num_cargo; i++) {
|
||||||
GoodsEntry *ge = &st->goods[i];
|
GoodsEntry *ge = &st->goods[i];
|
||||||
|
if (ge->data == nullptr) {
|
||||||
|
if (spare_ged != nullptr) {
|
||||||
|
ge->data = std::move(spare_ged);
|
||||||
|
} else {
|
||||||
|
ge->data.reset(new GoodsEntryData());
|
||||||
|
}
|
||||||
|
}
|
||||||
SlObject(ge, this->GetLoadDescription());
|
SlObject(ge, this->GetLoadDescription());
|
||||||
|
if (!IsSavegameVersionBefore(SLV_181)) ge->data->cargo.LoadSetReservedCount(_cargo_reserved_count);
|
||||||
if (IsSavegameVersionBefore(SLV_183)) {
|
if (IsSavegameVersionBefore(SLV_183)) {
|
||||||
SwapPackets(ge);
|
SwapPackets(ge);
|
||||||
}
|
}
|
||||||
@@ -300,10 +306,13 @@ public:
|
|||||||
|
|
||||||
/* Don't construct the packet with station here, because that'll fail with old savegames */
|
/* 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);
|
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);
|
ge->data->cargo.Append(cp, INVALID_STATION);
|
||||||
SB(ge->status, GoodsEntry::GES_RATING, 1, 1);
|
SB(ge->status, GoodsEntry::GES_RATING, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ge->data->MayBeRemoved()) {
|
||||||
|
spare_ged = std::move(ge->data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -58,7 +58,10 @@ template<bool Tfrom, bool Tvia>
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const StationCargoList &cargo_list = ::Station::Get(station_id)->goods[cargo_id].cargo;
|
const GoodsEntry &ge = ::Station::Get(station_id)->goods[cargo_id];
|
||||||
|
if (ge.data == nullptr) return 0;
|
||||||
|
|
||||||
|
const StationCargoList &cargo_list = ge.data->cargo;
|
||||||
if (!Tfrom && !Tvia) return cargo_list.TotalCount();
|
if (!Tfrom && !Tvia) return cargo_list.TotalCount();
|
||||||
|
|
||||||
uint16 cargo_count = 0;
|
uint16 cargo_count = 0;
|
||||||
@@ -106,7 +109,10 @@ template<bool Tfrom, bool Tvia>
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FlowStatMap &flows = ::Station::Get(station_id)->goods[cargo_id].flows;
|
const GoodsEntry &ge = ::Station::Get(station_id)->goods[cargo_id];
|
||||||
|
if (ge.data == nullptr) return 0;
|
||||||
|
|
||||||
|
const FlowStatMap &flows = ge.data->flows;
|
||||||
if (Tfrom) {
|
if (Tfrom) {
|
||||||
return Tvia ? flows.GetFlowFromVia(from_station_id, via_station_id) :
|
return Tvia ? flows.GetFlowFromVia(from_station_id, via_station_id) :
|
||||||
flows.GetFlowFrom(from_station_id);
|
flows.GetFlowFrom(from_station_id);
|
||||||
|
@@ -171,8 +171,11 @@ void ScriptStationList_CargoWaiting::Add(StationID station_id, CargoID cargo, St
|
|||||||
CargoCollector collector(this, station_id, cargo, other_station);
|
CargoCollector collector(this, station_id, cargo, other_station);
|
||||||
if (collector.GE() == nullptr) return;
|
if (collector.GE() == nullptr) return;
|
||||||
|
|
||||||
StationCargoList::ConstIterator iter = collector.GE()->cargo.Packets()->begin();
|
const GoodsEntry *ge = collector.GE();
|
||||||
StationCargoList::ConstIterator end = collector.GE()->cargo.Packets()->end();
|
if (ge->data == nullptr) return;
|
||||||
|
|
||||||
|
StationCargoList::ConstIterator iter = ge->data->cargo.Packets()->begin();
|
||||||
|
StationCargoList::ConstIterator end = ge->data->cargo.Packets()->end();
|
||||||
for (; iter != end; ++iter) {
|
for (; iter != end; ++iter) {
|
||||||
collector.Update<Tselector>((*iter)->SourceStation(), iter.GetKey(), (*iter)->Count());
|
collector.Update<Tselector>((*iter)->SourceStation(), iter.GetKey(), (*iter)->Count());
|
||||||
}
|
}
|
||||||
@@ -185,8 +188,11 @@ void ScriptStationList_CargoPlanned::Add(StationID station_id, CargoID cargo, St
|
|||||||
CargoCollector collector(this, station_id, cargo, other_station);
|
CargoCollector collector(this, station_id, cargo, other_station);
|
||||||
if (collector.GE() == nullptr) return;
|
if (collector.GE() == nullptr) return;
|
||||||
|
|
||||||
FlowStatMap::const_iterator iter = collector.GE()->flows.begin();
|
const GoodsEntry *ge = collector.GE();
|
||||||
FlowStatMap::const_iterator end = collector.GE()->flows.end();
|
if (ge->data == nullptr) return;
|
||||||
|
|
||||||
|
FlowStatMap::const_iterator iter = ge->data->flows.begin();
|
||||||
|
FlowStatMap::const_iterator end = ge->data->flows.end();
|
||||||
for (; iter != end; ++iter) {
|
for (; iter != end; ++iter) {
|
||||||
uint prev = 0;
|
uint prev = 0;
|
||||||
for (FlowStat::const_iterator flow_iter = iter->begin();
|
for (FlowStat::const_iterator flow_iter = iter->begin();
|
||||||
@@ -209,8 +215,11 @@ ScriptStationList_CargoWaitingViaByFrom::ScriptStationList_CargoWaitingViaByFrom
|
|||||||
CargoCollector collector(this, station_id, cargo, via);
|
CargoCollector collector(this, station_id, cargo, via);
|
||||||
if (collector.GE() == nullptr) return;
|
if (collector.GE() == nullptr) return;
|
||||||
|
|
||||||
|
const GoodsEntry *ge = collector.GE();
|
||||||
|
if (ge->data == nullptr) return;
|
||||||
|
|
||||||
std::pair<StationCargoList::ConstIterator, StationCargoList::ConstIterator> range =
|
std::pair<StationCargoList::ConstIterator, StationCargoList::ConstIterator> range =
|
||||||
collector.GE()->cargo.Packets()->equal_range(via);
|
ge->data->cargo.Packets()->equal_range(via);
|
||||||
for (StationCargoList::ConstIterator iter = range.first; iter != range.second; ++iter) {
|
for (StationCargoList::ConstIterator iter = range.first; iter != range.second; ++iter) {
|
||||||
collector.Update<CS_VIA_BY_FROM>((*iter)->SourceStation(), iter.GetKey(), (*iter)->Count());
|
collector.Update<CS_VIA_BY_FROM>((*iter)->SourceStation(), iter.GetKey(), (*iter)->Count());
|
||||||
}
|
}
|
||||||
@@ -255,8 +264,11 @@ ScriptStationList_CargoPlannedFromByVia::ScriptStationList_CargoPlannedFromByVia
|
|||||||
CargoCollector collector(this, station_id, cargo, from);
|
CargoCollector collector(this, station_id, cargo, from);
|
||||||
if (collector.GE() == nullptr) return;
|
if (collector.GE() == nullptr) return;
|
||||||
|
|
||||||
FlowStatMap::const_iterator iter = collector.GE()->flows.find(from);
|
const GoodsEntry *ge = collector.GE();
|
||||||
if (iter == collector.GE()->flows.end()) return;
|
if (ge->data == nullptr) return;
|
||||||
|
|
||||||
|
FlowStatMap::const_iterator iter = ge->data->flows.find(from);
|
||||||
|
if (iter == ge->data->flows.end()) return;
|
||||||
uint prev = 0;
|
uint prev = 0;
|
||||||
for (FlowStat::const_iterator flow_iter = iter->begin();
|
for (FlowStat::const_iterator flow_iter = iter->begin();
|
||||||
flow_iter != iter->end(); ++flow_iter) {
|
flow_iter != iter->end(); ++flow_iter) {
|
||||||
|
@@ -49,7 +49,8 @@ extern btree::btree_map<uint64, Money> _cargo_packet_deferred_payments;
|
|||||||
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
||||||
GoodsEntry *ge = &st->goods[c];
|
GoodsEntry *ge = &st->goods[c];
|
||||||
|
|
||||||
const StationCargoPacketMap *packets = ge->cargo.Packets();
|
if (ge->data == nullptr) continue;
|
||||||
|
const StationCargoPacketMap *packets = ge->data->cargo.Packets();
|
||||||
for (StationCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) {
|
for (StationCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) {
|
||||||
CargoPacket *cp = *it;
|
CargoPacket *cp = *it;
|
||||||
cp->source_xy = Station::IsValidID(cp->source) ? Station::Get(cp->source)->xy : st->xy;
|
cp->source_xy = Station::IsValidID(cp->source) ? Station::Get(cp->source)->xy : st->xy;
|
||||||
@@ -73,7 +74,9 @@ extern btree::btree_map<uint64, Money> _cargo_packet_deferred_payments;
|
|||||||
for (Vehicle *v : Vehicle::Iterate()) v->cargo.InvalidateCache();
|
for (Vehicle *v : Vehicle::Iterate()) v->cargo.InvalidateCache();
|
||||||
|
|
||||||
for (Station *st : Station::Iterate()) {
|
for (Station *st : Station::Iterate()) {
|
||||||
for (CargoID c = 0; c < NUM_CARGO; c++) st->goods[c].cargo.InvalidateCache();
|
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
||||||
|
if (st->goods[c].data != nullptr) st->goods[c].data->cargo.InvalidateCache();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +98,7 @@ extern btree::btree_map<uint64, Money> _cargo_packet_deferred_payments;
|
|||||||
Station *st = Station::Get(v->First()->last_station_visited);
|
Station *st = Station::Get(v->First()->last_station_visited);
|
||||||
assert_msg(st != nullptr, "%s", scope_dumper().VehicleInfo(v));
|
assert_msg(st != nullptr, "%s", scope_dumper().VehicleInfo(v));
|
||||||
for (CargoPacket *cp : iter.second) {
|
for (CargoPacket *cp : iter.second) {
|
||||||
st->goods[v->cargo_type].cargo.AfterLoadIncreaseReservationCount(cp->count);
|
st->goods[v->cargo_type].CreateData().cargo.AfterLoadIncreaseReservationCount(cp->count);
|
||||||
v->cargo.Append(cp, VehicleCargoList::MTA_LOAD);
|
v->cargo.Append(cp, VehicleCargoList::MTA_LOAD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -706,7 +706,7 @@ static bool LoadOldGood(LoadgameState *ls, int num)
|
|||||||
SB(ge->status, GoodsEntry::GES_ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
|
SB(ge->status, GoodsEntry::GES_ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
|
||||||
SB(ge->status, GoodsEntry::GES_RATING, 1, _cargo_source != 0xFF);
|
SB(ge->status, GoodsEntry::GES_RATING, 1, _cargo_source != 0xFF);
|
||||||
if (GB(_waiting_acceptance, 0, 12) != 0 && CargoPacket::CanAllocateItem()) {
|
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->CreateData().cargo.Append(new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_days, (_cargo_source == 0xFF) ? INVALID_STATION : _cargo_source, 0, 0),
|
||||||
INVALID_STATION);
|
INVALID_STATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -237,6 +237,7 @@ static uint16 _cargo_source;
|
|||||||
static uint32 _cargo_source_xy;
|
static uint32 _cargo_source_xy;
|
||||||
static uint8 _cargo_days;
|
static uint8 _cargo_days;
|
||||||
static Money _cargo_feeder_share;
|
static Money _cargo_feeder_share;
|
||||||
|
static uint _cargo_reserved_count;
|
||||||
|
|
||||||
static const SaveLoad _station_speclist_desc[] = {
|
static const SaveLoad _station_speclist_desc[] = {
|
||||||
SLE_CONDVAR(StationSpecList, grfid, SLE_UINT32, SLV_27, SL_MAX_VERSION),
|
SLE_CONDVAR(StationSpecList, grfid, SLE_UINT32, SLV_27, SL_MAX_VERSION),
|
||||||
@@ -295,7 +296,7 @@ SaveLoadTable GetGoodsDesc()
|
|||||||
SLE_CONDVAR(GoodsEntry, amount_fract, SLE_UINT8, SLV_150, SL_MAX_VERSION),
|
SLE_CONDVAR(GoodsEntry, amount_fract, SLE_UINT8, SLV_150, SL_MAX_VERSION),
|
||||||
SLEG_CONDPTRRING_X( _packets, REF_CARGO_PACKET, SLV_68, SLV_183, SlXvFeatureTest(XSLFTO_AND, XSLFI_CHILLPP, 0, 0)),
|
SLEG_CONDPTRRING_X( _packets, REF_CARGO_PACKET, SLV_68, SLV_183, SlXvFeatureTest(XSLFTO_AND, XSLFI_CHILLPP, 0, 0)),
|
||||||
SLEG_CONDVAR_X( _num_dests, SLE_UINT32, SLV_183, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_OR, XSLFI_CHILLPP)),
|
SLEG_CONDVAR_X( _num_dests, SLE_UINT32, SLV_183, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_OR, XSLFI_CHILLPP)),
|
||||||
SLE_CONDVAR(GoodsEntry, cargo.reserved_count, SLE_UINT, SLV_181, SL_MAX_VERSION),
|
SLEG_CONDVAR( _cargo_reserved_count,SLE_UINT, SLV_181, SL_MAX_VERSION),
|
||||||
SLE_CONDVAR(GoodsEntry, link_graph, SLE_UINT16, SLV_183, SL_MAX_VERSION),
|
SLE_CONDVAR(GoodsEntry, link_graph, SLE_UINT16, SLV_183, SL_MAX_VERSION),
|
||||||
SLE_CONDVAR(GoodsEntry, node, SLE_UINT16, SLV_183, SL_MAX_VERSION),
|
SLE_CONDVAR(GoodsEntry, node, SLE_UINT16, SLV_183, SL_MAX_VERSION),
|
||||||
SLEG_CONDVAR( _num_flows, SLE_UINT32, SLV_183, SL_MAX_VERSION),
|
SLEG_CONDVAR( _num_flows, SLE_UINT32, SLV_183, SL_MAX_VERSION),
|
||||||
@@ -321,7 +322,9 @@ static const SaveLoad _cargo_list_desc[] = {
|
|||||||
*/
|
*/
|
||||||
static void SwapPackets(GoodsEntry *ge)
|
static void SwapPackets(GoodsEntry *ge)
|
||||||
{
|
{
|
||||||
StationCargoPacketMap &ge_packets = const_cast<StationCargoPacketMap &>(*ge->cargo.Packets());
|
if (_packets.empty() && ge->data == nullptr) return;
|
||||||
|
|
||||||
|
StationCargoPacketMap &ge_packets = const_cast<StationCargoPacketMap &>(*ge->CreateData().cargo.Packets());
|
||||||
|
|
||||||
if (_packets.empty()) {
|
if (_packets.empty()) {
|
||||||
std::map<StationID, CargoPacketList>::iterator it(ge_packets.find(INVALID_STATION));
|
std::map<StationID, CargoPacketList>::iterator it(ge_packets.find(INVALID_STATION));
|
||||||
@@ -342,6 +345,7 @@ static void Load_STNS()
|
|||||||
_cargo_days = 0;
|
_cargo_days = 0;
|
||||||
_cargo_feeder_share = 0;
|
_cargo_feeder_share = 0;
|
||||||
_num_specs = 0;
|
_num_specs = 0;
|
||||||
|
_cargo_reserved_count = 0;
|
||||||
|
|
||||||
uint num_cargo = IsSavegameVersionBefore(SLV_55) ? 12 : IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES) ? 32 : NUM_CARGO;
|
uint num_cargo = IsSavegameVersionBefore(SLV_55) ? 12 : IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES) ? 32 : NUM_CARGO;
|
||||||
int index;
|
int index;
|
||||||
@@ -355,6 +359,7 @@ static void Load_STNS()
|
|||||||
for (CargoID i = 0; i < num_cargo; i++) {
|
for (CargoID i = 0; i < num_cargo; i++) {
|
||||||
GoodsEntry *ge = &st->goods[i];
|
GoodsEntry *ge = &st->goods[i];
|
||||||
SlObject(ge, GetGoodsDesc());
|
SlObject(ge, GetGoodsDesc());
|
||||||
|
if (_cargo_reserved_count) ge->CreateData().cargo.LoadSetReservedCount(_cargo_reserved_count);
|
||||||
SwapPackets(ge);
|
SwapPackets(ge);
|
||||||
if (IsSavegameVersionBefore(SLV_68)) {
|
if (IsSavegameVersionBefore(SLV_68)) {
|
||||||
SB(ge->status, GoodsEntry::GES_ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
|
SB(ge->status, GoodsEntry::GES_ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
|
||||||
@@ -370,7 +375,7 @@ static void Load_STNS()
|
|||||||
|
|
||||||
/* Don't construct the packet with station here, because that'll fail with old savegames */
|
/* 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);
|
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);
|
ge->CreateData().cargo.Append(cp, INVALID_STATION);
|
||||||
SB(ge->status, GoodsEntry::GES_RATING, 1, 1);
|
SB(ge->status, GoodsEntry::GES_RATING, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -544,10 +549,19 @@ static void RealSave_STNN(BaseStation *bst)
|
|||||||
if (!waypoint) {
|
if (!waypoint) {
|
||||||
Station *st = Station::From(bst);
|
Station *st = Station::From(bst);
|
||||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
||||||
_num_dests = (uint32)st->goods[i].cargo.Packets()->MapSize();
|
const GoodsEntryData *ged = st->goods[i].data.get();
|
||||||
_num_flows = (uint32)st->goods[i].flows.size();
|
if (ged != nullptr) {
|
||||||
|
_cargo_reserved_count = ged->cargo.ReservedCount();
|
||||||
|
_num_dests = (uint32)ged->cargo.Packets()->MapSize();
|
||||||
|
_num_flows = (uint32)ged->flows.size();
|
||||||
|
} else {
|
||||||
|
_cargo_reserved_count = 0;
|
||||||
|
_num_dests = 0;
|
||||||
|
_num_flows = 0;
|
||||||
|
}
|
||||||
SlObjectSaveFiltered(&st->goods[i], _filtered_goods_desc);
|
SlObjectSaveFiltered(&st->goods[i], _filtered_goods_desc);
|
||||||
for (FlowStatMap::const_iterator outer_it(st->goods[i].flows.begin()); outer_it != st->goods[i].flows.end(); ++outer_it) {
|
if (ged == nullptr) continue;
|
||||||
|
for (FlowStatMap::const_iterator outer_it(ged->flows.begin()); outer_it != ged->flows.end(); ++outer_it) {
|
||||||
uint32 sum_shares = 0;
|
uint32 sum_shares = 0;
|
||||||
FlowSaveLoad flow;
|
FlowSaveLoad flow;
|
||||||
flow.source = outer_it->GetOrigin();
|
flow.source = outer_it->GetOrigin();
|
||||||
@@ -571,7 +585,7 @@ static void RealSave_STNN(BaseStation *bst)
|
|||||||
}
|
}
|
||||||
SlWriteUint16(outer_it->GetRawFlags());
|
SlWriteUint16(outer_it->GetRawFlags());
|
||||||
}
|
}
|
||||||
for (StationCargoPacketMap::ConstMapIterator it(st->goods[i].cargo.Packets()->begin()); it != st->goods[i].cargo.Packets()->end(); ++it) {
|
for (StationCargoPacketMap::ConstMapIterator it(ged->cargo.Packets()->begin()); it != ged->cargo.Packets()->end(); ++it) {
|
||||||
SlObjectSaveFiltered(const_cast<StationCargoPacketMap::value_type *>(&(*it)), _cargo_list_desc); // _cargo_list_desc has no conditionals
|
SlObjectSaveFiltered(const_cast<StationCargoPacketMap::value_type *>(&(*it)), _cargo_list_desc); // _cargo_list_desc has no conditionals
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -620,6 +634,9 @@ static void Load_STNN()
|
|||||||
_num_specs = 0;
|
_num_specs = 0;
|
||||||
_num_roadstop_specs = 0;
|
_num_roadstop_specs = 0;
|
||||||
_num_roadstop_custom_tiles = 0;
|
_num_roadstop_custom_tiles = 0;
|
||||||
|
_cargo_reserved_count = 0;
|
||||||
|
|
||||||
|
std::unique_ptr<GoodsEntryData> spare_ged;
|
||||||
|
|
||||||
const uint num_cargo = IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES) ? 32 : NUM_CARGO;
|
const uint num_cargo = IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES) ? 32 : NUM_CARGO;
|
||||||
ReadBuffer *buffer = ReadBuffer::GetCurrent();
|
ReadBuffer *buffer = ReadBuffer::GetCurrent();
|
||||||
@@ -643,10 +660,19 @@ static void Load_STNN()
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (CargoID i = 0; i < num_cargo; i++) {
|
for (CargoID i = 0; i < num_cargo; i++) {
|
||||||
SlObjectLoadFiltered(&st->goods[i], _filtered_goods_desc);
|
GoodsEntry &ge = st->goods[i];
|
||||||
|
if (ge.data == nullptr) {
|
||||||
|
if (spare_ged != nullptr) {
|
||||||
|
ge.data = std::move(spare_ged);
|
||||||
|
} else {
|
||||||
|
ge.data.reset(new GoodsEntryData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SlObjectLoadFiltered(&ge, _filtered_goods_desc);
|
||||||
|
ge.data->cargo.LoadSetReservedCount(_cargo_reserved_count);
|
||||||
StationID prev_source = INVALID_STATION;
|
StationID prev_source = INVALID_STATION;
|
||||||
if (SlXvIsFeaturePresent(XSLFI_FLOW_STAT_FLAGS)) {
|
if (SlXvIsFeaturePresent(XSLFI_FLOW_STAT_FLAGS)) {
|
||||||
st->goods[i].flows.reserve(_num_flows);
|
ge.data->flows.reserve(_num_flows);
|
||||||
for (uint32 j = 0; j < _num_flows; ++j) {
|
for (uint32 j = 0; j < _num_flows; ++j) {
|
||||||
FlowSaveLoad flow;
|
FlowSaveLoad flow;
|
||||||
buffer->CheckBytes(2 + 4);
|
buffer->CheckBytes(2 + 4);
|
||||||
@@ -657,7 +683,7 @@ static void Load_STNN()
|
|||||||
flow.via = buffer->RawReadUint16();
|
flow.via = buffer->RawReadUint16();
|
||||||
flow.share = buffer->RawReadUint32();
|
flow.share = buffer->RawReadUint32();
|
||||||
flow.restricted = (buffer->RawReadByte() != 0);
|
flow.restricted = (buffer->RawReadByte() != 0);
|
||||||
FlowStat *fs = &(*(st->goods[i].flows.insert(st->goods[i].flows.end(), FlowStat(flow.source, flow.via, flow.share, flow.restricted))));
|
FlowStat *fs = &(*(ge.data->flows.insert(ge.data->flows.end(), FlowStat(flow.source, flow.via, flow.share, flow.restricted))));
|
||||||
for (uint32 k = 1; k < flow_count; ++k) {
|
for (uint32 k = 1; k < flow_count; ++k) {
|
||||||
buffer->CheckBytes(2 + 4 + 1);
|
buffer->CheckBytes(2 + 4 + 1);
|
||||||
flow.via = buffer->RawReadUint16();
|
flow.via = buffer->RawReadUint16();
|
||||||
@@ -679,7 +705,7 @@ static void Load_STNN()
|
|||||||
if (!IsSavegameVersionBefore(SLV_187)) flow.restricted = (buffer->ReadByte() != 0);
|
if (!IsSavegameVersionBefore(SLV_187)) flow.restricted = (buffer->ReadByte() != 0);
|
||||||
|
|
||||||
if (fs == nullptr || prev_source != flow.source) {
|
if (fs == nullptr || prev_source != flow.source) {
|
||||||
fs = &(*(st->goods[i].flows.insert(st->goods[i].flows.end(), FlowStat(flow.source, flow.via, flow.share, flow.restricted))));
|
fs = &(*(ge.data->flows.insert(ge.data->flows.end(), FlowStat(flow.source, flow.via, flow.share, flow.restricted))));
|
||||||
} else {
|
} else {
|
||||||
fs->AppendShare(flow.via, flow.share, flow.restricted);
|
fs->AppendShare(flow.via, flow.share, flow.restricted);
|
||||||
}
|
}
|
||||||
@@ -687,7 +713,7 @@ static void Load_STNN()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IsSavegameVersionBefore(SLV_183) && SlXvIsFeatureMissing(XSLFI_CHILLPP)) {
|
if (IsSavegameVersionBefore(SLV_183) && SlXvIsFeatureMissing(XSLFI_CHILLPP)) {
|
||||||
SwapPackets(&st->goods[i]);
|
SwapPackets(&ge);
|
||||||
} else {
|
} else {
|
||||||
if (SlXvIsFeaturePresent(XSLFI_CHILLPP)) {
|
if (SlXvIsFeaturePresent(XSLFI_CHILLPP)) {
|
||||||
SlSkipBytes(8);
|
SlSkipBytes(8);
|
||||||
@@ -701,11 +727,14 @@ static void Load_STNN()
|
|||||||
StationCargoPair pair;
|
StationCargoPair pair;
|
||||||
for (uint j = 0; j < _num_dests; ++j) {
|
for (uint j = 0; j < _num_dests; ++j) {
|
||||||
SlObjectLoadFiltered(&pair, _cargo_list_desc); // _cargo_list_desc has no conditionals
|
SlObjectLoadFiltered(&pair, _cargo_list_desc); // _cargo_list_desc has no conditionals
|
||||||
const_cast<StationCargoPacketMap &>(*(st->goods[i].cargo.Packets()))[pair.first].swap(pair.second);
|
const_cast<StationCargoPacketMap &>(*(ge.data->cargo.Packets()))[pair.first].swap(pair.second);
|
||||||
assert(pair.second.empty());
|
assert(pair.second.empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (SlXvIsFeatureMissing(XSLFI_ST_LAST_VEH_TYPE)) st->goods[i].last_vehicle_type = _old_last_vehicle_type;
|
if (SlXvIsFeatureMissing(XSLFI_ST_LAST_VEH_TYPE)) ge.last_vehicle_type = _old_last_vehicle_type;
|
||||||
|
if (ge.data->MayBeRemoved()) {
|
||||||
|
spare_ged = std::move(ge.data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
st->station_cargo_history.resize(CountBits(st->station_cargo_history_cargoes));
|
st->station_cargo_history.resize(CountBits(st->station_cargo_history_cargoes));
|
||||||
@@ -780,8 +809,10 @@ static void Ptrs_STNN()
|
|||||||
SwapPackets(ge);
|
SwapPackets(ge);
|
||||||
} else {
|
} else {
|
||||||
//SlObject(ge, GetGoodsDesc());
|
//SlObject(ge, GetGoodsDesc());
|
||||||
for (StationCargoPacketMap::ConstMapIterator it = ge->cargo.Packets()->begin(); it != ge->cargo.Packets()->end(); ++it) {
|
if (ge->data != nullptr) {
|
||||||
SlObjectPtrOrNullFiltered(const_cast<StationCargoPair *>(&(*it)), _cargo_list_desc); // _cargo_list_desc has no conditionals
|
for (StationCargoPacketMap::ConstMapIterator it = ge->data->cargo.Packets()->begin(); it != ge->data->cargo.Packets()->end(); ++it) {
|
||||||
|
SlObjectPtrOrNullFiltered(const_cast<StationCargoPair *>(&(*it)), _cargo_list_desc); // _cargo_list_desc has no conditionals
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -42,6 +42,8 @@ std::array<ExtraStationNameInfo, MAX_EXTRA_STATION_NAMES> _extra_station_names;
|
|||||||
uint _extra_station_names_used;
|
uint _extra_station_names_used;
|
||||||
uint8 _extra_station_names_probability;
|
uint8 _extra_station_names_probability;
|
||||||
|
|
||||||
|
const StationCargoList _empty_cargo_list{};
|
||||||
|
const FlowStatMap _empty_flows{};
|
||||||
|
|
||||||
StationKdtree _station_kdtree(Kdtree_StationXYFunc);
|
StationKdtree _station_kdtree(Kdtree_StationXYFunc);
|
||||||
|
|
||||||
@@ -93,7 +95,7 @@ Station::~Station()
|
|||||||
{
|
{
|
||||||
if (CleaningPool()) {
|
if (CleaningPool()) {
|
||||||
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
||||||
this->goods[c].cargo.OnCleanPool();
|
if (this->goods[c].data != nullptr) this->goods[c].data->cargo.OnCleanPool();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -113,9 +115,10 @@ Station::~Station()
|
|||||||
|
|
||||||
for (NodeID node = 0; node < lg->Size(); ++node) {
|
for (NodeID node = 0; node < lg->Size(); ++node) {
|
||||||
Station *st = Station::Get((*lg)[node].Station());
|
Station *st = Station::Get((*lg)[node].Station());
|
||||||
st->goods[c].flows.erase(this->index);
|
GoodsEntryData *ged = st->goods[c].data.get();
|
||||||
|
if (ged != nullptr) ged->flows.erase(this->index);
|
||||||
if (lg->GetConstEdge(node, this->goods[c].node).LastUpdate() != INVALID_DATE) {
|
if (lg->GetConstEdge(node, this->goods[c].node).LastUpdate() != INVALID_DATE) {
|
||||||
st->goods[c].flows.DeleteFlows(this->index);
|
if (ged != nullptr) ged->flows.DeleteFlows(this->index);
|
||||||
RerouteCargo(st, c, this->index, st->index);
|
RerouteCargo(st, c, this->index, st->index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -161,7 +164,7 @@ Station::~Station()
|
|||||||
DeleteStationNews(this->index);
|
DeleteStationNews(this->index);
|
||||||
|
|
||||||
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
for (CargoID c = 0; c < NUM_CARGO; c++) {
|
||||||
this->goods[c].cargo.Truncate();
|
if (this->goods[c].data != nullptr) this->goods[c].data->cargo.Truncate();
|
||||||
}
|
}
|
||||||
|
|
||||||
CargoPacket::InvalidateAllFrom(this->index);
|
CargoPacket::InvalidateAllFrom(this->index);
|
||||||
|
@@ -501,6 +501,16 @@ public:
|
|||||||
void SortStorage();
|
void SortStorage();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GoodsEntryData {
|
||||||
|
StationCargoList cargo; ///< The cargo packets of cargo waiting in this station
|
||||||
|
FlowStatMap flows; ///< Planned flows through this station.
|
||||||
|
|
||||||
|
bool MayBeRemoved() const
|
||||||
|
{
|
||||||
|
return this->cargo.Packets()->MapSize() == 0 && this->cargo.ReservedCount() == 0 && this->flows.empty();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores station stats for a single cargo.
|
* Stores station stats for a single cargo.
|
||||||
*/
|
*/
|
||||||
@@ -597,11 +607,12 @@ struct GoodsEntry {
|
|||||||
byte last_age;
|
byte last_age;
|
||||||
|
|
||||||
byte amount_fract; ///< Fractional part of the amount in the cargo list
|
byte amount_fract; ///< Fractional part of the amount in the cargo list
|
||||||
StationCargoList cargo; ///< The cargo packets of cargo waiting in this station
|
|
||||||
|
std::unique_ptr<GoodsEntryData> data;
|
||||||
|
|
||||||
LinkGraphID link_graph; ///< Link graph this station belongs to.
|
LinkGraphID link_graph; ///< Link graph this station belongs to.
|
||||||
NodeID node; ///< ID of node in link graph referring to this goods entry.
|
NodeID node; ///< ID of node in link graph referring to this goods entry.
|
||||||
FlowStatMap flows; ///< Planned flows through this station.
|
|
||||||
uint max_waiting_cargo; ///< Max cargo from this station waiting at any station.
|
uint max_waiting_cargo; ///< Max cargo from this station waiting at any station.
|
||||||
|
|
||||||
bool IsSupplyAllowed() const
|
bool IsSupplyAllowed() const
|
||||||
@@ -632,8 +643,10 @@ struct GoodsEntry {
|
|||||||
*/
|
*/
|
||||||
inline StationID GetVia(StationID source) const
|
inline StationID GetVia(StationID source) const
|
||||||
{
|
{
|
||||||
FlowStatMap::const_iterator flow_it(this->flows.find(source));
|
if (this->data == nullptr) return INVALID_STATION;
|
||||||
return flow_it != this->flows.end() ? flow_it->GetVia() : INVALID_STATION;
|
|
||||||
|
FlowStatMap::const_iterator flow_it(this->data->flows.find(source));
|
||||||
|
return flow_it != this->data->flows.end() ? flow_it->GetVia() : INVALID_STATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -646,8 +659,54 @@ struct GoodsEntry {
|
|||||||
*/
|
*/
|
||||||
inline StationID GetVia(StationID source, StationID excluded, StationID excluded2 = INVALID_STATION) const
|
inline StationID GetVia(StationID source, StationID excluded, StationID excluded2 = INVALID_STATION) const
|
||||||
{
|
{
|
||||||
FlowStatMap::const_iterator flow_it(this->flows.find(source));
|
if (this->data == nullptr) return INVALID_STATION;
|
||||||
return flow_it != this->flows.end() ? flow_it->GetVia(excluded, excluded2) : INVALID_STATION;
|
|
||||||
|
FlowStatMap::const_iterator flow_it(this->data->flows.find(source));
|
||||||
|
return flow_it != this->data->flows.end() ? flow_it->GetVia(excluded, excluded2) : INVALID_STATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
GoodsEntryData &CreateData()
|
||||||
|
{
|
||||||
|
if (this->data == nullptr) this->data.reset(new GoodsEntryData());
|
||||||
|
return *this->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
const GoodsEntryData &CreateData() const
|
||||||
|
{
|
||||||
|
if (this->data == nullptr) const_cast<GoodsEntry *>(this)->data.reset(new GoodsEntryData());
|
||||||
|
return *this->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint CargoAvailableCount() const
|
||||||
|
{
|
||||||
|
return this->data != nullptr ? this->data->cargo.AvailableCount() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint CargoReservedCount() const
|
||||||
|
{
|
||||||
|
return this->data != nullptr ? this->data->cargo.ReservedCount() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint CargoTotalCount() const
|
||||||
|
{
|
||||||
|
return this->data != nullptr ? this->data->cargo.TotalCount() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline uint CargoAvailableViaCount(StationID next) const
|
||||||
|
{
|
||||||
|
return this->data != nullptr ? this->data->cargo.AvailableViaCount(next) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const StationCargoList &ConstCargoList() const
|
||||||
|
{
|
||||||
|
extern const StationCargoList _empty_cargo_list;
|
||||||
|
return this->data != nullptr ? this->data->cargo : _empty_cargo_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FlowStatMap &ConstFlows() const
|
||||||
|
{
|
||||||
|
extern const FlowStatMap _empty_flows;
|
||||||
|
return this->data != nullptr ? this->data->flows : _empty_flows;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -469,7 +469,7 @@ void Station::UpdateCargoHistory()
|
|||||||
uint storage_offset = 0;
|
uint storage_offset = 0;
|
||||||
bool update_window = false;
|
bool update_window = false;
|
||||||
for (const CargoSpec *cs : CargoSpec::Iterate()) {
|
for (const CargoSpec *cs : CargoSpec::Iterate()) {
|
||||||
uint amount = this->goods[cs->Index()].cargo.TotalCount();
|
uint amount = this->goods[cs->Index()].CargoTotalCount();
|
||||||
if (!HasBit(this->station_cargo_history_cargoes, cs->Index())) {
|
if (!HasBit(this->station_cargo_history_cargoes, cs->Index())) {
|
||||||
if (amount == 0) {
|
if (amount == 0) {
|
||||||
/* No cargo present, and no history stored for this cargo, no work to do */
|
/* No cargo present, and no history stored for this cargo, no work to do */
|
||||||
@@ -4115,8 +4115,10 @@ static void TruncateCargo(const CargoSpec *cs, GoodsEntry *ge, uint amount = UIN
|
|||||||
/* If truncating also punish the source stations' ratings to
|
/* If truncating also punish the source stations' ratings to
|
||||||
* decrease the flow of incoming cargo. */
|
* decrease the flow of incoming cargo. */
|
||||||
|
|
||||||
|
if (ge->data == nullptr) return;
|
||||||
|
|
||||||
StationCargoAmountMap waiting_per_source;
|
StationCargoAmountMap waiting_per_source;
|
||||||
ge->cargo.Truncate(amount, &waiting_per_source);
|
ge->data->cargo.Truncate(amount, &waiting_per_source);
|
||||||
for (StationCargoAmountMap::iterator i(waiting_per_source.begin()); i != waiting_per_source.end(); ++i) {
|
for (StationCargoAmountMap::iterator i(waiting_per_source.begin()); i != waiting_per_source.end(); ++i) {
|
||||||
Station *source_station = Station::GetIfValid(i->first);
|
Station *source_station = Station::GetIfValid(i->first);
|
||||||
if (source_station == nullptr) continue;
|
if (source_station == nullptr) continue;
|
||||||
@@ -4290,12 +4292,12 @@ static void UpdateStationRating(Station *st)
|
|||||||
{
|
{
|
||||||
int rating = GetTargetRating(st, cs, ge);
|
int rating = GetTargetRating(st, cs, ge);
|
||||||
|
|
||||||
uint waiting = ge->cargo.AvailableCount();
|
uint waiting = ge->CargoAvailableCount();
|
||||||
|
|
||||||
/* num_dests is at least 1 if there is any cargo as
|
/* num_dests is at least 1 if there is any cargo as
|
||||||
* INVALID_STATION is also a destination.
|
* INVALID_STATION is also a destination.
|
||||||
*/
|
*/
|
||||||
const uint num_dests = (uint)ge->cargo.Packets()->MapSize();
|
const uint num_dests = ge->data != nullptr ? (uint)ge->data->cargo.Packets()->MapSize() : 0;
|
||||||
|
|
||||||
/* Average amount of cargo per next hop, but prefer solitary stations
|
/* Average amount of cargo per next hop, but prefer solitary stations
|
||||||
* with only one or two next hops. They are allowed to have more
|
* with only one or two next hops. They are allowed to have more
|
||||||
@@ -4352,12 +4354,12 @@ static void UpdateStationRating(Station *st)
|
|||||||
|
|
||||||
/* We can't truncate cargo that's already reserved for loading.
|
/* We can't truncate cargo that's already reserved for loading.
|
||||||
* Thus StoredCount() here. */
|
* Thus StoredCount() here. */
|
||||||
if (waiting_changed && waiting < ge->cargo.AvailableCount()) {
|
if (waiting_changed && waiting < ge->CargoAvailableCount()) {
|
||||||
/* Feed back the exact own waiting cargo at this station for the
|
/* Feed back the exact own waiting cargo at this station for the
|
||||||
* next rating calculation. */
|
* next rating calculation. */
|
||||||
ge->max_waiting_cargo = 0;
|
ge->max_waiting_cargo = 0;
|
||||||
|
|
||||||
TruncateCargo(cs, ge, ge->cargo.AvailableCount() - waiting);
|
TruncateCargo(cs, ge, ge->CargoAvailableCount() - waiting);
|
||||||
} else {
|
} else {
|
||||||
/* If the average number per next hop is low, be more forgiving. */
|
/* If the average number per next hop is low, be more forgiving. */
|
||||||
ge->max_waiting_cargo = waiting_avg;
|
ge->max_waiting_cargo = waiting_avg;
|
||||||
@@ -4388,7 +4390,7 @@ void RerouteCargo(Station *st, CargoID c, StationID avoid, StationID avoid2)
|
|||||||
GoodsEntry &ge = st->goods[c];
|
GoodsEntry &ge = st->goods[c];
|
||||||
|
|
||||||
/* Reroute cargo in station. */
|
/* Reroute cargo in station. */
|
||||||
ge.cargo.Reroute(UINT_MAX, &ge.cargo, avoid, avoid2, &ge);
|
if (ge.data != nullptr) ge.data->cargo.Reroute(UINT_MAX, &ge.data->cargo, avoid, avoid2, &ge);
|
||||||
|
|
||||||
/* Reroute cargo staged to be transferred. */
|
/* Reroute cargo staged to be transferred. */
|
||||||
for (Vehicle *v : st->loading_vehicles) {
|
for (Vehicle *v : st->loading_vehicles) {
|
||||||
@@ -4413,7 +4415,7 @@ void RerouteCargoFromSource(Station *st, CargoID c, StationID source, StationID
|
|||||||
GoodsEntry &ge = st->goods[c];
|
GoodsEntry &ge = st->goods[c];
|
||||||
|
|
||||||
/* Reroute cargo in station. */
|
/* Reroute cargo in station. */
|
||||||
ge.cargo.RerouteFromSource(UINT_MAX, &ge.cargo, source, avoid, avoid2, &ge);
|
if (ge.data != nullptr) ge.data->cargo.RerouteFromSource(UINT_MAX, &ge.data->cargo, source, avoid, avoid2, &ge);
|
||||||
|
|
||||||
/* Reroute cargo staged to be transferred. */
|
/* Reroute cargo staged to be transferred. */
|
||||||
for (Vehicle *v : st->loading_vehicles) {
|
for (Vehicle *v : st->loading_vehicles) {
|
||||||
@@ -4520,12 +4522,12 @@ void DeleteStaleLinks(Station *from)
|
|||||||
if (!updated) {
|
if (!updated) {
|
||||||
/* If it's still considered dead remove it. */
|
/* If it's still considered dead remove it. */
|
||||||
result = LinkGraph::EdgeIterationResult::EraseEdge;
|
result = LinkGraph::EdgeIterationResult::EraseEdge;
|
||||||
ge.flows.DeleteFlows(to->index);
|
if (ge.data != nullptr) ge.data->flows.DeleteFlows(to->index);
|
||||||
RerouteCargo(from, c, to->index, from->index);
|
RerouteCargo(from, c, to->index, from->index);
|
||||||
}
|
}
|
||||||
} else if (edge.LastUnrestrictedUpdate() != INVALID_DATE && (uint)(_date - edge.LastUnrestrictedUpdate()) > timeout) {
|
} else if (edge.LastUnrestrictedUpdate() != INVALID_DATE && (uint)(_date - edge.LastUnrestrictedUpdate()) > timeout) {
|
||||||
edge.Restrict();
|
edge.Restrict();
|
||||||
ge.flows.RestrictFlows(to->index);
|
if (ge.data != nullptr) ge.data->flows.RestrictFlows(to->index);
|
||||||
RerouteCargo(from, c, to->index, from->index);
|
RerouteCargo(from, c, to->index, from->index);
|
||||||
} else if (edge.LastRestrictedUpdate() != INVALID_DATE && (uint)(_date - edge.LastRestrictedUpdate()) > timeout) {
|
} else if (edge.LastRestrictedUpdate() != INVALID_DATE && (uint)(_date - edge.LastRestrictedUpdate()) > timeout) {
|
||||||
edge.Release();
|
edge.Release();
|
||||||
@@ -4697,7 +4699,7 @@ static uint UpdateStationWaiting(Station *st, CargoID type, uint amount, SourceT
|
|||||||
if (amount == 0) return 0;
|
if (amount == 0) return 0;
|
||||||
|
|
||||||
StationID next = ge.GetVia(st->index);
|
StationID next = ge.GetVia(st->index);
|
||||||
ge.cargo.Append(new CargoPacket(st->index, st->xy, amount, source_type, source_id), next);
|
ge.CreateData().cargo.Append(new CargoPacket(st->index, st->xy, amount, source_type, source_id), next);
|
||||||
LinkGraph *lg = nullptr;
|
LinkGraph *lg = nullptr;
|
||||||
if (ge.link_graph == INVALID_LINK_GRAPH) {
|
if (ge.link_graph == INVALID_LINK_GRAPH) {
|
||||||
if (LinkGraph::CanAllocateItem()) {
|
if (LinkGraph::CanAllocateItem()) {
|
||||||
@@ -5686,7 +5688,8 @@ void DumpStationFlowStats(char *b, const char *last)
|
|||||||
for (const Station *st : Station::Iterate()) {
|
for (const Station *st : Station::Iterate()) {
|
||||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
||||||
const GoodsEntry &ge = st->goods[i];
|
const GoodsEntry &ge = st->goods[i];
|
||||||
for (FlowStatMap::const_iterator it(ge.flows.begin()); it != ge.flows.end(); ++it) {
|
if (ge.data == nullptr) continue;
|
||||||
|
for (FlowStatMap::const_iterator it(ge.data->flows.begin()); it != ge.data->flows.end(); ++it) {
|
||||||
count_map[(uint32)it->size()]++;
|
count_map[(uint32)it->size()]++;
|
||||||
invalid_map[it->GetRawFlags() & 0x1F]++;
|
invalid_map[it->GetRawFlags() & 0x1F]++;
|
||||||
}
|
}
|
||||||
|
@@ -334,7 +334,7 @@ protected:
|
|||||||
int diff = 0;
|
int diff = 0;
|
||||||
|
|
||||||
for (CargoID j : SetCargoBitIterator(cargo_filter)) {
|
for (CargoID j : SetCargoBitIterator(cargo_filter)) {
|
||||||
diff += a->goods[j].cargo.TotalCount() - b->goods[j].cargo.TotalCount();
|
diff += a->goods[j].CargoTotalCount() - b->goods[j].CargoTotalCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
return diff < 0;
|
return diff < 0;
|
||||||
@@ -346,7 +346,7 @@ protected:
|
|||||||
int diff = 0;
|
int diff = 0;
|
||||||
|
|
||||||
for (CargoID j : SetCargoBitIterator(cargo_filter)) {
|
for (CargoID j : SetCargoBitIterator(cargo_filter)) {
|
||||||
diff += a->goods[j].cargo.AvailableCount() - b->goods[j].cargo.AvailableCount();
|
diff += a->goods[j].CargoAvailableCount() - b->goods[j].CargoAvailableCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
return diff < 0;
|
return diff < 0;
|
||||||
@@ -573,7 +573,7 @@ public:
|
|||||||
/* show cargo waiting and station ratings */
|
/* show cargo waiting and station ratings */
|
||||||
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
|
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
|
||||||
CargoID cid = cs->Index();
|
CargoID cid = cs->Index();
|
||||||
if (st->goods[cid].cargo.TotalCount() > 0) {
|
if (st->goods[cid].CargoTotalCount() > 0) {
|
||||||
/* For RTL we work in exactly the opposite direction. So
|
/* For RTL we work in exactly the opposite direction. So
|
||||||
* decrement the space needed first, then draw to the left
|
* decrement the space needed first, then draw to the left
|
||||||
* instead of drawing to the left and then incrementing
|
* instead of drawing to the left and then incrementing
|
||||||
@@ -582,7 +582,7 @@ public:
|
|||||||
x -= rating_width + rating_spacing;
|
x -= rating_width + rating_spacing;
|
||||||
if (x < tr.left) break;
|
if (x < tr.left) break;
|
||||||
}
|
}
|
||||||
StationsWndShowStationRating(x, x + rating_width, tr.top, cid, st->goods[cid].cargo.TotalCount(), st->goods[cid].rating);
|
StationsWndShowStationRating(x, x + rating_width, tr.top, cid, st->goods[cid].CargoTotalCount(), st->goods[cid].rating);
|
||||||
if (!rtl) {
|
if (!rtl) {
|
||||||
x += rating_width + rating_spacing;
|
x += rating_width + rating_spacing;
|
||||||
if (x > tr.right) break;
|
if (x > tr.right) break;
|
||||||
@@ -1649,7 +1649,9 @@ struct StationViewWindow : public Window {
|
|||||||
CargoDataEntry *cargo_entry = cached_destinations.InsertOrRetrieve(i);
|
CargoDataEntry *cargo_entry = cached_destinations.InsertOrRetrieve(i);
|
||||||
cargo_entry->Clear();
|
cargo_entry->Clear();
|
||||||
|
|
||||||
const FlowStatMap &flows = st->goods[i].flows;
|
if (st->goods[i].data == nullptr) return;
|
||||||
|
|
||||||
|
const FlowStatMap &flows = st->goods[i].data->flows;
|
||||||
for (const auto &it : flows) {
|
for (const auto &it : flows) {
|
||||||
StationID from = it.GetOrigin();
|
StationID from = it.GetOrigin();
|
||||||
CargoDataEntry *source_entry = cargo_entry->InsertOrRetrieve(from);
|
CargoDataEntry *source_entry = cargo_entry->InsertOrRetrieve(from);
|
||||||
@@ -1680,13 +1682,17 @@ struct StationViewWindow : public Window {
|
|||||||
{
|
{
|
||||||
if (depth <= 128 && Station::IsValidID(next) && Station::IsValidID(source)) {
|
if (depth <= 128 && Station::IsValidID(next) && Station::IsValidID(source)) {
|
||||||
CargoDataEntry tmp;
|
CargoDataEntry tmp;
|
||||||
const FlowStatMap &flowmap = Station::Get(next)->goods[cargo].flows;
|
const GoodsEntry &ge = Station::Get(next)->goods[cargo];
|
||||||
FlowStatMap::const_iterator map_it = flowmap.find(source);
|
|
||||||
if (map_it != flowmap.end()) {
|
if (ge.data != nullptr) {
|
||||||
uint32 prev_count = 0;
|
const FlowStatMap &flowmap = ge.data->flows;
|
||||||
for (FlowStat::const_iterator i = map_it->begin(); i != map_it->end(); ++i) {
|
FlowStatMap::const_iterator map_it = flowmap.find(source);
|
||||||
tmp.InsertOrRetrieve(i->second)->Update(i->first - prev_count);
|
if (map_it != flowmap.end()) {
|
||||||
prev_count = i->first;
|
uint32 prev_count = 0;
|
||||||
|
for (FlowStat::const_iterator i = map_it->begin(); i != map_it->end(); ++i) {
|
||||||
|
tmp.InsertOrRetrieve(i->second)->Update(i->first - prev_count);
|
||||||
|
prev_count = i->first;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1807,9 +1813,9 @@ struct StationViewWindow : public Window {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this->current_mode == MODE_WAITING) {
|
if (this->current_mode == MODE_WAITING) {
|
||||||
this->BuildCargoList(i, st->goods[i].cargo, cargo);
|
this->BuildCargoList(i, st->goods[i].ConstCargoList(), cargo);
|
||||||
} else {
|
} else {
|
||||||
this->BuildFlowList(i, st->goods[i].flows, cargo);
|
this->BuildFlowList(i, st->goods[i].ConstFlows(), cargo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1971,8 +1977,8 @@ struct StationViewWindow : public Window {
|
|||||||
sym = "+";
|
sym = "+";
|
||||||
} else {
|
} else {
|
||||||
/* Only draw '+' if there is something to be shown. */
|
/* Only draw '+' if there is something to be shown. */
|
||||||
const StationCargoList &list = Station::Get(this->window_number)->goods[cargo].cargo;
|
const GoodsEntry &ge = Station::Get(this->window_number)->goods[cargo];
|
||||||
if (grouping == GR_CARGO && (list.ReservedCount() > 0 || cd->HasTransfers())) {
|
if (grouping == GR_CARGO && (ge.CargoReservedCount() > 0 || cd->HasTransfers())) {
|
||||||
sym = "+";
|
sym = "+";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1909,15 +1909,16 @@ class NIHStationStruct : public NIHelper {
|
|||||||
for (const CargoSpec *cs : CargoSpec::Iterate()) {
|
for (const CargoSpec *cs : CargoSpec::Iterate()) {
|
||||||
const GoodsEntry *ge = &st->goods[cs->Index()];
|
const GoodsEntry *ge = &st->goods[cs->Index()];
|
||||||
|
|
||||||
const StationCargoPacketMap *pkts = ge->cargo.Packets();
|
if (ge->data == nullptr && ge->status == 0) {
|
||||||
if (pkts->empty() && ge->status == 0) {
|
|
||||||
/* Nothing of note to show */
|
/* Nothing of note to show */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const StationCargoPacketMap *pkts = ge->data != nullptr ? ge->data->cargo.Packets() : nullptr;
|
||||||
|
|
||||||
seprintf(buffer, lastof(buffer), " Goods entry: %u: %s", cs->Index(), GetStringPtr(cs->name));
|
seprintf(buffer, lastof(buffer), " Goods entry: %u: %s", cs->Index(), GetStringPtr(cs->name));
|
||||||
output.print(buffer);
|
output.print(buffer);
|
||||||
seprintf(buffer, lastof(buffer), " Status: %c%c%c%c%c%c%c",
|
char *b = buffer + seprintf(buffer, lastof(buffer), " Status: %c%c%c%c%c%c%c",
|
||||||
HasBit(ge->status, GoodsEntry::GES_ACCEPTANCE) ? 'a' : '-',
|
HasBit(ge->status, GoodsEntry::GES_ACCEPTANCE) ? 'a' : '-',
|
||||||
HasBit(ge->status, GoodsEntry::GES_RATING) ? 'r' : '-',
|
HasBit(ge->status, GoodsEntry::GES_RATING) ? 'r' : '-',
|
||||||
HasBit(ge->status, GoodsEntry::GES_EVER_ACCEPTED) ? 'e' : '-',
|
HasBit(ge->status, GoodsEntry::GES_EVER_ACCEPTED) ? 'e' : '-',
|
||||||
@@ -1925,15 +1926,17 @@ class NIHStationStruct : public NIHelper {
|
|||||||
HasBit(ge->status, GoodsEntry::GES_CURRENT_MONTH) ? 'c' : '-',
|
HasBit(ge->status, GoodsEntry::GES_CURRENT_MONTH) ? 'c' : '-',
|
||||||
HasBit(ge->status, GoodsEntry::GES_ACCEPTED_BIGTICK) ? 'b' : '-',
|
HasBit(ge->status, GoodsEntry::GES_ACCEPTED_BIGTICK) ? 'b' : '-',
|
||||||
HasBit(ge->status, GoodsEntry::GES_NO_CARGO_SUPPLY) ? 'n' : '-');
|
HasBit(ge->status, GoodsEntry::GES_NO_CARGO_SUPPLY) ? 'n' : '-');
|
||||||
|
if (ge->data != nullptr && ge->data->MayBeRemoved()) b += seprintf(b, lastof(buffer), ", (removable)");
|
||||||
|
if (ge->data == nullptr) b += seprintf(b, lastof(buffer), ", (no data)");
|
||||||
output.print(buffer);
|
output.print(buffer);
|
||||||
|
|
||||||
if (ge->amount_fract > 0) {
|
if (ge->amount_fract > 0) {
|
||||||
seprintf(buffer, lastof(buffer), " Amount fract: %u", ge->amount_fract);
|
seprintf(buffer, lastof(buffer), " Amount fract: %u", ge->amount_fract);
|
||||||
output.print(buffer);
|
output.print(buffer);
|
||||||
}
|
}
|
||||||
if (!pkts->empty()) {
|
if (pkts != nullptr && pkts->MapSize() > 0) {
|
||||||
seprintf(buffer, lastof(buffer), " Cargo packets: %u, available: %u, reserved: %u",
|
seprintf(buffer, lastof(buffer), " Cargo packets: %u, cargo packet keys: %u, available: %u, reserved: %u",
|
||||||
(uint)pkts->size(), ge->cargo.AvailableCount(), ge->cargo.ReservedCount());
|
(uint)pkts->size(), (uint)pkts->MapSize(), ge->CargoAvailableCount(), ge->CargoReservedCount());
|
||||||
output.print(buffer);
|
output.print(buffer);
|
||||||
}
|
}
|
||||||
if (ge->link_graph != INVALID_LINK_GRAPH) {
|
if (ge->link_graph != INVALID_LINK_GRAPH) {
|
||||||
@@ -1944,12 +1947,12 @@ class NIHStationStruct : public NIHelper {
|
|||||||
seprintf(buffer, lastof(buffer), " Max waiting cargo: %u", ge->max_waiting_cargo);
|
seprintf(buffer, lastof(buffer), " Max waiting cargo: %u", ge->max_waiting_cargo);
|
||||||
output.print(buffer);
|
output.print(buffer);
|
||||||
}
|
}
|
||||||
if (ge->flows.size() > 0) {
|
if (ge->data != nullptr && ge->data->flows.size() > 0) {
|
||||||
size_t total_shares = 0;
|
size_t total_shares = 0;
|
||||||
for (const FlowStat &fs : ge->flows) {
|
for (const FlowStat &fs : ge->data->flows) {
|
||||||
total_shares += fs.size();
|
total_shares += fs.size();
|
||||||
}
|
}
|
||||||
seprintf(buffer, lastof(buffer), " Flows: %u, total shares: %u", (uint)ge->flows.size(), (uint)total_shares);
|
seprintf(buffer, lastof(buffer), " Flows: %u, total shares: %u", (uint)ge->data->flows.size(), (uint)total_shares);
|
||||||
output.print(buffer);
|
output.print(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3318,7 +3318,7 @@ void Vehicle::CancelReservation(StationID next, Station *st)
|
|||||||
VehicleCargoList &cargo = v->cargo;
|
VehicleCargoList &cargo = v->cargo;
|
||||||
if (cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) {
|
if (cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) {
|
||||||
DEBUG(misc, 1, "cancelling cargo reservation");
|
DEBUG(misc, 1, "cancelling cargo reservation");
|
||||||
cargo.Return(UINT_MAX, &st->goods[v->cargo_type].cargo, next);
|
cargo.Return(UINT_MAX, &st->goods[v->cargo_type].CreateData().cargo, next);
|
||||||
cargo.SetTransferLoadPlace(st->xy);
|
cargo.SetTransferLoadPlace(st->xy);
|
||||||
}
|
}
|
||||||
cargo.KeepAll();
|
cargo.KeepAll();
|
||||||
|
@@ -307,7 +307,7 @@ void ShowStationViewportTooltip(Window *w, const TileIndex tile)
|
|||||||
SetDParam(0, cs->name);
|
SetDParam(0, cs->name);
|
||||||
SetDParam(1, ToPercent8(goods_entry->rating));
|
SetDParam(1, ToPercent8(goods_entry->rating));
|
||||||
SetDParam(2, cs->Index());
|
SetDParam(2, cs->Index());
|
||||||
SetDParam(3, goods_entry->cargo.TotalCount());
|
SetDParam(3, goods_entry->CargoTotalCount());
|
||||||
msg += GetString(STR_STATION_VIEW_CARGO_LINE_TOOLTIP);
|
msg += GetString(STR_STATION_VIEW_CARGO_LINE_TOOLTIP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user